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 
10 #include "llvm/ADT/Triple.h"
13 #include "llvm/IR/Dominators.h"
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/IR/Intrinsics.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/IR/Type.h"
19 #include "llvm/InitializePasses.h"
20 #include "llvm/Pass.h"
21 #include "llvm/Transforms/Utils.h"
22 
23 using namespace llvm;
24 
25 static void insertCall(Function &CurFn, StringRef Func,
26  Instruction *InsertionPt, DebugLoc DL) {
27  Module &M = *InsertionPt->getParent()->getParent()->getParent();
28  LLVMContext &C = InsertionPt->getParent()->getContext();
29 
30  if (Func == "mcount" ||
31  Func == ".mcount" ||
32  Func == "llvm.arm.gnu.eabi.mcount" ||
33  Func == "\01_mcount" ||
34  Func == "\01mcount" ||
35  Func == "__mcount" ||
36  Func == "_mcount" ||
37  Func == "__cyg_profile_func_enter_bare") {
38  Triple TargetTriple(M.getTargetTriple());
39  if (TargetTriple.isOSAIX() && Func == "__mcount") {
40  Type *SizeTy = M.getDataLayout().getIntPtrType(C);
41  Type *SizePtrTy = SizeTy->getPointerTo();
42  GlobalVariable *GV = new GlobalVariable(M, SizeTy, /*isConstant=*/false,
44  ConstantInt::get(SizeTy, 0));
45  CallInst *Call = CallInst::Create(
46  M.getOrInsertFunction(Func,
47  FunctionType::get(Type::getVoidTy(C), {SizePtrTy},
48  /*isVarArg=*/false)),
49  {GV}, "", InsertionPt);
50  Call->setDebugLoc(DL);
51  } else {
52  FunctionCallee Fn = M.getOrInsertFunction(Func, Type::getVoidTy(C));
53  CallInst *Call = CallInst::Create(Fn, "", InsertionPt);
54  Call->setDebugLoc(DL);
55  }
56  return;
57  }
58 
59  if (Func == "__cyg_profile_func_enter" || Func == "__cyg_profile_func_exit") {
60  Type *ArgTypes[] = {Type::getInt8PtrTy(C), Type::getInt8PtrTy(C)};
61 
62  FunctionCallee Fn = M.getOrInsertFunction(
63  Func, FunctionType::get(Type::getVoidTy(C), ArgTypes, false));
64 
65  Instruction *RetAddr = CallInst::Create(
66  Intrinsic::getDeclaration(&M, Intrinsic::returnaddress),
68  InsertionPt);
69  RetAddr->setDebugLoc(DL);
70 
72  RetAddr};
73 
74  CallInst *Call =
75  CallInst::Create(Fn, ArrayRef<Value *>(Args), "", InsertionPt);
76  Call->setDebugLoc(DL);
77  return;
78  }
79 
80  // We only know how to call a fixed set of instrumentation functions, because
81  // they all expect different arguments, etc.
82  report_fatal_error(Twine("Unknown instrumentation function: '") + Func + "'");
83 }
84 
85 static bool runOnFunction(Function &F, bool PostInlining) {
86  StringRef EntryAttr = PostInlining ? "instrument-function-entry-inlined"
87  : "instrument-function-entry";
88 
89  StringRef ExitAttr = PostInlining ? "instrument-function-exit-inlined"
90  : "instrument-function-exit";
91 
92  StringRef EntryFunc = F.getFnAttribute(EntryAttr).getValueAsString();
93  StringRef ExitFunc = F.getFnAttribute(ExitAttr).getValueAsString();
94 
95  bool Changed = false;
96 
97  // If the attribute is specified, insert instrumentation and then "consume"
98  // the attribute so that it's not inserted again if the pass should happen to
99  // run later for some reason.
100 
101  if (!EntryFunc.empty()) {
102  DebugLoc DL;
103  if (auto SP = F.getSubprogram())
104  DL = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
105 
106  insertCall(F, EntryFunc, &*F.begin()->getFirstInsertionPt(), DL);
107  Changed = true;
108  F.removeFnAttr(EntryAttr);
109  }
110 
111  if (!ExitFunc.empty()) {
112  for (BasicBlock &BB : F) {
113  Instruction *T = BB.getTerminator();
114  if (!isa<ReturnInst>(T))
115  continue;
116 
117  // If T is preceded by a musttail call, that's the real terminator.
118  if (CallInst *CI = BB.getTerminatingMustTailCall())
119  T = CI;
120 
121  DebugLoc DL;
122  if (DebugLoc TerminatorDL = T->getDebugLoc())
123  DL = TerminatorDL;
124  else if (auto SP = F.getSubprogram())
125  DL = DILocation::get(SP->getContext(), 0, 0, SP);
126 
127  insertCall(F, ExitFunc, T, DL);
128  Changed = true;
129  }
130  F.removeFnAttr(ExitAttr);
131  }
132 
133  return Changed;
134 }
135 
140  PA.preserveSet<CFGAnalyses>();
141  return PA;
142 }
143 
145  raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
147  ->printPipeline(OS, MapClassName2PassName);
148  OS << "<";
149  if (PostInlining)
150  OS << "post-inline";
151  OS << ">";
152 }
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:1481
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::GlobalVariable
Definition: GlobalVariable.h:39
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
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
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:53
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
llvm::GlobalValue::InternalLinkage
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
llvm::Triple::isOSAIX
bool isOSAIX() const
Tests whether the OS is AIX.
Definition: Triple.h:668
Utils.h
insertCall
static void insertCall(Function &CurFn, StringRef Func, Instruction *InsertionPt, DebugLoc DL)
Definition: EntryExitInstrumenter.cpp:25
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:652
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:356
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Triple.h
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:144
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:85
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Function.h
llvm::Type::getPointerTo
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:774
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:137
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