Mercurial > hg > CbC > CbC_llvm
view llvm/tools/llvm-exegesis/lib/LlvmState.cpp @ 266:00f31e85ec16 default tip
Added tag current for changeset 31d058e83c98
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Oct 2023 10:13:55 +0900 |
parents | 1f2b6ac9f198 |
children |
line wrap: on
line source
//===-- LlvmState.cpp -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "LlvmState.h" #include "Target.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/TargetParser/Host.h" namespace llvm { namespace exegesis { Expected<LLVMState> LLVMState::Create(std::string TripleName, std::string CpuName, const StringRef Features, bool UseDummyPerfCounters) { if (TripleName.empty()) TripleName = Triple::normalize(sys::getDefaultTargetTriple()); Triple TheTriple(TripleName); // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(/*MArch=*/"", TheTriple, Error); if (!TheTarget) { return llvm::make_error<llvm::StringError>("no LLVM target for triple " + TripleName, llvm::inconvertibleErrorCode()); } // Update Triple with the updated triple from the target lookup. TripleName = TheTriple.str(); if (CpuName == "native") CpuName = std::string(llvm::sys::getHostCPUName()); std::unique_ptr<MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, CpuName, "")); assert(STI && "Unable to create subtarget info!"); if (!STI->isCPUStringValid(CpuName)) { return llvm::make_error<llvm::StringError>(Twine("invalid CPU name (") .concat(CpuName) .concat(") for triple ") .concat(TripleName), llvm::inconvertibleErrorCode()); } const TargetOptions Options; std::unique_ptr<const TargetMachine> TM( static_cast<LLVMTargetMachine *>(TheTarget->createTargetMachine( TripleName, CpuName, Features, Options, Reloc::Model::Static))); if (!TM) { return llvm::make_error<llvm::StringError>( "unable to create target machine", llvm::inconvertibleErrorCode()); } const ExegesisTarget *ET = TripleName.empty() ? &ExegesisTarget::getDefault() : ExegesisTarget::lookup(TM->getTargetTriple()); if (!ET) { return llvm::make_error<llvm::StringError>( "no Exegesis target for triple " + TripleName, llvm::inconvertibleErrorCode()); } const PfmCountersInfo &PCI = UseDummyPerfCounters ? ET->getDummyPfmCounters() : ET->getPfmCounters(CpuName); return LLVMState(std::move(TM), ET, &PCI); } LLVMState::LLVMState(std::unique_ptr<const TargetMachine> TM, const ExegesisTarget *ET, const PfmCountersInfo *PCI) : TheExegesisTarget(ET), TheTargetMachine(std::move(TM)), PfmCounters(PCI), OpcodeNameToOpcodeIdxMapping(createOpcodeNameToOpcodeIdxMapping()), RegNameToRegNoMapping(createRegNameToRegNoMapping()) { BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine()); for (const unsigned Reg : TheExegesisTarget->getUnavailableRegisters()) ReservedRegs.set(Reg); RATC.reset( new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs))); IC.reset(new InstructionsCache(getInstrInfo(), getRATC())); } std::unique_ptr<LLVMTargetMachine> LLVMState::createTargetMachine() const { return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>( TheTargetMachine->getTarget().createTargetMachine( TheTargetMachine->getTargetTriple().normalize(), TheTargetMachine->getTargetCPU(), TheTargetMachine->getTargetFeatureString(), TheTargetMachine->Options, Reloc::Model::Static))); } std::unique_ptr<const DenseMap<StringRef, unsigned>> LLVMState::createOpcodeNameToOpcodeIdxMapping() const { const MCInstrInfo &InstrInfo = getInstrInfo(); auto Map = std::make_unique<DenseMap<StringRef, unsigned>>( InstrInfo.getNumOpcodes()); for (unsigned I = 0, E = InstrInfo.getNumOpcodes(); I < E; ++I) (*Map)[InstrInfo.getName(I)] = I; assert(Map->size() == InstrInfo.getNumOpcodes() && "Size prediction failed"); return std::move(Map); } std::unique_ptr<const DenseMap<StringRef, unsigned>> LLVMState::createRegNameToRegNoMapping() const { const MCRegisterInfo &RegInfo = getRegInfo(); auto Map = std::make_unique<DenseMap<StringRef, unsigned>>(RegInfo.getNumRegs()); // Special-case RegNo 0, which would otherwise be spelled as ''. (*Map)[kNoRegister] = 0; for (unsigned I = 1, E = RegInfo.getNumRegs(); I < E; ++I) (*Map)[RegInfo.getName(I)] = I; assert(Map->size() == RegInfo.getNumRegs() && "Size prediction failed"); return std::move(Map); } bool LLVMState::canAssemble(const MCInst &Inst) const { MCContext Context(TheTargetMachine->getTargetTriple(), TheTargetMachine->getMCAsmInfo(), TheTargetMachine->getMCRegisterInfo(), TheTargetMachine->getMCSubtargetInfo()); std::unique_ptr<const MCCodeEmitter> CodeEmitter( TheTargetMachine->getTarget().createMCCodeEmitter( *TheTargetMachine->getMCInstrInfo(), Context)); assert(CodeEmitter && "unable to create code emitter"); SmallVector<char, 16> Tmp; SmallVector<MCFixup, 4> Fixups; CodeEmitter->encodeInstruction(Inst, Tmp, Fixups, *TheTargetMachine->getMCSubtargetInfo()); return Tmp.size() > 0; } } // namespace exegesis } // namespace llvm