MipsOs16.cpp revision f2058addc2aa221d0fd744180a2c04a38ebddcd0
1//===---- MipsOs16.cpp for Mips Option -Os16 --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an optimization phase for the MIPS target. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "mips-os16" 15#include "MipsOs16.h" 16#include "llvm/IR/Module.h" 17#include "llvm/Support/CommandLine.h" 18#include "llvm/Support/Debug.h" 19#include "llvm/Support/raw_ostream.h" 20 21 22static cl::opt<std::string> Mips32FunctionMask( 23 "mips32-function-mask", 24 cl::init(""), 25 cl::desc("Force function to be mips32"), 26 cl::Hidden); 27 28namespace { 29 30 // Figure out if we need float point based on the function signature. 31 // We need to move variables in and/or out of floating point 32 // registers because of the ABI 33 // 34 bool needsFPFromSig(Function &F) { 35 Type* RetType = F.getReturnType(); 36 switch (RetType->getTypeID()) { 37 case Type::FloatTyID: 38 case Type::DoubleTyID: 39 return true; 40 default: 41 ; 42 } 43 if (F.arg_size() >=1) { 44 Argument &Arg = F.getArgumentList().front(); 45 switch (Arg.getType()->getTypeID()) { 46 case Type::FloatTyID: 47 case Type::DoubleTyID: 48 return true; 49 default: 50 ; 51 } 52 } 53 return false; 54 } 55 56 // Figure out if the function will need floating point operations 57 // 58 bool needsFP(Function &F) { 59 if (needsFPFromSig(F)) 60 return true; 61 for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 62 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); 63 I != E; ++I) { 64 const Instruction &Inst = *I; 65 switch (Inst.getOpcode()) { 66 case Instruction::FAdd: 67 case Instruction::FSub: 68 case Instruction::FMul: 69 case Instruction::FDiv: 70 case Instruction::FRem: 71 case Instruction::FPToUI: 72 case Instruction::FPToSI: 73 case Instruction::UIToFP: 74 case Instruction::SIToFP: 75 case Instruction::FPTrunc: 76 case Instruction::FPExt: 77 case Instruction::FCmp: 78 return true; 79 default: 80 ; 81 } 82 if (const CallInst *CI = dyn_cast<CallInst>(I)) { 83 DEBUG(dbgs() << "Working on call" << "\n"); 84 Function &F_ = *CI->getCalledFunction(); 85 if (needsFPFromSig(F_)) 86 return true; 87 } 88 } 89 return false; 90 } 91} 92namespace llvm { 93 94 95bool MipsOs16::runOnModule(Module &M) { 96 bool usingMask = Mips32FunctionMask.length() > 0; 97 bool doneUsingMask = false; // this will make it stop repeating 98 DEBUG(dbgs() << "Run on Module MipsOs16 \n" << Mips32FunctionMask << "\n"); 99 if (usingMask) 100 DEBUG(dbgs() << "using mask \n" << Mips32FunctionMask << "\n"); 101 unsigned int functionIndex = 0; 102 bool modified = false; 103 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { 104 if (F->isDeclaration()) continue; 105 DEBUG(dbgs() << "Working on " << F->getName() << "\n"); 106 if (usingMask) { 107 if (!doneUsingMask) { 108 if (functionIndex == Mips32FunctionMask.length()) 109 functionIndex = 0; 110 switch (Mips32FunctionMask[functionIndex]) { 111 case '1': 112 DEBUG(dbgs() << "mask forced mips32: " << F->getName() << "\n"); 113 F->addFnAttr("nomips16"); 114 break; 115 case '.': 116 doneUsingMask = true; 117 break; 118 default: 119 break; 120 } 121 functionIndex++; 122 } 123 } 124 else { 125 if (needsFP(*F)) { 126 DEBUG(dbgs() << "os16 forced mips32: " << F->getName() << "\n"); 127 F->addFnAttr("nomips16"); 128 } 129 else { 130 DEBUG(dbgs() << "os16 forced mips16: " << F->getName() << "\n"); 131 F->addFnAttr("mips16"); 132 } 133 } 134 } 135 return modified; 136} 137 138char MipsOs16::ID = 0; 139 140} 141 142ModulePass *llvm::createMipsOs16(MipsTargetMachine &TM) { 143 return new MipsOs16; 144} 145 146 147