LLVM: lib/Transforms/Utils/MisExpect.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

41#include

42#include

43#include

44#include

45

46#define DEBUG_TYPE "misexpect"

47

48using namespace llvm;

49using namespace misexpect;

50

51namespace llvm {

52

53

54

57 cl::desc("Use this option to turn on/off "

58 "warnings about incorrect usage of llvm.expect intrinsics."));

59

60

62 "misexpect-tolerance", cl::init(0),

63 cl::desc("Prevents emitting diagnostics when profile counts are "

64 "within N% of the threshold.."));

65

66}

67

68namespace {

69

70bool isMisExpectDiagEnabled(LLVMContext &Ctx) {

72}

73

77}

78

80 assert(I != nullptr && "MisExpect target Instruction cannot be nullptr");

82 if (auto *B = dyn_cast(I)) {

83 Ret = dyn_cast(B->getCondition());

84 }

85

86

87

88

89

90

91

92

93

94 else if (auto *S = dyn_cast(I)) {

95 Ret = dyn_cast(S->getCondition());

96 }

98}

99

102 double PercentageCorrect = (double)ProfCount / TotalCount;

103 auto PerString =

104 formatv("{0:P} ({1} / {2})", PercentageCorrect, ProfCount, TotalCount);

106 "Potential performance regression from use of the llvm.expect intrinsic: "

107 "Annotation was correct on {0} of profiled executions.",

108 PerString);

109 Twine Msg(PerString);

111 if (isMisExpectDiagEnabled(Ctx))

115}

116

117}

118

119namespace llvm {

120namespace misexpect {

121

124

125

126

127

128

131 size_t MaxIndex = 0;

136 MaxIndex = Idx;

137 }

140 }

141 }

142

143 const uint64_t ProfiledWeight = RealWeights[MaxIndex];

144 const uint64_t RealWeightsTotal =

145 std::accumulate(RealWeights.begin(), RealWeights.end(), (uint64_t)0,

146 std::plus<uint64_t>());

147 const uint64_t NumUnlikelyTargets = RealWeights.size() - 1;

148

151

152

154 "TotalBranchWeight is less than the Likely branch weight");

155

156

157

158

161

162 uint64_t ScaledThreshold = LikelyProbablilty.scale(RealWeightsTotal);

163

164

165 auto Tolerance = getMisExpectTolerance(I.getContext());

166 Tolerance = std::clamp(Tolerance, 0u, 99u);

167

168

169

170 if (Tolerance > 0)

171 ScaledThreshold *= (1.0 - Tolerance / 100.0);

172

173

174 if (ProfiledWeight < ScaledThreshold)

175 emitMisexpectDiagnostic(&I, I.getContext(), ProfiledWeight,

176 RealWeightsTotal);

177}

178

181

182

183

184

185

187 return;

190 return;

192}

193

198 return;

200}

201

204 bool IsFrontend) {

205 if (IsFrontend) {

207 } else {

209 }

210}

211

212}

213}

214#undef DEBUG_TYPE

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

static cl::opt< uint32_t > UnlikelyBranchWeight("unlikely-branch-weight", cl::Hidden, cl::init(1), cl::desc("Weight of the branch unlikely to be taken (default = 1)"))

static cl::opt< uint32_t > LikelyBranchWeight("likely-branch-weight", cl::Hidden, cl::init(2000), cl::desc("Weight of the branch likely to be taken (default = 2000)"))

This file contains the declarations for profiling metadata utility functions.

const SmallVectorImpl< MachineOperand > & Cond

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

static BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)

Diagnostic information for MisExpect analysis.

This is an important class for using LLVM in a threaded context.

bool getMisExpectWarningRequested() const

void diagnose(const DiagnosticInfo &DI)

Report a message to the currently installed diagnostic handler.

uint32_t getDiagnosticsMisExpectTolerance() const

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

initializer< Ty > init(const Ty &Val)

void checkFrontendInstrumentation(Instruction &I, const ArrayRef< uint32_t > ExpectedWeights)

checkFrontendInstrumentation - compares PGO counters to the thresholds used for llvm....

void checkExpectAnnotations(Instruction &I, const ArrayRef< uint32_t > ExistingWeights, bool IsFrontend)

checkExpectAnnotations - compares PGO counters to the thresholds used for llvm.expect and warns if th...

void checkBackendInstrumentation(Instruction &I, const llvm::ArrayRef< uint32_t > RealWeights)

checkBackendInstrumentation - compares PGO counters to the thresholds used for llvm....

void verifyMisExpect(Instruction &I, ArrayRef< uint32_t > RealWeights, const ArrayRef< uint32_t > ExpectedWeights)

veryifyMisExpect - compares RealWeights to the thresholds used for llvm.expect and warns if the PGO c...

This is an optimization pass for GlobalISel generic memory operations.

static cl::opt< bool > PGOWarnMisExpect("pgo-warn-misexpect", cl::init(false), cl::Hidden, cl::desc("Use this option to turn on/off " "warnings about incorrect usage of llvm.expect intrinsics."))

bool hasBranchWeightOrigin(const Instruction &I)

Check if Branch Weight Metadata has an "expected" field from an llvm.expect* intrinsic.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

static cl::opt< uint32_t > MisExpectTolerance("misexpect-tolerance", cl::init(0), cl::desc("Prevents emitting diagnostics when profile counts are " "within N% of the threshold.."))

bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)

Extract branch weights from MD_prof metadata.