LLVM  16.0.0git
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/Dominators.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/Instructions.h"
15 #include "llvm/IR/Intrinsics.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/Type.h"
18 #include "llvm/InitializePasses.h"
19 #include "llvm/Pass.h"
20 #include "llvm/Transforms/Utils.h"
21 
22 using namespace llvm;
23 
24 static void insertCall(Function &CurFn, StringRef Func,
25  Instruction *InsertionPt, DebugLoc DL) {
26  Module &M = *InsertionPt->getParent()->getParent()->getParent();
27  LLVMContext &C = InsertionPt->getParent()->getContext();
28 
29  if (Func == "mcount" ||
30  Func == ".mcount" ||
31  Func == "llvm.arm.gnu.eabi.mcount" ||
32  Func == "\01_mcount" ||
33  Func == "\01mcount" ||
34  Func == "__mcount" ||
35  Func == "_mcount" ||
36  Func == "__cyg_profile_func_enter_bare") {
37  FunctionCallee Fn = M.getOrInsertFunction(Func, Type::getVoidTy(C));
38  CallInst *Call = CallInst::Create(Fn, "", InsertionPt);
39  Call->setDebugLoc(DL);
40  return;
41  }
42 
43  if (Func == "__cyg_profile_func_enter" || Func == "__cyg_profile_func_exit") {
44  Type *ArgTypes[] = {Type::getInt8PtrTy(C), Type::getInt8PtrTy(C)};
45 
46  FunctionCallee Fn = M.getOrInsertFunction(
47  Func, FunctionType::get(Type::getVoidTy(C), ArgTypes, false));
48 
49  Instruction *RetAddr = CallInst::Create(
50  Intrinsic::getDeclaration(&M, Intrinsic::returnaddress),
52  InsertionPt);
53  RetAddr->setDebugLoc(DL);
54 
56  RetAddr};
57 
58  CallInst *Call =
59  CallInst::Create(Fn, ArrayRef<Value *>(Args), "", InsertionPt);
60  Call->setDebugLoc(DL);
61  return;
62  }
63 
64  // We only know how to call a fixed set of instrumentation functions, because
65  // they all expect different arguments, etc.
66  report_fatal_error(Twine("Unknown instrumentation function: '") + Func + "'");
67 }
68 
69 static bool runOnFunction(Function &F, bool PostInlining) {
70  StringRef EntryAttr = PostInlining ? "instrument-function-entry-inlined"
71  : "instrument-function-entry";
72 
73  StringRef ExitAttr = PostInlining ? "instrument-function-exit-inlined"
74  : "instrument-function-exit";
75 
76  StringRef EntryFunc = F.getFnAttribute(EntryAttr).getValueAsString();
77  StringRef ExitFunc = F.getFnAttribute(ExitAttr).getValueAsString();
78 
79  bool Changed = false;
80 
81  // If the attribute is specified, insert instrumentation and then "consume"
82  // the attribute so that it's not inserted again if the pass should happen to
83  // run later for some reason.
84 
85  if (!EntryFunc.empty()) {
86  DebugLoc DL;
87  if (auto SP = F.getSubprogram())
88  DL = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
89 
90  insertCall(F, EntryFunc, &*F.begin()->getFirstInsertionPt(), DL);
91  Changed = true;
92  F.removeFnAttr(EntryAttr);
93  }
94 
95  if (!ExitFunc.empty()) {
96  for (BasicBlock &BB : F) {
97  Instruction *T = BB.getTerminator();
98  if (!isa<ReturnInst>(T))
99  continue;
100 
101  // If T is preceded by a musttail call, that's the real terminator.
102  if (CallInst *CI = BB.getTerminatingMustTailCall())
103  T = CI;
104 
105  DebugLoc DL;
106  if (DebugLoc TerminatorDL = T->getDebugLoc())
107  DL = TerminatorDL;
108  else if (auto SP = F.getSubprogram())
109  DL = DILocation::get(SP->getContext(), 0, 0, SP);
110 
111  insertCall(F, ExitFunc, T, DL);
112  Changed = true;
113  }
114  F.removeFnAttr(ExitAttr);
115  }
116 
117  return Changed;
118 }
119 
124  PA.preserveSet<CFGAnalyses>();
125  return PA;
126 }
127 
129  raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
131  ->printPipeline(OS, MapClassName2PassName);
132  OS << "<";
133  if (PostInlining)
134  OS << "post-inline";
135  OS << ">";
136 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
llvm::EntryExitInstrumenterPass::PostInlining
bool PostInlining
Definition: EntryExitInstrumenter.h:33
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::Intrinsic::getDeclaration
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:1421
llvm::Type::getInt8PtrTy
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:291
llvm::BasicBlock::getParent
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:104
DebugInfoMetadata.h
llvm::PassInfoMixin
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:371
T
llvm::Function
Definition: Function.h:60
Pass.h
llvm::ConstantExpr::getBitCast
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2202
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:361
GlobalsModRef.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:239
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1400
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
Intrinsics.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::CallInst::Create
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Definition: Instructions.h:1517
llvm::Instruction
Definition: Instruction.h:42
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::ConstantInt::get
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:879
Utils.h
insertCall
static void insertCall(Function &CurFn, StringRef Func, Instruction *InsertionPt, DebugLoc DL)
Definition: EntryExitInstrumenter.cpp:24
Type.h
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLFunctionalExtras.h:36
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:650
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
llvm::Instruction::setDebugLoc
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:351
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::EntryExitInstrumenterPass::printPipeline
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Definition: EntryExitInstrumenter.cpp:128
llvm::CFGAnalyses
Represents analyses that only rely on functions' control flow.
Definition: PassManager.h:113
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::BasicBlock::getContext
LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition: BasicBlock.cpp:35
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Function.h
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:222
Instructions.h
llvm::PreservedAnalyses::preserveSet
void preserveSet()
Mark an analysis set as preserved.
Definition: PassManager.h:188
Dominators.h
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:91
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
llvm::EntryExitInstrumenterPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: EntryExitInstrumenter.cpp:121
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1474
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
EntryExitInstrumenter.h
InitializePasses.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74