LLVM  3.7.0
MipsTargetMachine.cpp
Go to the documentation of this file.
1 //===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Implements the info about Mips target spec.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MipsTargetMachine.h"
15 #include "Mips.h"
16 #include "Mips16FrameLowering.h"
17 #include "Mips16ISelDAGToDAG.h"
18 #include "Mips16ISelLowering.h"
19 #include "Mips16InstrInfo.h"
20 #include "MipsFrameLowering.h"
21 #include "MipsInstrInfo.h"
22 #include "MipsSEFrameLowering.h"
23 #include "MipsSEISelDAGToDAG.h"
24 #include "MipsSEISelLowering.h"
25 #include "MipsSEInstrInfo.h"
26 #include "MipsTargetObjectFile.h"
28 #include "llvm/CodeGen/Passes.h"
30 #include "llvm/Support/Debug.h"
33 #include "llvm/Transforms/Scalar.h"
34 
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "mips"
38 
39 extern "C" void LLVMInitializeMipsTarget() {
40  // Register the target.
45 }
46 
47 static std::string computeDataLayout(const Triple &TT, StringRef CPU,
48  const TargetOptions &Options,
49  bool isLittle) {
50  std::string Ret = "";
51  MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions);
52 
53  // There are both little and big endian mips.
54  if (isLittle)
55  Ret += "e";
56  else
57  Ret += "E";
58 
59  Ret += "-m:m";
60 
61  // Pointers are 32 bit on some ABIs.
62  if (!ABI.IsN64())
63  Ret += "-p:32:32";
64 
65  // 8 and 16 bit integers only need to have natural alignment, but try to
66  // align them to 32 bits. 64 bit integers have natural alignment.
67  Ret += "-i8:8:32-i16:16:32-i64:64";
68 
69  // 32 bit registers are always available and the stack is at least 64 bit
70  // aligned. On N64 64 bit registers are also available and the stack is
71  // 128 bit aligned.
72  if (ABI.IsN64() || ABI.IsN32())
73  Ret += "-n32:64-S128";
74  else
75  Ret += "-n32-S64";
76 
77  return Ret;
78 }
79 
80 // On function prologue, the stack is created by decrementing
81 // its pointer. Once decremented, all references are done with positive
82 // offset from the stack/frame pointer, using StackGrowsUp enables
83 // an easier handling.
84 // Using CodeModel::Large enables different CALL behavior.
86  StringRef CPU, StringRef FS,
87  const TargetOptions &Options,
89  CodeGenOpt::Level OL, bool isLittle)
90  : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
91  CPU, FS, Options, RM, CM, OL),
92  isLittle(isLittle), TLOF(make_unique<MipsTargetObjectFile>()),
93  ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)),
94  Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this),
95  NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16",
96  isLittle, *this),
97  Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16",
98  isLittle, *this) {
99  Subtarget = &DefaultSubtarget;
100  initAsmInfo();
101 }
102 
104 
105 void MipsebTargetMachine::anchor() { }
106 
108  StringRef CPU, StringRef FS,
109  const TargetOptions &Options,
112  : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
113 
114 void MipselTargetMachine::anchor() { }
115 
117  StringRef CPU, StringRef FS,
118  const TargetOptions &Options,
121  : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
122 
123 const MipsSubtarget *
125  Attribute CPUAttr = F.getFnAttribute("target-cpu");
126  Attribute FSAttr = F.getFnAttribute("target-features");
127 
128  std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
129  ? CPUAttr.getValueAsString().str()
130  : TargetCPU;
131  std::string FS = !FSAttr.hasAttribute(Attribute::None)
132  ? FSAttr.getValueAsString().str()
133  : TargetFS;
134  bool hasMips16Attr =
136  bool hasNoMips16Attr =
138 
139  // FIXME: This is related to the code below to reset the target options,
140  // we need to know whether or not the soft float flag is set on the
141  // function, so we can enable it as a subtarget feature.
142  bool softFloat =
143  F.hasFnAttribute("use-soft-float") &&
144  F.getFnAttribute("use-soft-float").getValueAsString() == "true";
145 
146  if (hasMips16Attr)
147  FS += FS.empty() ? "+mips16" : ",+mips16";
148  else if (hasNoMips16Attr)
149  FS += FS.empty() ? "-mips16" : ",-mips16";
150  if (softFloat)
151  FS += FS.empty() ? "+soft-float" : ",+soft-float";
152 
153  auto &I = SubtargetMap[CPU + FS];
154  if (!I) {
155  // This needs to be done before we create a new subtarget since any
156  // creation will depend on the TM and the code generation flags on the
157  // function that reside in TargetOptions.
159  I = llvm::make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle,
160  *this);
161  }
162  return I.get();
163 }
164 
166  DEBUG(dbgs() << "resetSubtarget\n");
167 
168  Subtarget = const_cast<MipsSubtarget *>(getSubtargetImpl(*MF->getFunction()));
169  MF->setSubtarget(Subtarget);
170  return;
171 }
172 
173 namespace {
174 /// Mips Code Generator Pass Configuration Options.
175 class MipsPassConfig : public TargetPassConfig {
176 public:
177  MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM)
178  : TargetPassConfig(TM, PM) {
179  // The current implementation of long branch pass requires a scratch
180  // register ($at) to be available before branch instructions. Tail merging
181  // can break this requirement, so disable it when long branch pass is
182  // enabled.
183  EnableTailMerge = !getMipsSubtarget().enableLongBranchPass();
184  }
185 
186  MipsTargetMachine &getMipsTargetMachine() const {
187  return getTM<MipsTargetMachine>();
188  }
189 
190  const MipsSubtarget &getMipsSubtarget() const {
191  return *getMipsTargetMachine().getSubtargetImpl();
192  }
193 
194  void addIRPasses() override;
195  bool addInstSelector() override;
196  void addMachineSSAOptimization() override;
197  void addPreEmitPass() override;
198 
199  void addPreRegAlloc() override;
200 
201 };
202 } // namespace
203 
205  return new MipsPassConfig(this, PM);
206 }
207 
208 void MipsPassConfig::addIRPasses() {
210  addPass(createAtomicExpandPass(&getMipsTargetMachine()));
211  if (getMipsSubtarget().os16())
212  addPass(createMipsOs16Pass(getMipsTargetMachine()));
213  if (getMipsSubtarget().inMips16HardFloat())
214  addPass(createMips16HardFloatPass(getMipsTargetMachine()));
215 }
216 // Install an instruction selector pass using
217 // the ISelDag to gen Mips code.
218 bool MipsPassConfig::addInstSelector() {
219  addPass(createMipsModuleISelDagPass(getMipsTargetMachine()));
220  addPass(createMips16ISelDag(getMipsTargetMachine()));
221  addPass(createMipsSEISelDag(getMipsTargetMachine()));
222  return false;
223 }
224 
225 void MipsPassConfig::addMachineSSAOptimization() {
226  addPass(createMipsOptimizePICCallPass(getMipsTargetMachine()));
228 }
229 
230 void MipsPassConfig::addPreRegAlloc() {
231  if (getOptLevel() == CodeGenOpt::None)
232  addPass(createMipsOptimizePICCallPass(getMipsTargetMachine()));
233 }
234 
236  return TargetIRAnalysis([this](Function &F) {
237  if (Subtarget->allowMixed16_32()) {
238  DEBUG(errs() << "No Target Transform Info Pass Added\n");
239  // FIXME: This is no longer necessary as the TTI returned is per-function.
241  }
242 
243  DEBUG(errs() << "Target Transform Info Pass Added\n");
244  return TargetTransformInfo(BasicTTIImpl(this, F));
245  });
246 }
247 
248 // Implemented by targets that want to run passes immediately before
249 // machine code is emitted. return true if -print-machineinstrs should
250 // print out the code after the passes.
251 void MipsPassConfig::addPreEmitPass() {
252  MipsTargetMachine &TM = getMipsTargetMachine();
253  addPass(createMipsDelaySlotFillerPass(TM));
254  addPass(createMipsLongBranchPass(TM));
255  addPass(createMipsConstantIslandPass(TM));
256 }
static ARMBaseTargetMachine::ARMABI computeTargetABI(const Triple &TT, StringRef CPU, const TargetOptions &Options)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
MCTargetOptions MCOptions
Machine level options.
MipsTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL, bool isLittle)
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
Definition: Passes.cpp:377
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with...
FunctionPass * createMipsOptimizePICCallPass(MipsTargetMachine &TM)
Return an OptimizeCall object.
Analysis pass providing the TargetTransformInfo.
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:188
void resetSubtarget(MachineFunction *MF)
Reset the subtarget for the Mips target.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:225
F(f)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
virtual void addMachineSSAOptimization()
addMachineSSAOptimization - Add standard passes that optimize machine instructions in SSA form...
Definition: Passes.cpp:585
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:147
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
FunctionPass * createMipsSEISelDag(MipsTargetMachine &TM)
FunctionPass * createAtomicExpandPass(const TargetMachine *TM)
No attributes have been set.
Definition: Attributes.h:66
#define false
Definition: ConvertUTF.c:65
Target-Independent Code Generator Pass Configuration Options.
Target TheMips64elTarget
Target TheMips64Target
static std::string computeDataLayout(const Triple &TT, StringRef CPU, const TargetOptions &Options, bool isLittle)
#define true
Definition: ConvertUTF.c:66
Concrete BasicTTIImpl that can be used if no further customization is needed.
Definition: BasicTTIImpl.h:792
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
Definition: STLExtras.h:354
FunctionPass * createMipsLongBranchPass(MipsTargetMachine &TM)
createMipsLongBranchPass - Returns a pass that converts branches to long branches.
bool IsN32() const
Definition: MipsABIInfo.h:44
void setSubtarget(const TargetSubtargetInfo *ST)
bool IsN64() const
Definition: MipsABIInfo.h:45
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
This class describes a target machine that is implemented with the LLVM target-independent code gener...
FunctionPass * createMipsModuleISelDagPass(MipsTargetMachine &TM)
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
MipsebTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL)
ModulePass * createMips16HardFloatPass(MipsTargetMachine &TM)
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetIRAnalysis getTargetIRAnalysis() override
Get a TargetIRAnalysis implementation for the target.
FunctionPass * createMipsDelaySlotFillerPass(MipsTargetMachine &TM)
createMipsDelaySlotFillerPass - Returns a pass that fills in delay slots in Mips MachineFunctions ...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
Target - Wrapper for Target specific information.
ModulePass * createMipsOs16Pass(MipsTargetMachine &TM)
Definition: MipsOs16.cpp:154
FunctionPass * createMipsConstantIslandPass(MipsTargetMachine &tm)
createMipsLongBranchPass - Returns a pass that converts branches to long branches.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:372
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:217
#define I(x, y, z)
Definition: MD5.cpp:54
void resetTargetOptions(const Function &F) const
Reset the target options based on the function's attributes.
const MipsSubtarget * getSubtargetImpl() const
bool allowMixed16_32() const
Target TheMipselTarget
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:140
static MipsABIInfo computeTargetABI(const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
Definition: MipsABIInfo.cpp:50
RegisterTargetMachine - Helper template for registering a target machine implementation, for use in the target machine initialization function.
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:365
#define DEBUG(X)
Definition: Debug.h:92
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
This pass exposes codegen information to IR-level passes.
MipselTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL)
FunctionPass * createMips16ISelDag(MipsTargetMachine &TM)
Target TheMipsTarget
void LLVMInitializeMipsTarget()
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110