LLVM  7.0.0svn
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 
12 #include "llvm/CodeGen/Passes.h"
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/Type.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Transforms/Scalar.h"
20 using namespace llvm;
21 
22 static void insertCall(Function &CurFn, StringRef Func,
23  Instruction *InsertionPt, DebugLoc DL) {
24  Module &M = *InsertionPt->getParent()->getParent()->getParent();
25  LLVMContext &C = InsertionPt->getParent()->getContext();
26 
27  if (Func == "mcount" ||
28  Func == ".mcount" ||
29  Func == "\01__gnu_mcount_nc" ||
30  Func == "\01_mcount" ||
31  Func == "\01mcount" ||
32  Func == "__mcount" ||
33  Func == "_mcount" ||
34  Func == "__cyg_profile_func_enter_bare") {
36  CallInst *Call = CallInst::Create(Fn, "", InsertionPt);
37  Call->setDebugLoc(DL);
38  return;
39  }
40 
41  if (Func == "__cyg_profile_func_enter" || Func == "__cyg_profile_func_exit") {
42  Type *ArgTypes[] = {Type::getInt8PtrTy(C), Type::getInt8PtrTy(C)};
43 
45  Func, FunctionType::get(Type::getVoidTy(C), ArgTypes, false));
46 
47  Instruction *RetAddr = CallInst::Create(
48  Intrinsic::getDeclaration(&M, Intrinsic::returnaddress),
50  InsertionPt);
51  RetAddr->setDebugLoc(DL);
52 
54  RetAddr};
55 
56  CallInst *Call =
57  CallInst::Create(Fn, ArrayRef<Value *>(Args), "", InsertionPt);
58  Call->setDebugLoc(DL);
59  return;
60  }
61 
62  // We only know how to call a fixed set of instrumentation functions, because
63  // they all expect different arguments, etc.
64  report_fatal_error(Twine("Unknown instrumentation function: '") + Func + "'");
65 }
66 
67 static bool runOnFunction(Function &F, bool PostInlining) {
68  StringRef EntryAttr = PostInlining ? "instrument-function-entry-inlined"
69  : "instrument-function-entry";
70 
71  StringRef ExitAttr = PostInlining ? "instrument-function-exit-inlined"
72  : "instrument-function-exit";
73 
74  StringRef EntryFunc = F.getFnAttribute(EntryAttr).getValueAsString();
75  StringRef ExitFunc = F.getFnAttribute(ExitAttr).getValueAsString();
76 
77  bool Changed = false;
78 
79  // If the attribute is specified, insert instrumentation and then "consume"
80  // the attribute so that it's not inserted again if the pass should happen to
81  // run later for some reason.
82 
83  if (!EntryFunc.empty()) {
84  DebugLoc DL;
85  if (auto SP = F.getSubprogram())
86  DL = DebugLoc::get(SP->getScopeLine(), 0, SP);
87 
88  insertCall(F, EntryFunc, &*F.begin()->getFirstInsertionPt(), DL);
89  Changed = true;
91  }
92 
93  if (!ExitFunc.empty()) {
94  for (BasicBlock &BB : F) {
95  TerminatorInst *T = BB.getTerminator();
96  DebugLoc DL;
97  if (DebugLoc TerminatorDL = T->getDebugLoc())
98  DL = TerminatorDL;
99  else if (auto SP = F.getSubprogram())
100  DL = DebugLoc::get(0, 0, SP);
101 
102  if (isa<ReturnInst>(T)) {
103  insertCall(F, ExitFunc, T, DL);
104  Changed = true;
105  }
106  }
107  F.removeAttribute(AttributeList::FunctionIndex, ExitAttr);
108  }
109 
110  return Changed;
111 }
112 
113 namespace {
114 struct EntryExitInstrumenter : public FunctionPass {
115  static char ID;
116  EntryExitInstrumenter() : FunctionPass(ID) {
118  }
119  void getAnalysisUsage(AnalysisUsage &AU) const override {
121  }
122  bool runOnFunction(Function &F) override { return ::runOnFunction(F, false); }
123 };
125 
126 struct PostInlineEntryExitInstrumenter : public FunctionPass {
127  static char ID;
128  PostInlineEntryExitInstrumenter() : FunctionPass(ID) {
131  }
132  void getAnalysisUsage(AnalysisUsage &AU) const override {
134  }
135  bool runOnFunction(Function &F) override { return ::runOnFunction(F, true); }
136 };
138 }
139 
141  EntryExitInstrumenter, "ee-instrument",
142  "Instrument function entry/exit with calls to e.g. mcount() (pre inlining)",
143  false, false)
144 INITIALIZE_PASS(PostInlineEntryExitInstrumenter, "post-inline-ee-instrument",
145  "Instrument function entry/exit with calls to e.g. mcount() "
146  "(post inlining)",
148 
150  return new EntryExitInstrumenter();
151 }
152 
154  return new PostInlineEntryExitInstrumenter();
155 }
156 
159  runOnFunction(F, PostInlining);
161  PA.preserveSet<CFGAnalyses>();
162  return PA;
163 }
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:115
Compute iterated dominance frontiers using a linear time algorithm.
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:142
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
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)
static CallInst * Create(Value *Func, ArrayRef< Value *> Args, ArrayRef< OperandBundleDef > Bundles=None, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
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
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
iterator begin()
Definition: Function.h:634
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:980
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:1727
static bool runOnFunction(Function &F, bool PostInlining)
Subclasses of this class are all able to terminate a basic block.
Definition: InstrTypes.h:55
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:153
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:282
LLVM Basic Block Representation.
Definition: BasicBlock.h:59
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:1505
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:383
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:598
FunctionPass * createPostInlineEntryExitInstrumenterPass()
Represents analyses that only rely on functions&#39; control flow.
Definition: PassManager.h:114
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:285
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:189
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:108
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:565
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:312
print Print MemDeps of function
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