LLVM  14.0.0git
Mips16HardFloat.cpp
Go to the documentation of this file.
1 //===- Mips16HardFloat.cpp for Mips16 Hard Float --------------------------===//
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 // This file defines a pass needed for Mips16 Hard Float
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MipsTargetMachine.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/IR/Value.h"
17 #include "llvm/Support/Debug.h"
19 #include <algorithm>
20 #include <string>
21 
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "mips16-hard-float"
25 
26 namespace {
27 
28  class Mips16HardFloat : public ModulePass {
29  public:
30  static char ID;
31 
33 
34  StringRef getPassName() const override { return "MIPS16 Hard Float Pass"; }
35 
36  void getAnalysisUsage(AnalysisUsage &AU) const override {
39  }
40 
41  bool runOnModule(Module &M) override;
42  };
43 
44 } // end anonymous namespace
45 
46 static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText) {
47  std::vector<Type *> AsmArgTypes;
48  std::vector<Value *> AsmArgs;
49 
50  FunctionType *AsmFTy =
51  FunctionType::get(Type::getVoidTy(C), AsmArgTypes, false);
52  InlineAsm *IA = InlineAsm::get(AsmFTy, AsmText, "", true,
53  /* IsAlignStack */ false, InlineAsm::AD_ATT);
54  CallInst::Create(IA, AsmArgs, "", BB);
55 }
56 
57 char Mips16HardFloat::ID = 0;
58 
59 //
60 // Return types that matter for hard float are:
61 // float, double, complex float, and complex double
62 //
65 };
66 
67 //
68 // Determine which FP return type this function has
69 //
71  switch (T->getTypeID()) {
72  case Type::FloatTyID:
73  return FRet;
74  case Type::DoubleTyID:
75  return DRet;
76  case Type::StructTyID: {
77  StructType *ST = cast<StructType>(T);
78  if (ST->getNumElements() != 2)
79  break;
80  if ((ST->getElementType(0)->isFloatTy()) &&
81  (ST->getElementType(1)->isFloatTy()))
82  return CFRet;
83  if ((ST->getElementType(0)->isDoubleTy()) &&
84  (ST->getElementType(1)->isDoubleTy()))
85  return CDRet;
86  break;
87  }
88  default:
89  break;
90  }
91  return NoFPRet;
92 }
93 
94 // Parameter type that matter are float, (float, float), (float, double),
95 // double, (double, double), (double, float)
99 };
100 
101 // which floating point parameter signature variant we are dealing with
105 
107  switch (F.arg_size()) {
108  case 0:
109  return NoSig;
110  case 1:{
111  TypeID ArgTypeID = F.getFunctionType()->getParamType(0)->getTypeID();
112  switch (ArgTypeID) {
113  case FloatTyID:
114  return FSig;
115  case DoubleTyID:
116  return DSig;
117  default:
118  return NoSig;
119  }
120  }
121  default: {
122  TypeID ArgTypeID0 = F.getFunctionType()->getParamType(0)->getTypeID();
123  TypeID ArgTypeID1 = F.getFunctionType()->getParamType(1)->getTypeID();
124  switch(ArgTypeID0) {
125  case FloatTyID: {
126  switch (ArgTypeID1) {
127  case FloatTyID:
128  return FFSig;
129  case DoubleTyID:
130  return FDSig;
131  default:
132  return FSig;
133  }
134  }
135  case DoubleTyID: {
136  switch (ArgTypeID1) {
137  case FloatTyID:
138  return DFSig;
139  case DoubleTyID:
140  return DDSig;
141  default:
142  return DSig;
143  }
144  }
145  default:
146  return NoSig;
147  }
148  }
149  }
150  llvm_unreachable("can't get here");
151 }
152 
153 // Figure out if we need float point based on the function parameters.
154 // We need to move variables in and/or out of floating point
155 // registers because of the ABI
157  if (F.arg_size() >=1) {
158  Type *ArgType = F.getFunctionType()->getParamType(0);
159  switch (ArgType->getTypeID()) {
160  case Type::FloatTyID:
161  case Type::DoubleTyID:
162  return true;
163  default:
164  break;
165  }
166  }
167  return false;
168 }
169 
171  Type* RetType = F.getReturnType();
172  return whichFPReturnVariant(RetType) != NoFPRet;
173 }
174 
176  Type* RetType = FT.getReturnType();
177  return whichFPReturnVariant(RetType) != NoFPRet;
178 }
179 
182 }
183 
184 // We swap between FP and Integer registers to allow Mips16 and Mips32 to
185 // interoperate
186 static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE,
187  bool ToFP) {
188  std::string MI = ToFP ? "mtc1 ": "mfc1 ";
189  std::string AsmText;
190 
191  switch (PV) {
192  case FSig:
193  AsmText += MI + "$$4, $$f12\n";
194  break;
195 
196  case FFSig:
197  AsmText += MI + "$$4, $$f12\n";
198  AsmText += MI + "$$5, $$f14\n";
199  break;
200 
201  case FDSig:
202  AsmText += MI + "$$4, $$f12\n";
203  if (LE) {
204  AsmText += MI + "$$6, $$f14\n";
205  AsmText += MI + "$$7, $$f15\n";
206  } else {
207  AsmText += MI + "$$7, $$f14\n";
208  AsmText += MI + "$$6, $$f15\n";
209  }
210  break;
211 
212  case DSig:
213  if (LE) {
214  AsmText += MI + "$$4, $$f12\n";
215  AsmText += MI + "$$5, $$f13\n";
216  } else {
217  AsmText += MI + "$$5, $$f12\n";
218  AsmText += MI + "$$4, $$f13\n";
219  }
220  break;
221 
222  case DDSig:
223  if (LE) {
224  AsmText += MI + "$$4, $$f12\n";
225  AsmText += MI + "$$5, $$f13\n";
226  AsmText += MI + "$$6, $$f14\n";
227  AsmText += MI + "$$7, $$f15\n";
228  } else {
229  AsmText += MI + "$$5, $$f12\n";
230  AsmText += MI + "$$4, $$f13\n";
231  AsmText += MI + "$$7, $$f14\n";
232  AsmText += MI + "$$6, $$f15\n";
233  }
234  break;
235 
236  case DFSig:
237  if (LE) {
238  AsmText += MI + "$$4, $$f12\n";
239  AsmText += MI + "$$5, $$f13\n";
240  } else {
241  AsmText += MI + "$$5, $$f12\n";
242  AsmText += MI + "$$4, $$f13\n";
243  }
244  AsmText += MI + "$$6, $$f14\n";
245  break;
246 
247  case NoSig:
248  break;
249  }
250 
251  return AsmText;
252 }
253 
254 // Make sure that we know we already need a stub for this function.
255 // Having called needsFPHelperFromSig
257  const MipsTargetMachine &TM) {
258  // for now we only need them for static relocation
259  if (TM.isPositionIndependent())
260  return;
261  LLVMContext &Context = M->getContext();
262  bool LE = TM.isLittleEndian();
263  std::string Name(F.getName());
264  std::string SectionName = ".mips16.call.fp." + Name;
265  std::string StubName = "__call_stub_fp_" + Name;
266  //
267  // see if we already have the stub
268  //
269  Function *FStub = M->getFunction(StubName);
270  if (FStub && !FStub->isDeclaration()) return;
271  FStub = Function::Create(F.getFunctionType(),
272  Function::InternalLinkage, StubName, M);
273  FStub->addFnAttr("mips16_fp_stub");
274  FStub->addFnAttr(Attribute::Naked);
275  FStub->addFnAttr(Attribute::NoInline);
276  FStub->addFnAttr(Attribute::NoUnwind);
277  FStub->addFnAttr("nomips16");
278  FStub->setSection(SectionName);
279  BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
282 
283  std::string AsmText;
284  AsmText += ".set reorder\n";
285  AsmText += swapFPIntParams(PV, M, LE, true);
286  if (RV != NoFPRet) {
287  AsmText += "move $$18, $$31\n";
288  AsmText += "jal " + Name + "\n";
289  } else {
290  AsmText += "lui $$25, %hi(" + Name + ")\n";
291  AsmText += "addiu $$25, $$25, %lo(" + Name + ")\n";
292  }
293 
294  switch (RV) {
295  case FRet:
296  AsmText += "mfc1 $$2, $$f0\n";
297  break;
298 
299  case DRet:
300  if (LE) {
301  AsmText += "mfc1 $$2, $$f0\n";
302  AsmText += "mfc1 $$3, $$f1\n";
303  } else {
304  AsmText += "mfc1 $$3, $$f0\n";
305  AsmText += "mfc1 $$2, $$f1\n";
306  }
307  break;
308 
309  case CFRet:
310  if (LE) {
311  AsmText += "mfc1 $$2, $$f0\n";
312  AsmText += "mfc1 $$3, $$f2\n";
313  } else {
314  AsmText += "mfc1 $$3, $$f0\n";
315  AsmText += "mfc1 $$3, $$f2\n";
316  }
317  break;
318 
319  case CDRet:
320  if (LE) {
321  AsmText += "mfc1 $$4, $$f2\n";
322  AsmText += "mfc1 $$5, $$f3\n";
323  AsmText += "mfc1 $$2, $$f0\n";
324  AsmText += "mfc1 $$3, $$f1\n";
325 
326  } else {
327  AsmText += "mfc1 $$5, $$f2\n";
328  AsmText += "mfc1 $$4, $$f3\n";
329  AsmText += "mfc1 $$3, $$f0\n";
330  AsmText += "mfc1 $$2, $$f1\n";
331  }
332  break;
333 
334  case NoFPRet:
335  break;
336  }
337 
338  if (RV != NoFPRet)
339  AsmText += "jr $$18\n";
340  else
341  AsmText += "jr $$25\n";
342  emitInlineAsm(Context, BB, AsmText);
343 
344  new UnreachableInst(Context, BB);
345 }
346 
347 // Functions that are llvm intrinsics and don't need helpers.
348 static const char *const IntrinsicInline[] = {
349  "fabs", "fabsf",
350  "llvm.ceil.f32", "llvm.ceil.f64",
351  "llvm.copysign.f32", "llvm.copysign.f64",
352  "llvm.cos.f32", "llvm.cos.f64",
353  "llvm.exp.f32", "llvm.exp.f64",
354  "llvm.exp2.f32", "llvm.exp2.f64",
355  "llvm.fabs.f32", "llvm.fabs.f64",
356  "llvm.floor.f32", "llvm.floor.f64",
357  "llvm.fma.f32", "llvm.fma.f64",
358  "llvm.log.f32", "llvm.log.f64",
359  "llvm.log10.f32", "llvm.log10.f64",
360  "llvm.nearbyint.f32", "llvm.nearbyint.f64",
361  "llvm.pow.f32", "llvm.pow.f64",
362  "llvm.powi.f32.i32", "llvm.powi.f64.i32",
363  "llvm.rint.f32", "llvm.rint.f64",
364  "llvm.round.f32", "llvm.round.f64",
365  "llvm.sin.f32", "llvm.sin.f64",
366  "llvm.sqrt.f32", "llvm.sqrt.f64",
367  "llvm.trunc.f32", "llvm.trunc.f64",
368 };
369 
370 static bool isIntrinsicInline(Function *F) {
371  return std::binary_search(std::begin(IntrinsicInline),
372  std::end(IntrinsicInline), F->getName());
373 }
374 
375 // Returns of float, double and complex need to be handled with a helper
376 // function.
378  const MipsTargetMachine &TM) {
379  bool Modified = false;
380  LLVMContext &C = M->getContext();
381  Type *MyVoid = Type::getVoidTy(C);
382  for (auto &BB: F)
383  for (auto &I: BB) {
384  if (const ReturnInst *RI = dyn_cast<ReturnInst>(&I)) {
385  Value *RVal = RI->getReturnValue();
386  if (!RVal) continue;
387  //
388  // If there is a return value and it needs a helper function,
389  // figure out which one and add a call before the actual
390  // return to this helper. The purpose of the helper is to move
391  // floating point values from their soft float return mapping to
392  // where they would have been mapped to in floating point registers.
393  //
394  Type *T = RVal->getType();
396  if (RV == NoFPRet) continue;
397  static const char *const Helper[NoFPRet] = {
398  "__mips16_ret_sf", "__mips16_ret_df", "__mips16_ret_sc",
399  "__mips16_ret_dc"
400  };
401  const char *Name = Helper[RV];
402  AttributeList A;
403  Value *Params[] = {RVal};
404  Modified = true;
405  //
406  // These helper functions have a different calling ABI so
407  // this __Mips16RetHelper indicates that so that later
408  // during call setup, the proper call lowering to the helper
409  // functions will take place.
410  //
411  A = A.addFnAttribute(C, "__Mips16RetHelper");
412  A = A.addFnAttribute(C, Attribute::ReadNone);
413  A = A.addFnAttribute(C, Attribute::NoInline);
414  FunctionCallee F = (M->getOrInsertFunction(Name, A, MyVoid, T));
415  CallInst::Create(F, Params, "", &I);
416  } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
417  FunctionType *FT = CI->getFunctionType();
418  Function *F_ = CI->getCalledFunction();
419  if (needsFPReturnHelper(*FT) &&
420  !(F_ && isIntrinsicInline(F_))) {
421  Modified=true;
422  F.addFnAttr("saveS2");
423  }
424  if (F_ && !isIntrinsicInline(F_)) {
425  // pic mode calls are handled by already defined
426  // helper functions
427  if (needsFPReturnHelper(*F_)) {
428  Modified=true;
429  F.addFnAttr("saveS2");
430  }
431  if (!TM.isPositionIndependent()) {
432  if (needsFPHelperFromSig(*F_)) {
433  assureFPCallStub(*F_, M, TM);
434  Modified=true;
435  }
436  }
437  }
438  }
439  }
440  return Modified;
441 }
442 
444  const MipsTargetMachine &TM) {
445  bool PicMode = TM.isPositionIndependent();
446  bool LE = TM.isLittleEndian();
447  LLVMContext &Context = M->getContext();
448  std::string Name(F->getName());
449  std::string SectionName = ".mips16.fn." + Name;
450  std::string StubName = "__fn_stub_" + Name;
451  std::string LocalName = "$$__fn_local_" + Name;
452  Function *FStub = Function::Create
453  (F->getFunctionType(),
454  Function::InternalLinkage, StubName, M);
455  FStub->addFnAttr("mips16_fp_stub");
456  FStub->addFnAttr(Attribute::Naked);
457  FStub->addFnAttr(Attribute::NoUnwind);
458  FStub->addFnAttr(Attribute::NoInline);
459  FStub->addFnAttr("nomips16");
460  FStub->setSection(SectionName);
461  BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
462 
463  std::string AsmText;
464  if (PicMode) {
465  AsmText += ".set noreorder\n";
466  AsmText += ".cpload $$25\n";
467  AsmText += ".set reorder\n";
468  AsmText += ".reloc 0, R_MIPS_NONE, " + Name + "\n";
469  AsmText += "la $$25, " + LocalName + "\n";
470  } else
471  AsmText += "la $$25, " + Name + "\n";
472  AsmText += swapFPIntParams(PV, M, LE, false);
473  AsmText += "jr $$25\n";
474  AsmText += LocalName + " = " + Name + "\n";
475  emitInlineAsm(Context, BB, AsmText);
476 
477  new UnreachableInst(FStub->getContext(), BB);
478 }
479 
480 // remove the use-soft-float attribute
482  AttrBuilder B;
483  LLVM_DEBUG(errs() << "removing -use-soft-float\n");
484  B.addAttribute("use-soft-float", "false");
485  F.removeFnAttrs(B);
486  if (F.hasFnAttribute("use-soft-float")) {
487  LLVM_DEBUG(errs() << "still has -use-soft-float\n");
488  }
489  F.addFnAttrs(B);
490 }
491 
492 // This pass only makes sense when the underlying chip has floating point but
493 // we are compiling as mips16.
494 // For all mips16 functions (that are not stubs we have already generated), or
495 // declared via attributes as nomips16, we must:
496 // 1) fixup all returns of float, double, single and double complex
497 // by calling a helper function before the actual return.
498 // 2) generate helper functions (stubs) that can be called by mips32
499 // functions that will move parameters passed normally passed in
500 // floating point
501 // registers the soft float equivalents.
502 // 3) in the case of static relocation, generate helper functions so that
503 // mips16 functions can call extern functions of unknown type (mips16 or
504 // mips32).
505 // 4) TBD. For pic, calls to extern functions of unknown type are handled by
506 // predefined helper functions in libc but this work is currently done
507 // during call lowering but it should be moved here in the future.
508 bool Mips16HardFloat::runOnModule(Module &M) {
509  auto &TM = static_cast<const MipsTargetMachine &>(
510  getAnalysis<TargetPassConfig>().getTM<TargetMachine>());
511  LLVM_DEBUG(errs() << "Run on Module Mips16HardFloat\n");
512  bool Modified = false;
513  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
514  if (F->hasFnAttribute("nomips16") &&
515  F->hasFnAttribute("use-soft-float")) {
517  continue;
518  }
519  if (F->isDeclaration() || F->hasFnAttribute("mips16_fp_stub") ||
520  F->hasFnAttribute("nomips16")) continue;
521  Modified |= fixupFPReturnAndCall(*F, &M, TM);
523  if (V != NoSig) {
524  Modified = true;
525  createFPFnStub(&*F, &M, V, TM);
526  }
527  }
528  return Modified;
529 }
530 
532  return new Mips16HardFloat();
533 }
assureFPCallStub
static void assureFPCallStub(Function &F, Module *M, const MipsTargetMachine &TM)
Definition: Mips16HardFloat.cpp:256
FFSig
@ FFSig
Definition: Mips16HardFloat.cpp:97
fixupFPReturnAndCall
static bool fixupFPReturnAndCall(Function &F, Module *M, const MipsTargetMachine &TM)
Definition: Mips16HardFloat.cpp:377
llvm::MipsTargetMachine
Definition: MipsTargetMachine.h:27
llvm::Type::FloatTyID
@ FloatTyID
32-bit floating point type
Definition: Type.h:58
FPReturnVariant
FPReturnVariant
Definition: Mips16HardFloat.cpp:63
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm::Type::DoubleTyID
@ DoubleTyID
64-bit floating point type
Definition: Type.h:59
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
FloatTyID
const Type::TypeID FloatTyID
Definition: Mips16HardFloat.cpp:103
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::ReturnInst
Return a value (possibly void), from a function.
Definition: Instructions.h:2986
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
llvm::Module::iterator
FunctionListType::iterator iterator
The Function iterators.
Definition: Module.h:92
T
llvm::Function
Definition: Function.h:62
llvm::InlineAsm::AD_ATT
@ AD_ATT
Definition: InlineAsm.h:34
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:363
llvm::Type::getTypeID
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:135
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:321
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
llvm::AttributeList
Definition: Attributes.h:399
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
llvm::sys::path::begin
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:224
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
llvm::createMips16HardFloatPass
ModulePass * createMips16HardFloatPass()
Definition: Mips16HardFloat.cpp:531
MipsTargetMachine.h
DSig
@ DSig
Definition: Mips16HardFloat.cpp:98
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:56
isIntrinsicInline
static bool isIntrinsicInline(Function *F)
Definition: Mips16HardFloat.cpp:370
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::GlobalValue::isDeclaration
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:228
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::GlobalObject::setSection
void setSection(StringRef S)
Change the section for this global.
Definition: Globals.cpp:212
DRet
@ DRet
Definition: Mips16HardFloat.cpp:64
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::CallInst::Create
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Definition: Instructions.h:1518
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
whichFPReturnVariant
static FPReturnVariant whichFPReturnVariant(Type *T)
Definition: Mips16HardFloat.cpp:70
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LocalName
Definition: ItaniumDemangle.h:1001
LoopDeletionResult::Modified
@ Modified
llvm::AArch64CC::LE
@ LE
Definition: AArch64BaseInfo.h:268
llvm::GlobalValue::InternalLinkage
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
FDSig
@ FDSig
Definition: Mips16HardFloat.cpp:97
llvm::InlineAsm::get
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition: InlineAsm.cpp:42
DoubleTyID
const Type::TypeID DoubleTyID
Definition: Mips16HardFloat.cpp:104
llvm::TargetPassConfig
Target-Independent Code Generator Pass Configuration Options.
Definition: TargetPassConfig.h:84
llvm::InlineAsm
Definition: InlineAsm.h:31
createFPFnStub
static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsTargetMachine &TM)
Definition: Mips16HardFloat.cpp:443
llvm::Function::getReturnType
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:182
CDRet
@ CDRet
Definition: Mips16HardFloat.cpp:64
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::AttrBuilder
Definition: Attributes.h:931
FRet
@ FRet
Definition: Mips16HardFloat.cpp:64
DDSig
@ DDSig
Definition: Mips16HardFloat.cpp:98
TargetPassConfig.h
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:139
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:79
emitInlineAsm
static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText)
Definition: Mips16HardFloat.cpp:46
needsFPHelperFromSig
static bool needsFPHelperFromSig(Function &F)
Definition: Mips16HardFloat.cpp:180
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Mips16HardFloat
static cl::opt< bool > Mips16HardFloat("mips16-hard-float", cl::NotHidden, cl::desc("Enable mips16 hard float."), cl::init(false))
llvm::StructType
Class to represent struct types.
Definition: DerivedTypes.h:213
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
NoFPRet
@ NoFPRet
Definition: Mips16HardFloat.cpp:64
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
removeUseSoftFloat
static void removeUseSoftFloat(Function &F)
Definition: Mips16HardFloat.cpp:481
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:100
CFRet
@ CFRet
Definition: Mips16HardFloat.cpp:64
needsFPStubFromParams
static bool needsFPStubFromParams(Function &F)
Definition: Mips16HardFloat.cpp:156
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
DFSig
@ DFSig
Definition: Mips16HardFloat.cpp:98
llvm::SectionName
Definition: DWARFSection.h:21
needsFPReturnHelper
static bool needsFPReturnHelper(Function &F)
Definition: Mips16HardFloat.cpp:170
swapFPIntParams
static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE, bool ToFP)
Definition: Mips16HardFloat.cpp:186
IntrinsicInline
static const char *const IntrinsicInline[]
Definition: Mips16HardFloat.cpp:348
FPParamVariant
FPParamVariant
Definition: Mips16HardFloat.cpp:96
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:224
llvm::Type::StructTyID
@ StructTyID
Structures.
Definition: Type.h:74
NoSig
@ NoSig
Definition: Mips16HardFloat.cpp:98
llvm::Function::addFnAttr
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.cpp:536
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
llvm::Pass::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:93
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1475
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::UnreachableInst
This function has undefined behavior.
Definition: Instructions.h:4713
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::Type::TypeID
TypeID
Definitions of all of the base types for the Type system.
Definition: Type.h:54
whichFPParamVariantNeeded
static FPParamVariant whichFPParamVariantNeeded(Function &F)
Definition: Mips16HardFloat.cpp:106
FSig
@ FSig
Definition: Mips16HardFloat.cpp:97
raw_ostream.h
Value.h
llvm::FunctionType::getReturnType
Type * getReturnType() const
Definition: DerivedTypes.h:124
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
Debug.h
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37