LLVM  8.0.1
EntryExitInstrumenter.cpp
Go to the documentation of this file.
1 //===- EntryExitInstrumenter.cpp - Function Entry/Exit Instrumentation ----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/Instructions.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/IR/Type.h"
17 #include "llvm/Pass.h"
18 #include "llvm/Transforms/Utils.h"
19 using namespace llvm;
20 
21 static void insertCall(Function &CurFn, StringRef Func,
22  Instruction *InsertionPt, DebugLoc DL) {
23  Module &M = *InsertionPt->getParent()->getParent()->getParent();
24  LLVMContext &C = InsertionPt->getParent()->getContext();
25 
26  if (Func == "mcount" ||
27  Func == ".mcount" ||
28  Func == "\01__gnu_mcount_nc" ||
29  Func == "\01_mcount" ||
30  Func == "\01mcount" ||
31  Func == "__mcount" ||
32  Func == "_mcount" ||
33  Func == "__cyg_profile_func_enter_bare") {
35  CallInst *Call = CallInst::Create(Fn, "", InsertionPt);
36  Call->setDebugLoc(DL);
37  return;
38  }
39 
40  if (Func == "__cyg_profile_func_enter" || Func == "__cyg_profile_func_exit") {
41  Type *ArgTypes[] = {Type::getInt8PtrTy(C), Type::getInt8PtrTy(C)};
42 
44  Func, FunctionType::get(Type::getVoidTy(C), ArgTypes, false));
45 
46  Instruction *RetAddr = CallInst::Create(
49  InsertionPt);
50  RetAddr->setDebugLoc(DL);
51 
53  RetAddr};
54 
55  CallInst *Call =
56  CallInst::Create(Fn, ArrayRef<Value *>(Args), "", InsertionPt);
57  Call->setDebugLoc(DL);
58  return;
59  }
60 
61  // We only know how to call a fixed set of instrumentation functions, because
62  // they all expect different arguments, etc.
63  report_fatal_error(Twine("Unknown instrumentation function: '") + Func + "'");
64 }
65 
66 static bool runOnFunction(Function &F, bool PostInlining) {
67  StringRef EntryAttr = PostInlining ? "instrument-function-entry-inlined"
68  : "instrument-function-entry";
69 
70  StringRef ExitAttr = PostInlining ? "instrument-function-exit-inlined"
71  : "instrument-function-exit";
72 
73  StringRef EntryFunc = F.getFnAttribute(EntryAttr).getValueAsString();
74  StringRef ExitFunc = F.getFnAttribute(ExitAttr).getValueAsString();
75 
76  bool Changed = false;
77 
78  // If the attribute is specified, insert instrumentation and then "consume"
79  // the attribute so that it's not inserted again if the pass should happen to
80  // run later for some reason.
81 
82  if (!EntryFunc.empty()) {
83  DebugLoc DL;
84  if (auto SP = F.getSubprogram())
85  DL = DebugLoc::get(SP->getScopeLine(), 0, SP);
86 
87  insertCall(F, EntryFunc, &*F.begin()->getFirstInsertionPt(), DL);
88  Changed = true;
90  }
91 
92  if (!ExitFunc.empty()) {
93  for (BasicBlock &BB : F) {
94  Instruction *T = BB.getTerminator();
95  if (!isa<ReturnInst>(T))
96  continue;
97 
98  // If T is preceded by a musttail call, that's the real terminator.
99  Instruction *Prev = T->getPrevNode();
100  if (BitCastInst *BCI = dyn_cast_or_null<BitCastInst>(Prev))
101  Prev = BCI->getPrevNode();
102  if (CallInst *CI = dyn_cast_or_null<CallInst>(Prev)) {
103  if (CI->isMustTailCall())
104  T = CI;
105  }
106 
107  DebugLoc DL;
108  if (DebugLoc TerminatorDL = T->getDebugLoc())
109  DL = TerminatorDL;
110  else if (auto SP = F.getSubprogram())
111  DL = DebugLoc::get(0, 0, SP);
112 
113  insertCall(F, ExitFunc, T, DL);
114  Changed = true;
115  }
116  F.removeAttribute(AttributeList::FunctionIndex, ExitAttr);
117  }
118 
119  return Changed;
120 }
121 
122 namespace {
123 struct EntryExitInstrumenter : public FunctionPass {
124  static char ID;
125  EntryExitInstrumenter() : FunctionPass(ID) {
127  }
128  void getAnalysisUsage(AnalysisUsage &AU) const override {
130  }
131  bool runOnFunction(Function &F) override { return ::runOnFunction(F, false); }
132 };
134 
135 struct PostInlineEntryExitInstrumenter : public FunctionPass {
136  static char ID;
137  PostInlineEntryExitInstrumenter() : FunctionPass(ID) {
140  }
141  void getAnalysisUsage(AnalysisUsage &AU) const override {
143  }
144  bool runOnFunction(Function &F) override { return ::runOnFunction(F, true); }
145 };
147 }
148 
150  EntryExitInstrumenter, "ee-instrument",
151  "Instrument function entry/exit with calls to e.g. mcount() (pre inlining)",
152  false, false)
153 INITIALIZE_PASS(PostInlineEntryExitInstrumenter, "post-inline-ee-instrument",
154  "Instrument function entry/exit with calls to e.g. mcount() "
155  "(post inlining)",
157 
159  return new EntryExitInstrumenter();
160 }
161 
163  return new PostInlineEntryExitInstrumenter();
164 }
165 
168  runOnFunction(F, PostInlining);
170  PA.preserveSet<CFGAnalyses>();
171  return PA;
172 }
Legacy wrapper pass to provide the GlobalsAAResult object.
void initializeEntryExitInstrumenterPass(PassRegistry &)
uint64_t CallInst * C
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:22
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:24
post inline ee instrument
This is the interface for a simple mod/ref and alias analysis over globals.
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:144
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
This class represents a function call, abstracting a target machine&#39;s calling convention.
static void insertCall(Function &CurFn, StringRef Func, Instruction *InsertionPt, DebugLoc DL)
A debug info location.
Definition: DebugLoc.h:34
F(f)
post inline ee Instrument function entry exit with calls to e g mcount() " "(post inlining)"
LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition: BasicBlock.cpp:33
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
This class represents a no-op cast from one type to another.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
iterator begin()
Definition: Function.h:656
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1020
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:1773
static bool runOnFunction(Function &F, bool PostInlining)
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:154
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:308
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
DISubprogram * getSubprogram() const
Get the attached subprogram.
Definition: Metadata.cpp:1508
This is an important base class in LLVM.
Definition: Constant.h:42
amdgpu inline
void removeAttribute(unsigned i, Attribute::AttrKind Kind)
removes the attribute from the list of attributes.
Definition: Function.cpp:404
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:161
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:297
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:220
TargetPassConfig.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Module.h This file contains the declarations for the Module class.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:622
FunctionPass * createPostInlineEntryExitInstrumenterPass()
Represents analyses that only rely on functions&#39; control flow.
Definition: PassManager.h:115
INITIALIZE_PASS(EntryExitInstrumenter, "ee-instrument", "Instrument function entry/exit with calls to e.g. mcount() (pre inlining)", false, false) INITIALIZE_PASS(PostInlineEntryExitInstrumenter
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:311
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:176
StringRef getValueAsString() const
Return the attribute&#39;s value as a string.
Definition: Attributes.cpp:195
void preserveSet()
Mark an analysis set as preserved.
Definition: PassManager.h:190
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:107
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:566
LLVM Value Representation.
Definition: Value.h:73
amdgpu Simplify well known AMD library calls
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:331
print Print MemDeps of function
print Instructions which execute on loop entry
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
A container for analyses that lazily runs them and caches their results.
FunctionPass * createEntryExitInstrumenterPass()
void initializePostInlineEntryExitInstrumenterPass(PassRegistry &)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
const BasicBlock * getParent() const
Definition: Instruction.h:67