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

1

2

3

4

5

6

7

8

9

10

11

12

13

25

26using namespace llvm;

27

28#define DEBUG_TYPE "kernel-info"

29

30namespace {

31

32

35

36public:

39

40

41 bool ExternalNotKernel = false;

42

43

45

46

47

48

49

50

51

52

53 int64_t Allocas = 0;

54 int64_t AllocasDyn = 0;

55 int64_t AllocasStaticSizeSum = 0;

56

57

58 int64_t DirectCalls = 0;

59 int64_t IndirectCalls = 0;

60

61

62

63 int64_t DirectCallsToDefinedFunctions = 0;

64

65

66 int64_t InlineAssemblyCalls = 0;

67

68

69 int64_t Invokes = 0;

70

71

72 unsigned FlatAddrspace;

73

74

75 int64_t FlatAddrspaceAccesses = 0;

76};

77

78}

79

82 SmallString<100> Name;

84 if (auto *SubProgram = F->getSubprogram()) {

85 if (SubProgram->isArtificial())

86 R << "artificial ";

87 Name = SubProgram->getName();

88 }

89 }

90 if (Name.empty()) {

92 V->printAsOperand(OS, false, M);

93 }

94 if (!Kind.empty())

95 R << Kind << " ";

96 R << "'" << Name << "'";

97}

98

102

106 ORE.emit([&] {

109 bool Artificial = false;

111 if (!DVRs.empty()) {

115 Artificial = DVR.Variable->isArtificial();

116 }

119 R << "in ";

121 R << ", ";

122 if (Artificial)

123 R << "artificial ";

126 Alloca.printAsOperand(OS, false, Caller.getParent());

127 R << "alloca ('" << ValName << "') ";

128 if (!DbgName.empty())

129 R << "for '" << DbgName << "' ";

130 else

131 R << "without debug info ";

132 R << "with ";

133 if (StaticSize)

134 R << "static size of " << itostr(StaticSize) << " bytes";

135 else

136 R << "dynamic size";

137 return R;

138 });

139}

140

144 ORE.emit([&] {

146 R << "in ";

148 R << ", " << CallKind << ", callee is ";

150 return R;

151 });

152}

153

157 ORE.emit([&] {

159 R << "in ";

162 R << ", '" << II->getCalledFunction()->getName() << "' call";

163 } else {

164 R << ", '" << Inst.getOpcodeName() << "' instruction";

165 }

169 Inst.printAsOperand(OS, false, Caller.getParent());

170 R << " ('" << Name << "')";

171 }

172 R << " accesses memory in flat address space";

173 return R;

174 });

175}

176

177void KernelInfo::updateForBB(const BasicBlock &BB,

180 const Module &M = *F.getParent();

181 const DataLayout &DL = M.getDataLayout();

184 ++Allocas;

185 TypeSize::ScalarTy StaticSize = 0;

186 if (std::optional Size = Alloca->getAllocationSize(DL)) {

187 StaticSize = Size->getFixedValue();

189 (TypeSize::ScalarTy)std::numeric_limits<int64_t>::max());

190 AllocasStaticSizeSum += StaticSize;

191 } else {

192 ++AllocasDyn;

193 }

196 SmallString<40> CallKind;

197 SmallString<40> RemarkKind;

199 ++IndirectCalls;

200 CallKind += "indirect";

201 RemarkKind += "Indirect";

202 } else {

203 ++DirectCalls;

204 CallKind += "direct";

205 RemarkKind += "Direct";

206 }

208 ++Invokes;

209 CallKind += " invoke";

210 RemarkKind += "Invoke";

211 } else {

212 CallKind += " call";

213 RemarkKind += "Call";

214 }

217 if (Callee->isIntrinsic() && Callee->isDeclaration()) {

218 ++DirectCallsToDefinedFunctions;

219 CallKind += " to defined function";

220 RemarkKind += "ToDefinedFunction";

221 }

223 ++InlineAssemblyCalls;

224 CallKind += " to inline assembly";

225 RemarkKind += "ToInlineAssembly";

226 }

227 }

230 if (MI->getDestAddressSpace() == FlatAddrspace) {

231 ++FlatAddrspaceAccesses;

233 } else if (const AnyMemTransferInst *MT =

235 if (MT->getSourceAddressSpace() == FlatAddrspace) {

236 ++FlatAddrspaceAccesses;

238 }

239 }

240 }

242 if (Load->getPointerAddressSpace() == FlatAddrspace) {

243 ++FlatAddrspaceAccesses;

245 }

247 if (Store->getPointerAddressSpace() == FlatAddrspace) {

248 ++FlatAddrspaceAccesses;

250 }

252 if (At->getPointerAddressSpace() == FlatAddrspace) {

253 ++FlatAddrspaceAccesses;

255 }

257 if (At->getPointerAddressSpace() == FlatAddrspace) {

258 ++FlatAddrspaceAccesses;

260 }

261 }

262 }

263}

264

267 ORE.emit([&] {

269 R << "in ";

271 R << ", " << Name << " = " << itostr(Value);

272 return R;

273 });

274}

275

278 if (F.hasFnAttribute(Name))

279 return std::nullopt;

280 return F.getFnAttributeAsParsedInteger(Name);

281}

282

284 TargetMachine *TM) {

285 KernelInfo KI;

286 TargetTransformInfo &TheTTI = FAM.getResult(F);

288

289

290 KI.ExternalNotKernel = F.hasExternalLinkage() && F.hasKernelCallingConv();

291 for (StringRef Name : {"omp_target_num_teams", "omp_target_thread_limit"}) {

293 KI.LaunchBounds.push_back({Name, *Val});

294 }

296

297 auto &ORE = FAM.getResult(F);

298 for (const auto &BB : F)

299 KI.updateForBB(BB, ORE);

300

301#define REMARK_PROPERTY(PROP_NAME) \

302 remarkProperty(ORE, F, #PROP_NAME, KI.PROP_NAME)

304 for (auto LB : KI.LaunchBounds)

315#undef REMARK_PROPERTY

316}

317

320

321 if (F.getContext().getDiagHandlerPtr()->isPassedOptRemarkEnabled(DEBUG_TYPE))

322 KernelInfo::emitKernelInfo(F, AM, TM);

324}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Module.h This file contains the declarations for the Module class.

This header defines various interfaces for pass management in LLVM.

static void remarkCall(OptimizationRemarkEmitter &ORE, const Function &Caller, const CallBase &Call, StringRef CallKind, StringRef RemarkKind)

Definition KernelInfo.cpp:141

static void remarkAlloca(OptimizationRemarkEmitter &ORE, const Function &Caller, const AllocaInst &Alloca, TypeSize::ScalarTy StaticSize)

Definition KernelInfo.cpp:103

static std::optional< int64_t > parseFnAttrAsInteger(Function &F, StringRef Name)

Definition KernelInfo.cpp:276

static void remarkProperty(OptimizationRemarkEmitter &ORE, const Function &F, StringRef Name, int64_t Value)

Definition KernelInfo.cpp:265

static void remarkFlatAddrspaceAccess(OptimizationRemarkEmitter &ORE, const Function &Caller, const Instruction &Inst)

Definition KernelInfo.cpp:154

#define REMARK_PROPERTY(PROP_NAME)

static void identifyCallee(OptimizationRemark &R, const Module *M, const Value *V, StringRef Kind="")

Definition KernelInfo.cpp:80

static void identifyFunction(OptimizationRemark &R, const Function &F)

Definition KernelInfo.cpp:99

Machine Check Debug Module

uint64_t IntrinsicInst * II

FunctionAnalysisManager FAM

This file defines the SmallString class.

This pass exposes codegen information to IR-level passes.

an instruction to allocate memory on the stack

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

LLVM Basic Block Representation.

const Function * getParent() const

Return the enclosing method, or null if none.

LLVM_ABI iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const

Return a const iterator range over the instructions in the block, skipping any debug instructions.

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

bool isInlineAsm() const

Check if this call is an inline asm statement.

Function * getCalledFunction() const

Returns the function called, or null if this is an indirect function invocation or the function signa...

LLVM_ABI bool isIndirectCall() const

Return true if the callsite is an indirect call.

StringRef getName() const

DebugLoc getDebugLoc() const

Record of a variable value-assignment, aka a non instruction representation of the dbg....

DbgRecordParamRef< DILocalVariable > Variable

DILocalVariable * getVariable() const

const char * getOpcodeName() const

A wrapper class for inspecting calls to intrinsic functions.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

Definition KernelInfo.cpp:318

A Module instance is used to store all the information related to an LLVM module.

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

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

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

Primary interface to the complete machine description for the target machine.

LLVM_ABI unsigned getFlatAddressSpace() const

Returns the address space ID for a target's 'flat' address space.

LLVM_ABI void collectKernelLaunchBounds(const Function &F, SmallVectorImpl< std::pair< StringRef, int64_t > > &LB) const

Collect kernel launch bounds for F into LB.

bool isVoidTy() const

Return true if this is 'void'.

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const

Print the name of this Value out to the specified raw_ostream.

const ParentTy * getParent() const

A raw_ostream that writes to an SmallVector or SmallString.

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI TinyPtrVector< DbgVariableRecord * > findDVRDeclares(Value *V)

Finds dbg.declare records declaring local variables as living in the memory that 'V' points to.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

std::string itostr(int64_t X)