Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- SystemZShortenInst.cpp - Instruction-shortening pass --------------===//
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 tries to replace instructions with shorter forms.  For example,
10
// IILF can be replaced with LLILL or LLILH if the constant fits and if the
11
// other 32 bits of the GR64 destination are not live.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "SystemZTargetMachine.h"
16
#include "llvm/CodeGen/LivePhysRegs.h"
17
#include "llvm/CodeGen/MachineFunctionPass.h"
18
#include "llvm/CodeGen/MachineInstrBuilder.h"
19
#include "llvm/CodeGen/TargetRegisterInfo.h"
20
21
using namespace llvm;
22
23
#define DEBUG_TYPE "systemz-shorten-inst"
24
25
namespace {
26
class SystemZShortenInst : public MachineFunctionPass {
27
public:
28
  static char ID;
29
  SystemZShortenInst(const SystemZTargetMachine &tm);
30
31
9.10k
  StringRef getPassName() const override {
32
9.10k
    return "SystemZ Instruction Shortening";
33
9.10k
  }
34
35
  bool processBlock(MachineBasicBlock &MBB);
36
  bool runOnMachineFunction(MachineFunction &F) override;
37
999
  MachineFunctionProperties getRequiredProperties() const override {
38
999
    return MachineFunctionProperties().set(
39
999
        MachineFunctionProperties::Property::NoVRegs);
40
999
  }
41
42
private:
43
  bool shortenIIF(MachineInstr &MI, unsigned LLIxL, unsigned LLIxH);
44
  bool shortenOn0(MachineInstr &MI, unsigned Opcode);
45
  bool shortenOn01(MachineInstr &MI, unsigned Opcode);
46
  bool shortenOn001(MachineInstr &MI, unsigned Opcode);
47
  bool shortenOn001AddCC(MachineInstr &MI, unsigned Opcode);
48
  bool shortenFPConv(MachineInstr &MI, unsigned Opcode);
49
  bool shortenSelect(MachineInstr &MI, unsigned Opcode);
50
51
  const SystemZInstrInfo *TII;
52
  const TargetRegisterInfo *TRI;
53
  LivePhysRegs LiveRegs;
54
};
55
56
char SystemZShortenInst::ID = 0;
57
} // end anonymous namespace
58
59
1.00k
FunctionPass *llvm::createSystemZShortenInstPass(SystemZTargetMachine &TM) {
60
1.00k
  return new SystemZShortenInst(TM);
61
1.00k
}
62
63
SystemZShortenInst::SystemZShortenInst(const SystemZTargetMachine &tm)
64
1.00k
  : MachineFunctionPass(ID), TII(nullptr) {}
65
66
// Tie operands if MI has become a two-address instruction.
67
240
static void tieOpsIfNeeded(MachineInstr &MI) {
68
240
  if (MI.getDesc().getOperandConstraint(0, MCOI::TIED_TO) &&
69
240
      !MI.getOperand(0).isTied())
70
240
    MI.tieOperands(0, 1);
71
240
}
72
73
// MI loads one word of a GPR using an IIxF instruction and LLIxL and LLIxH
74
// are the halfword immediate loads for the same word.  Try to use one of them
75
// instead of IIxF.
76
bool SystemZShortenInst::shortenIIF(MachineInstr &MI, unsigned LLIxL,
77
452
                                    unsigned LLIxH) {
78
452
  unsigned Reg = MI.getOperand(0).getReg();
79
452
  // The new opcode will clear the other half of the GR64 reg, so
80
452
  // cancel if that is live.
81
452
  unsigned thisSubRegIdx =
82
452
      (SystemZ::GRH32BitRegClass.contains(Reg) ? 
SystemZ::subreg_h32370
83
452
                                               : 
SystemZ::subreg_l3282
);
84
452
  unsigned otherSubRegIdx =
85
452
      (thisSubRegIdx == SystemZ::subreg_l32 ? 
SystemZ::subreg_h3282
86
452
                                            : 
SystemZ::subreg_l32370
);
87
452
  unsigned GR64BitReg =
88
452
      TRI->getMatchingSuperReg(Reg, thisSubRegIdx, &SystemZ::GR64BitRegClass);
89
452
  unsigned OtherReg = TRI->getSubReg(GR64BitReg, otherSubRegIdx);
90
452
  if (LiveRegs.contains(OtherReg))
91
357
    return false;
92
95
93
95
  uint64_t Imm = MI.getOperand(1).getImm();
94
95
  if (SystemZ::isImmLL(Imm)) {
95
25
    MI.setDesc(TII->get(LLIxL));
96
25
    MI.getOperand(0).setReg(SystemZMC::getRegAsGR64(Reg));
97
25
    return true;
98
25
  }
99
70
  if (SystemZ::isImmLH(Imm)) {
100
43
    MI.setDesc(TII->get(LLIxH));
101
43
    MI.getOperand(0).setReg(SystemZMC::getRegAsGR64(Reg));
102
43
    MI.getOperand(1).setImm(Imm >> 16);
103
43
    return true;
104
43
  }
105
27
  return false;
106
27
}
107
108
// Change MI's opcode to Opcode if register operand 0 has a 4-bit encoding.
109
859
bool SystemZShortenInst::shortenOn0(MachineInstr &MI, unsigned Opcode) {
110
859
  if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16) {
111
695
    MI.setDesc(TII->get(Opcode));
112
695
    return true;
113
695
  }
114
164
  return false;
115
164
}
116
117
// Change MI's opcode to Opcode if register operands 0 and 1 have a
118
// 4-bit encoding.
119
115
bool SystemZShortenInst::shortenOn01(MachineInstr &MI, unsigned Opcode) {
120
115
  if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
121
115
      SystemZMC::getFirstReg(MI.getOperand(1).getReg()) < 16) {
122
84
    MI.setDesc(TII->get(Opcode));
123
84
    return true;
124
84
  }
125
31
  return false;
126
31
}
127
128
// Change MI's opcode to Opcode if register operands 0, 1 and 2 have a
129
// 4-bit encoding and if operands 0 and 1 are tied. Also ties op 0
130
// with op 1, if MI becomes 2-address.
131
325
bool SystemZShortenInst::shortenOn001(MachineInstr &MI, unsigned Opcode) {
132
325
  if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
133
325
      
MI.getOperand(1).getReg() == MI.getOperand(0).getReg()261
&&
134
325
      
SystemZMC::getFirstReg(MI.getOperand(2).getReg()) < 16243
) {
135
240
    MI.setDesc(TII->get(Opcode));
136
240
    tieOpsIfNeeded(MI);
137
240
    return true;
138
240
  }
139
85
  return false;
140
85
}
141
142
// Calls shortenOn001 if CCLive is false. CC def operand is added in
143
// case of success.
144
220
bool SystemZShortenInst::shortenOn001AddCC(MachineInstr &MI, unsigned Opcode) {
145
220
  if (!LiveRegs.contains(SystemZ::CC) && shortenOn001(MI, Opcode)) {
146
143
    MachineInstrBuilder(*MI.getParent()->getParent(), &MI)
147
143
      .addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead);
148
143
    return true;
149
143
  }
150
77
  return false;
151
77
}
152
153
// MI is a vector-style conversion instruction with the operand order:
154
// destination, source, exact-suppress, rounding-mode.  If both registers
155
// have a 4-bit encoding then change it to Opcode, which has operand order:
156
// destination, rouding-mode, source, exact-suppress.
157
81
bool SystemZShortenInst::shortenFPConv(MachineInstr &MI, unsigned Opcode) {
158
81
  if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
159
81
      
SystemZMC::getFirstReg(MI.getOperand(1).getReg()) < 1680
) {
160
55
    MachineOperand Dest(MI.getOperand(0));
161
55
    MachineOperand Src(MI.getOperand(1));
162
55
    MachineOperand Suppress(MI.getOperand(2));
163
55
    MachineOperand Mode(MI.getOperand(3));
164
55
    MI.RemoveOperand(3);
165
55
    MI.RemoveOperand(2);
166
55
    MI.RemoveOperand(1);
167
55
    MI.RemoveOperand(0);
168
55
    MI.setDesc(TII->get(Opcode));
169
55
    MachineInstrBuilder(*MI.getParent()->getParent(), &MI)
170
55
        .add(Dest)
171
55
        .add(Mode)
172
55
        .add(Src)
173
55
        .add(Suppress);
174
55
    return true;
175
55
  }
176
26
  return false;
177
26
}
178
179
// MI is a three-operand select instruction.  If one of the sources match
180
// the destination, convert to the equivalent load-on-condition.
181
25
bool SystemZShortenInst::shortenSelect(MachineInstr &MI, unsigned Opcode) {
182
25
  if (MI.getOperand(0).getReg() == MI.getOperand(1).getReg()) {
183
10
    MI.setDesc(TII->get(Opcode));
184
10
    MI.tieOperands(0, 1);
185
10
    return true;
186
10
  }
187
15
  if (MI.getOperand(0).getReg() == MI.getOperand(2).getReg()) {
188
3
    TII->commuteInstruction(MI, false, 1, 2);
189
3
    MI.setDesc(TII->get(Opcode));
190
3
    MI.tieOperands(0, 1);
191
3
    return true;
192
3
  }
193
12
  return false;
194
12
}
195
196
// Process all instructions in MBB.  Return true if something changed.
197
11.0k
bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) {
198
11.0k
  bool Changed = false;
199
11.0k
200
11.0k
  // Set up the set of live registers at the end of MBB (live out)
201
11.0k
  LiveRegs.clear();
202
11.0k
  LiveRegs.addLiveOuts(MBB);
203
11.0k
204
11.0k
  // Iterate backwards through the block looking for instructions to change.
205
76.6k
  for (auto MBBI = MBB.rbegin(), MBBE = MBB.rend(); MBBI != MBBE; 
++MBBI65.6k
) {
206
65.6k
    MachineInstr &MI = *MBBI;
207
65.6k
    switch (MI.getOpcode()) {
208
65.6k
    case SystemZ::IILF:
209
82
      Changed |= shortenIIF(MI, SystemZ::LLILL, SystemZ::LLILH);
210
82
      break;
211
65.6k
212
65.6k
    case SystemZ::IIHF:
213
370
      Changed |= shortenIIF(MI, SystemZ::LLIHL, SystemZ::LLIHH);
214
370
      break;
215
65.6k
216
65.6k
    case SystemZ::SELR:
217
11
      Changed |= shortenSelect(MI, SystemZ::LOCR);
218
11
      break;
219
65.6k
220
65.6k
    case SystemZ::SELFHR:
221
6
      Changed |= shortenSelect(MI, SystemZ::LOCFHR);
222
6
      break;
223
65.6k
224
65.6k
    case SystemZ::SELGR:
225
8
      Changed |= shortenSelect(MI, SystemZ::LOCGR);
226
8
      break;
227
65.6k
228
65.6k
    case SystemZ::WFADB:
229
30
      Changed |= shortenOn001AddCC(MI, SystemZ::ADBR);
230
30
      break;
231
65.6k
232
65.6k
    case SystemZ::WFASB:
233
26
      Changed |= shortenOn001AddCC(MI, SystemZ::AEBR);
234
26
      break;
235
65.6k
236
65.6k
    case SystemZ::WFDDB:
237
26
      Changed |= shortenOn001(MI, SystemZ::DDBR);
238
26
      break;
239
65.6k
240
65.6k
    case SystemZ::WFDSB:
241
26
      Changed |= shortenOn001(MI, SystemZ::DEBR);
242
26
      break;
243
65.6k
244
65.6k
    case SystemZ::WFIDB:
245
42
      Changed |= shortenFPConv(MI, SystemZ::FIDBRA);
246
42
      break;
247
65.6k
248
65.6k
    case SystemZ::WFISB:
249
24
      Changed |= shortenFPConv(MI, SystemZ::FIEBRA);
250
24
      break;
251
65.6k
252
65.6k
    case SystemZ::WLDEB:
253
9
      Changed |= shortenOn01(MI, SystemZ::LDEBR);
254
9
      break;
255
65.6k
256
65.6k
    case SystemZ::WLEDB:
257
15
      Changed |= shortenFPConv(MI, SystemZ::LEDBRA);
258
15
      break;
259
65.6k
260
65.6k
    case SystemZ::WFMDB:
261
27
      Changed |= shortenOn001(MI, SystemZ::MDBR);
262
27
      break;
263
65.6k
264
65.6k
    case SystemZ::WFMSB:
265
26
      Changed |= shortenOn001(MI, SystemZ::MEEBR);
266
26
      break;
267
65.6k
268
65.6k
    case SystemZ::WFLCDB:
269
3
      Changed |= shortenOn01(MI, SystemZ::LCDFR);
270
3
      break;
271
65.6k
272
65.6k
    case SystemZ::WFLCSB:
273
2
      Changed |= shortenOn01(MI, SystemZ::LCDFR_32);
274
2
      break;
275
65.6k
276
65.6k
    case SystemZ::WFLNDB:
277
3
      Changed |= shortenOn01(MI, SystemZ::LNDFR);
278
3
      break;
279
65.6k
280
65.6k
    case SystemZ::WFLNSB:
281
2
      Changed |= shortenOn01(MI, SystemZ::LNDFR_32);
282
2
      break;
283
65.6k
284
65.6k
    case SystemZ::WFLPDB:
285
5
      Changed |= shortenOn01(MI, SystemZ::LPDFR);
286
5
      break;
287
65.6k
288
65.6k
    case SystemZ::WFLPSB:
289
2
      Changed |= shortenOn01(MI, SystemZ::LPDFR_32);
290
2
      break;
291
65.6k
292
65.6k
    case SystemZ::WFSQDB:
293
22
      Changed |= shortenOn01(MI, SystemZ::SQDBR);
294
22
      break;
295
65.6k
296
65.6k
    case SystemZ::WFSQSB:
297
22
      Changed |= shortenOn01(MI, SystemZ::SQEBR);
298
22
      break;
299
65.6k
300
65.6k
    case SystemZ::WFSDB:
301
138
      Changed |= shortenOn001AddCC(MI, SystemZ::SDBR);
302
138
      break;
303
65.6k
304
65.6k
    case SystemZ::WFSSB:
305
26
      Changed |= shortenOn001AddCC(MI, SystemZ::SEBR);
306
26
      break;
307
65.6k
308
65.6k
    case SystemZ::WFCDB:
309
24
      Changed |= shortenOn01(MI, SystemZ::CDBR);
310
24
      break;
311
65.6k
312
65.6k
    case SystemZ::WFCSB:
313
21
      Changed |= shortenOn01(MI, SystemZ::CEBR);
314
21
      break;
315
65.6k
316
65.6k
    case SystemZ::VL32:
317
232
      // For z13 we prefer LDE over LE to avoid partial register dependencies.
318
232
      Changed |= shortenOn0(MI, SystemZ::LDE32);
319
232
      break;
320
65.6k
321
65.6k
    case SystemZ::VST32:
322
84
      Changed |= shortenOn0(MI, SystemZ::STE);
323
84
      break;
324
65.6k
325
65.6k
    case SystemZ::VL64:
326
336
      Changed |= shortenOn0(MI, SystemZ::LD);
327
336
      break;
328
65.6k
329
65.6k
    case SystemZ::VST64:
330
207
      Changed |= shortenOn0(MI, SystemZ::STD);
331
207
      break;
332
65.6k
333
65.6k
    default: {
334
63.7k
      int TwoOperandOpcode = SystemZ::getTwoOperandOpcode(MI.getOpcode());
335
63.7k
      if (TwoOperandOpcode == -1)
336
63.0k
        break;
337
756
338
756
      if ((MI.getOperand(0).getReg() != MI.getOperand(1).getReg()) &&
339
756
          
(119
!MI.isCommutable()119
||
340
119
           
MI.getOperand(0).getReg() != MI.getOperand(2).getReg()60
||
341
119
           
!TII->commuteInstruction(MI, false, 1, 2)44
))
342
75
          break;
343
681
344
681
      MI.setDesc(TII->get(TwoOperandOpcode));
345
681
      MI.tieOperands(0, 1);
346
681
      if (TwoOperandOpcode == SystemZ::SLL ||
347
681
          
TwoOperandOpcode == SystemZ::SLA675
||
348
681
          
TwoOperandOpcode == SystemZ::SRL675
||
349
681
          
TwoOperandOpcode == SystemZ::SRA568
) {
350
120
        // These shifts only use the low 6 bits of the shift count.
351
120
        MachineOperand &ImmMO = MI.getOperand(3);
352
120
        ImmMO.setImm(ImmMO.getImm() & 0xfff);
353
120
      }
354
681
      Changed = true;
355
681
      break;
356
681
    }
357
65.6k
    }
358
65.6k
359
65.6k
    LiveRegs.stepBackward(MI);
360
65.6k
  }
361
11.0k
362
11.0k
  return Changed;
363
11.0k
}
364
365
8.10k
bool SystemZShortenInst::runOnMachineFunction(MachineFunction &F) {
366
8.10k
  if (skipFunction(F.getFunction()))
367
0
    return false;
368
8.10k
369
8.10k
  const SystemZSubtarget &ST = F.getSubtarget<SystemZSubtarget>();
370
8.10k
  TII = ST.getInstrInfo();
371
8.10k
  TRI = ST.getRegisterInfo();
372
8.10k
  LiveRegs.init(*TRI);
373
8.10k
374
8.10k
  bool Changed = false;
375
8.10k
  for (auto &MBB : F)
376
11.0k
    Changed |= processBlock(MBB);
377
8.10k
378
8.10k
  return Changed;
379
8.10k
}