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 (->isIntrinsic() &&
->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 (.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() && .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)