1 //===-- Assembler.cpp -------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
11 #include "SnippetRepetitor.h"
13 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
14 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
15 #include "llvm/CodeGen/MachineInstrBuilder.h"
16 #include "llvm/CodeGen/MachineModuleInfo.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/TargetInstrInfo.h"
19 #include "llvm/CodeGen/TargetPassConfig.h"
20 #include "llvm/CodeGen/TargetSubtargetInfo.h"
21 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
22 #include "llvm/IR/LegacyPassManager.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/Support/MemoryBuffer.h"
29 static constexpr const char ModuleID
[] = "ExegesisInfoTest";
30 static constexpr const char FunctionID
[] = "foo";
32 // Fills the given basic block with register setup code, and returns true if
33 // all registers could be setup correctly.
35 generateSnippetSetupCode(const ExegesisTarget
&ET
,
36 const llvm::MCSubtargetInfo
*const MSI
,
37 llvm::ArrayRef
<RegisterValue
> RegisterInitialValues
,
38 BasicBlockFiller
&BBF
) {
39 bool IsSnippetSetupComplete
= true;
40 for (const RegisterValue
&RV
: RegisterInitialValues
) {
41 // Load a constant in the register.
42 const auto SetRegisterCode
= ET
.setRegTo(*MSI
, RV
.Register
, RV
.Value
);
43 if (SetRegisterCode
.empty())
44 IsSnippetSetupComplete
= false;
45 BBF
.addInstructions(SetRegisterCode
);
47 return IsSnippetSetupComplete
;
50 // Small utility function to add named passes.
51 static bool addPass(llvm::PassManagerBase
&PM
, llvm::StringRef PassName
,
52 llvm::TargetPassConfig
&TPC
) {
53 const llvm::PassRegistry
*PR
= llvm::PassRegistry::getPassRegistry();
54 const llvm::PassInfo
*PI
= PR
->getPassInfo(PassName
);
56 llvm::errs() << " run-pass " << PassName
<< " is not registered.\n";
60 if (!PI
->getNormalCtor()) {
61 llvm::errs() << " cannot create pass: " << PI
->getPassName() << "\n";
64 llvm::Pass
*P
= PI
->getNormalCtor()();
65 std::string Banner
= std::string("After ") + std::string(P
->getPassName());
67 TPC
.printAndVerify(Banner
);
72 llvm::MachineFunction
&
73 createVoidVoidPtrMachineFunction(llvm::StringRef FunctionID
,
75 llvm::MachineModuleInfo
*MMI
) {
76 llvm::Type
*const ReturnType
= llvm::Type::getInt32Ty(Module
->getContext());
77 llvm::Type
*const MemParamType
= llvm::PointerType::get(
78 llvm::Type::getInt8Ty(Module
->getContext()), 0 /*default address space*/);
79 llvm::FunctionType
*FunctionType
=
80 llvm::FunctionType::get(ReturnType
, {MemParamType
}, false);
81 llvm::Function
*const F
= llvm::Function::Create(
82 FunctionType
, llvm::GlobalValue::InternalLinkage
, FunctionID
, Module
);
83 // Making sure we can create a MachineFunction out of this Function even if it
85 F
->setIsMaterializable(true);
86 return MMI
->getOrCreateMachineFunction(*F
);
89 BasicBlockFiller::BasicBlockFiller(llvm::MachineFunction
&MF
,
90 llvm::MachineBasicBlock
*MBB
,
91 const llvm::MCInstrInfo
*MCII
)
92 : MF(MF
), MBB(MBB
), MCII(MCII
) {}
94 void BasicBlockFiller::addInstruction(const llvm::MCInst
&Inst
,
95 const llvm::DebugLoc
&DL
) {
96 const unsigned Opcode
= Inst
.getOpcode();
97 const llvm::MCInstrDesc
&MCID
= MCII
->get(Opcode
);
98 llvm::MachineInstrBuilder Builder
= llvm::BuildMI(MBB
, DL
, MCID
);
99 for (unsigned OpIndex
= 0, E
= Inst
.getNumOperands(); OpIndex
< E
;
101 const llvm::MCOperand
&Op
= Inst
.getOperand(OpIndex
);
103 const bool IsDef
= OpIndex
< MCID
.getNumDefs();
105 const llvm::MCOperandInfo
&OpInfo
= MCID
.operands().begin()[OpIndex
];
106 if (IsDef
&& !OpInfo
.isOptionalDef())
107 Flags
|= llvm::RegState::Define
;
108 Builder
.addReg(Op
.getReg(), Flags
);
109 } else if (Op
.isImm()) {
110 Builder
.addImm(Op
.getImm());
111 } else if (!Op
.isValid()) {
112 llvm_unreachable("Operand is not set");
114 llvm_unreachable("Not yet implemented");
119 void BasicBlockFiller::addInstructions(ArrayRef
<llvm::MCInst
> Insts
,
120 const llvm::DebugLoc
&DL
) {
121 for (const MCInst
&Inst
: Insts
)
122 addInstruction(Inst
, DL
);
125 void BasicBlockFiller::addReturn(const llvm::DebugLoc
&DL
) {
126 // Insert the return code.
127 const llvm::TargetInstrInfo
*TII
= MF
.getSubtarget().getInstrInfo();
128 if (TII
->getReturnOpcode() < TII
->getNumOpcodes()) {
129 llvm::BuildMI(MBB
, DL
, TII
->get(TII
->getReturnOpcode()));
131 llvm::MachineIRBuilder
MIB(MF
);
133 MF
.getSubtarget().getCallLowering()->lowerReturn(MIB
, nullptr, {});
137 FunctionFiller::FunctionFiller(llvm::MachineFunction
&MF
,
138 std::vector
<unsigned> RegistersSetUp
)
139 : MF(MF
), MCII(MF
.getTarget().getMCInstrInfo()), Entry(addBasicBlock()),
140 RegistersSetUp(std::move(RegistersSetUp
)) {}
142 BasicBlockFiller
FunctionFiller::addBasicBlock() {
143 llvm::MachineBasicBlock
*MBB
= MF
.CreateMachineBasicBlock();
145 return BasicBlockFiller(MF
, MBB
, MCII
);
148 ArrayRef
<unsigned> FunctionFiller::getRegistersSetUp() const {
149 return RegistersSetUp
;
152 static std::unique_ptr
<llvm::Module
>
153 createModule(const std::unique_ptr
<llvm::LLVMContext
> &Context
,
154 const llvm::DataLayout DL
) {
155 auto Module
= std::make_unique
<llvm::Module
>(ModuleID
, *Context
);
156 Module
->setDataLayout(DL
);
160 llvm::BitVector
getFunctionReservedRegs(const llvm::TargetMachine
&TM
) {
161 std::unique_ptr
<llvm::LLVMContext
> Context
=
162 std::make_unique
<llvm::LLVMContext
>();
163 std::unique_ptr
<llvm::Module
> Module
=
164 createModule(Context
, TM
.createDataLayout());
165 // TODO: This only works for targets implementing LLVMTargetMachine.
166 const LLVMTargetMachine
&LLVMTM
= static_cast<const LLVMTargetMachine
&>(TM
);
167 std::unique_ptr
<llvm::MachineModuleInfoWrapperPass
> MMIWP
=
168 std::make_unique
<llvm::MachineModuleInfoWrapperPass
>(&LLVMTM
);
169 llvm::MachineFunction
&MF
= createVoidVoidPtrMachineFunction(
170 FunctionID
, Module
.get(), &MMIWP
.get()->getMMI());
171 // Saving reserved registers for client.
172 return MF
.getSubtarget().getRegisterInfo()->getReservedRegs(MF
);
175 void assembleToStream(const ExegesisTarget
&ET
,
176 std::unique_ptr
<llvm::LLVMTargetMachine
> TM
,
177 llvm::ArrayRef
<unsigned> LiveIns
,
178 llvm::ArrayRef
<RegisterValue
> RegisterInitialValues
,
179 const FillFunction
&Fill
,
180 llvm::raw_pwrite_stream
&AsmStream
) {
181 std::unique_ptr
<llvm::LLVMContext
> Context
=
182 std::make_unique
<llvm::LLVMContext
>();
183 std::unique_ptr
<llvm::Module
> Module
=
184 createModule(Context
, TM
->createDataLayout());
185 std::unique_ptr
<llvm::MachineModuleInfoWrapperPass
> MMIWP
=
186 std::make_unique
<llvm::MachineModuleInfoWrapperPass
>(TM
.get());
187 llvm::MachineFunction
&MF
= createVoidVoidPtrMachineFunction(
188 FunctionID
, Module
.get(), &MMIWP
.get()->getMMI());
190 // We need to instruct the passes that we're done with SSA and virtual
192 auto &Properties
= MF
.getProperties();
193 Properties
.set(llvm::MachineFunctionProperties::Property::NoVRegs
);
194 Properties
.reset(llvm::MachineFunctionProperties::Property::IsSSA
);
195 Properties
.set(llvm::MachineFunctionProperties::Property::NoPHIs
);
197 for (const unsigned Reg
: LiveIns
)
198 MF
.getRegInfo().addLiveIn(Reg
);
200 std::vector
<unsigned> RegistersSetUp
;
201 for (const auto &InitValue
: RegisterInitialValues
) {
202 RegistersSetUp
.push_back(InitValue
.Register
);
204 FunctionFiller
Sink(MF
, std::move(RegistersSetUp
));
205 auto Entry
= Sink
.getEntry();
206 for (const unsigned Reg
: LiveIns
)
207 Entry
.MBB
->addLiveIn(Reg
);
209 const bool IsSnippetSetupComplete
= generateSnippetSetupCode(
210 ET
, TM
->getMCSubtargetInfo(), RegisterInitialValues
, Entry
);
212 // If the snippet setup is not complete, we disable liveliness tracking. This
213 // means that we won't know what values are in the registers.
214 if (!IsSnippetSetupComplete
)
215 Properties
.reset(llvm::MachineFunctionProperties::Property::TracksLiveness
);
219 // prologue/epilogue pass needs the reserved registers to be frozen, this
220 // is usually done by the SelectionDAGISel pass.
221 MF
.getRegInfo().freezeReservedRegs(MF
);
223 // We create the pass manager, run the passes to populate AsmBuffer.
224 llvm::MCContext
&MCContext
= MMIWP
->getMMI().getContext();
225 llvm::legacy::PassManager PM
;
227 llvm::TargetLibraryInfoImpl
TLII(llvm::Triple(Module
->getTargetTriple()));
228 PM
.add(new llvm::TargetLibraryInfoWrapperPass(TLII
));
230 llvm::TargetPassConfig
*TPC
= TM
->createPassConfig(PM
);
232 PM
.add(MMIWP
.release());
233 TPC
->printAndVerify("MachineFunctionGenerator::assemble");
234 // Add target-specific passes.
235 ET
.addTargetSpecificPasses(PM
);
236 TPC
->printAndVerify("After ExegesisTarget::addTargetSpecificPasses");
237 // Adding the following passes:
238 // - machineverifier: checks that the MachineFunction is well formed.
239 // - prologepilog: saves and restore callee saved registers.
240 for (const char *PassName
: {"machineverifier", "prologepilog"})
241 if (addPass(PM
, PassName
, *TPC
))
242 llvm::report_fatal_error("Unable to add a mandatory pass");
243 TPC
->setInitialized();
245 // AsmPrinter is responsible for generating the assembly into AsmBuffer.
246 if (TM
->addAsmPrinter(PM
, AsmStream
, nullptr,
247 llvm::TargetMachine::CGFT_ObjectFile
, MCContext
))
248 llvm::report_fatal_error("Cannot add AsmPrinter passes");
250 PM
.run(*Module
); // Run all the passes
253 llvm::object::OwningBinary
<llvm::object::ObjectFile
>
254 getObjectFromBuffer(llvm::StringRef InputData
) {
255 // Storing the generated assembly into a MemoryBuffer that owns the memory.
256 std::unique_ptr
<llvm::MemoryBuffer
> Buffer
=
257 llvm::MemoryBuffer::getMemBufferCopy(InputData
);
258 // Create the ObjectFile from the MemoryBuffer.
259 std::unique_ptr
<llvm::object::ObjectFile
> Obj
= llvm::cantFail(
260 llvm::object::ObjectFile::createObjectFile(Buffer
->getMemBufferRef()));
261 // Returning both the MemoryBuffer and the ObjectFile.
262 return llvm::object::OwningBinary
<llvm::object::ObjectFile
>(
263 std::move(Obj
), std::move(Buffer
));
266 llvm::object::OwningBinary
<llvm::object::ObjectFile
>
267 getObjectFromFile(llvm::StringRef Filename
) {
268 return llvm::cantFail(llvm::object::ObjectFile::createObjectFile(Filename
));
273 // Implementation of this class relies on the fact that a single object with a
274 // single function will be loaded into memory.
275 class TrackingSectionMemoryManager
: public llvm::SectionMemoryManager
{
277 explicit TrackingSectionMemoryManager(uintptr_t *CodeSize
)
278 : CodeSize(CodeSize
) {}
280 uint8_t *allocateCodeSection(uintptr_t Size
, unsigned Alignment
,
282 llvm::StringRef SectionName
) override
{
284 return llvm::SectionMemoryManager::allocateCodeSection(
285 Size
, Alignment
, SectionID
, SectionName
);
289 uintptr_t *const CodeSize
= nullptr;
294 ExecutableFunction::ExecutableFunction(
295 std::unique_ptr
<llvm::LLVMTargetMachine
> TM
,
296 llvm::object::OwningBinary
<llvm::object::ObjectFile
> &&ObjectFileHolder
)
297 : Context(std::make_unique
<llvm::LLVMContext
>()) {
298 assert(ObjectFileHolder
.getBinary() && "cannot create object file");
299 // Initializing the execution engine.
300 // We need to use the JIT EngineKind to be able to add an object file.
302 uintptr_t CodeSize
= 0;
305 llvm::EngineBuilder(createModule(Context
, TM
->createDataLayout()))
307 .setMCPU(TM
->getTargetCPU())
308 .setEngineKind(llvm::EngineKind::JIT
)
309 .setMCJITMemoryManager(
310 std::make_unique
<TrackingSectionMemoryManager
>(&CodeSize
))
311 .create(TM
.release()));
313 llvm::report_fatal_error(Error
);
314 // Adding the generated object file containing the assembled function.
315 // The ExecutionEngine makes sure the object file is copied into an
317 ExecEngine
->addObjectFile(std::move(ObjectFileHolder
));
318 // Fetching function bytes.
320 llvm::StringRef(reinterpret_cast<const char *>(
321 ExecEngine
->getFunctionAddress(FunctionID
)),
325 } // namespace exegesis