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"
15#include "llvm/IR/Analysis.h"
17#include "llvm/IR/Module.h"
18#include "llvm/IR/PassManager.h"
19#include "llvm/Pass.h"
20#include "llvm/Support/Debug.h"
22
23using namespace llvm;
24
25#define DEBUG_TYPE "mips-os16"
26
27namespace {
28class MipsOs16Legacy : public ModulePass {
29public:
30 static char ID;
31
32 MipsOs16Legacy() : ModulePass(ID) {}
33
34 StringRef getPassName() const override { return "MIPS Os16 Optimization"; }
35
36 bool runOnModule(Module &M) override;
37
38 void getAnalysisUsage(AnalysisUsage &AU) const override {
39 AU.setPreservesCFG();
41 }
42};
43
44char MipsOs16Legacy::ID = 0;
45} // namespace
46
47// Figure out if we need float point based on the function signature.
48// We need to move variables in and/or out of floating point
49// registers because of the ABI
50//
51static bool needsFPFromSig(Function &F) {
52 Type* RetType = F.getReturnType();
53 switch (RetType->getTypeID()) {
54 case Type::FloatTyID:
56 return true;
57 default:
58 ;
59 }
60 if (F.arg_size() >=1) {
61 Argument &Arg = *F.arg_begin();
62 switch (Arg.getType()->getTypeID()) {
63 case Type::FloatTyID:
65 return true;
66 default:
67 ;
68 }
69 }
70 return false;
71}
72
73// Figure out if the function will need floating point operations
74//
75static bool needsFP(Function &F) {
76 if (needsFPFromSig(F))
77 return true;
78 for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
79 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
80 I != E; ++I) {
81 const Instruction &Inst = *I;
82 switch (Inst.getOpcode()) {
83 case Instruction::FAdd:
84 case Instruction::FSub:
85 case Instruction::FMul:
86 case Instruction::FDiv:
87 case Instruction::FRem:
88 case Instruction::FPToUI:
89 case Instruction::FPToSI:
90 case Instruction::UIToFP:
91 case Instruction::SIToFP:
92 case Instruction::FPTrunc:
93 case Instruction::FPExt:
94 case Instruction::FCmp:
95 return true;
96 default:
97 ;
98 }
99 if (const CallInst *CI = dyn_cast<CallInst>(I)) {
100 LLVM_DEBUG(dbgs() << "Working on call"
101 << "\n");
102 Function &F_ = *CI->getCalledFunction();
103 if (needsFPFromSig(F_))
104 return true;
105 }
106 }
107 return false;
108}
109
110static bool runOs16OnModule(Module &M) {
111 const MipsOptions &Opts =
112 M.getContext().getLibraryOptions().get<MipsOptions>();
113 StringRef Mips32FunctionMask = Opts.mips32_function_mask;
114 bool usingMask = !Mips32FunctionMask.empty();
115 bool doneUsingMask = false; // this will make it stop repeating
116
117 LLVM_DEBUG(dbgs() << "Run on Module MipsOs16 \n"
118 << Mips32FunctionMask << "\n");
119 if (usingMask)
120 LLVM_DEBUG(dbgs() << "using mask \n" << Mips32FunctionMask << "\n");
121
122 unsigned int functionIndex = 0;
123 bool modified = false;
124
125 for (auto &F : M) {
126 if (F.isDeclaration())
127 continue;
128
129 LLVM_DEBUG(dbgs() << "Working on " << F.getName() << "\n");
130 if (usingMask) {
131 if (!doneUsingMask) {
132 if (functionIndex == Mips32FunctionMask.size())
133 functionIndex = 0;
134 switch (Mips32FunctionMask[functionIndex]) {
135 case '1':
136 LLVM_DEBUG(dbgs() << "mask forced mips32: " << F.getName() << "\n");
137 F.addFnAttr("nomips16");
138 break;
139 case '.':
140 doneUsingMask = true;
141 break;
142 default:
143 break;
144 }
145 functionIndex++;
146 }
147 }
148 else {
149 if (needsFP(F)) {
150 LLVM_DEBUG(dbgs() << "os16 forced mips32: " << F.getName() << "\n");
151 F.addFnAttr("nomips16");
152 }
153 else {
154 LLVM_DEBUG(dbgs() << "os16 forced mips16: " << F.getName() << "\n");
155 F.addFnAttr("mips16");
156 }
157 }
158 }
159
160 return modified;
161}
162
163ModulePass *llvm::createMipsOs16LegacyPass() { return new MipsOs16Legacy(); }
164
165bool MipsOs16Legacy::runOnModule(Module &M) { return runOs16OnModule(M); }
166
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#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:51
static bool needsFP(Function &F)
Definition MipsOs16.cpp:75
static bool runOs16OnModule(Module &M)
Definition MipsOs16.cpp:110
ModuleAnalysisManager MAM
#define LLVM_DEBUG(...)
Definition Debug.h:119
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:280
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
InstListType::const_iterator const_iterator
Definition BasicBlock.h:171
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
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.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
Definition MipsOs16.cpp:167
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition Pass.h:253
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition Pass.cpp:114
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
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
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
Pass manager infrastructure for declaring and invalidating analyses.
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
ModulePass * createMipsOs16LegacyPass()
Definition MipsOs16.cpp:163
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39