brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · d7bf9c1 Raw
166 lines · cpp
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-exception6//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 21namespace llvm {22namespace exegesis {23 24Expected<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    // case for cross generating, when native arch and target mismatch47    if ((Triple(sys::getProcessTriple()).getArch() !=48         Triple(TripleName).getArch()))49      return make_error<StringError>(50          "A CPU must be explicitly specified when cross compiling. To see all "51          "possible options for " +52              TripleName + " triple use -mcpu=help",53          inconvertibleErrorCode());54    CpuName = std::string(sys::getHostCPUName());55  }56 57  std::unique_ptr<MCSubtargetInfo> STI(58      TheTarget->createMCSubtargetInfo(TheTriple, CpuName, ""));59  if (!STI) {60    return make_error<StringError>("unable to create subtarget info",61                                   inconvertibleErrorCode());62  }63 64  assert(STI && "Unable to create subtarget info!");65  if (!STI->isCPUStringValid(CpuName)) {66    return make_error<StringError>(Twine("invalid CPU name (")67                                       .concat(CpuName)68                                       .concat(") for triple ")69                                       .concat(TripleName),70                                   inconvertibleErrorCode());71  }72  const TargetOptions Options;73  std::unique_ptr<const TargetMachine> TM(TheTarget->createTargetMachine(74      TheTriple, CpuName, Features, Options, Reloc::Model::Static));75  if (!TM) {76    return make_error<StringError>("unable to create target machine",77                                   inconvertibleErrorCode());78  }79 80  const ExegesisTarget *ET =81      TripleName.empty() ? &ExegesisTarget::getDefault()82                         : ExegesisTarget::lookup(TM->getTargetTriple());83  if (!ET) {84    return make_error<StringError>("no Exegesis target for triple " +85                                       TripleName,86                                   inconvertibleErrorCode());87  }88  const PfmCountersInfo &PCI = UseDummyPerfCounters89                                   ? ET->getDummyPfmCounters()90                                   : ET->getPfmCounters(CpuName);91  return LLVMState(std::move(TM), ET, &PCI);92}93 94LLVMState::LLVMState(std::unique_ptr<const TargetMachine> TM,95                     const ExegesisTarget *ET, const PfmCountersInfo *PCI)96    : TheExegesisTarget(ET), TheTargetMachine(std::move(TM)), PfmCounters(PCI),97      OpcodeNameToOpcodeIdxMapping(createOpcodeNameToOpcodeIdxMapping()),98      RegNameToRegNoMapping(createRegNameToRegNoMapping()) {99  BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine());100  for (const MCPhysReg Reg : TheExegesisTarget->getUnavailableRegisters())101    ReservedRegs.set(Reg);102  RATC.reset(103      new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs)));104  IC.reset(new InstructionsCache(getInstrInfo(), getRATC()));105}106 107std::unique_ptr<TargetMachine> LLVMState::createTargetMachine() const {108  return std::unique_ptr<TargetMachine>(109      TheTargetMachine->getTarget().createTargetMachine(110          Triple(TheTargetMachine->getTargetTriple().normalize()),111          TheTargetMachine->getTargetCPU(),112          TheTargetMachine->getTargetFeatureString(), TheTargetMachine->Options,113          Reloc::Model::Static));114}115 116std::optional<MCRegister>117LLVMState::getRegisterNumberFromName(StringRef RegisterName) const {118  auto RegisterIt = RegNameToRegNoMapping->find(RegisterName);119  if (RegisterIt == RegNameToRegNoMapping->end())120    return std::nullopt;121  return RegisterIt->second;122}123 124std::unique_ptr<const DenseMap<StringRef, unsigned>>125LLVMState::createOpcodeNameToOpcodeIdxMapping() const {126  const MCInstrInfo &InstrInfo = getInstrInfo();127  auto Map = std::make_unique<DenseMap<StringRef, unsigned>>(128      InstrInfo.getNumOpcodes());129  for (unsigned I = 0, E = InstrInfo.getNumOpcodes(); I < E; ++I)130    (*Map)[InstrInfo.getName(I)] = I;131  assert(Map->size() == InstrInfo.getNumOpcodes() && "Size prediction failed");132  return std::move(Map);133}134 135std::unique_ptr<const DenseMap<StringRef, MCRegister>>136LLVMState::createRegNameToRegNoMapping() const {137  const MCRegisterInfo &RegInfo = getRegInfo();138  auto Map =139      std::make_unique<DenseMap<StringRef, MCRegister>>(RegInfo.getNumRegs());140  // Special-case RegNo 0, which would otherwise be spelled as ''.141  (*Map)[kNoRegister] = 0;142  for (unsigned I = 1, E = RegInfo.getNumRegs(); I < E; ++I)143    (*Map)[RegInfo.getName(I)] = I;144  assert(Map->size() == RegInfo.getNumRegs() && "Size prediction failed");145  return std::move(Map);146}147 148bool LLVMState::canAssemble(const MCInst &Inst) const {149  MCContext Context(TheTargetMachine->getTargetTriple(),150                    TheTargetMachine->getMCAsmInfo(),151                    TheTargetMachine->getMCRegisterInfo(),152                    TheTargetMachine->getMCSubtargetInfo());153  std::unique_ptr<const MCCodeEmitter> CodeEmitter(154      TheTargetMachine->getTarget().createMCCodeEmitter(155          *TheTargetMachine->getMCInstrInfo(), Context));156  assert(CodeEmitter && "unable to create code emitter");157  SmallVector<char, 16> Tmp;158  SmallVector<MCFixup, 4> Fixups;159  CodeEmitter->encodeInstruction(Inst, Tmp, Fixups,160                                 *TheTargetMachine->getMCSubtargetInfo());161  return Tmp.size() > 0;162}163 164} // namespace exegesis165} // namespace llvm166