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