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