Allow SymbolUserOpInterface operators to be used in RemoveDeadValues Pass (#117405)
[llvm-project.git] / llvm / tools / llvm-exegesis / lib / LlvmState.cpp
blob4c44c59286ccfb18319b2804d3dc4c1c51404cec
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 //===----------------------------------------------------------------------===//
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"
21 namespace llvm {
22 namespace exegesis {
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());
31 Triple TheTriple(TripleName);
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());
42 // Update Triple with the updated triple from the target lookup.
43 TripleName = TheTriple.str();
45 if (CpuName == "native")
46 CpuName = std::string(sys::getHostCPUName());
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());
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());
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());
74 const PfmCountersInfo &PCI = UseDummyPerfCounters
75 ? ET->getDummyPfmCounters()
76 : ET->getPfmCounters(CpuName);
77 return LLVMState(std::move(TM), ET, &PCI);
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 unsigned Reg : TheExegesisTarget->getUnavailableRegisters())
87 ReservedRegs.set(Reg);
88 RATC.reset(
89 new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs)));
90 IC.reset(new InstructionsCache(getInstrInfo(), getRATC()));
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));
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;
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);
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);
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;
150 } // namespace exegesis
151 } // namespace llvm