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