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"
12 #include "SubprocessMemory.h"
14 #include "llvm/Analysis/TargetLibraryInfo.h"
15 #include "llvm/CodeGen/FunctionLoweringInfo.h"
16 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
17 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineModuleInfo.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/CodeGen/TargetInstrInfo.h"
22 #include "llvm/CodeGen/TargetPassConfig.h"
23 #include "llvm/CodeGen/TargetSubtargetInfo.h"
24 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
25 #include "llvm/IR/BasicBlock.h"
26 #include "llvm/IR/Instructions.h"
27 #include "llvm/IR/LegacyPassManager.h"
28 #include "llvm/MC/MCInstrInfo.h"
29 #include "llvm/Support/Alignment.h"
30 #include "llvm/Support/MemoryBuffer.h"
31 #include "llvm/Support/raw_ostream.h"
34 #include "perfmon/perf_event.h"
40 static constexpr const char ModuleID
[] = "ExegesisInfoTest";
41 static constexpr const char FunctionID
[] = "foo";
42 static const Align
kFunctionAlignment(4096);
44 // Fills the given basic block with register setup code, and returns true if
45 // all registers could be setup correctly.
46 static bool generateSnippetSetupCode(
47 const ExegesisTarget
&ET
, const MCSubtargetInfo
*const MSI
,
48 ArrayRef
<RegisterValue
> RegisterInitialValues
, BasicBlockFiller
&BBF
,
49 const BenchmarkKey
&Key
, bool GenerateMemoryInstructions
) {
50 bool IsSnippetSetupComplete
= true;
51 if (GenerateMemoryInstructions
) {
52 BBF
.addInstructions(ET
.generateMemoryInitialSetup());
53 for (const MemoryMapping
&MM
: Key
.MemoryMappings
) {
54 BBF
.addInstructions(ET
.generateMmap(
55 MM
.Address
, Key
.MemoryValues
.at(MM
.MemoryValueName
).SizeBytes
,
56 ET
.getAuxiliaryMemoryStartAddress() +
57 sizeof(int) * (Key
.MemoryValues
.at(MM
.MemoryValueName
).Index
+
58 SubprocessMemory::AuxiliaryMemoryOffset
)));
60 BBF
.addInstructions(ET
.setStackRegisterToAuxMem());
62 for (const RegisterValue
&RV
: RegisterInitialValues
) {
63 // Load a constant in the register.
64 const auto SetRegisterCode
= ET
.setRegTo(*MSI
, RV
.Register
, RV
.Value
);
65 if (SetRegisterCode
.empty())
66 IsSnippetSetupComplete
= false;
67 BBF
.addInstructions(SetRegisterCode
);
69 if (GenerateMemoryInstructions
) {
71 BBF
.addInstructions(ET
.configurePerfCounter(PERF_EVENT_IOC_RESET
, true));
74 return IsSnippetSetupComplete
;
77 // Small utility function to add named passes.
78 static bool addPass(PassManagerBase
&PM
, StringRef PassName
,
79 TargetPassConfig
&TPC
) {
80 const PassRegistry
*PR
= PassRegistry::getPassRegistry();
81 const PassInfo
*PI
= PR
->getPassInfo(PassName
);
83 errs() << " run-pass " << PassName
<< " is not registered.\n";
87 if (!PI
->getNormalCtor()) {
88 errs() << " cannot create pass: " << PI
->getPassName() << "\n";
91 Pass
*P
= PI
->getNormalCtor()();
92 std::string Banner
= std::string("After ") + std::string(P
->getPassName());
94 TPC
.printAndVerify(Banner
);
99 MachineFunction
&createVoidVoidPtrMachineFunction(StringRef FunctionName
,
101 MachineModuleInfo
*MMI
) {
102 Type
*const ReturnType
= Type::getInt32Ty(Module
->getContext());
103 Type
*const MemParamType
= PointerType::get(
104 Type::getInt8Ty(Module
->getContext()), 0 /*default address space*/);
105 FunctionType
*FunctionType
=
106 FunctionType::get(ReturnType
, {MemParamType
}, false);
107 Function
*const F
= Function::Create(
108 FunctionType
, GlobalValue::InternalLinkage
, FunctionName
, Module
);
109 BasicBlock
*BB
= BasicBlock::Create(Module
->getContext(), "", F
);
110 new UnreachableInst(Module
->getContext(), BB
);
111 return MMI
->getOrCreateMachineFunction(*F
);
114 BasicBlockFiller::BasicBlockFiller(MachineFunction
&MF
, MachineBasicBlock
*MBB
,
115 const MCInstrInfo
*MCII
)
116 : MF(MF
), MBB(MBB
), MCII(MCII
) {}
118 void BasicBlockFiller::addInstruction(const MCInst
&Inst
, const DebugLoc
&DL
) {
119 const unsigned Opcode
= Inst
.getOpcode();
120 const MCInstrDesc
&MCID
= MCII
->get(Opcode
);
121 MachineInstrBuilder Builder
= BuildMI(MBB
, DL
, MCID
);
122 for (unsigned OpIndex
= 0, E
= Inst
.getNumOperands(); OpIndex
< E
;
124 const MCOperand
&Op
= Inst
.getOperand(OpIndex
);
126 const bool IsDef
= OpIndex
< MCID
.getNumDefs();
128 const MCOperandInfo
&OpInfo
= MCID
.operands().begin()[OpIndex
];
129 if (IsDef
&& !OpInfo
.isOptionalDef())
130 Flags
|= RegState::Define
;
131 Builder
.addReg(Op
.getReg(), Flags
);
132 } else if (Op
.isImm()) {
133 Builder
.addImm(Op
.getImm());
134 } else if (!Op
.isValid()) {
135 llvm_unreachable("Operand is not set");
137 llvm_unreachable("Not yet implemented");
142 void BasicBlockFiller::addInstructions(ArrayRef
<MCInst
> Insts
,
143 const DebugLoc
&DL
) {
144 for (const MCInst
&Inst
: Insts
)
145 addInstruction(Inst
, DL
);
148 void BasicBlockFiller::addReturn(const ExegesisTarget
&ET
,
149 bool SubprocessCleanup
, const DebugLoc
&DL
) {
150 // Insert cleanup code
151 if (SubprocessCleanup
) {
153 addInstructions(ET
.configurePerfCounter(PERF_EVENT_IOC_DISABLE
, false));
154 #endif // HAVE_LIBPFM
156 addInstructions(ET
.generateExitSyscall(0));
159 // Insert the return code.
160 const TargetInstrInfo
*TII
= MF
.getSubtarget().getInstrInfo();
161 if (TII
->getReturnOpcode() < TII
->getNumOpcodes()) {
162 BuildMI(MBB
, DL
, TII
->get(TII
->getReturnOpcode()));
164 MachineIRBuilder
MIB(MF
);
167 FunctionLoweringInfo FuncInfo
;
168 FuncInfo
.CanLowerReturn
= true;
169 MF
.getSubtarget().getCallLowering()->lowerReturn(MIB
, nullptr, {}, FuncInfo
,
174 FunctionFiller::FunctionFiller(MachineFunction
&MF
,
175 std::vector
<unsigned> RegistersSetUp
)
176 : MF(MF
), MCII(MF
.getTarget().getMCInstrInfo()), Entry(addBasicBlock()),
177 RegistersSetUp(std::move(RegistersSetUp
)) {}
179 BasicBlockFiller
FunctionFiller::addBasicBlock() {
180 MachineBasicBlock
*MBB
= MF
.CreateMachineBasicBlock();
182 return BasicBlockFiller(MF
, MBB
, MCII
);
185 ArrayRef
<unsigned> FunctionFiller::getRegistersSetUp() const {
186 return RegistersSetUp
;
189 static std::unique_ptr
<Module
>
190 createModule(const std::unique_ptr
<LLVMContext
> &Context
, const DataLayout
&DL
) {
191 auto Mod
= std::make_unique
<Module
>(ModuleID
, *Context
);
192 Mod
->setDataLayout(DL
);
196 BitVector
getFunctionReservedRegs(const TargetMachine
&TM
) {
197 std::unique_ptr
<LLVMContext
> Context
= std::make_unique
<LLVMContext
>();
198 std::unique_ptr
<Module
> Module
= createModule(Context
, TM
.createDataLayout());
199 // TODO: This only works for targets implementing LLVMTargetMachine.
200 const LLVMTargetMachine
&LLVMTM
= static_cast<const LLVMTargetMachine
&>(TM
);
201 auto MMIWP
= std::make_unique
<MachineModuleInfoWrapperPass
>(&LLVMTM
);
202 MachineFunction
&MF
= createVoidVoidPtrMachineFunction(
203 FunctionID
, Module
.get(), &MMIWP
->getMMI());
204 // Saving reserved registers for client.
205 return MF
.getSubtarget().getRegisterInfo()->getReservedRegs(MF
);
208 Error
assembleToStream(const ExegesisTarget
&ET
,
209 std::unique_ptr
<LLVMTargetMachine
> TM
,
210 ArrayRef
<unsigned> LiveIns
,
211 ArrayRef
<RegisterValue
> RegisterInitialValues
,
212 const FillFunction
&Fill
, raw_pwrite_stream
&AsmStream
,
213 const BenchmarkKey
&Key
,
214 bool GenerateMemoryInstructions
) {
215 auto Context
= std::make_unique
<LLVMContext
>();
216 std::unique_ptr
<Module
> Module
=
217 createModule(Context
, TM
->createDataLayout());
218 auto MMIWP
= std::make_unique
<MachineModuleInfoWrapperPass
>(TM
.get());
219 MachineFunction
&MF
= createVoidVoidPtrMachineFunction(
220 FunctionID
, Module
.get(), &MMIWP
.get()->getMMI());
221 MF
.ensureAlignment(kFunctionAlignment
);
223 // We need to instruct the passes that we're done with SSA and virtual
225 auto &Properties
= MF
.getProperties();
226 Properties
.set(MachineFunctionProperties::Property::NoVRegs
);
227 Properties
.reset(MachineFunctionProperties::Property::IsSSA
);
228 Properties
.set(MachineFunctionProperties::Property::NoPHIs
);
230 for (const unsigned Reg
: LiveIns
)
231 MF
.getRegInfo().addLiveIn(Reg
);
233 if (GenerateMemoryInstructions
) {
234 for (const unsigned Reg
: ET
.getArgumentRegisters())
235 MF
.getRegInfo().addLiveIn(Reg
);
236 // Add a live in for registers that need saving so that the machine verifier
237 // doesn't fail if the register is never defined.
238 for (const unsigned Reg
: ET
.getRegistersNeedSaving())
239 MF
.getRegInfo().addLiveIn(Reg
);
242 std::vector
<unsigned> RegistersSetUp
;
243 for (const auto &InitValue
: RegisterInitialValues
) {
244 RegistersSetUp
.push_back(InitValue
.Register
);
246 FunctionFiller
Sink(MF
, std::move(RegistersSetUp
));
247 auto Entry
= Sink
.getEntry();
249 for (const unsigned Reg
: LiveIns
)
250 Entry
.MBB
->addLiveIn(Reg
);
252 if (GenerateMemoryInstructions
) {
253 for (const unsigned Reg
: ET
.getArgumentRegisters())
254 Entry
.MBB
->addLiveIn(Reg
);
255 // Add a live in for registers that need saving so that the machine verifier
256 // doesn't fail if the register is never defined.
257 for (const unsigned Reg
: ET
.getRegistersNeedSaving())
258 Entry
.MBB
->addLiveIn(Reg
);
261 const bool IsSnippetSetupComplete
= generateSnippetSetupCode(
262 ET
, TM
->getMCSubtargetInfo(), RegisterInitialValues
, Entry
, Key
,
263 GenerateMemoryInstructions
);
265 // If the snippet setup is not complete, we disable liveliness tracking. This
266 // means that we won't know what values are in the registers.
267 // FIXME: this should probably be an assertion.
268 if (!IsSnippetSetupComplete
)
269 Properties
.reset(MachineFunctionProperties::Property::TracksLiveness
);
273 // prologue/epilogue pass needs the reserved registers to be frozen, this
274 // is usually done by the SelectionDAGISel pass.
275 MF
.getRegInfo().freezeReservedRegs(MF
);
277 // We create the pass manager, run the passes to populate AsmBuffer.
278 MCContext
&MCContext
= MMIWP
->getMMI().getContext();
279 legacy::PassManager PM
;
281 TargetLibraryInfoImpl
TLII(Triple(Module
->getTargetTriple()));
282 PM
.add(new TargetLibraryInfoWrapperPass(TLII
));
284 TargetPassConfig
*TPC
= TM
->createPassConfig(PM
);
286 PM
.add(MMIWP
.release());
287 TPC
->printAndVerify("MachineFunctionGenerator::assemble");
288 // Add target-specific passes.
289 ET
.addTargetSpecificPasses(PM
);
290 TPC
->printAndVerify("After ExegesisTarget::addTargetSpecificPasses");
291 // Adding the following passes:
292 // - postrapseudos: expands pseudo return instructions used on some targets.
293 // - machineverifier: checks that the MachineFunction is well formed.
294 // - prologepilog: saves and restore callee saved registers.
295 for (const char *PassName
:
296 {"postrapseudos", "machineverifier", "prologepilog"})
297 if (addPass(PM
, PassName
, *TPC
))
298 return make_error
<Failure
>("Unable to add a mandatory pass");
299 TPC
->setInitialized();
301 // AsmPrinter is responsible for generating the assembly into AsmBuffer.
302 if (TM
->addAsmPrinter(PM
, AsmStream
, nullptr, CodeGenFileType::ObjectFile
,
304 return make_error
<Failure
>("Cannot add AsmPrinter passes");
306 PM
.run(*Module
); // Run all the passes
307 return Error::success();
310 object::OwningBinary
<object::ObjectFile
>
311 getObjectFromBuffer(StringRef InputData
) {
312 // Storing the generated assembly into a MemoryBuffer that owns the memory.
313 std::unique_ptr
<MemoryBuffer
> Buffer
=
314 MemoryBuffer::getMemBufferCopy(InputData
);
315 // Create the ObjectFile from the MemoryBuffer.
316 std::unique_ptr
<object::ObjectFile
> Obj
=
317 cantFail(object::ObjectFile::createObjectFile(Buffer
->getMemBufferRef()));
318 // Returning both the MemoryBuffer and the ObjectFile.
319 return object::OwningBinary
<object::ObjectFile
>(std::move(Obj
),
323 object::OwningBinary
<object::ObjectFile
> getObjectFromFile(StringRef Filename
) {
324 return cantFail(object::ObjectFile::createObjectFile(Filename
));
329 // Implementation of this class relies on the fact that a single object with a
330 // single function will be loaded into memory.
331 class TrackingSectionMemoryManager
: public SectionMemoryManager
{
333 explicit TrackingSectionMemoryManager(uintptr_t *CodeSize
)
334 : CodeSize(CodeSize
) {}
336 uint8_t *allocateCodeSection(uintptr_t Size
, unsigned Alignment
,
338 StringRef SectionName
) override
{
340 return SectionMemoryManager::allocateCodeSection(Size
, Alignment
, SectionID
,
345 uintptr_t *const CodeSize
= nullptr;
350 ExecutableFunction::ExecutableFunction(
351 std::unique_ptr
<LLVMTargetMachine
> TM
,
352 object::OwningBinary
<object::ObjectFile
> &&ObjectFileHolder
)
353 : Context(std::make_unique
<LLVMContext
>()) {
354 assert(ObjectFileHolder
.getBinary() && "cannot create object file");
355 // Initializing the execution engine.
356 // We need to use the JIT EngineKind to be able to add an object file.
358 uintptr_t CodeSize
= 0;
361 EngineBuilder(createModule(Context
, TM
->createDataLayout()))
363 .setMCPU(TM
->getTargetCPU())
364 .setEngineKind(EngineKind::JIT
)
365 .setMCJITMemoryManager(
366 std::make_unique
<TrackingSectionMemoryManager
>(&CodeSize
))
367 .create(TM
.release()));
369 report_fatal_error(Twine(Error
));
370 // Adding the generated object file containing the assembled function.
371 // The ExecutionEngine makes sure the object file is copied into an
373 ExecEngine
->addObjectFile(std::move(ObjectFileHolder
));
374 // Fetching function bytes.
375 const uint64_t FunctionAddress
= ExecEngine
->getFunctionAddress(FunctionID
);
376 assert(isAligned(kFunctionAlignment
, FunctionAddress
) &&
377 "function is not properly aligned");
379 StringRef(reinterpret_cast<const char *>(FunctionAddress
), CodeSize
);
382 Error
getBenchmarkFunctionBytes(const StringRef InputData
,
383 std::vector
<uint8_t> &Bytes
) {
384 const auto Holder
= getObjectFromBuffer(InputData
);
385 const auto *Obj
= Holder
.getBinary();
386 // See RuntimeDyldImpl::loadObjectImpl(Obj) for much more complete
389 // Find the only function in the object file.
390 SmallVector
<object::SymbolRef
, 1> Functions
;
391 for (auto &Sym
: Obj
->symbols()) {
392 auto SymType
= Sym
.getType();
393 if (SymType
&& *SymType
== object::SymbolRef::Type::ST_Function
)
394 Functions
.push_back(Sym
);
396 if (Functions
.size() != 1)
397 return make_error
<Failure
>("Exactly one function expected");
399 // Find the containing section - it is assumed to contain only this function.
400 auto SectionOrErr
= Functions
.front().getSection();
401 if (!SectionOrErr
|| *SectionOrErr
== Obj
->section_end())
402 return make_error
<Failure
>("Section not found");
404 auto Address
= Functions
.front().getAddress();
405 if (!Address
|| *Address
!= SectionOrErr
.get()->getAddress())
406 return make_error
<Failure
>("Unexpected layout");
408 auto ContentsOrErr
= SectionOrErr
.get()->getContents();
410 return ContentsOrErr
.takeError();
411 Bytes
.assign(ContentsOrErr
->begin(), ContentsOrErr
->end());
412 return Error::success();
415 } // namespace exegesis