1 //===-- DelaySlotFiller.cpp - SPARC delay slot filler ---------------------===//
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
7 //===----------------------------------------------------------------------===//
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
12 //===----------------------------------------------------------------------===//
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"
27 #define DEBUG_TYPE "delay-slot-filler"
29 STATISTIC(FilledSlots
, "Number of delay slots filled");
31 static cl::opt
<bool> DisableDelaySlotFiller(
32 "disable-sparc-delay-filler",
34 cl::desc("Disable the Sparc delay slot filler."),
38 struct Filler
: public MachineFunctionPass
{
39 const SparcSubtarget
*Subtarget
= nullptr;
42 Filler() : MachineFunctionPass(ID
) {}
44 StringRef
getPassName() const override
{ return "SPARC Delay Slot Filler"; }
46 bool runOnMachineBasicBlock(MachineBasicBlock
&MBB
);
47 bool runOnMachineFunction(MachineFunction
&F
) override
{
49 Subtarget
= &F
.getSubtarget
<SparcSubtarget
>();
51 // This pass invalidates liveness information when it reorders
52 // instructions to fill delay slot.
53 F
.getRegInfo().invalidateLiveness();
55 for (MachineBasicBlock
&MBB
: F
)
56 Changed
|= runOnMachineBasicBlock(MBB
);
60 MachineFunctionProperties
getRequiredProperties() const override
{
61 return MachineFunctionProperties().set(
62 MachineFunctionProperties::Property::NoVRegs
);
65 void insertCallDefsUses(MachineBasicBlock::iterator MI
,
66 SmallSet
<unsigned, 32>& RegDefs
,
67 SmallSet
<unsigned, 32>& RegUses
);
69 void insertDefsUses(MachineBasicBlock::iterator MI
,
70 SmallSet
<unsigned, 32>& RegDefs
,
71 SmallSet
<unsigned, 32>& RegUses
);
73 bool IsRegInSet(SmallSet
<unsigned, 32>& RegSet
,
76 bool delayHasHazard(MachineBasicBlock::iterator candidate
,
77 bool &sawLoad
, bool &sawStore
,
78 SmallSet
<unsigned, 32> &RegDefs
,
79 SmallSet
<unsigned, 32> &RegUses
);
81 MachineBasicBlock::iterator
82 findDelayInstr(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator slot
);
84 bool needsUnimp(MachineBasicBlock::iterator I
, unsigned &StructSize
);
86 bool tryCombineRestoreWithPrevInst(MachineBasicBlock
&MBB
,
87 MachineBasicBlock::iterator MBBI
);
91 } // end of anonymous namespace
93 /// createSparcDelaySlotFillerPass - Returns a pass that fills in delay
94 /// slots in Sparc MachineFunctions
96 FunctionPass
*llvm::createSparcDelaySlotFillerPass() {
101 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
102 /// We assume there is only one delay slot per delayed instruction.
104 bool Filler::runOnMachineBasicBlock(MachineBasicBlock
&MBB
) {
105 bool Changed
= false;
106 Subtarget
= &MBB
.getParent()->getSubtarget
<SparcSubtarget
>();
107 const TargetInstrInfo
*TII
= Subtarget
->getInstrInfo();
109 for (MachineBasicBlock::iterator I
= MBB
.begin(); I
!= MBB
.end(); ) {
110 MachineBasicBlock::iterator MI
= I
;
113 // If MI is restore, try combining it with previous inst.
114 if (!DisableDelaySlotFiller
&&
115 (MI
->getOpcode() == SP::RESTORErr
116 || MI
->getOpcode() == SP::RESTOREri
)) {
117 Changed
|= tryCombineRestoreWithPrevInst(MBB
, MI
);
121 // TODO: If we ever want to support v7, this needs to be extended
122 // to cover all floating point operations.
123 if (!Subtarget
->isV9() &&
124 (MI
->getOpcode() == SP::FCMPS
|| MI
->getOpcode() == SP::FCMPD
125 || MI
->getOpcode() == SP::FCMPQ
)) {
126 BuildMI(MBB
, I
, MI
->getDebugLoc(), TII
->get(SP::NOP
));
131 // If MI has no delay slot, skip.
132 if (!MI
->hasDelaySlot())
135 MachineBasicBlock::iterator D
= MBB
.end();
137 if (!DisableDelaySlotFiller
)
138 D
= findDelayInstr(MBB
, MI
);
144 BuildMI(MBB
, I
, MI
->getDebugLoc(), TII
->get(SP::NOP
));
146 MBB
.splice(I
, &MBB
, D
);
148 unsigned structSize
= 0;
149 if (needsUnimp(MI
, structSize
)) {
150 MachineBasicBlock::iterator J
= MI
;
151 ++J
; // skip the delay filler.
152 assert (J
!= MBB
.end() && "MI needs a delay instruction.");
153 BuildMI(MBB
, ++J
, MI
->getDebugLoc(),
154 TII
->get(SP::UNIMP
)).addImm(structSize
);
155 // Bundle the delay filler and unimp with the instruction.
156 MIBundleBuilder(MBB
, MachineBasicBlock::iterator(MI
), J
);
158 MIBundleBuilder(MBB
, MachineBasicBlock::iterator(MI
), I
);
164 MachineBasicBlock::iterator
165 Filler::findDelayInstr(MachineBasicBlock
&MBB
,
166 MachineBasicBlock::iterator slot
)
168 SmallSet
<unsigned, 32> RegDefs
;
169 SmallSet
<unsigned, 32> RegUses
;
170 bool sawLoad
= false;
171 bool sawStore
= false;
173 if (slot
== MBB
.begin())
176 unsigned Opc
= slot
->getOpcode();
178 if (Opc
== SP::RET
|| Opc
== SP::TLS_CALL
)
181 if (Opc
== SP::RETL
|| Opc
== SP::TAIL_CALL
|| Opc
== SP::TAIL_CALLri
) {
182 MachineBasicBlock::iterator J
= slot
;
185 if (J
->getOpcode() == SP::RESTORErr
186 || J
->getOpcode() == SP::RESTOREri
) {
187 // change retl to ret.
189 slot
->setDesc(Subtarget
->getInstrInfo()->get(SP::RET
));
194 // Call's delay filler can def some of call's uses.
196 insertCallDefsUses(slot
, RegDefs
, RegUses
);
198 insertDefsUses(slot
, RegDefs
, RegUses
);
202 MachineBasicBlock::iterator I
= slot
;
205 done
= (I
== MBB
.begin());
210 // skip debug instruction
211 if (I
->isDebugInstr())
214 if (I
->hasUnmodeledSideEffects() || I
->isInlineAsm() || I
->isPosition() ||
215 I
->hasDelaySlot() || I
->isBundledWithSucc())
218 if (delayHasHazard(I
, sawLoad
, sawStore
, RegDefs
, RegUses
)) {
219 insertDefsUses(I
, RegDefs
, RegUses
);
228 bool Filler::delayHasHazard(MachineBasicBlock::iterator candidate
,
231 SmallSet
<unsigned, 32> &RegDefs
,
232 SmallSet
<unsigned, 32> &RegUses
)
235 if (candidate
->isImplicitDef() || candidate
->isKill())
238 if (candidate
->mayLoad()) {
244 if (candidate
->mayStore()) {
252 for (const MachineOperand
&MO
: candidate
->operands()) {
256 Register Reg
= MO
.getReg();
259 // check whether Reg is defined or used before delay slot.
260 if (IsRegInSet(RegDefs
, Reg
) || IsRegInSet(RegUses
, Reg
))
264 // check whether Reg is defined before delay slot.
265 if (IsRegInSet(RegDefs
, Reg
))
270 unsigned Opcode
= candidate
->getOpcode();
271 // LD and LDD may have NOPs inserted afterwards in the case of some LEON
272 // processors, so we can't use the delay slot if this feature is switched-on.
273 if (Subtarget
->insertNOPLoad()
275 Opcode
>= SP::LDDArr
&& Opcode
<= SP::LDrr
)
278 // Same as above for FDIV and FSQRT on some LEON processors.
279 if (Subtarget
->fixAllFDIVSQRT()
281 Opcode
>= SP::FDIVD
&& Opcode
<= SP::FSQRTD
)
284 if (Subtarget
->fixTN0009() && candidate
->mayStore())
287 if (Subtarget
->fixTN0013()) {
303 void Filler::insertCallDefsUses(MachineBasicBlock::iterator MI
,
304 SmallSet
<unsigned, 32>& RegDefs
,
305 SmallSet
<unsigned, 32>& RegUses
)
307 // Call defines o7, which is visible to the instruction in delay slot.
308 RegDefs
.insert(SP::O7
);
310 switch(MI
->getOpcode()) {
311 default: llvm_unreachable("Unknown opcode.");
316 assert(MI
->getNumOperands() >= 2);
317 const MachineOperand
&Reg
= MI
->getOperand(0);
318 assert(Reg
.isReg() && "CALL first operand is not a register.");
319 assert(Reg
.isUse() && "CALL first operand is not a use.");
320 RegUses
.insert(Reg
.getReg());
322 const MachineOperand
&Operand1
= MI
->getOperand(1);
323 if (Operand1
.isImm() || Operand1
.isGlobal())
325 assert(Operand1
.isReg() && "CALLrr second operand is not a register.");
326 assert(Operand1
.isUse() && "CALLrr second operand is not a use.");
327 RegUses
.insert(Operand1
.getReg());
332 // Insert Defs and Uses of MI into the sets RegDefs and RegUses.
333 void Filler::insertDefsUses(MachineBasicBlock::iterator MI
,
334 SmallSet
<unsigned, 32>& RegDefs
,
335 SmallSet
<unsigned, 32>& RegUses
)
337 for (const MachineOperand
&MO
: MI
->operands()) {
341 Register Reg
= MO
.getReg();
347 // Implicit register uses of retl are return values and
348 // retl does not use them.
349 if (MO
.isImplicit() && MI
->getOpcode() == SP::RETL
)
356 // returns true if the Reg or its alias is in the RegSet.
357 bool Filler::IsRegInSet(SmallSet
<unsigned, 32>& RegSet
, unsigned Reg
)
359 // Check Reg and all aliased Registers.
360 for (MCRegAliasIterator
AI(Reg
, Subtarget
->getRegisterInfo(), true);
362 if (RegSet
.count(*AI
))
367 bool Filler::needsUnimp(MachineBasicBlock::iterator I
, unsigned &StructSize
)
372 unsigned structSizeOpNum
= 0;
373 switch (I
->getOpcode()) {
374 default: llvm_unreachable("Unknown call opcode.");
382 case SP::TLS_CALL
: return false;
383 case SP::TAIL_CALLri
:
384 case SP::TAIL_CALL
: return false;
387 const MachineOperand
&MO
= I
->getOperand(structSizeOpNum
);
390 StructSize
= MO
.getImm();
394 static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI
,
395 MachineBasicBlock::iterator AddMI
,
396 const TargetInstrInfo
*TII
)
398 // Before: add <op0>, <op1>, %i[0-7]
399 // restore %g0, %g0, %i[0-7]
401 // After : restore <op0>, <op1>, %o[0-7]
403 Register reg
= AddMI
->getOperand(0).getReg();
404 if (reg
< SP::I0
|| reg
> SP::I7
)
408 RestoreMI
->eraseFromParent();
410 // Change ADD to RESTORE.
411 AddMI
->setDesc(TII
->get((AddMI
->getOpcode() == SP::ADDrr
)
415 // Map the destination register.
416 AddMI
->getOperand(0).setReg(reg
- SP::I0
+ SP::O0
);
421 static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI
,
422 MachineBasicBlock::iterator OrMI
,
423 const TargetInstrInfo
*TII
)
425 // Before: or <op0>, <op1>, %i[0-7]
426 // restore %g0, %g0, %i[0-7]
427 // and <op0> or <op1> is zero,
429 // After : restore <op0>, <op1>, %o[0-7]
431 Register reg
= OrMI
->getOperand(0).getReg();
432 if (reg
< SP::I0
|| reg
> SP::I7
)
435 // check whether it is a copy.
436 if (OrMI
->getOpcode() == SP::ORrr
437 && OrMI
->getOperand(1).getReg() != SP::G0
438 && OrMI
->getOperand(2).getReg() != SP::G0
)
441 if (OrMI
->getOpcode() == SP::ORri
442 && OrMI
->getOperand(1).getReg() != SP::G0
443 && (!OrMI
->getOperand(2).isImm() || OrMI
->getOperand(2).getImm() != 0))
447 RestoreMI
->eraseFromParent();
449 // Change OR to RESTORE.
450 OrMI
->setDesc(TII
->get((OrMI
->getOpcode() == SP::ORrr
)
454 // Map the destination register.
455 OrMI
->getOperand(0).setReg(reg
- SP::I0
+ SP::O0
);
460 static bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI
,
461 MachineBasicBlock::iterator SetHiMI
,
462 const TargetInstrInfo
*TII
)
464 // Before: sethi imm3, %i[0-7]
465 // restore %g0, %g0, %g0
467 // After : restore %g0, (imm3<<10), %o[0-7]
469 Register reg
= SetHiMI
->getOperand(0).getReg();
470 if (reg
< SP::I0
|| reg
> SP::I7
)
473 if (!SetHiMI
->getOperand(1).isImm())
476 int64_t imm
= SetHiMI
->getOperand(1).getImm();
478 // Is it a 3 bit immediate?
482 // Make it a 13 bit immediate.
483 imm
= (imm
<< 10) & 0x1FFF;
485 assert(RestoreMI
->getOpcode() == SP::RESTORErr
);
487 RestoreMI
->setDesc(TII
->get(SP::RESTOREri
));
489 RestoreMI
->getOperand(0).setReg(reg
- SP::I0
+ SP::O0
);
490 RestoreMI
->getOperand(1).setReg(SP::G0
);
491 RestoreMI
->getOperand(2).ChangeToImmediate(imm
);
494 // Erase the original SETHI.
495 SetHiMI
->eraseFromParent();
500 bool Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock
&MBB
,
501 MachineBasicBlock::iterator MBBI
)
503 // No previous instruction.
504 if (MBBI
== MBB
.begin())
507 // assert that MBBI is a "restore %g0, %g0, %g0".
508 assert(MBBI
->getOpcode() == SP::RESTORErr
509 && MBBI
->getOperand(0).getReg() == SP::G0
510 && MBBI
->getOperand(1).getReg() == SP::G0
511 && MBBI
->getOperand(2).getReg() == SP::G0
);
513 MachineBasicBlock::iterator PrevInst
= std::prev(MBBI
);
515 // It cannot be combined with a bundled instruction.
516 if (PrevInst
->isBundledWithSucc())
519 const TargetInstrInfo
*TII
= Subtarget
->getInstrInfo();
521 switch (PrevInst
->getOpcode()) {
524 case SP::ADDri
: return combineRestoreADD(MBBI
, PrevInst
, TII
); break;
526 case SP::ORri
: return combineRestoreOR(MBBI
, PrevInst
, TII
); break;
527 case SP::SETHIi
: return combineRestoreSETHIi(MBBI
, PrevInst
, TII
); break;
529 // It cannot combine with the previous instruction.