Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Hexagon/HexagonVectorPrint.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- HexagonVectorPrint.cpp - Generate vector printing instructions -----===//
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 pass adds the capability to generate pseudo vector/predicate register
10
// printing instructions. These pseudo instructions should be used with the
11
// simulator, NEVER on hardware.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "HexagonInstrInfo.h"
16
#include "HexagonSubtarget.h"
17
#include "llvm/ADT/StringRef.h"
18
#include "llvm/CodeGen/MachineBasicBlock.h"
19
#include "llvm/CodeGen/MachineFunction.h"
20
#include "llvm/CodeGen/MachineFunctionPass.h"
21
#include "llvm/CodeGen/MachineInstr.h"
22
#include "llvm/CodeGen/MachineInstrBuilder.h"
23
#include "llvm/CodeGen/MachineOperand.h"
24
#include "llvm/CodeGen/TargetOpcodes.h"
25
#include "llvm/IR/DebugLoc.h"
26
#include "llvm/IR/InlineAsm.h"
27
#include "llvm/Pass.h"
28
#include "llvm/Support/CommandLine.h"
29
#include "llvm/Support/Debug.h"
30
#include "llvm/Support/ErrorHandling.h"
31
#include "llvm/Support/raw_ostream.h"
32
#include <string>
33
#include <vector>
34
35
using namespace llvm;
36
37
#define DEBUG_TYPE "hexagon-vector-print"
38
39
static cl::opt<bool> TraceHexVectorStoresOnly("trace-hex-vector-stores-only",
40
  cl::Hidden, cl::ZeroOrMore, cl::init(false),
41
  cl::desc("Enables tracing of vector stores"));
42
43
namespace llvm {
44
45
FunctionPass *createHexagonVectorPrint();
46
void initializeHexagonVectorPrintPass(PassRegistry&);
47
48
} // end namespace llvm
49
50
namespace {
51
52
class HexagonVectorPrint : public MachineFunctionPass {
53
  const HexagonSubtarget *QST = nullptr;
54
  const HexagonInstrInfo *QII = nullptr;
55
  const HexagonRegisterInfo *QRI = nullptr;
56
57
public:
58
  static char ID;
59
60
2
  HexagonVectorPrint() : MachineFunctionPass(ID) {
61
2
    initializeHexagonVectorPrintPass(*PassRegistry::getPassRegistry());
62
2
  }
63
64
4
  StringRef getPassName() const override { return "Hexagon VectorPrint pass"; }
65
66
  bool runOnMachineFunction(MachineFunction &Fn) override;
67
};
68
69
} // end anonymous namespace
70
71
char HexagonVectorPrint::ID = 0;
72
73
13
static bool isVecReg(unsigned Reg) {
74
13
  return (Reg >= Hexagon::V0 && Reg <= Hexagon::V31)
75
13
      || 
(0
Reg >= Hexagon::W00
&&
Reg <= Hexagon::W150
)
76
13
      || 
(0
Reg >= Hexagon::Q00
&&
Reg <= Hexagon::Q30
);
77
13
}
78
79
5
static std::string getStringReg(unsigned R) {
80
5
  if (R >= Hexagon::V0 && R <= Hexagon::V31) {
81
5
    static const char* S[] = { "20", "21", "22", "23", "24", "25", "26", "27",
82
5
                        "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
83
5
                        "30", "31", "32", "33", "34", "35", "36", "37",
84
5
                        "38", "39", "3a", "3b", "3c", "3d", "3e", "3f"};
85
5
    return S[R-Hexagon::V0];
86
5
  }
87
0
  if (R >= Hexagon::Q0 && R <= Hexagon::Q3) {
88
0
    static const char* S[] = { "00", "01", "02", "03"};
89
0
    return S[R-Hexagon::Q0];
90
0
91
0
  }
92
0
  llvm_unreachable("valid vreg");
93
0
}
94
95
static void addAsmInstr(MachineBasicBlock *MBB, unsigned Reg,
96
                        MachineBasicBlock::instr_iterator I,
97
                        const DebugLoc &DL, const HexagonInstrInfo *QII,
98
5
                        MachineFunction &Fn) {
99
5
  std::string VDescStr = ".long 0x1dffe0" + getStringReg(Reg);
100
5
  const char *cstr = Fn.createExternalSymbolName(VDescStr);
101
5
  unsigned ExtraInfo = InlineAsm::Extra_HasSideEffects;
102
5
  BuildMI(*MBB, I, DL, QII->get(TargetOpcode::INLINEASM))
103
5
    .addExternalSymbol(cstr)
104
5
    .addImm(ExtraInfo);
105
5
}
106
107
15
static bool getInstrVecReg(const MachineInstr &MI, unsigned &Reg) {
108
15
  if (MI.getNumOperands() < 1) 
return false0
;
109
15
  // Vec load or compute.
110
15
  if (MI.getOperand(0).isReg() && MI.getOperand(0).isDef()) {
111
9
    Reg = MI.getOperand(0).getReg();
112
9
    if (isVecReg(Reg))
113
9
      return !TraceHexVectorStoresOnly;
114
6
  }
115
6
  // Vec store.
116
6
  if (MI.mayStore() && 
MI.getNumOperands() >= 34
&&
MI.getOperand(2).isReg()4
) {
117
4
    Reg = MI.getOperand(2).getReg();
118
4
    if (isVecReg(Reg))
119
4
      return true;
120
2
  }
121
2
  // Vec store post increment.
122
2
  if (MI.mayStore() && 
MI.getNumOperands() >= 40
&&
MI.getOperand(3).isReg()0
) {
123
0
    Reg = MI.getOperand(3).getReg();
124
0
    if (isVecReg(Reg))
125
0
      return true;
126
2
  }
127
2
  return false;
128
2
}
129
130
2
bool HexagonVectorPrint::runOnMachineFunction(MachineFunction &Fn) {
131
2
  bool Changed = false;
132
2
  QST = &Fn.getSubtarget<HexagonSubtarget>();
133
2
  QRI = QST->getRegisterInfo();
134
2
  QII = QST->getInstrInfo();
135
2
  std::vector<MachineInstr *> VecPrintList;
136
2
  for (auto &MBB : Fn)
137
10
    
for (auto &MI : MBB)2
{
138
10
      if (MI.isBundle()) {
139
0
        MachineBasicBlock::instr_iterator MII = MI.getIterator();
140
0
        for (++MII; MII != MBB.instr_end() && MII->isInsideBundle(); ++MII) {
141
0
          if (MII->getNumOperands() < 1)
142
0
            continue;
143
0
          unsigned Reg = 0;
144
0
          if (getInstrVecReg(*MII, Reg)) {
145
0
            VecPrintList.push_back((&*MII));
146
0
            LLVM_DEBUG(dbgs() << "Found vector reg inside bundle \n";
147
0
                       MII->dump());
148
0
          }
149
0
        }
150
10
      } else {
151
10
        unsigned Reg = 0;
152
10
        if (getInstrVecReg(MI, Reg)) {
153
5
          VecPrintList.push_back(&MI);
154
5
          LLVM_DEBUG(dbgs() << "Found vector reg \n"; MI.dump());
155
5
        }
156
10
      }
157
10
    }
158
2
159
2
  Changed = !VecPrintList.empty();
160
2
  if (!Changed)
161
0
    return Changed;
162
2
163
5
  
for (auto *I : VecPrintList)2
{
164
5
    DebugLoc DL = I->getDebugLoc();
165
5
    MachineBasicBlock *MBB = I->getParent();
166
5
    LLVM_DEBUG(dbgs() << "Evaluating V MI\n"; I->dump());
167
5
    unsigned Reg = 0;
168
5
    if (!getInstrVecReg(*I, Reg))
169
5
      
llvm_unreachable0
("Need a vector reg");
170
5
    MachineBasicBlock::instr_iterator MII = I->getIterator();
171
5
    if (I->isInsideBundle()) {
172
0
      LLVM_DEBUG(dbgs() << "add to end of bundle\n"; I->dump());
173
0
      while (MBB->instr_end() != MII && MII->isInsideBundle())
174
0
        MII++;
175
5
    } else {
176
5
      LLVM_DEBUG(dbgs() << "add after instruction\n"; I->dump());
177
5
      MII++;
178
5
    }
179
5
    if (MBB->instr_end() == MII)
180
0
      continue;
181
5
182
5
    if (Reg >= Hexagon::V0 && Reg <= Hexagon::V31) {
183
5
      LLVM_DEBUG(dbgs() << "adding dump for V" << Reg - Hexagon::V0 << '\n');
184
5
      addAsmInstr(MBB, Reg, MII, DL, QII, Fn);
185
5
    } else 
if (0
Reg >= Hexagon::W00
&&
Reg <= Hexagon::W150
) {
186
0
      LLVM_DEBUG(dbgs() << "adding dump for W" << Reg - Hexagon::W0 << '\n');
187
0
      addAsmInstr(MBB, Hexagon::V0 + (Reg - Hexagon::W0) * 2 + 1,
188
0
                  MII, DL, QII, Fn);
189
0
      addAsmInstr(MBB, Hexagon::V0 + (Reg - Hexagon::W0) * 2,
190
0
                   MII, DL, QII, Fn);
191
0
    } else if (Reg >= Hexagon::Q0 && Reg <= Hexagon::Q3) {
192
0
      LLVM_DEBUG(dbgs() << "adding dump for Q" << Reg - Hexagon::Q0 << '\n');
193
0
      addAsmInstr(MBB, Reg, MII, DL, QII, Fn);
194
0
    } else
195
0
      llvm_unreachable("Bad Vector reg");
196
5
  }
197
2
  return Changed;
198
2
}
199
200
//===----------------------------------------------------------------------===//
201
//                         Public Constructor Functions
202
//===----------------------------------------------------------------------===//
203
INITIALIZE_PASS(HexagonVectorPrint, "hexagon-vector-print",
204
  "Hexagon VectorPrint pass", false, false)
205
206
2
FunctionPass *llvm::createHexagonVectorPrint() {
207
2
  return new HexagonVectorPrint();
208
2
}