Coverage Report

Created: 2019-07-24 05:18

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