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 const MipsOptions &Opts =
106 M.getContext().getLibraryOptions().get<MipsOptions>();
107 StringRef Mips32FunctionMask = Opts.mips32_function_mask;
108 bool usingMask = !Mips32FunctionMask.empty();
109 bool doneUsingMask = false; // this will make it stop repeating
110
111 LLVM_DEBUG(dbgs() << "Run on Module MipsOs16 \n"
112 << Mips32FunctionMask << "\n");
113 if (usingMask)
114 LLVM_DEBUG(dbgs() << "using mask \n" << Mips32FunctionMask << "\n");
115
116 unsigned int functionIndex = 0;
117 bool modified = false;
118
119 for (auto &F : M) {
120 if (F.isDeclaration())
121 continue;
122
123 LLVM_DEBUG(dbgs() << "Working on " << F.getName() << "\n");
124 if (usingMask) {
125 if (!doneUsingMask) {
126 if (functionIndex == Mips32FunctionMask.size())
127 functionIndex = 0;
128 switch (Mips32FunctionMask[functionIndex]) {
129 case '1':
130 LLVM_DEBUG(dbgs() << "mask forced mips32: " << F.getName() << "\n");
131 F.addFnAttr("nomips16");
132 break;
133 case '.':
134 doneUsingMask = true;
135 break;
136 default:
137 break;
138 }
139 functionIndex++;
140 }
141 }
142 else {
143 if (needsFP(F)) {
144 LLVM_DEBUG(dbgs() << "os16 forced mips32: " << F.getName() << "\n");
145 F.addFnAttr("nomips16");
146 }
147 else {
148 LLVM_DEBUG(dbgs() << "os16 forced mips16: " << F.getName() << "\n");
149 F.addFnAttr("mips16");
150 }
151 }
152 }
153
154 return modified;
155}
156
157ModulePass *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
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:157