MipsOs16.cpp revision 0323d4b169279414862174f38ae04add6b747a60
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 DEBUG(dbgs() << "Run on Module MipsOs16 \n" << Mips32FunctionMask << "\n"); 98 if (usingMask) 99 DEBUG(dbgs() << "using mask \n" << Mips32FunctionMask << "\n"); 100 unsigned int functionIndex = 0; 101 bool modified = false; 102 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { 103 if (F->isDeclaration()) continue; 104 DEBUG(dbgs() << "Working on " << F->getName() << "\n"); 105 if (usingMask) { 106 if ((functionIndex < Mips32FunctionMask.length()) && 107 (Mips32FunctionMask[functionIndex] == '1')) { 108 DEBUG(dbgs() << "mask forced mips32: " << F->getName() << "\n"); 109 F->addFnAttr("nomips16"); 110 } 111 functionIndex++; 112 } 113 else { 114 if (needsFP(*F)) { 115 DEBUG(dbgs() << "os16 forced mips32: " << F->getName() << "\n"); 116 F->addFnAttr("nomips16"); 117 } 118 else { 119 DEBUG(dbgs() << "os16 forced mips16: " << F->getName() << "\n"); 120 F->addFnAttr("mips16"); 121 } 122 } 123 } 124 return modified; 125} 126 127char MipsOs16::ID = 0; 128 129} 130 131ModulePass *llvm::createMipsOs16(MipsTargetMachine &TM) { 132 return new MipsOs16; 133} 134 135 136