1 //===-- LlvmState.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 "LlvmState.h" 10 #include "Target.h" 11 #include "llvm/ADT/SmallVector.h" 12 #include "llvm/MC/MCCodeEmitter.h" 13 #include "llvm/MC/MCContext.h" 14 #include "llvm/MC/MCFixup.h" 15 #include "llvm/MC/MCObjectFileInfo.h" 16 #include "llvm/MC/TargetRegistry.h" 17 #include "llvm/Target/TargetMachine.h" 18 #include "llvm/Target/TargetOptions.h" 19 #include "llvm/TargetParser/Host.h" 20 21 namespace llvm { 22 namespace exegesis { 23 24 Expected<LLVMState> LLVMState::Create(std::string TripleName, 25 std::string CpuName, 26 const StringRef Features, 27 bool UseDummyPerfCounters) { 28 if (TripleName.empty()) 29 TripleName = Triple::normalize(sys::getDefaultTargetTriple()); 30 31 Triple TheTriple(TripleName); 32 33 // Get the target specific parser. 34 std::string Error; 35 const Target *TheTarget = 36 TargetRegistry::lookupTarget(/*MArch=*/"", TheTriple, Error); 37 if (!TheTarget) { 38 return make_error<StringError>("no LLVM target for triple " + TripleName, 39 inconvertibleErrorCode()); 40 } 41 42 // Update Triple with the updated triple from the target lookup. 43 TripleName = TheTriple.str(); 44 45 if (CpuName == "native") 46 CpuName = std::string(sys::getHostCPUName()); 47 48 std::unique_ptr<MCSubtargetInfo> STI( 49 TheTarget->createMCSubtargetInfo(TripleName, CpuName, "")); 50 assert(STI && "Unable to create subtarget info!"); 51 if (!STI->isCPUStringValid(CpuName)) { 52 return make_error<StringError>(Twine("invalid CPU name (") 53 .concat(CpuName) 54 .concat(") for triple ") 55 .concat(TripleName), 56 inconvertibleErrorCode()); 57 } 58 const TargetOptions Options; 59 std::unique_ptr<const TargetMachine> TM(TheTarget->createTargetMachine( 60 TripleName, CpuName, Features, Options, Reloc::Model::Static)); 61 if (!TM) { 62 return make_error<StringError>("unable to create target machine", 63 inconvertibleErrorCode()); 64 } 65 66 const ExegesisTarget *ET = 67 TripleName.empty() ? &ExegesisTarget::getDefault() 68 : ExegesisTarget::lookup(TM->getTargetTriple()); 69 if (!ET) { 70 return make_error<StringError>("no Exegesis target for triple " + 71 TripleName, 72 inconvertibleErrorCode()); 73 } 74 const PfmCountersInfo &PCI = UseDummyPerfCounters 75 ? ET->getDummyPfmCounters() 76 : ET->getPfmCounters(CpuName); 77 return LLVMState(std::move(TM), ET, &PCI); 78 } 79 80 LLVMState::LLVMState(std::unique_ptr<const TargetMachine> TM, 81 const ExegesisTarget *ET, const PfmCountersInfo *PCI) 82 : TheExegesisTarget(ET), TheTargetMachine(std::move(TM)), PfmCounters(PCI), 83 OpcodeNameToOpcodeIdxMapping(createOpcodeNameToOpcodeIdxMapping()), 84 RegNameToRegNoMapping(createRegNameToRegNoMapping()) { 85 BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine()); 86 for (const MCPhysReg Reg : TheExegesisTarget->getUnavailableRegisters()) 87 ReservedRegs.set(Reg); 88 RATC.reset( 89 new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs))); 90 IC.reset(new InstructionsCache(getInstrInfo(), getRATC())); 91 } 92 93 std::unique_ptr<TargetMachine> LLVMState::createTargetMachine() const { 94 return std::unique_ptr<TargetMachine>( 95 TheTargetMachine->getTarget().createTargetMachine( 96 TheTargetMachine->getTargetTriple().normalize(), 97 TheTargetMachine->getTargetCPU(), 98 TheTargetMachine->getTargetFeatureString(), TheTargetMachine->Options, 99 Reloc::Model::Static)); 100 } 101 102 std::optional<MCRegister> 103 LLVMState::getRegisterNumberFromName(StringRef RegisterName) const { 104 auto RegisterIt = RegNameToRegNoMapping->find(RegisterName); 105 if (RegisterIt == RegNameToRegNoMapping->end()) 106 return std::nullopt; 107 return RegisterIt->second; 108 } 109 110 std::unique_ptr<const DenseMap<StringRef, unsigned>> 111 LLVMState::createOpcodeNameToOpcodeIdxMapping() const { 112 const MCInstrInfo &InstrInfo = getInstrInfo(); 113 auto Map = std::make_unique<DenseMap<StringRef, unsigned>>( 114 InstrInfo.getNumOpcodes()); 115 for (unsigned I = 0, E = InstrInfo.getNumOpcodes(); I < E; ++I) 116 (*Map)[InstrInfo.getName(I)] = I; 117 assert(Map->size() == InstrInfo.getNumOpcodes() && "Size prediction failed"); 118 return std::move(Map); 119 } 120 121 std::unique_ptr<const DenseMap<StringRef, MCRegister>> 122 LLVMState::createRegNameToRegNoMapping() const { 123 const MCRegisterInfo &RegInfo = getRegInfo(); 124 auto Map = 125 std::make_unique<DenseMap<StringRef, MCRegister>>(RegInfo.getNumRegs()); 126 // Special-case RegNo 0, which would otherwise be spelled as ''. 127 (*Map)[kNoRegister] = 0; 128 for (unsigned I = 1, E = RegInfo.getNumRegs(); I < E; ++I) 129 (*Map)[RegInfo.getName(I)] = I; 130 assert(Map->size() == RegInfo.getNumRegs() && "Size prediction failed"); 131 return std::move(Map); 132 } 133 134 bool LLVMState::canAssemble(const MCInst &Inst) const { 135 MCContext Context(TheTargetMachine->getTargetTriple(), 136 TheTargetMachine->getMCAsmInfo(), 137 TheTargetMachine->getMCRegisterInfo(), 138 TheTargetMachine->getMCSubtargetInfo()); 139 std::unique_ptr<const MCCodeEmitter> CodeEmitter( 140 TheTargetMachine->getTarget().createMCCodeEmitter( 141 *TheTargetMachine->getMCInstrInfo(), Context)); 142 assert(CodeEmitter && "unable to create code emitter"); 143 SmallVector<char, 16> Tmp; 144 SmallVector<MCFixup, 4> Fixups; 145 CodeEmitter->encodeInstruction(Inst, Tmp, Fixups, 146 *TheTargetMachine->getMCSubtargetInfo()); 147 return Tmp.size() > 0; 148 } 149 150 } // namespace exegesis 151 } // namespace llvm 152