Coverage Report

Created: 2017-10-03 07:32

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