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