LLVM  12.0.0git
RISCVTargetMachine.cpp
Go to the documentation of this file.
1 //===-- RISCVTargetMachine.cpp - Define TargetMachine for RISCV -----------===//
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 // Implements the info about RISCV target spec.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVTargetMachine.h"
14 #include "RISCV.h"
15 #include "RISCVTargetObjectFile.h"
18 #include "Utils/RISCVBaseInfo.h"
19 #include "llvm/ADT/STLExtras.h"
25 #include "llvm/CodeGen/Passes.h"
29 #include "llvm/InitializePasses.h"
33 using namespace llvm;
34 
41 }
42 
43 static StringRef computeDataLayout(const Triple &TT) {
44  if (TT.isArch64Bit()) {
45  return "e-m:e-p:64:64-i64:64-i128:128-n64-S128";
46  } else {
47  assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported");
48  return "e-m:e-p:32:32-i64:64-n32-S128";
49  }
50 }
51 
54  if (!RM.hasValue())
55  return Reloc::Static;
56  return *RM;
57 }
58 
60  StringRef CPU, StringRef FS,
61  const TargetOptions &Options,
64  CodeGenOpt::Level OL, bool JIT)
65  : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
66  getEffectiveRelocModel(TT, RM),
67  getEffectiveCodeModel(CM, CodeModel::Small), OL),
68  TLOF(std::make_unique<RISCVELFTargetObjectFile>()) {
69  initAsmInfo();
70 
71  // RISC-V supports the MachineOutliner.
72  setMachineOutliner(true);
73 }
74 
75 const RISCVSubtarget *
77  Attribute CPUAttr = F.getFnAttribute("target-cpu");
78  Attribute FSAttr = F.getFnAttribute("target-features");
79 
80  std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
81  ? CPUAttr.getValueAsString().str()
82  : TargetCPU;
83  std::string FS = !FSAttr.hasAttribute(Attribute::None)
84  ? FSAttr.getValueAsString().str()
85  : TargetFS;
86  std::string Key = CPU + FS;
87  auto &I = SubtargetMap[Key];
88  if (!I) {
89  // This needs to be done before we create a new subtarget since any
90  // creation will depend on the TM and the code generation flags on the
91  // function that reside in TargetOptions.
93  auto ABIName = Options.MCOptions.getABIName();
94  if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
95  F.getParent()->getModuleFlag("target-abi"))) {
96  auto TargetABI = RISCVABI::getTargetABI(ABIName);
97  if (TargetABI != RISCVABI::ABI_Unknown &&
98  ModuleTargetABI->getString() != ABIName) {
99  report_fatal_error("-target-abi option != target-abi module flag");
100  }
101  ABIName = ModuleTargetABI->getString();
102  }
103  I = std::make_unique<RISCVSubtarget>(TargetTriple, CPU, FS, ABIName, *this);
104  }
105  return I.get();
106 }
107 
110  return TargetTransformInfo(RISCVTTIImpl(this, F));
111 }
112 
113 namespace {
114 class RISCVPassConfig : public TargetPassConfig {
115 public:
116  RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM)
117  : TargetPassConfig(TM, PM) {}
118 
119  RISCVTargetMachine &getRISCVTargetMachine() const {
120  return getTM<RISCVTargetMachine>();
121  }
122 
123  void addIRPasses() override;
124  bool addInstSelector() override;
125  bool addIRTranslator() override;
126  bool addLegalizeMachineIR() override;
127  bool addRegBankSelect() override;
128  bool addGlobalInstructionSelect() override;
129  void addPreEmitPass() override;
130  void addPreEmitPass2() override;
131  void addPreSched2() override;
132  void addPreRegAlloc() override;
133 };
134 }
135 
137  return new RISCVPassConfig(*this, PM);
138 }
139 
140 void RISCVPassConfig::addIRPasses() {
141  addPass(createAtomicExpandPass());
143 }
144 
145 bool RISCVPassConfig::addInstSelector() {
146  addPass(createRISCVISelDag(getRISCVTargetMachine()));
147 
148  return false;
149 }
150 
151 bool RISCVPassConfig::addIRTranslator() {
152  addPass(new IRTranslator());
153  return false;
154 }
155 
156 bool RISCVPassConfig::addLegalizeMachineIR() {
157  addPass(new Legalizer());
158  return false;
159 }
160 
161 bool RISCVPassConfig::addRegBankSelect() {
162  addPass(new RegBankSelect());
163  return false;
164 }
165 
166 bool RISCVPassConfig::addGlobalInstructionSelect() {
167  addPass(new InstructionSelect());
168  return false;
169 }
170 
171 void RISCVPassConfig::addPreSched2() {}
172 
173 void RISCVPassConfig::addPreEmitPass() { addPass(&BranchRelaxationPassID); }
174 
175 void RISCVPassConfig::addPreEmitPass2() {
176  addPass(createRISCVExpandPseudoPass());
177  // Schedule the expansion of AMOs at the last possible moment, avoiding the
178  // possibility for other passes to break the requirements for forward
179  // progress in the LR/SC block.
181 }
182 
183 void RISCVPassConfig::addPreRegAlloc() {
185 }
const RISCVSubtarget * getSubtargetImpl() const =delete
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
CodeModel::Model getEffectiveCodeModel(Optional< CodeModel::Model > CM, CodeModel::Model Default)
Helper method for getting the code model, returning Default if CM does not have a value...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:248
MCTargetOptions MCOptions
Machine level options.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:23
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
void initializeRISCVExpandPseudoPass(PassRegistry &)
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with...
Definition: TargetMachine.h:84
char & BranchRelaxationPassID
BranchRelaxation - This pass replaces branches that need to jump further than is supported by a branc...
F(f)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget()
Definition: BitVector.h:959
void resetTargetOptions(const Function &F) const
Reset the target options based on the function&#39;s attributes.
No attributes have been set.
Definition: Attributes.h:72
Target & getTheRISCV32Target()
FunctionPass * createRISCVExpandAtomicPseudoPass()
Target-Independent Code Generator Pass Configuration Options.
FunctionPass * createRISCVISelDag(RISCVTargetMachine &TM)
Key
PAL metadata keys.
RegisterTargetMachine - Helper template for registering a target machine implementation, for use in the target machine initialization function.
bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1307
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:282
static Reloc::Model getEffectiveRelocModel(Optional< Reloc::Model > RM)
This pass implements the reg bank selector pass used in the GlobalISel pipeline.
Definition: RegBankSelect.h:90
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Definition: Module.cpp:321
Target & getTheRISCV64Target()
This class describes a target machine that is implemented with the LLVM target-independent code gener...
void setMachineOutliner(bool Enable)
ABI getTargetABI(StringRef ABIName)
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:131
This pass is responsible for selecting generic machine instructions to target-specific instructions...
Target - Wrapper for Target specific information.
std::string TargetCPU
Definition: TargetMachine.h:85
TargetTransformInfo getTargetTransformInfo(const Function &F) override
Get a TargetTransformInfo implementation for the target.
bool hasValue() const
Definition: Optional.h:259
StringRef getABIName() const
getABIName - If this returns a non-empty string this represents the textual name of the ABI that we w...
This file defines a TargetTransformInfo::Concept conforming object specific to the RISC-V target mach...
StringRef getValueAsString() const
Return the attribute&#39;s value as a string.
Definition: Attributes.cpp:267
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1303
static StringRef computeDataLayout(const Triple &TT)
TargetOptions Options
FunctionPass * createRISCVMergeBaseOffsetOptPass()
Returns an instance of the Merge Base Offset Optimization pass.
#define I(x, y, z)
Definition: MD5.cpp:59
FunctionPass * createRISCVExpandPseudoPass()
std::string TargetFS
Definition: TargetMachine.h:86
RISCVTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional< Reloc::Model > RM, Optional< CodeModel::Model > CM, CodeGenOpt::Level OL, bool JIT)
This file declares the IRTranslator pass.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:572
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:340
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
A single uniqued string.
Definition: Metadata.h:602
This implementation is used for RISCV ELF targets.
This pass exposes codegen information to IR-level passes.
FunctionPass * createAtomicExpandPass()
void initializeGlobalISel(PassRegistry &)
Initialize all passes linked into the GlobalISel library.
Definition: GlobalISel.cpp:18