LLVM  14.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"
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(); }
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:29
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: AllocatorList.h:23
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
llvm::Function
Definition: Function.h:62
llvm::createMipsOs16Pass
ModulePass * createMipsOs16Pass()
Definition: MipsOs16.cpp:159
llvm::Type::getTypeID
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:135
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
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:56
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:206
CommandLine.h
llvm::Instruction::getOpcode
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:160
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:45
llvm::cl::opt
Definition: CommandLine.h:1432
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:441
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
needsFPFromSig
static bool needsFPFromSig(Function &F)
Definition: MipsOs16.cpp:49
Instructions.h
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1469
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:73
llvm::cl::desc
Definition: CommandLine.h:412
raw_ostream.h
Debug.h
llvm::Function::const_iterator
BasicBlockListType::const_iterator const_iterator
Definition: Function.h:69
llvm::BasicBlock::const_iterator
InstListType::const_iterator const_iterator
Definition: BasicBlock.h:91
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38