LLVM: lib/Analysis/CodeMetrics.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

22

23#define DEBUG_TYPE "code-metrics"

24

25using namespace llvm;

26

27static void

31 const User *U = dyn_cast(V);

32 if (!U)

33 return;

34

35 for (const Value *Operand : U->operands())

36 if (Visited.insert(Operand).second)

37 if (const auto *I = dyn_cast(Operand))

38 if (I->mayHaveSideEffects() && I->isTerminator())

40}

41

45

46

47

48

49

50

51

52 for (int i = 0; i < (int)Worklist.size(); ++i) {

53 const Value *V = Worklist[i];

54

56 "Failed to add a worklist entry to our visited set!");

57

58

59 if (all\_of(V->users(), [&](const User *U) { return EphValues.count(U); }))

60 continue;

61

63 LLVM_DEBUG(dbgs() << "Ephemeral Value: " << *V << "\n");

64

65

67 }

68}

69

70

76

77 for (auto &AssumeVH : AC->assumptions()) {

78 if (!AssumeVH)

79 continue;

81

82

83

84

85 if (!L->contains(I->getParent()))

86 continue;

87

88 if (EphValues.insert(I).second)

90 }

91

93}

94

100

101 for (auto &AssumeVH : AC->assumptions()) {

102 if (!AssumeVH)

103 continue;

104 Instruction *I = cast(AssumeVH);

105 assert(I->getParent()->getParent() == F &&

106 "Found assumption for the wrong function!");

107

108 if (EphValues.insert(I).second)

110 }

111

113}

114

116 if (!L)

117 return false;

118 if (!isa(I))

119 return false;

120 for (const auto *U : I.users()) {

121 if (!L->contains(cast(U)))

122 return true;

123 }

124 return false;

125}

126

127

128

132 const Loop *L) {

136

137 if (EphValues.count(&I))

138 continue;

139

140

141 if (const auto *Call = dyn_cast(&I)) {

142 if (const Function *F = Call->getCalledFunction()) {

144

145

146

147

148

149 if (!Call->isNoInline() && IsLoweredToCall &&

150 ((F->hasInternalLinkage() && F->hasOneLiveUse()) ||

151 PrepareForLTO)) {

153 }

154

155

156

157

158

161

162 if (IsLoweredToCall)

164 } else {

165

166

167 if (!Call->isInlineAsm())

169 }

170 }

171

172 if (const AllocaInst *AI = dyn_cast(&I)) {

173 if (!AI->isStaticAlloca())

175 }

176

177 if (isa(I) || I.getType()->isVectorTy())

179

180 if (I.getType()->isTokenTy() && !isa(I) &&

181 I.isUsedOutsideOfBlock(BB)) {

183 << "\n Cannot duplicate a token value used outside "

184 "the current block (except convergence control).\n");

186 }

187

188 if (const CallBase *CB = dyn_cast(&I)) {

189 if (CB->cannotDuplicate())

191

192

193

194

195 if (Convergence <= ConvergenceKind::Controlled && CB->isConvergent()) {

196 if (isa(CB) ||

197 CB->getConvergenceControlToken()) {

199 LLVM_DEBUG(dbgs() << "Found controlled convergence:\n" << I << "\n");

202 else {

205 }

206 } else {

209 }

210 }

211 }

212

214 }

215

218

219

220

221

222

223

224

225

226

227

228

229

231

232

235}

static bool extendsConvergenceOutsideLoop(const Instruction &I, const Loop *L)

static void appendSpeculatableOperands(const Value *V, SmallPtrSetImpl< const Value * > &Visited, SmallVectorImpl< const Value * > &Worklist)

static void completeEphemeralValues(SmallPtrSetImpl< const Value * > &Visited, SmallVectorImpl< const Value * > &Worklist, SmallPtrSetImpl< const Value * > &EphValues)

This file defines an InstructionCost class that is used when calculating the cost of an instruction,...

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

This file defines the SmallPtrSet class.

This pass exposes codegen information to IR-level passes.

an instruction to allocate memory on the stack

A cache of @llvm.assume calls within a function.

MutableArrayRef< ResultElem > assumptions()

Access the list of assumption handles currently tracked for this function.

LLVM Basic Block Representation.

const Function * getParent() const

Return the enclosing method, or null if none.

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

Represents a single loop in the control flow graph.

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

size_type count(ConstPtrType Ptr) const

count - Return 1 if the specified pointer is in the set, 0 otherwise.

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

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

This pass provides access to the codegen interfaces that are needed for IR-level transformations.

@ TCK_CodeSize

Instruction code size.

bool isLoweredToCall(const Function *F) const

Test whether calls to a function lower to actual program function calls.

InstructionCost getInstructionCost(const User *U, ArrayRef< const Value * > Operands, TargetCostKind CostKind) const

Estimate the cost of a given IR user when lowered.

LLVM Value Representation.

This is an optimization pass for GlobalISel generic memory operations.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

bool usesDynamicAlloca

True if this function calls alloca (in the C sense).

unsigned NumBlocks

Number of analyzed blocks.

ConvergenceKind Convergence

The kind of convergence specified in this function.

bool notDuplicatable

True if this function cannot be duplicated.

unsigned NumInlineCandidates

The number of calls to internal functions with a single caller.

bool isRecursive

True if this function calls itself.

static void collectEphemeralValues(const Loop *L, AssumptionCache *AC, SmallPtrSetImpl< const Value * > &EphValues)

Collect a loop's ephemeral values (those used only by an assume or similar intrinsics in the loop).

unsigned NumRets

How many 'ret' instructions the blocks contain.

DenseMap< const BasicBlock *, InstructionCost > NumBBInsts

Keeps track of basic block code size estimates.

void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI, const SmallPtrSetImpl< const Value * > &EphValues, bool PrepareForLTO=false, const Loop *L=nullptr)

Add information about a block to the current state.

unsigned NumCalls

Keep track of the number of calls to 'big' functions.

unsigned NumVectorInsts

How many instructions produce vector values.

InstructionCost NumInsts

Code size cost of the analyzed blocks.