LLVM  16.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"
18 #include "llvm/Support/ModRef.h"
20 #include <algorithm>
21 #include <string>
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "mips16-hard-float"
26 
27 namespace {
28 
29  class Mips16HardFloat : public ModulePass {
30  public:
31  static char ID;
32 
34 
35  StringRef getPassName() const override { return "MIPS16 Hard Float Pass"; }
36 
37  void getAnalysisUsage(AnalysisUsage &AU) const override {
40  }
41 
42  bool runOnModule(Module &M) override;
43  };
44 
45 } // end anonymous namespace
46 
47 static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText) {
48  std::vector<Type *> AsmArgTypes;
49  std::vector<Value *> AsmArgs;
50 
51  FunctionType *AsmFTy =
52  FunctionType::get(Type::getVoidTy(C), AsmArgTypes, false);
53  InlineAsm *IA = InlineAsm::get(AsmFTy, AsmText, "", true,
54  /* IsAlignStack */ false, InlineAsm::AD_ATT);
55  CallInst::Create(IA, AsmArgs, "", BB);
56 }
57 
58 char Mips16HardFloat::ID = 0;
59 
60 //
61 // Return types that matter for hard float are:
62 // float, double, complex float, and complex double
63 //
66 };
67 
68 //
69 // Determine which FP return type this function has
70 //
72  switch (T->getTypeID()) {
73  case Type::FloatTyID:
74  return FRet;
75  case Type::DoubleTyID:
76  return DRet;
77  case Type::StructTyID: {
78  StructType *ST = cast<StructType>(T);
79  if (ST->getNumElements() != 2)
80  break;
81  if ((ST->getElementType(0)->isFloatTy()) &&
82  (ST->getElementType(1)->isFloatTy()))
83  return CFRet;
84  if ((ST->getElementType(0)->isDoubleTy()) &&
85  (ST->getElementType(1)->isDoubleTy()))
86  return CDRet;
87  break;
88  }
89  default:
90  break;
91  }
92  return NoFPRet;
93 }
94 
95 // Parameter type that matter are float, (float, float), (float, double),
96 // double, (double, double), (double, float)
100 };
101 
102 // which floating point parameter signature variant we are dealing with
106 
108  switch (F.arg_size()) {
109  case 0:
110  return NoSig;
111  case 1:{
112  TypeID ArgTypeID = F.getFunctionType()->getParamType(0)->getTypeID();
113  switch (ArgTypeID) {
114  case FloatTyID:
115  return FSig;
116  case DoubleTyID:
117  return DSig;
118  default:
119  return NoSig;
120  }
121  }
122  default: {
123  TypeID ArgTypeID0 = F.getFunctionType()->getParamType(0)->getTypeID();
124  TypeID ArgTypeID1 = F.getFunctionType()->getParamType(1)->getTypeID();
125  switch(ArgTypeID0) {
126  case FloatTyID: {
127  switch (ArgTypeID1) {
128  case FloatTyID:
129  return FFSig;
130  case DoubleTyID:
131  return FDSig;
132  default:
133  return FSig;
134  }
135  }
136  case DoubleTyID: {
137  switch (ArgTypeID1) {
138  case FloatTyID:
139  return DFSig;
140  case DoubleTyID:
141  return DDSig;
142  default:
143  return DSig;
144  }
145  }
146  default:
147  return NoSig;
148  }
149  }
150  }
151  llvm_unreachable("can't get here");
152 }
153 
154 // Figure out if we need float point based on the function parameters.
155 // We need to move variables in and/or out of floating point
156 // registers because of the ABI
158  if (F.arg_size() >=1) {
159  Type *ArgType = F.getFunctionType()->getParamType(0);
160  switch (ArgType->getTypeID()) {
161  case Type::FloatTyID:
162  case Type::DoubleTyID:
163  return true;
164  default:
165  break;
166  }
167  }
168  return false;
169 }
170 
172  Type* RetType = F.getReturnType();
173  return whichFPReturnVariant(RetType) != NoFPRet;
174 }
175 
177  Type* RetType = FT.getReturnType();
178  return whichFPReturnVariant(RetType) != NoFPRet;
179 }
180 
183 }
184 
185 // We swap between FP and Integer registers to allow Mips16 and Mips32 to
186 // interoperate
187 static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE,
188  bool ToFP) {
189  std::string MI = ToFP ? "mtc1 ": "mfc1 ";
190  std::string AsmText;
191 
192  switch (PV) {
193  case FSig:
194  AsmText += MI + "$$4, $$f12\n";
195  break;
196 
197  case FFSig:
198  AsmText += MI + "$$4, $$f12\n";
199  AsmText += MI + "$$5, $$f14\n";
200  break;
201 
202  case FDSig:
203  AsmText += MI + "$$4, $$f12\n";
204  if (LE) {
205  AsmText += MI + "$$6, $$f14\n";
206  AsmText += MI + "$$7, $$f15\n";
207  } else {
208  AsmText += MI + "$$7, $$f14\n";
209  AsmText += MI + "$$6, $$f15\n";
210  }
211  break;
212 
213  case DSig:
214  if (LE) {
215  AsmText += MI + "$$4, $$f12\n";
216  AsmText += MI + "$$5, $$f13\n";
217  } else {
218  AsmText += MI + "$$5, $$f12\n";
219  AsmText += MI + "$$4, $$f13\n";
220  }
221  break;
222 
223  case DDSig:
224  if (LE) {
225  AsmText += MI + "$$4, $$f12\n";
226  AsmText += MI + "$$5, $$f13\n";
227  AsmText += MI + "$$6, $$f14\n";
228  AsmText += MI + "$$7, $$f15\n";
229  } else {
230  AsmText += MI + "$$5, $$f12\n";
231  AsmText += MI + "$$4, $$f13\n";
232  AsmText += MI + "$$7, $$f14\n";
233  AsmText += MI + "$$6, $$f15\n";
234  }
235  break;
236 
237  case DFSig:
238  if (LE) {
239  AsmText += MI + "$$4, $$f12\n";
240  AsmText += MI + "$$5, $$f13\n";
241  } else {
242  AsmText += MI + "$$5, $$f12\n";
243  AsmText += MI + "$$4, $$f13\n";
244  }
245  AsmText += MI + "$$6, $$f14\n";
246  break;
247 
248  case NoSig:
249  break;
250  }
251 
252  return AsmText;
253 }
254 
255 // Make sure that we know we already need a stub for this function.
256 // Having called needsFPHelperFromSig
258  const MipsTargetMachine &TM) {
259  // for now we only need them for static relocation
260  if (TM.isPositionIndependent())
261  return;
262  LLVMContext &Context = M->getContext();
263  bool LE = TM.isLittleEndian();
264  std::string Name(F.getName());
265  std::string SectionName = ".mips16.call.fp." + Name;
266  std::string StubName = "__call_stub_fp_" + Name;
267  //
268  // see if we already have the stub
269  //
270  Function *FStub = M->getFunction(StubName);
271  if (FStub && !FStub->isDeclaration()) return;
272  FStub = Function::Create(F.getFunctionType(),
273  Function::InternalLinkage, StubName, M);
274  FStub->addFnAttr("mips16_fp_stub");
275  FStub->addFnAttr(Attribute::Naked);
276  FStub->addFnAttr(Attribute::NoInline);
277  FStub->addFnAttr(Attribute::NoUnwind);
278  FStub->addFnAttr("nomips16");
279  FStub->setSection(SectionName);
280  BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
283 
284  std::string AsmText;
285  AsmText += ".set reorder\n";
286  AsmText += swapFPIntParams(PV, M, LE, true);
287  if (RV != NoFPRet) {
288  AsmText += "move $$18, $$31\n";
289  AsmText += "jal " + Name + "\n";
290  } else {
291  AsmText += "lui $$25, %hi(" + Name + ")\n";
292  AsmText += "addiu $$25, $$25, %lo(" + Name + ")\n";
293  }
294 
295  switch (RV) {
296  case FRet:
297  AsmText += "mfc1 $$2, $$f0\n";
298  break;
299 
300  case DRet:
301  if (LE) {
302  AsmText += "mfc1 $$2, $$f0\n";
303  AsmText += "mfc1 $$3, $$f1\n";
304  } else {
305  AsmText += "mfc1 $$3, $$f0\n";
306  AsmText += "mfc1 $$2, $$f1\n";
307  }
308  break;
309 
310  case CFRet:
311  if (LE) {
312  AsmText += "mfc1 $$2, $$f0\n";
313  AsmText += "mfc1 $$3, $$f2\n";
314  } else {
315  AsmText += "mfc1 $$3, $$f0\n";
316  AsmText += "mfc1 $$3, $$f2\n";
317  }
318  break;
319 
320  case CDRet:
321  if (LE) {
322  AsmText += "mfc1 $$4, $$f2\n";
323  AsmText += "mfc1 $$5, $$f3\n";
324  AsmText += "mfc1 $$2, $$f0\n";
325  AsmText += "mfc1 $$3, $$f1\n";
326 
327  } else {
328  AsmText += "mfc1 $$5, $$f2\n";
329  AsmText += "mfc1 $$4, $$f3\n";
330  AsmText += "mfc1 $$3, $$f0\n";
331  AsmText += "mfc1 $$2, $$f1\n";
332  }
333  break;
334 
335  case NoFPRet:
336  break;
337  }
338 
339  if (RV != NoFPRet)
340  AsmText += "jr $$18\n";
341  else
342  AsmText += "jr $$25\n";
343  emitInlineAsm(Context, BB, AsmText);
344 
345  new UnreachableInst(Context, BB);
346 }
347 
348 // Functions that are llvm intrinsics and don't need helpers.
349 static const char *const IntrinsicInline[] = {
350  "fabs", "fabsf",
351  "llvm.ceil.f32", "llvm.ceil.f64",
352  "llvm.copysign.f32", "llvm.copysign.f64",
353  "llvm.cos.f32", "llvm.cos.f64",
354  "llvm.exp.f32", "llvm.exp.f64",
355  "llvm.exp2.f32", "llvm.exp2.f64",
356  "llvm.fabs.f32", "llvm.fabs.f64",
357  "llvm.floor.f32", "llvm.floor.f64",
358  "llvm.fma.f32", "llvm.fma.f64",
359  "llvm.log.f32", "llvm.log.f64",
360  "llvm.log10.f32", "llvm.log10.f64",
361  "llvm.nearbyint.f32", "llvm.nearbyint.f64",
362  "llvm.pow.f32", "llvm.pow.f64",
363  "llvm.powi.f32.i32", "llvm.powi.f64.i32",
364  "llvm.rint.f32", "llvm.rint.f64",
365  "llvm.round.f32", "llvm.round.f64",
366  "llvm.sin.f32", "llvm.sin.f64",
367  "llvm.sqrt.f32", "llvm.sqrt.f64",
368  "llvm.trunc.f32", "llvm.trunc.f64",
369 };
370 
371 static bool isIntrinsicInline(Function *F) {
372  return std::binary_search(std::begin(IntrinsicInline),
373  std::end(IntrinsicInline), F->getName());
374 }
375 
376 // Returns of float, double and complex need to be handled with a helper
377 // function.
379  const MipsTargetMachine &TM) {
380  bool Modified = false;
381  LLVMContext &C = M->getContext();
382  Type *MyVoid = Type::getVoidTy(C);
383  for (auto &BB: F)
384  for (auto &I: BB) {
385  if (const ReturnInst *RI = dyn_cast<ReturnInst>(&I)) {
386  Value *RVal = RI->getReturnValue();
387  if (!RVal) continue;
388  //
389  // If there is a return value and it needs a helper function,
390  // figure out which one and add a call before the actual
391  // return to this helper. The purpose of the helper is to move
392  // floating point values from their soft float return mapping to
393  // where they would have been mapped to in floating point registers.
394  //
395  Type *T = RVal->getType();
397  if (RV == NoFPRet) continue;
398  static const char *const Helper[NoFPRet] = {
399  "__mips16_ret_sf", "__mips16_ret_df", "__mips16_ret_sc",
400  "__mips16_ret_dc"
401  };
402  const char *Name = Helper[RV];
403  AttributeList A;
404  Value *Params[] = {RVal};
405  Modified = true;
406  //
407  // These helper functions have a different calling ABI so
408  // this __Mips16RetHelper indicates that so that later
409  // during call setup, the proper call lowering to the helper
410  // functions will take place.
411  //
412  A = A.addFnAttribute(C, "__Mips16RetHelper");
413  A = A.addFnAttribute(
415  A = A.addFnAttribute(C, Attribute::NoInline);
416  FunctionCallee F = (M->getOrInsertFunction(Name, A, MyVoid, T));
417  CallInst::Create(F, Params, "", &I);
418  } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
419  FunctionType *FT = CI->getFunctionType();
420  Function *F_ = CI->getCalledFunction();
421  if (needsFPReturnHelper(*FT) &&
422  !(F_ && isIntrinsicInline(F_))) {
423  Modified=true;
424  F.addFnAttr("saveS2");
425  }
426  if (F_ && !isIntrinsicInline(F_)) {
427  // pic mode calls are handled by already defined
428  // helper functions
429  if (needsFPReturnHelper(*F_)) {
430  Modified=true;
431  F.addFnAttr("saveS2");
432  }
433  if (!TM.isPositionIndependent()) {
434  if (needsFPHelperFromSig(*F_)) {
435  assureFPCallStub(*F_, M, TM);
436  Modified=true;
437  }
438  }
439  }
440  }
441  }
442  return Modified;
443 }
444 
446  const MipsTargetMachine &TM) {
447  bool PicMode = TM.isPositionIndependent();
448  bool LE = TM.isLittleEndian();
449  LLVMContext &Context = M->getContext();
450  std::string Name(F->getName());
451  std::string SectionName = ".mips16.fn." + Name;
452  std::string StubName = "__fn_stub_" + Name;
453  std::string LocalName = "$$__fn_local_" + Name;
454  Function *FStub = Function::Create
455  (F->getFunctionType(),
456  Function::InternalLinkage, StubName, M);
457  FStub->addFnAttr("mips16_fp_stub");
458  FStub->addFnAttr(Attribute::Naked);
459  FStub->addFnAttr(Attribute::NoUnwind);
460  FStub->addFnAttr(Attribute::NoInline);
461  FStub->addFnAttr("nomips16");
462  FStub->setSection(SectionName);
463  BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
464 
465  std::string AsmText;
466  if (PicMode) {
467  AsmText += ".set noreorder\n";
468  AsmText += ".cpload $$25\n";
469  AsmText += ".set reorder\n";
470  AsmText += ".reloc 0, R_MIPS_NONE, " + Name + "\n";
471  AsmText += "la $$25, " + LocalName + "\n";
472  } else
473  AsmText += "la $$25, " + Name + "\n";
474  AsmText += swapFPIntParams(PV, M, LE, false);
475  AsmText += "jr $$25\n";
476  AsmText += LocalName + " = " + Name + "\n";
477  emitInlineAsm(Context, BB, AsmText);
478 
479  new UnreachableInst(FStub->getContext(), BB);
480 }
481 
482 // remove the use-soft-float attribute
484  LLVM_DEBUG(errs() << "removing -use-soft-float\n");
485  F.removeFnAttr("use-soft-float");
486  if (F.hasFnAttribute("use-soft-float")) {
487  LLVM_DEBUG(errs() << "still has -use-soft-float\n");
488  }
489  F.addFnAttr("use-soft-float", "false");
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:257
FFSig
@ FFSig
Definition: Mips16HardFloat.cpp:98
fixupFPReturnAndCall
static bool fixupFPReturnAndCall(Function &F, Module *M, const MipsTargetMachine &TM)
Definition: Mips16HardFloat.cpp:378
llvm::MipsTargetMachine
Definition: MipsTargetMachine.h:27
llvm::Type::FloatTyID
@ FloatTyID
32-bit floating point type
Definition: Type.h:58
FPReturnVariant
FPReturnVariant
Definition: Mips16HardFloat.cpp:64
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
llvm::Type::DoubleTyID
@ DoubleTyID
64-bit floating point type
Definition: Type.h:59
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
ModRef.h
FloatTyID
const Type::TypeID FloatTyID
Definition: Mips16HardFloat.cpp:104
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:3050
llvm::AArch64PACKey::ID
ID
Definition: AArch64BaseInfo.h:818
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:248
llvm::Module::iterator
FunctionListType::iterator iterator
The Function iterators.
Definition: Module.h:90
T
llvm::Function
Definition: Function.h:60
llvm::InlineAsm::AD_ATT
@ AD_ATT
Definition: InlineAsm.h:36
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:361
llvm::Type::getTypeID
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:136
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:432
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
llvm::sys::path::begin
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:226
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:891
llvm::createMips16HardFloatPass
ModulePass * createMips16HardFloatPass()
Definition: Mips16HardFloat.cpp:531
MipsTargetMachine.h
DSig
@ DSig
Definition: Mips16HardFloat.cpp:99
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:55
isIntrinsicInline
static bool isIntrinsicInline(Function *F)
Definition: Mips16HardFloat.cpp:371
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
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:266
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:243
DRet
@ DRet
Definition: Mips16HardFloat.cpp:65
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::Attribute::getWithMemoryEffects
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:214
llvm::CallInst::Create
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Definition: Instructions.h:1517
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
whichFPReturnVariant
static FPReturnVariant whichFPReturnVariant(Type *T)
Definition: Mips16HardFloat.cpp:71
LocalName
Definition: ItaniumDemangle.h:1039
LoopDeletionResult::Modified
@ Modified
llvm::AArch64CC::LE
@ LE
Definition: AArch64BaseInfo.h:268
llvm::AArch64PACKey::IA
@ IA
Definition: AArch64BaseInfo.h:819
llvm::GlobalValue::InternalLinkage
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
FDSig
@ FDSig
Definition: Mips16HardFloat.cpp:98
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:43
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
DoubleTyID
const Type::TypeID DoubleTyID
Definition: Mips16HardFloat.cpp:105
llvm::TargetPassConfig
Target-Independent Code Generator Pass Configuration Options.
Definition: TargetPassConfig.h:84
llvm::InlineAsm
Definition: InlineAsm.h:33
createFPFnStub
static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, const MipsTargetMachine &TM)
Definition: Mips16HardFloat.cpp:445
llvm::Function::getReturnType
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:180
CDRet
@ CDRet
Definition: Mips16HardFloat.cpp:65
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:67
I
#define I(x, y, z)
Definition: MD5.cpp:58
FRet
@ FRet
Definition: Mips16HardFloat.cpp:65
DDSig
@ DDSig
Definition: Mips16HardFloat.cpp:99
TargetPassConfig.h
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
llvm::MemoryEffects::none
static MemoryEffects none()
Create MemoryEffects that cannot read or write any memory.
Definition: ModRef.h:118
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
emitInlineAsm
static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText)
Definition: Mips16HardFloat.cpp:47
needsFPHelperFromSig
static bool needsFPHelperFromSig(Function &F)
Definition: Mips16HardFloat.cpp:181
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
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:50
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
NoFPRet
@ NoFPRet
Definition: Mips16HardFloat.cpp:65
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:483
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:97
CFRet
@ CFRet
Definition: Mips16HardFloat.cpp:65
needsFPStubFromParams
static bool needsFPStubFromParams(Function &F)
Definition: Mips16HardFloat.cpp:157
DFSig
@ DFSig
Definition: Mips16HardFloat.cpp:99
llvm::SectionName
Definition: DWARFSection.h:21
needsFPReturnHelper
static bool needsFPReturnHelper(Function &F)
Definition: Mips16HardFloat.cpp:171
swapFPIntParams
static std::string swapFPIntParams(FPParamVariant PV, Module *M, bool LE, bool ToFP)
Definition: Mips16HardFloat.cpp:187
IntrinsicInline
static const char *const IntrinsicInline[]
Definition: Mips16HardFloat.cpp:349
FPParamVariant
FPParamVariant
Definition: Mips16HardFloat.cpp:97
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:222
llvm::Type::StructTyID
@ StructTyID
Structures.
Definition: Type.h:74
NoSig
@ NoSig
Definition: Mips16HardFloat.cpp:99
llvm::Function::addFnAttr
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.cpp:539
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:98
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:1474
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:4768
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:107
FSig
@ FSig
Definition: Mips16HardFloat.cpp:98
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