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