LLVM  14.0.0git
IndirectThunks.h
Go to the documentation of this file.
1 //===---- IndirectThunks.h - Indirect Thunk Base Class ----------*- C++ -*-===//
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 ///
9 /// \file
10 /// Contains a base class for Passes that inject an MI thunk.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CODEGEN_INDIRECTTHUNKS_H
15 #define LLVM_CODEGEN_INDIRECTTHUNKS_H
16 
19 #include "llvm/IR/IRBuilder.h"
20 #include "llvm/IR/Module.h"
21 
22 namespace llvm {
23 
24 template <typename Derived> class ThunkInserter {
25  Derived &getDerived() { return *static_cast<Derived *>(this); }
26 
27 protected:
31  bool Comdat = true);
32 
33 public:
34  void init(Module &M) {
35  InsertedThunks = false;
36  getDerived().doInitialization(M);
37  }
38  // return `true` if `MMI` or `MF` was modified
39  bool run(MachineModuleInfo &MMI, MachineFunction &MF);
40 };
41 
42 template <typename Derived>
44  StringRef Name, bool Comdat) {
45  assert(Name.startswith(getDerived().getThunkPrefix()) &&
46  "Created a thunk with an unexpected prefix!");
47 
48  Module &M = const_cast<Module &>(*MMI.getModule());
49  LLVMContext &Ctx = M.getContext();
50  auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
54  Name, &M);
55  if (Comdat) {
56  F->setVisibility(GlobalValue::HiddenVisibility);
57  F->setComdat(M.getOrInsertComdat(Name));
58  }
59 
60  // Add Attributes so that we don't create a frame, unwind information, or
61  // inline.
62  AttrBuilder B;
63  B.addAttribute(llvm::Attribute::NoUnwind);
64  B.addAttribute(llvm::Attribute::Naked);
65  F->addFnAttrs(B);
66 
67  // Populate our function a bit so that we can verify.
68  BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
69  IRBuilder<> Builder(Entry);
70 
71  Builder.CreateRetVoid();
72 
73  // MachineFunctions aren't created automatically for the IR-level constructs
74  // we already made. Create them and insert them into the module.
76  // A MachineBasicBlock must not be created for the Entry block; code
77  // generation from an empty naked function in C source code also does not
78  // generate one. At least GlobalISel asserts if this invariant isn't
79  // respected.
80 
81  // Set MF properties. We never use vregs...
83 }
84 
85 template <typename Derived>
87  // If MF is not a thunk, check to see if we need to insert a thunk.
88  if (!MF.getName().startswith(getDerived().getThunkPrefix())) {
89  // If we've already inserted a thunk, nothing else to do.
90  if (InsertedThunks)
91  return false;
92 
93  // Only add a thunk if one of the functions has the corresponding feature
94  // enabled in its subtarget, and doesn't enable external thunks.
95  // FIXME: Conditionalize on indirect calls so we don't emit a thunk when
96  // nothing will end up calling it.
97  // FIXME: It's a little silly to look at every function just to enumerate
98  // the subtargets, but eventually we'll want to look at them for indirect
99  // calls, so maybe this is OK.
100  if (!getDerived().mayUseThunk(MF))
101  return false;
102 
103  getDerived().insertThunks(MMI);
104  InsertedThunks = true;
105  return true;
106  }
107 
108  // If this *is* a thunk function, we need to populate it with the correct MI.
109  getDerived().populateThunk(MF);
110  return true;
111 }
112 
113 } // namespace llvm
114 
115 #endif
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:286
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
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::GlobalValue::HiddenVisibility
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:64
llvm::Function
Definition: Function.h:61
llvm::IRBuilder<>
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:325
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::ThunkInserter::createThunkFunction
void createThunkFunction(MachineModuleInfo &MMI, StringRef Name, bool Comdat=true)
Definition: IndirectThunks.h:43
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::MachineFunction::getProperties
const MachineFunctionProperties & getProperties() const
Get the function properties.
Definition: MachineFunction.h:717
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachineFunctionProperties::set
MachineFunctionProperties & set(Property P)
Definition: MachineFunction.h:169
llvm::MachineModuleInfo
This class contains meta information specific to a module.
Definition: MachineModuleInfo.h:78
llvm::GlobalValue::InternalLinkage
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
llvm::Comdat
Definition: Comdat.h:31
llvm::MachineFunctionProperties::Property::NoVRegs
@ NoVRegs
llvm::ThunkInserter::InsertedThunks
bool InsertedThunks
Definition: IndirectThunks.h:28
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::AttrBuilder
Definition: Attributes.h:907
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition: MachineFunction.cpp:541
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:138
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineModuleInfo.h
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:650
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:100
llvm::MachineModuleInfo::getOrCreateMachineFunction
MachineFunction & getOrCreateMachineFunction(Function &F)
Returns the MachineFunction constructed for the IR function F.
Definition: MachineModuleInfo.cpp:291
llvm::ThunkInserter::run
bool run(MachineModuleInfo &MMI, MachineFunction &MF)
Definition: IndirectThunks.h:86
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::ThunkInserter
Definition: IndirectThunks.h:24
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:186
llvm::ThunkInserter::init
void init(Module &M)
Definition: IndirectThunks.h:34
llvm::ThunkInserter::doInitialization
void doInitialization(Module &M)
Definition: IndirectThunks.h:29
MachineFunction.h
llvm::GlobalValue::LinkOnceODRLinkage
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:51
llvm::MachineModuleInfo::getModule
const Module * getModule() const
Definition: MachineModuleInfo.h:174