LLVM  9.0.0svn
MipsOs16.cpp
Go to the documentation of this file.
1 //===---- MipsOs16.cpp for Mips Option -Os16 --------===//
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 an optimization phase for the MIPS target.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "Mips.h"
14 #include "llvm/IR/Instructions.h"
15 #include "llvm/IR/Module.h"
17 #include "llvm/Support/Debug.h"
19 
20 using namespace llvm;
21 
22 #define DEBUG_TYPE "mips-os16"
23 
25  "mips32-function-mask",
26  cl::init(""),
27  cl::desc("Force function to be mips32"),
28  cl::Hidden);
29 
30 namespace {
31  class MipsOs16 : public ModulePass {
32  public:
33  static char ID;
34 
35  MipsOs16() : ModulePass(ID) {}
36 
37  StringRef getPassName() const override { return "MIPS Os16 Optimization"; }
38 
39  bool runOnModule(Module &M) override;
40  };
41 
42  char MipsOs16::ID = 0;
43 }
44 
45 // Figure out if we need float point based on the function signature.
46 // We need to move variables in and/or out of floating point
47 // registers because of the ABI
48 //
49 static bool needsFPFromSig(Function &F) {
50  Type* RetType = F.getReturnType();
51  switch (RetType->getTypeID()) {
52  case Type::FloatTyID:
53  case Type::DoubleTyID:
54  return true;
55  default:
56  ;
57  }
58  if (F.arg_size() >=1) {
59  Argument &Arg = *F.arg_begin();
60  switch (Arg.getType()->getTypeID()) {
61  case Type::FloatTyID:
62  case Type::DoubleTyID:
63  return true;
64  default:
65  ;
66  }
67  }
68  return false;
69 }
70 
71 // Figure out if the function will need floating point operations
72 //
73 static bool needsFP(Function &F) {
74  if (needsFPFromSig(F))
75  return true;
76  for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
77  for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
78  I != E; ++I) {
79  const Instruction &Inst = *I;
80  switch (Inst.getOpcode()) {
81  case Instruction::FAdd:
82  case Instruction::FSub:
83  case Instruction::FMul:
84  case Instruction::FDiv:
85  case Instruction::FRem:
86  case Instruction::FPToUI:
87  case Instruction::FPToSI:
88  case Instruction::UIToFP:
89  case Instruction::SIToFP:
90  case Instruction::FPTrunc:
91  case Instruction::FPExt:
92  case Instruction::FCmp:
93  return true;
94  default:
95  ;
96  }
97  if (const CallInst *CI = dyn_cast<CallInst>(I)) {
98  LLVM_DEBUG(dbgs() << "Working on call"
99  << "\n");
100  Function &F_ = *CI->getCalledFunction();
101  if (needsFPFromSig(F_))
102  return true;
103  }
104  }
105  return false;
106 }
107 
108 
109 bool MipsOs16::runOnModule(Module &M) {
110  bool usingMask = Mips32FunctionMask.length() > 0;
111  bool doneUsingMask = false; // this will make it stop repeating
112 
113  LLVM_DEBUG(dbgs() << "Run on Module MipsOs16 \n"
114  << Mips32FunctionMask << "\n");
115  if (usingMask)
116  LLVM_DEBUG(dbgs() << "using mask \n" << Mips32FunctionMask << "\n");
117 
118  unsigned int functionIndex = 0;
119  bool modified = false;
120 
121  for (auto &F : M) {
122  if (F.isDeclaration())
123  continue;
124 
125  LLVM_DEBUG(dbgs() << "Working on " << F.getName() << "\n");
126  if (usingMask) {
127  if (!doneUsingMask) {
128  if (functionIndex == Mips32FunctionMask.length())
129  functionIndex = 0;
130  switch (Mips32FunctionMask[functionIndex]) {
131  case '1':
132  LLVM_DEBUG(dbgs() << "mask forced mips32: " << F.getName() << "\n");
133  F.addFnAttr("nomips16");
134  break;
135  case '.':
136  doneUsingMask = true;
137  break;
138  default:
139  break;
140  }
141  functionIndex++;
142  }
143  }
144  else {
145  if (needsFP(F)) {
146  LLVM_DEBUG(dbgs() << "os16 forced mips32: " << F.getName() << "\n");
147  F.addFnAttr("nomips16");
148  }
149  else {
150  LLVM_DEBUG(dbgs() << "os16 forced mips16: " << F.getName() << "\n");
151  F.addFnAttr("mips16");
152  }
153  }
154  }
155 
156  return modified;
157 }
158 
159 ModulePass *llvm::createMipsOs16Pass() { return new MipsOs16(); }
This class represents an incoming formal argument to a Function.
Definition: Argument.h:29
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
2: 32-bit floating point type
Definition: Type.h:58
iterator end()
Definition: Function.h:674
This class represents a function call, abstracting a target machine&#39;s calling convention.
F(f)
static cl::opt< std::string > Mips32FunctionMask("mips32-function-mask", cl::init(""), cl::desc("Force function to be mips32"), cl::Hidden)
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:137
static bool needsFPFromSig(Function &F)
Definition: MipsOs16.cpp:49
static bool needsFP(Function &F)
Definition: MipsOs16.cpp:73
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:244
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:125
iterator begin()
Definition: Function.h:672
ModulePass * createMipsOs16Pass()
Definition: MipsOs16.cpp:159
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:168
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
size_t arg_size() const
Definition: Function.h:714
arg_iterator arg_begin()
Definition: Function.h:687
Iterator for intrusive lists based on ilist_node.
Module.h This file contains the declarations for the Module class.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
#define I(x, y, z)
Definition: MD5.cpp:58
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:224
3: 64-bit floating point type
Definition: Type.h:59
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
#define LLVM_DEBUG(X)
Definition: Debug.h:122