Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Sparc/DelaySlotFiller.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- DelaySlotFiller.cpp - SPARC delay slot filler ---------------------===//
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 is a simple local pass that attempts to fill delay slots with useful
10
// instructions. If no instructions can be moved into the delay slot, then a
11
// NOP is placed.
12
//===----------------------------------------------------------------------===//
13
14
#include "Sparc.h"
15
#include "SparcSubtarget.h"
16
#include "llvm/ADT/SmallSet.h"
17
#include "llvm/ADT/Statistic.h"
18
#include "llvm/CodeGen/MachineFunctionPass.h"
19
#include "llvm/CodeGen/MachineInstrBuilder.h"
20
#include "llvm/CodeGen/MachineRegisterInfo.h"
21
#include "llvm/CodeGen/TargetInstrInfo.h"
22
#include "llvm/CodeGen/TargetRegisterInfo.h"
23
#include "llvm/Support/CommandLine.h"
24
#include "llvm/Target/TargetMachine.h"
25
26
using namespace llvm;
27
28
#define DEBUG_TYPE "delay-slot-filler"
29
30
STATISTIC(FilledSlots, "Number of delay slots filled");
31
32
static cl::opt<bool> DisableDelaySlotFiller(
33
  "disable-sparc-delay-filler",
34
  cl::init(false),
35
  cl::desc("Disable the Sparc delay slot filler."),
36
  cl::Hidden);
37
38
namespace {
39
  struct Filler : public MachineFunctionPass {
40
    const SparcSubtarget *Subtarget;
41
42
    static char ID;
43
198
    Filler() : MachineFunctionPass(ID) {}
44
45
889
    StringRef getPassName() const override { return "SPARC Delay Slot Filler"; }
46
47
    bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
48
691
    bool runOnMachineFunction(MachineFunction &F) override {
49
691
      bool Changed = false;
50
691
      Subtarget = &F.getSubtarget<SparcSubtarget>();
51
691
52
691
      // This pass invalidates liveness information when it reorders
53
691
      // instructions to fill delay slot.
54
691
      F.getRegInfo().invalidateLiveness();
55
691
56
691
      for (MachineFunction::iterator FI = F.begin(), FE = F.end();
57
1.68k
           FI != FE; 
++FI993
)
58
993
        Changed |= runOnMachineBasicBlock(*FI);
59
691
      return Changed;
60
691
    }
61
62
198
    MachineFunctionProperties getRequiredProperties() const override {
63
198
      return MachineFunctionProperties().set(
64
198
          MachineFunctionProperties::Property::NoVRegs);
65
198
    }
66
67
    void insertCallDefsUses(MachineBasicBlock::iterator MI,
68
                            SmallSet<unsigned, 32>& RegDefs,
69
                            SmallSet<unsigned, 32>& RegUses);
70
71
    void insertDefsUses(MachineBasicBlock::iterator MI,
72
                        SmallSet<unsigned, 32>& RegDefs,
73
                        SmallSet<unsigned, 32>& RegUses);
74
75
    bool IsRegInSet(SmallSet<unsigned, 32>& RegSet,
76
                    unsigned Reg);
77
78
    bool delayHasHazard(MachineBasicBlock::iterator candidate,
79
                        bool &sawLoad, bool &sawStore,
80
                        SmallSet<unsigned, 32> &RegDefs,
81
                        SmallSet<unsigned, 32> &RegUses);
82
83
    MachineBasicBlock::iterator
84
    findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot);
85
86
    bool needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize);
87
88
    bool tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB,
89
                                       MachineBasicBlock::iterator MBBI);
90
91
  };
92
  char Filler::ID = 0;
93
} // end of anonymous namespace
94
95
/// createSparcDelaySlotFillerPass - Returns a pass that fills in delay
96
/// slots in Sparc MachineFunctions
97
///
98
198
FunctionPass *llvm::createSparcDelaySlotFillerPass() {
99
198
  return new Filler;
100
198
}
101
102
103
/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
104
/// We assume there is only one delay slot per delayed instruction.
105
///
106
993
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
107
993
  bool Changed = false;
108
993
  Subtarget = &MBB.getParent()->getSubtarget<SparcSubtarget>();
109
993
  const TargetInstrInfo *TII = Subtarget->getInstrInfo();
110
993
111
18.8k
  for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) {
112
17.8k
    MachineBasicBlock::iterator MI = I;
113
17.8k
    ++I;
114
17.8k
115
17.8k
    // If MI is restore, try combining it with previous inst.
116
17.8k
    if (!DisableDelaySlotFiller &&
117
17.8k
        
(16.5k
MI->getOpcode() == SP::RESTORErr16.5k
118
16.5k
         || 
MI->getOpcode() == SP::RESTOREri16.2k
)) {
119
293
      Changed |= tryCombineRestoreWithPrevInst(MBB, MI);
120
293
      continue;
121
293
    }
122
17.5k
123
17.5k
    // TODO: If we ever want to support v7, this needs to be extended
124
17.5k
    // to cover all floating point operations.
125
17.5k
    if (!Subtarget->isV9() &&
126
17.5k
        
(14.1k
MI->getOpcode() == SP::FCMPS14.1k
||
MI->getOpcode() == SP::FCMPD14.1k
127
14.1k
         || 
MI->getOpcode() == SP::FCMPQ14.1k
)) {
128
19
      BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP));
129
19
      Changed = true;
130
19
      continue;
131
19
    }
132
17.5k
133
17.5k
    // If MI has no delay slot, skip.
134
17.5k
    if (!MI->hasDelaySlot())
135
16.3k
      continue;
136
1.25k
137
1.25k
    MachineBasicBlock::iterator D = MBB.end();
138
1.25k
139
1.25k
    if (!DisableDelaySlotFiller)
140
1.09k
      D = findDelayInstr(MBB, MI);
141
1.25k
142
1.25k
    ++FilledSlots;
143
1.25k
    Changed = true;
144
1.25k
145
1.25k
    if (D == MBB.end())
146
409
      BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP));
147
850
    else
148
850
      MBB.splice(I, &MBB, D);
149
1.25k
150
1.25k
    unsigned structSize = 0;
151
1.25k
    if (needsUnimp(MI, structSize)) {
152
29
      MachineBasicBlock::iterator J = MI;
153
29
      ++J; // skip the delay filler.
154
29
      assert (J != MBB.end() && "MI needs a delay instruction.");
155
29
      BuildMI(MBB, ++J, MI->getDebugLoc(),
156
29
              TII->get(SP::UNIMP)).addImm(structSize);
157
29
      // Bundle the delay filler and unimp with the instruction.
158
29
      MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), J);
159
1.23k
    } else {
160
1.23k
      MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), I);
161
1.23k
    }
162
1.25k
  }
163
993
  return Changed;
164
993
}
165
166
MachineBasicBlock::iterator
167
Filler::findDelayInstr(MachineBasicBlock &MBB,
168
                       MachineBasicBlock::iterator slot)
169
1.09k
{
170
1.09k
  SmallSet<unsigned, 32> RegDefs;
171
1.09k
  SmallSet<unsigned, 32> RegUses;
172
1.09k
  bool sawLoad = false;
173
1.09k
  bool sawStore = false;
174
1.09k
175
1.09k
  if (slot == MBB.begin())
176
48
    return MBB.end();
177
1.04k
178
1.04k
  if (slot->getOpcode() == SP::RET || slot->getOpcode() == SP::TLS_CALL)
179
8
    return MBB.end();
180
1.03k
181
1.03k
  if (slot->getOpcode() == SP::RETL) {
182
581
    MachineBasicBlock::iterator J = slot;
183
581
    --J;
184
581
185
581
    if (J->getOpcode() == SP::RESTORErr
186
581
        || 
J->getOpcode() == SP::RESTOREri301
) {
187
293
      // change retl to ret.
188
293
      slot->setDesc(Subtarget->getInstrInfo()->get(SP::RET));
189
293
      return J;
190
293
    }
191
741
  }
192
741
193
741
  // Call's delay filler can def some of call's uses.
194
741
  if (slot->isCall())
195
276
    insertCallDefsUses(slot, RegDefs, RegUses);
196
465
  else
197
465
    insertDefsUses(slot, RegDefs, RegUses);
198
741
199
741
  bool done = false;
200
741
201
741
  MachineBasicBlock::iterator I = slot;
202
741
203
1.06k
  while (!done) {
204
1.00k
    done = (I == MBB.begin());
205
1.00k
206
1.00k
    if (!done)
207
941
      --I;
208
1.00k
209
1.00k
    // skip debug instruction
210
1.00k
    if (I->isDebugInstr())
211
3
      continue;
212
1.00k
213
1.00k
    if (I->hasUnmodeledSideEffects() || 
I->isInlineAsm()952
||
I->isPosition()950
||
214
1.00k
        
I->hasDelaySlot()916
||
I->isBundledWithSucc()882
)
215
120
      break;
216
882
217
882
    if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
218
325
      insertDefsUses(I, RegDefs, RegUses);
219
325
      continue;
220
325
    }
221
557
222
557
    return I;
223
557
  }
224
741
  
return MBB.end()184
;
225
741
}
226
227
bool Filler::delayHasHazard(MachineBasicBlock::iterator candidate,
228
                            bool &sawLoad,
229
                            bool &sawStore,
230
                            SmallSet<unsigned, 32> &RegDefs,
231
                            SmallSet<unsigned, 32> &RegUses)
232
882
{
233
882
234
882
  if (candidate->isImplicitDef() || 
candidate->isKill()881
)
235
5
    return true;
236
877
237
877
  if (candidate->mayLoad()) {
238
101
    sawLoad = true;
239
101
    if (sawStore)
240
0
      return true;
241
877
  }
242
877
243
877
  if (candidate->mayStore()) {
244
184
    if (sawStore)
245
1
      return true;
246
183
    sawStore = true;
247
183
    if (sawLoad)
248
35
      return true;
249
841
  }
250
841
251
2.71k
  
for (unsigned i = 0, e = candidate->getNumOperands(); 841
i!= e;
++i1.87k
) {
252
2.15k
    const MachineOperand &MO = candidate->getOperand(i);
253
2.15k
    if (!MO.isReg())
254
398
      continue; // skip
255
1.75k
256
1.75k
    unsigned Reg = MO.getReg();
257
1.75k
258
1.75k
    if (MO.isDef()) {
259
680
      // check whether Reg is defined or used before delay slot.
260
680
      if (IsRegInSet(RegDefs, Reg) || 
IsRegInSet(RegUses, Reg)535
)
261
260
        return true;
262
1.49k
    }
263
1.49k
    if (MO.isUse()) {
264
1.07k
      // check whether Reg is defined before delay slot.
265
1.07k
      if (IsRegInSet(RegDefs, Reg))
266
18
        return true;
267
1.07k
    }
268
1.49k
  }
269
841
270
841
  unsigned Opcode = candidate->getOpcode();
271
563
  // LD and LDD may have NOPs inserted afterwards in the case of some LEON
272
563
  // processors, so we can't use the delay slot if this feature is switched-on.
273
563
  if (Subtarget->insertNOPLoad()
274
563
      &&
275
563
      
Opcode >= SP::LDDArr6
&&
Opcode <= SP::LDrr2
)
276
2
    return true;
277
561
278
561
  // Same as above for FDIV and FSQRT on some LEON processors.
279
561
  if (Subtarget->fixAllFDIVSQRT()
280
561
      &&
281
561
      
Opcode >= SP::FDIVD5
&&
Opcode <= SP::FSQRTD4
)
282
4
    return true;
283
557
284
557
285
557
  return false;
286
557
}
287
288
289
void Filler::insertCallDefsUses(MachineBasicBlock::iterator MI,
290
                                SmallSet<unsigned, 32>& RegDefs,
291
                                SmallSet<unsigned, 32>& RegUses)
292
276
{
293
276
  // Call defines o7, which is visible to the instruction in delay slot.
294
276
  RegDefs.insert(SP::O7);
295
276
296
276
  switch(MI->getOpcode()) {
297
276
  
default: 0
llvm_unreachable0
("Unknown opcode.");
298
276
  
case SP::CALL: break268
;
299
276
  case SP::CALLrr:
300
8
  case SP::CALLri:
301
8
    assert(MI->getNumOperands() >= 2);
302
8
    const MachineOperand &Reg = MI->getOperand(0);
303
8
    assert(Reg.isReg() && "CALL first operand is not a register.");
304
8
    assert(Reg.isUse() && "CALL first operand is not a use.");
305
8
    RegUses.insert(Reg.getReg());
306
8
307
8
    const MachineOperand &Operand1 = MI->getOperand(1);
308
8
    if (Operand1.isImm() || Operand1.isGlobal())
309
3
        break;
310
5
    assert(Operand1.isReg() && "CALLrr second operand is not a register.");
311
5
    assert(Operand1.isUse() && "CALLrr second operand is not a use.");
312
5
    RegUses.insert(Operand1.getReg());
313
5
    break;
314
276
  }
315
276
}
316
317
// Insert Defs and Uses of MI into the sets RegDefs and RegUses.
318
void Filler::insertDefsUses(MachineBasicBlock::iterator MI,
319
                            SmallSet<unsigned, 32>& RegDefs,
320
                            SmallSet<unsigned, 32>& RegUses)
321
790
{
322
2.79k
  for (unsigned i = 0, e = MI->getNumOperands(); i != e; 
++i2.00k
) {
323
2.00k
    const MachineOperand &MO = MI->getOperand(i);
324
2.00k
    if (!MO.isReg())
325
758
      continue;
326
1.24k
327
1.24k
    unsigned Reg = MO.getReg();
328
1.24k
    if (Reg == 0)
329
0
      continue;
330
1.24k
    if (MO.isDef())
331
327
      RegDefs.insert(Reg);
332
1.24k
    if (MO.isUse()) {
333
920
      // Implicit register uses of retl are return values and
334
920
      // retl does not use them.
335
920
      if (MO.isImplicit() && 
MI->getOpcode() == SP::RETL374
)
336
212
        continue;
337
708
      RegUses.insert(Reg);
338
708
    }
339
1.24k
  }
340
790
}
341
342
// returns true if the Reg or its alias is in the RegSet.
343
bool Filler::IsRegInSet(SmallSet<unsigned, 32>& RegSet, unsigned Reg)
344
2.29k
{
345
2.29k
  // Check Reg and all aliased Registers.
346
2.29k
  for (MCRegAliasIterator AI(Reg, Subtarget->getRegisterInfo(), true);
347
6.72k
       AI.isValid(); 
++AI4.43k
)
348
4.71k
    if (RegSet.count(*AI))
349
278
      return true;
350
2.29k
  
return false2.01k
;
351
2.29k
}
352
353
bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)
354
1.25k
{
355
1.25k
  if (!I->isCall())
356
894
    return false;
357
365
358
365
  unsigned structSizeOpNum = 0;
359
365
  switch (I->getOpcode()) {
360
365
  
default: 0
llvm_unreachable0
("Unknown call opcode.");
361
365
  
case SP::CALL: structSizeOpNum = 1; break349
;
362
365
  case SP::CALLrr:
363
8
  case SP::CALLri: structSizeOpNum = 2; break;
364
8
  case SP::TLS_CALL: return false;
365
357
  }
366
357
367
357
  const MachineOperand &MO = I->getOperand(structSizeOpNum);
368
357
  if (!MO.isImm())
369
328
    return false;
370
29
  StructSize = MO.getImm();
371
29
  return true;
372
29
}
373
374
static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI,
375
                              MachineBasicBlock::iterator AddMI,
376
                              const TargetInstrInfo *TII)
377
13
{
378
13
  // Before:  add  <op0>, <op1>, %i[0-7]
379
13
  //          restore %g0, %g0, %i[0-7]
380
13
  //
381
13
  // After :  restore <op0>, <op1>, %o[0-7]
382
13
383
13
  unsigned reg = AddMI->getOperand(0).getReg();
384
13
  if (reg < SP::I0 || reg > SP::I7)
385
2
    return false;
386
11
387
11
  // Erase RESTORE.
388
11
  RestoreMI->eraseFromParent();
389
11
390
11
  // Change ADD to RESTORE.
391
11
  AddMI->setDesc(TII->get((AddMI->getOpcode() == SP::ADDrr)
392
11
                          ? 
SP::RESTORErr9
393
11
                          : 
SP::RESTOREri2
));
394
11
395
11
  // Map the destination register.
396
11
  AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
397
11
398
11
  return true;
399
11
}
400
401
static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI,
402
                             MachineBasicBlock::iterator OrMI,
403
                             const TargetInstrInfo *TII)
404
92
{
405
92
  // Before:  or  <op0>, <op1>, %i[0-7]
406
92
  //          restore %g0, %g0, %i[0-7]
407
92
  //    and <op0> or <op1> is zero,
408
92
  //
409
92
  // After :  restore <op0>, <op1>, %o[0-7]
410
92
411
92
  unsigned reg = OrMI->getOperand(0).getReg();
412
92
  if (reg < SP::I0 || reg > SP::I7)
413
0
    return false;
414
92
415
92
  // check whether it is a copy.
416
92
  if (OrMI->getOpcode() == SP::ORrr
417
92
      && 
OrMI->getOperand(1).getReg() != SP::G080
418
92
      && 
OrMI->getOperand(2).getReg() != SP::G01
)
419
1
    return false;
420
91
421
91
  if (OrMI->getOpcode() == SP::ORri
422
91
      && 
OrMI->getOperand(1).getReg() != SP::G012
423
91
      && 
(2
!OrMI->getOperand(2).isImm()2
||
OrMI->getOperand(2).getImm() != 02
))
424
2
    return false;
425
89
426
89
  // Erase RESTORE.
427
89
  RestoreMI->eraseFromParent();
428
89
429
89
  // Change OR to RESTORE.
430
89
  OrMI->setDesc(TII->get((OrMI->getOpcode() == SP::ORrr)
431
89
                         ? 
SP::RESTORErr79
432
89
                         : 
SP::RESTOREri10
));
433
89
434
89
  // Map the destination register.
435
89
  OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
436
89
437
89
  return true;
438
89
}
439
440
static bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI,
441
                                 MachineBasicBlock::iterator SetHiMI,
442
                                 const TargetInstrInfo *TII)
443
3
{
444
3
  // Before:  sethi imm3, %i[0-7]
445
3
  //          restore %g0, %g0, %g0
446
3
  //
447
3
  // After :  restore %g0, (imm3<<10), %o[0-7]
448
3
449
3
  unsigned reg = SetHiMI->getOperand(0).getReg();
450
3
  if (reg < SP::I0 || reg > SP::I7)
451
0
    return false;
452
3
453
3
  if (!SetHiMI->getOperand(1).isImm())
454
0
    return false;
455
3
456
3
  int64_t imm = SetHiMI->getOperand(1).getImm();
457
3
458
3
  // Is it a 3 bit immediate?
459
3
  if (!isInt<3>(imm))
460
2
    return false;
461
1
462
1
  // Make it a 13 bit immediate.
463
1
  imm = (imm << 10) & 0x1FFF;
464
1
465
1
  assert(RestoreMI->getOpcode() == SP::RESTORErr);
466
1
467
1
  RestoreMI->setDesc(TII->get(SP::RESTOREri));
468
1
469
1
  RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
470
1
  RestoreMI->getOperand(1).setReg(SP::G0);
471
1
  RestoreMI->getOperand(2).ChangeToImmediate(imm);
472
1
473
1
474
1
  // Erase the original SETHI.
475
1
  SetHiMI->eraseFromParent();
476
1
477
1
  return true;
478
1
}
479
480
bool Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB,
481
                                        MachineBasicBlock::iterator MBBI)
482
293
{
483
293
  // No previous instruction.
484
293
  if (MBBI == MBB.begin())
485
10
    return false;
486
283
487
283
  // assert that MBBI is a "restore %g0, %g0, %g0".
488
283
  assert(MBBI->getOpcode() == SP::RESTORErr
489
283
         && MBBI->getOperand(0).getReg() == SP::G0
490
283
         && MBBI->getOperand(1).getReg() == SP::G0
491
283
         && MBBI->getOperand(2).getReg() == SP::G0);
492
283
493
283
  MachineBasicBlock::iterator PrevInst = std::prev(MBBI);
494
283
495
283
  // It cannot be combined with a bundled instruction.
496
283
  if (PrevInst->isBundledWithSucc())
497
29
    return false;
498
254
499
254
  const TargetInstrInfo *TII = Subtarget->getInstrInfo();
500
254
501
254
  switch (PrevInst->getOpcode()) {
502
254
  
default: break146
;
503
254
  case SP::ADDrr:
504
13
  case SP::ADDri: return combineRestoreADD(MBBI, PrevInst, TII); 
break0
;
505
92
  case SP::ORrr:
506
92
  case SP::ORri:  return combineRestoreOR(MBBI, PrevInst, TII); 
break0
;
507
92
  
case SP::SETHIi: return combineRestoreSETHIi(MBBI, PrevInst, TII)3
;
break0
;
508
146
  }
509
146
  // It cannot combine with the previous instruction.
510
146
  return false;
511
146
}