Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Sparc/LeonPasses.cpp
Line
Count
Source
1
//===------ LeonPasses.cpp - Define passes specific to LEON ---------------===//
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
//
10
//===----------------------------------------------------------------------===//
11
12
#include "LeonPasses.h"
13
#include "llvm/CodeGen/ISDOpcodes.h"
14
#include "llvm/CodeGen/MachineFunction.h"
15
#include "llvm/CodeGen/MachineInstr.h"
16
#include "llvm/CodeGen/MachineInstrBuilder.h"
17
#include "llvm/CodeGen/MachineRegisterInfo.h"
18
#include "llvm/IR/DiagnosticInfo.h"
19
#include "llvm/IR/LLVMContext.h"
20
#include "llvm/Support/raw_ostream.h"
21
using namespace llvm;
22
23
LEONMachineFunctionPass::LEONMachineFunctionPass(char &ID)
24
7
    : MachineFunctionPass(ID) {}
25
26
//*****************************************************************************
27
//**** InsertNOPLoad pass
28
//*****************************************************************************
29
// This pass fixes the incorrectly working Load instructions that exists for
30
// some earlier versions of the LEON processor line. NOP instructions must
31
// be inserted after the load instruction to ensure that the Load instruction
32
// behaves as expected for these processors.
33
//
34
// This pass inserts a NOP after any LD or LDF instruction.
35
//
36
char InsertNOPLoad::ID = 0;
37
38
3
InsertNOPLoad::InsertNOPLoad() : LEONMachineFunctionPass(ID) {}
39
40
6
bool InsertNOPLoad::runOnMachineFunction(MachineFunction &MF) {
41
6
  Subtarget = &MF.getSubtarget<SparcSubtarget>();
42
6
  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
43
6
  DebugLoc DL = DebugLoc();
44
6
45
6
  bool Modified = false;
46
12
  for (auto MFI = MF.begin(), E = MF.end(); MFI != E; 
++MFI6
) {
47
6
    MachineBasicBlock &MBB = *MFI;
48
44
    for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; 
++MBBI38
) {
49
38
      MachineInstr &MI = *MBBI;
50
38
      unsigned Opcode = MI.getOpcode();
51
38
      if (Opcode >= SP::LDDArr && 
Opcode <= SP::LDrr28
) {
52
7
        MachineBasicBlock::iterator NMBBI = std::next(MBBI);
53
7
        BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
54
7
        Modified = true;
55
7
      }
56
38
    }
57
6
  }
58
6
59
6
  return Modified;
60
6
}
61
62
63
64
//*****************************************************************************
65
//**** DetectRoundChange pass
66
//*****************************************************************************
67
// To prevent any explicit change of the default rounding mode, this pass
68
// detects any call of the fesetround function.
69
// A warning is generated to ensure the user knows this has happened.
70
//
71
// Detects an erratum in UT699 LEON 3 processor
72
73
char DetectRoundChange::ID = 0;
74
75
1
DetectRoundChange::DetectRoundChange() : LEONMachineFunctionPass(ID) {}
76
77
1
bool DetectRoundChange::runOnMachineFunction(MachineFunction &MF) {
78
1
  Subtarget = &MF.getSubtarget<SparcSubtarget>();
79
1
80
1
  bool Modified = false;
81
2
  for (auto MFI = MF.begin(), E = MF.end(); MFI != E; 
++MFI1
) {
82
1
    MachineBasicBlock &MBB = *MFI;
83
7
    for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; 
++MBBI6
) {
84
6
      MachineInstr &MI = *MBBI;
85
6
      unsigned Opcode = MI.getOpcode();
86
6
      if (Opcode == SP::CALL && 
MI.getNumOperands() > 01
) {
87
1
        MachineOperand &MO = MI.getOperand(0);
88
1
89
1
        if (MO.isGlobal()) {
90
1
          StringRef FuncName = MO.getGlobal()->getName();
91
1
          if (FuncName.compare_lower("fesetround") == 0) {
92
1
            errs() << "Error: You are using the detectroundchange "
93
1
                      "option to detect rounding changes that will "
94
1
                      "cause LEON errata. The only way to fix this "
95
1
                      "is to remove the call to fesetround from "
96
1
                      "the source code.\n";
97
1
          }
98
1
        }
99
1
      }
100
6
    }
101
1
  }
102
1
103
1
  return Modified;
104
1
}
105
106
//*****************************************************************************
107
//**** FixAllFDIVSQRT pass
108
//*****************************************************************************
109
// This pass fixes the incorrectly working FDIVx and FSQRTx instructions that
110
// exist for some earlier versions of the LEON processor line. Five NOP
111
// instructions need to be inserted after these instructions to ensure the
112
// correct result is placed in the destination registers before they are used.
113
//
114
// This pass implements two fixes:
115
//  1) fixing the FSQRTS and FSQRTD instructions.
116
//  2) fixing the FDIVS and FDIVD instructions.
117
//
118
// FSQRTS and FDIVS are converted to FDIVD and FSQRTD respectively earlier in
119
// the pipeline when this option is enabled, so this pass needs only to deal
120
// with the changes that still need implementing for the "double" versions
121
// of these instructions.
122
//
123
char FixAllFDIVSQRT::ID = 0;
124
125
3
FixAllFDIVSQRT::FixAllFDIVSQRT() : LEONMachineFunctionPass(ID) {}
126
127
6
bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) {
128
6
  Subtarget = &MF.getSubtarget<SparcSubtarget>();
129
6
  const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
130
6
  DebugLoc DL = DebugLoc();
131
6
132
6
  bool Modified = false;
133
12
  for (auto MFI = MF.begin(), E = MF.end(); MFI != E; 
++MFI6
) {
134
6
    MachineBasicBlock &MBB = *MFI;
135
149
    for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; 
++MBBI143
) {
136
143
      MachineInstr &MI = *MBBI;
137
143
      unsigned Opcode = MI.getOpcode();
138
143
139
143
      // Note: FDIVS and FSQRTS cannot be generated when this erratum fix is
140
143
      // switched on so we don't need to check for them here. They will
141
143
      // already have been converted to FSQRTD or FDIVD earlier in the
142
143
      // pipeline.
143
143
      if (Opcode == SP::FSQRTD || 
Opcode == SP::FDIVD141
) {
144
24
        for (int InsertedCount = 0; InsertedCount < 5; 
InsertedCount++20
)
145
20
          BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
146
4
147
4
        MachineBasicBlock::iterator NMBBI = std::next(MBBI);
148
116
        for (int InsertedCount = 0; InsertedCount < 28; 
InsertedCount++112
)
149
112
          BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
150
4
151
4
        Modified = true;
152
4
      }
153
143
    }
154
6
  }
155
6
156
6
  return Modified;
157
6
}