LLVM  10.0.0svn
EntryExitInstrumenter.cpp
Go to the documentation of this file.
1 //===- EntryExitInstrumenter.cpp - Function Entry/Exit Instrumentation ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
12 #include "llvm/IR/Function.h"
13 #include "llvm/IR/Instructions.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/IR/Type.h"
16 #include "llvm/Pass.h"
17 #include "llvm/Transforms/Utils.h"
18 using namespace llvm;
19 
20 static void insertCall(Function &CurFn, StringRef Func,
21  Instruction *InsertionPt, DebugLoc DL) {
22  Module &M = *InsertionPt->getParent()->getParent()->getParent();
23  LLVMContext &C = InsertionPt->getParent()->getContext();
24 
25  if (Func == "mcount" ||
26  Func == ".mcount" ||
27  Func == "llvm.arm.gnu.eabi.mcount" ||
28  Func == "\01_mcount" ||
29  Func == "\01mcount" ||
30  Func == "__mcount" ||
31  Func == "_mcount" ||
32  Func == "__cyg_profile_func_enter_bare") {
34  CallInst *Call = CallInst::Create(Fn, "", InsertionPt);
35  Call->setDebugLoc(DL);
36  return;
37  }
38 
39  if (Func == "__cyg_profile_func_enter" || Func == "__cyg_profile_func_exit") {
40  Type *ArgTypes[] = {Type::getInt8PtrTy(C), Type::getInt8PtrTy(C)};
41 
43  Func, FunctionType::get(Type::getVoidTy(C), ArgTypes, false));
44 
45  Instruction *RetAddr = CallInst::Create(
46  Intrinsic::getDeclaration(&M, Intrinsic::returnaddress),
48  InsertionPt);
49  RetAddr->setDebugLoc(DL);
50 
52  RetAddr};
53 
54  CallInst *Call =
55  CallInst::Create(Fn, ArrayRef<Value *>(Args), "", InsertionPt);
56  Call->setDebugLoc(DL);
57  return;
58  }
59 
60  // We only know how to call a fixed set of instrumentation functions, because
61  // they all expect different arguments, etc.
62  report_fatal_error(Twine("Unknown instrumentation function: '") + Func + "'");
63 }
64 
65 static bool runOnFunction(Function &F, bool PostInlining) {
66  StringRef EntryAttr = PostInlining ? "instrument-function-entry-inlined"
67  : "instrument-function-entry";
68 
69  StringRef ExitAttr = PostInlining ? "instrument-function-exit-inlined"
70  : "instrument-function-exit";
71 
72  StringRef EntryFunc = F.getFnAttribute(EntryAttr).getValueAsString();
73  StringRef ExitFunc = F.getFnAttribute(ExitAttr).getValueAsString();
74 
75  bool Changed = false;
76 
77  // If the attribute is specified, insert instrumentation and then "consume"
78  // the attribute so that it's not inserted again if the pass should happen to
79  // run later for some reason.
80 
81  if (!EntryFunc.empty()) {
82  DebugLoc DL;
83  if (auto SP = F.getSubprogram())
84  DL = DebugLoc::get(SP->getScopeLine(), 0, SP);
85 
86  insertCall(F, EntryFunc, &*F.begin()->getFirstInsertionPt(), DL);
87  Changed = true;
89  }
90 
91  if (!ExitFunc.empty()) {
92  for (BasicBlock &BB : F) {
93  Instruction *T = BB.getTerminator();
94  if (!isa<ReturnInst>(T))
95  continue;
96 
97  // If T is preceded by a musttail call, that's the real terminator.
98  Instruction *Prev = T->getPrevNode();
99  if (BitCastInst *BCI = dyn_cast_or_null<BitCastInst>(Prev))
100  Prev = BCI->getPrevNode();
101  if (CallInst *CI = dyn_cast_or_null<CallInst>(Prev)) {
102  if (CI->isMustTailCall())
103  T = CI;
104  }
105 
106  DebugLoc DL;
107  if (DebugLoc TerminatorDL = T->getDebugLoc())
108  DL = TerminatorDL;
109  else if (auto SP = F.getSubprogram())
110  DL = DebugLoc::get(0, 0, SP);
111 
112  insertCall(F, ExitFunc, T, DL);
113  Changed = true;
114  }
115  F.removeAttribute(AttributeList::FunctionIndex, ExitAttr);
116  }
117 
118  return Changed;
119 }
120 
121 namespace {
122 struct EntryExitInstrumenter : public FunctionPass {
123  static char ID;
124  EntryExitInstrumenter() : FunctionPass(ID) {
126  }
127  void getAnalysisUsage(AnalysisUsage &AU) const override {
129  }
130  bool runOnFunction(Function &F) override { return ::runOnFunction(F, false); }
131 };
133 
134 struct PostInlineEntryExitInstrumenter : public FunctionPass {
135  static char ID;
136  PostInlineEntryExitInstrumenter() : FunctionPass(ID) {
139  }
140  void getAnalysisUsage(AnalysisUsage &AU) const override {
142  }
143  bool runOnFunction(Function &F) override { return ::runOnFunction(F, true); }
144 };
146 }
147 
149  EntryExitInstrumenter, "ee-instrument",
150  "Instrument function entry/exit with calls to e.g. mcount() (pre inlining)",
151  false, false)
152 INITIALIZE_PASS(PostInlineEntryExitInstrumenter, "post-inline-ee-instrument",
153  "Instrument function entry/exit with calls to e.g. mcount() "
154  "(post inlining)",
156 
158  return new EntryExitInstrumenter();
159 }
160 
162  return new PostInlineEntryExitInstrumenter();
163 }
164 
167  runOnFunction(F, PostInlining);
169  PA.preserveSet<CFGAnalyses>();
170  return PA;
171 }
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:21
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:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
post inline ee instrument
This is the interface for a simple mod/ref and alias analysis over globals.
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:66
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:170
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:33
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:32
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:140
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:32
iterator begin()
Definition: Function.h:685
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:1093
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:1804
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:328
LLVM Basic Block Representation.
Definition: BasicBlock.h:57
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:64
DISubprogram * getSubprogram() const
Get the attached subprogram.
Definition: Metadata.cpp:1522
amdgpu inline
void removeAttribute(unsigned i, Attribute::AttrKind Kind)
removes the attribute from the list of attributes.
Definition: Function.cpp:417
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:165
constexpr double e
Definition: MathExtras.h:57
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:301
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:224
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:653
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:143
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:331
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:180
StringRef getValueAsString() const
Return the attribute&#39;s value as a string.
Definition: Attributes.cpp:220
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:106
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:575
LLVM Value Representation.
Definition: Value.h:74
amdgpu Simplify well known AMD library calls
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:333
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:48
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:66