LLVM 20.0.0git
MipsDelaySlotFiller.cpp
Go to the documentation of this file.
1//===- MipsDelaySlotFiller.cpp - Mips 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// Simple pass to fill delay slots with useful instructions.
10//
11//===----------------------------------------------------------------------===//
12
14#include "Mips.h"
15#include "MipsInstrInfo.h"
16#include "MipsSubtarget.h"
17#include "llvm/ADT/BitVector.h"
18#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/Statistic.h"
23#include "llvm/ADT/StringRef.h"
37#include "llvm/MC/MCInstrDesc.h"
44#include <algorithm>
45#include <cassert>
46#include <iterator>
47#include <memory>
48#include <utility>
49
50using namespace llvm;
51
52#define DEBUG_TYPE "mips-delay-slot-filler"
53
54STATISTIC(FilledSlots, "Number of delay slots filled");
55STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that"
56 " are not NOP.");
57
59 "disable-mips-delay-filler",
60 cl::init(false),
61 cl::desc("Fill all delay slots with NOPs."),
63
65 "disable-mips-df-forward-search",
66 cl::init(true),
67 cl::desc("Disallow MIPS delay filler to search forward."),
69
71 "disable-mips-df-succbb-search",
72 cl::init(true),
73 cl::desc("Disallow MIPS delay filler to search successor basic blocks."),
75
77 "disable-mips-df-backward-search",
78 cl::init(false),
79 cl::desc("Disallow MIPS delay filler to search backward."),
81
83 CB_Never, ///< The policy 'never' may in some circumstances or for some
84 ///< ISAs not be absolutely adhered to.
85 CB_Optimal, ///< Optimal is the default and will produce compact branches
86 ///< when delay slots cannot be filled.
87 CB_Always ///< 'always' may in some circumstances may not be
88 ///< absolutely adhered to there may not be a corresponding
89 ///< compact form of a branch.
90};
91
93 "mips-compact-branches", cl::Optional, cl::init(CB_Optimal),
94 cl::desc("MIPS Specific: Compact branch policy."),
96 "Do not use compact branches if possible."),
97 clEnumValN(CB_Optimal, "optimal",
98 "Use compact branches where appropriate (default)."),
99 clEnumValN(CB_Always, "always",
100 "Always use compact branches if possible.")));
101
102namespace {
103
104 using Iter = MachineBasicBlock::iterator;
105 using ReverseIter = MachineBasicBlock::reverse_iterator;
107
108 class RegDefsUses {
109 public:
110 RegDefsUses(const TargetRegisterInfo &TRI);
111
112 void init(const MachineInstr &MI);
113
114 /// This function sets all caller-saved registers in Defs.
115 void setCallerSaved(const MachineInstr &MI);
116
117 /// This function sets all unallocatable registers in Defs.
118 void setUnallocatableRegs(const MachineFunction &MF);
119
120 /// Set bits in Uses corresponding to MBB's live-out registers except for
121 /// the registers that are live-in to SuccBB.
122 void addLiveOut(const MachineBasicBlock &MBB,
123 const MachineBasicBlock &SuccBB);
124
125 bool update(const MachineInstr &MI, unsigned Begin, unsigned End);
126
127 private:
128 bool checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses, unsigned Reg,
129 bool IsDef) const;
130
131 /// Returns true if Reg or its alias is in RegSet.
132 bool isRegInSet(const BitVector &RegSet, unsigned Reg) const;
133
134 const TargetRegisterInfo &TRI;
135 BitVector Defs, Uses;
136 };
137
138 /// Base class for inspecting loads and stores.
139 class InspectMemInstr {
140 public:
141 InspectMemInstr(bool ForbidMemInstr_) : ForbidMemInstr(ForbidMemInstr_) {}
142 virtual ~InspectMemInstr() = default;
143
144 /// Return true if MI cannot be moved to delay slot.
145 bool hasHazard(const MachineInstr &MI);
146
147 protected:
148 /// Flags indicating whether loads or stores have been seen.
149 bool OrigSeenLoad = false;
150 bool OrigSeenStore = false;
151 bool SeenLoad = false;
152 bool SeenStore = false;
153
154 /// Memory instructions are not allowed to move to delay slot if this flag
155 /// is true.
156 bool ForbidMemInstr;
157
158 private:
159 virtual bool hasHazard_(const MachineInstr &MI) = 0;
160 };
161
162 /// This subclass rejects any memory instructions.
163 class NoMemInstr : public InspectMemInstr {
164 public:
165 NoMemInstr() : InspectMemInstr(true) {}
166
167 private:
168 bool hasHazard_(const MachineInstr &MI) override { return true; }
169 };
170
171 /// This subclass accepts loads from stacks and constant loads.
172 class LoadFromStackOrConst : public InspectMemInstr {
173 public:
174 LoadFromStackOrConst() : InspectMemInstr(false) {}
175
176 private:
177 bool hasHazard_(const MachineInstr &MI) override;
178 };
179
180 /// This subclass uses memory dependence information to determine whether a
181 /// memory instruction can be moved to a delay slot.
182 class MemDefsUses : public InspectMemInstr {
183 public:
184 explicit MemDefsUses(const MachineFrameInfo *MFI);
185
186 private:
188
189 bool hasHazard_(const MachineInstr &MI) override;
190
191 /// Update Defs and Uses. Return true if there exist dependences that
192 /// disqualify the delay slot candidate between V and values in Uses and
193 /// Defs.
194 bool updateDefsUses(ValueType V, bool MayStore);
195
196 /// Get the list of underlying objects of MI's memory operand.
198 SmallVectorImpl<ValueType> &Objects) const;
199
200 const MachineFrameInfo *MFI;
202
203 /// Flags indicating whether loads or stores with no underlying objects have
204 /// been seen.
205 bool SeenNoObjLoad = false;
206 bool SeenNoObjStore = false;
207 };
208
209 class MipsDelaySlotFiller : public MachineFunctionPass {
210 public:
211 MipsDelaySlotFiller() : MachineFunctionPass(ID) {
213 }
214
215 StringRef getPassName() const override { return "Mips Delay Slot Filler"; }
216
217 bool runOnMachineFunction(MachineFunction &F) override {
218 TM = &F.getTarget();
219 bool Changed = false;
220 for (MachineBasicBlock &MBB : F)
221 Changed |= runOnMachineBasicBlock(MBB);
222
223 // This pass invalidates liveness information when it reorders
224 // instructions to fill delay slot. Without this, -verify-machineinstrs
225 // will fail.
226 if (Changed)
227 F.getRegInfo().invalidateLiveness();
228
229 return Changed;
230 }
231
234 MachineFunctionProperties::Property::NoVRegs);
235 }
236
237 void getAnalysisUsage(AnalysisUsage &AU) const override {
240 }
241
242 static char ID;
243
244 private:
245 bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
246
247 Iter replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch,
248 const DebugLoc &DL);
249
250 /// This function checks if it is valid to move Candidate to the delay slot
251 /// and returns true if it isn't. It also updates memory and register
252 /// dependence information.
253 bool delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU,
254 InspectMemInstr &IM) const;
255
256 /// This function searches range [Begin, End) for an instruction that can be
257 /// moved to the delay slot. Returns true on success.
258 template<typename IterTy>
259 bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,
260 RegDefsUses &RegDU, InspectMemInstr &IM, Iter Slot,
261 IterTy &Filler) const;
262
263 /// This function searches in the backward direction for an instruction that
264 /// can be moved to the delay slot. Returns true on success.
265 bool searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const;
266
267 /// This function searches MBB in the forward direction for an instruction
268 /// that can be moved to the delay slot. Returns true on success.
269 bool searchForward(MachineBasicBlock &MBB, Iter Slot) const;
270
271 /// This function searches one of MBB's successor blocks for an instruction
272 /// that can be moved to the delay slot and inserts clones of the
273 /// instruction into the successor's predecessor blocks.
274 bool searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const;
275
276 /// Pick a successor block of MBB. Return NULL if MBB doesn't have a
277 /// successor block that is not a landing pad.
278 MachineBasicBlock *selectSuccBB(MachineBasicBlock &B) const;
279
280 /// This function analyzes MBB and returns an instruction with an unoccupied
281 /// slot that branches to Dst.
282 std::pair<MipsInstrInfo::BranchType, MachineInstr *>
283 getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const;
284
285 /// Examine Pred and see if it is possible to insert an instruction into
286 /// one of its branches delay slot or its end.
287 bool examinePred(MachineBasicBlock &Pred, const MachineBasicBlock &Succ,
288 RegDefsUses &RegDU, bool &HasMultipleSuccs,
289 BB2BrMap &BrMap) const;
290
291 bool terminateSearch(const MachineInstr &Candidate) const;
292
293 const TargetMachine *TM = nullptr;
294 };
295
296} // end anonymous namespace
297
298char MipsDelaySlotFiller::ID = 0;
299
300static bool hasUnoccupiedSlot(const MachineInstr *MI) {
301 return MI->hasDelaySlot() && !MI->isBundledWithSucc();
302}
303
304INITIALIZE_PASS(MipsDelaySlotFiller, DEBUG_TYPE,
305 "Fill delay slot for MIPS", false, false)
306
307/// This function inserts clones of Filler into predecessor blocks.
308static void insertDelayFiller(Iter Filler, const BB2BrMap &BrMap) {
309 MachineFunction *MF = Filler->getParent()->getParent();
310
311 for (const auto &I : BrMap) {
312 if (I.second) {
313 MIBundleBuilder(I.second).append(MF->CloneMachineInstr(&*Filler));
314 ++UsefulSlots;
315 } else {
316 I.first->push_back(MF->CloneMachineInstr(&*Filler));
317 }
318 }
319}
320
321/// This function adds registers Filler defines to MBB's live-in register list.
322static void addLiveInRegs(Iter Filler, MachineBasicBlock &MBB) {
323 for (const MachineOperand &MO : Filler->operands()) {
324 unsigned R;
325
326 if (!MO.isReg() || !MO.isDef() || !(R = MO.getReg()))
327 continue;
328
329#ifndef NDEBUG
330 const MachineFunction &MF = *MBB.getParent();
332 "Shouldn't move an instruction with unallocatable registers across "
333 "basic block boundaries.");
334#endif
335
336 if (!MBB.isLiveIn(R))
337 MBB.addLiveIn(R);
338 }
339}
340
341RegDefsUses::RegDefsUses(const TargetRegisterInfo &TRI)
342 : TRI(TRI), Defs(TRI.getNumRegs(), false), Uses(TRI.getNumRegs(), false) {}
343
344void RegDefsUses::init(const MachineInstr &MI) {
345 // Add all register operands which are explicit and non-variadic.
346 update(MI, 0, MI.getDesc().getNumOperands());
347
348 // If MI is a call, add RA to Defs to prevent users of RA from going into
349 // delay slot.
350 if (MI.isCall())
351 Defs.set(Mips::RA);
352
353 // Add all implicit register operands of branch instructions except
354 // register AT.
355 if (MI.isBranch()) {
356 update(MI, MI.getDesc().getNumOperands(), MI.getNumOperands());
357 Defs.reset(Mips::AT);
358 }
359}
360
361void RegDefsUses::setCallerSaved(const MachineInstr &MI) {
362 assert(MI.isCall());
363
364 // Add RA/RA_64 to Defs to prevent users of RA/RA_64 from going into
365 // the delay slot. The reason is that RA/RA_64 must not be changed
366 // in the delay slot so that the callee can return to the caller.
367 if (MI.definesRegister(Mips::RA, /*TRI=*/nullptr) ||
368 MI.definesRegister(Mips::RA_64, /*TRI=*/nullptr)) {
369 Defs.set(Mips::RA);
370 Defs.set(Mips::RA_64);
371 }
372
373 // If MI is a call, add all caller-saved registers to Defs.
374 BitVector CallerSavedRegs(TRI.getNumRegs(), true);
375
376 CallerSavedRegs.reset(Mips::ZERO);
377 CallerSavedRegs.reset(Mips::ZERO_64);
378
379 for (const MCPhysReg *R = TRI.getCalleeSavedRegs(MI.getParent()->getParent());
380 *R; ++R)
381 for (MCRegAliasIterator AI(*R, &TRI, true); AI.isValid(); ++AI)
382 CallerSavedRegs.reset(*AI);
383
384 Defs |= CallerSavedRegs;
385}
386
387void RegDefsUses::setUnallocatableRegs(const MachineFunction &MF) {
388 BitVector AllocSet = TRI.getAllocatableSet(MF);
389
390 for (unsigned R : AllocSet.set_bits())
391 for (MCRegAliasIterator AI(R, &TRI, false); AI.isValid(); ++AI)
392 AllocSet.set(*AI);
393
394 AllocSet.set(Mips::ZERO);
395 AllocSet.set(Mips::ZERO_64);
396
397 Defs |= AllocSet.flip();
398}
399
400void RegDefsUses::addLiveOut(const MachineBasicBlock &MBB,
401 const MachineBasicBlock &SuccBB) {
402 for (const MachineBasicBlock *S : MBB.successors())
403 if (S != &SuccBB)
404 for (const auto &LI : S->liveins())
405 Uses.set(LI.PhysReg);
406}
407
408bool RegDefsUses::update(const MachineInstr &MI, unsigned Begin, unsigned End) {
409 BitVector NewDefs(TRI.getNumRegs()), NewUses(TRI.getNumRegs());
410 bool HasHazard = false;
411
412 for (unsigned I = Begin; I != End; ++I) {
413 const MachineOperand &MO = MI.getOperand(I);
414
415 if (MO.isReg() && MO.getReg()) {
416 if (checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef())) {
417 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found register hazard for operand "
418 << I << ": ";
419 MO.dump());
420 HasHazard = true;
421 }
422 }
423 }
424
425 Defs |= NewDefs;
426 Uses |= NewUses;
427
428 return HasHazard;
429}
430
431bool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
432 unsigned Reg, bool IsDef) const {
433 if (IsDef) {
434 NewDefs.set(Reg);
435 // check whether Reg has already been defined or used.
436 return (isRegInSet(Defs, Reg) || isRegInSet(Uses, Reg));
437 }
438
439 NewUses.set(Reg);
440 // check whether Reg has already been defined.
441 return isRegInSet(Defs, Reg);
442}
443
444bool RegDefsUses::isRegInSet(const BitVector &RegSet, unsigned Reg) const {
445 // Check Reg and all aliased Registers.
446 for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
447 if (RegSet.test(*AI))
448 return true;
449 return false;
450}
451
452bool InspectMemInstr::hasHazard(const MachineInstr &MI) {
453 if (!MI.mayStore() && !MI.mayLoad())
454 return false;
455
456 if (ForbidMemInstr)
457 return true;
458
459 OrigSeenLoad = SeenLoad;
460 OrigSeenStore = SeenStore;
461 SeenLoad |= MI.mayLoad();
462 SeenStore |= MI.mayStore();
463
464 // If MI is an ordered or volatile memory reference, disallow moving
465 // subsequent loads and stores to delay slot.
466 if (MI.hasOrderedMemoryRef() && (OrigSeenLoad || OrigSeenStore)) {
467 ForbidMemInstr = true;
468 return true;
469 }
470
471 return hasHazard_(MI);
472}
473
474bool LoadFromStackOrConst::hasHazard_(const MachineInstr &MI) {
475 if (MI.mayStore())
476 return true;
477
478 if (!MI.hasOneMemOperand() || !(*MI.memoperands_begin())->getPseudoValue())
479 return true;
480
481 if (const PseudoSourceValue *PSV =
482 (*MI.memoperands_begin())->getPseudoValue()) {
483 if (isa<FixedStackPseudoSourceValue>(PSV))
484 return false;
485 return !PSV->isConstant(nullptr) && !PSV->isStack();
486 }
487
488 return true;
489}
490
491MemDefsUses::MemDefsUses(const MachineFrameInfo *MFI_)
492 : InspectMemInstr(false), MFI(MFI_) {}
493
494bool MemDefsUses::hasHazard_(const MachineInstr &MI) {
495 bool HasHazard = false;
496
497 // Check underlying object list.
499 if (getUnderlyingObjects(MI, Objs)) {
500 for (ValueType VT : Objs)
501 HasHazard |= updateDefsUses(VT, MI.mayStore());
502 return HasHazard;
503 }
504
505 // No underlying objects found.
506 HasHazard = MI.mayStore() && (OrigSeenLoad || OrigSeenStore);
507 HasHazard |= MI.mayLoad() || OrigSeenStore;
508
509 SeenNoObjLoad |= MI.mayLoad();
510 SeenNoObjStore |= MI.mayStore();
511
512 return HasHazard;
513}
514
515bool MemDefsUses::updateDefsUses(ValueType V, bool MayStore) {
516 if (MayStore)
517 return !Defs.insert(V).second || Uses.count(V) || SeenNoObjStore ||
518 SeenNoObjLoad;
519
520 Uses.insert(V);
521 return Defs.count(V) || SeenNoObjStore;
522}
523
524bool MemDefsUses::
525getUnderlyingObjects(const MachineInstr &MI,
526 SmallVectorImpl<ValueType> &Objects) const {
527 if (!MI.hasOneMemOperand())
528 return false;
529
530 auto & MMO = **MI.memoperands_begin();
531
532 if (const PseudoSourceValue *PSV = MMO.getPseudoValue()) {
533 if (!PSV->isAliased(MFI))
534 return false;
535 Objects.push_back(PSV);
536 return true;
537 }
538
539 if (const Value *V = MMO.getValue()) {
541 ::getUnderlyingObjects(V, Objs);
542
543 for (const Value *UValue : Objs) {
544 if (!isIdentifiedObject(V))
545 return false;
546
547 Objects.push_back(UValue);
548 }
549 return true;
550 }
551
552 return false;
553}
554
555// Replace Branch with the compact branch instruction.
556Iter MipsDelaySlotFiller::replaceWithCompactBranch(MachineBasicBlock &MBB,
557 Iter Branch,
558 const DebugLoc &DL) {
560 const MipsInstrInfo *TII = STI.getInstrInfo();
561
562 unsigned NewOpcode = TII->getEquivalentCompactForm(Branch);
563 Branch = TII->genInstrWithNewOpc(NewOpcode, Branch);
564
565 auto *ToErase = cast<MachineInstr>(&*std::next(Branch));
566 // Update call site info for the Branch.
567 if (ToErase->shouldUpdateCallSiteInfo())
568 ToErase->getMF()->moveCallSiteInfo(ToErase, cast<MachineInstr>(&*Branch));
569 ToErase->eraseFromParent();
570 return Branch;
571}
572
573// For given opcode returns opcode of corresponding instruction with short
574// delay slot.
575// For the pseudo TAILCALL*_MM instructions return the short delay slot
576// form. Unfortunately, TAILCALL<->b16 is denied as b16 has a limited range
577// that is too short to make use of for tail calls.
578static int getEquivalentCallShort(int Opcode) {
579 switch (Opcode) {
580 case Mips::BGEZAL:
581 return Mips::BGEZALS_MM;
582 case Mips::BLTZAL:
583 return Mips::BLTZALS_MM;
584 case Mips::JAL:
585 case Mips::JAL_MM:
586 return Mips::JALS_MM;
587 case Mips::JALR:
588 return Mips::JALRS_MM;
589 case Mips::JALR16_MM:
590 return Mips::JALRS16_MM;
591 case Mips::TAILCALL_MM:
592 llvm_unreachable("Attempting to shorten the TAILCALL_MM pseudo!");
593 case Mips::TAILCALLREG:
594 return Mips::JR16_MM;
595 default:
596 llvm_unreachable("Unexpected call instruction for microMIPS.");
597 }
598}
599
600/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
601/// We assume there is only one delay slot per delayed instruction.
602bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
603 bool Changed = false;
605 bool InMicroMipsMode = STI.inMicroMipsMode();
606 const MipsInstrInfo *TII = STI.getInstrInfo();
607
608 for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
609 if (!hasUnoccupiedSlot(&*I))
610 continue;
611
612 // Delay slot filling is disabled at -O0, or in microMIPS32R6.
614 (TM->getOptLevel() != CodeGenOptLevel::None) &&
615 !(InMicroMipsMode && STI.hasMips32r6())) {
616
617 bool Filled = false;
618
619 if (MipsCompactBranchPolicy.getValue() != CB_Always ||
620 !TII->getEquivalentCompactForm(I)) {
621 if (searchBackward(MBB, *I)) {
622 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
623 " in backwards search.\n");
624 Filled = true;
625 } else if (I->isTerminator()) {
626 if (searchSuccBBs(MBB, I)) {
627 Filled = true;
628 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
629 " in successor BB search.\n");
630 }
631 } else if (searchForward(MBB, I)) {
632 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
633 " in forwards search.\n");
634 Filled = true;
635 }
636 }
637
638 if (Filled) {
639 // Get instruction with delay slot.
640 MachineBasicBlock::instr_iterator DSI = I.getInstrIterator();
641
642 if (InMicroMipsMode && TII->getInstSizeInBytes(*std::next(DSI)) == 2 &&
643 DSI->isCall()) {
644 // If instruction in delay slot is 16b change opcode to
645 // corresponding instruction with short delay slot.
646
647 // TODO: Implement an instruction mapping table of 16bit opcodes to
648 // 32bit opcodes so that an instruction can be expanded. This would
649 // save 16 bits as a TAILCALL_MM pseudo requires a fullsized nop.
650 // TODO: Permit b16 when branching backwards to the same function
651 // if it is in range.
652 DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode())));
653 }
654 ++FilledSlots;
655 Changed = true;
656 continue;
657 }
658 }
659
660 // For microMIPS if instruction is BEQ or BNE with one ZERO register, then
661 // instead of adding NOP replace this instruction with the corresponding
662 // compact branch instruction, i.e. BEQZC or BNEZC. Additionally
663 // PseudoReturn and PseudoIndirectBranch are expanded to JR_MM, so they can
664 // be replaced with JRC16_MM.
665
666 // For MIPSR6 attempt to produce the corresponding compact (no delay slot)
667 // form of the CTI. For indirect jumps this will not require inserting a
668 // NOP and for branches will hopefully avoid requiring a NOP.
669 if ((InMicroMipsMode ||
671 TII->getEquivalentCompactForm(I)) {
672 I = replaceWithCompactBranch(MBB, I, I->getDebugLoc());
673 Changed = true;
674 continue;
675 }
676
677 // Bundle the NOP to the instruction with the delay slot.
678 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": could not fill delay slot for ";
679 I->dump());
680 TII->insertNop(MBB, std::next(I), I->getDebugLoc());
681 MIBundleBuilder(MBB, I, std::next(I, 2));
682 ++FilledSlots;
683 Changed = true;
684 }
685
686 return Changed;
687}
688
689template <typename IterTy>
690bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
691 IterTy End, RegDefsUses &RegDU,
692 InspectMemInstr &IM, Iter Slot,
693 IterTy &Filler) const {
694 for (IterTy I = Begin; I != End;) {
695 IterTy CurrI = I;
696 ++I;
697 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": checking instruction: "; CurrI->dump());
698 // skip debug value
699 if (CurrI->isDebugInstr()) {
700 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": ignoring debug instruction: ";
701 CurrI->dump());
702 continue;
703 }
704
705 if (CurrI->isBundle()) {
706 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": ignoring BUNDLE instruction: ";
707 CurrI->dump());
708 // However, we still need to update the register def-use information.
709 RegDU.update(*CurrI, 0, CurrI->getNumOperands());
710 continue;
711 }
712
713 if (terminateSearch(*CurrI)) {
714 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": should terminate search: ";
715 CurrI->dump());
716 break;
717 }
718
719 assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) &&
720 "Cannot put calls, returns or branches in delay slot.");
721
722 if (CurrI->isKill()) {
723 CurrI->eraseFromParent();
724 continue;
725 }
726
727 if (delayHasHazard(*CurrI, RegDU, IM))
728 continue;
729
731 if (STI.isTargetNaCl()) {
732 // In NaCl, instructions that must be masked are forbidden in delay slots.
733 // We only check for loads, stores and SP changes. Calls, returns and
734 // branches are not checked because non-NaCl targets never put them in
735 // delay slots.
736 unsigned AddrIdx;
737 if ((isBasePlusOffsetMemoryAccess(CurrI->getOpcode(), &AddrIdx) &&
738 baseRegNeedsLoadStoreMask(CurrI->getOperand(AddrIdx).getReg())) ||
739 CurrI->modifiesRegister(Mips::SP, STI.getRegisterInfo()))
740 continue;
741 }
742
743 bool InMicroMipsMode = STI.inMicroMipsMode();
744 const MipsInstrInfo *TII = STI.getInstrInfo();
745 unsigned Opcode = (*Slot).getOpcode();
746
747 // In mips1-4, should not put mflo into the delay slot for the return.
748 if ((IsMFLOMFHI(CurrI->getOpcode())) &&
749 (!STI.hasMips32() && !STI.hasMips5()))
750 continue;
751
752 // This is complicated by the tail call optimization. For non-PIC code
753 // there is only a 32bit sized unconditional branch which can be assumed
754 // to be able to reach the target. b16 only has a range of +/- 1 KB.
755 // It's entirely possible that the target function is reachable with b16
756 // but we don't have enough information to make that decision.
757 if (InMicroMipsMode && TII->getInstSizeInBytes(*CurrI) == 2 &&
758 (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||
759 Opcode == Mips::PseudoIndirectBranch_MM ||
760 Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL))
761 continue;
762 // Instructions LWP/SWP and MOVEP should not be in a delay slot as that
763 // results in unpredictable behaviour
764 if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM ||
765 Opcode == Mips::MOVEP_MM))
766 continue;
767
768 Filler = CurrI;
769 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot: ";
770 CurrI->dump());
771
772 return true;
773 }
774
775 return false;
776}
777
778bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB,
779 MachineInstr &Slot) const {
781 return false;
782
783 auto *Fn = MBB.getParent();
784 RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo());
785 MemDefsUses MemDU(&Fn->getFrameInfo());
786 ReverseIter Filler;
787
788 RegDU.init(Slot);
789
791 if (!searchRange(MBB, ++SlotI.getReverse(), MBB.rend(), RegDU, MemDU, Slot,
792 Filler)) {
793 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
794 "slot using backwards search.\n");
795 return false;
796 }
797
798 MBB.splice(std::next(SlotI), &MBB, Filler.getReverse());
799 MIBundleBuilder(MBB, SlotI, std::next(SlotI, 2));
800 ++UsefulSlots;
801 return true;
802}
803
804bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB,
805 Iter Slot) const {
806 // Can handle only calls.
807 if (DisableForwardSearch || !Slot->isCall())
808 return false;
809
810 RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo());
811 NoMemInstr NM;
812 Iter Filler;
813
814 RegDU.setCallerSaved(*Slot);
815
816 if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) {
817 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
818 "slot using forwards search.\n");
819 return false;
820 }
821
822 MBB.splice(std::next(Slot), &MBB, Filler);
823 MIBundleBuilder(MBB, Slot, std::next(Slot, 2));
824 ++UsefulSlots;
825 return true;
826}
827
828bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB,
829 Iter Slot) const {
831 return false;
832
833 MachineBasicBlock *SuccBB = selectSuccBB(MBB);
834
835 if (!SuccBB)
836 return false;
837
838 RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo());
839 bool HasMultipleSuccs = false;
840 BB2BrMap BrMap;
841 std::unique_ptr<InspectMemInstr> IM;
842 Iter Filler;
843 auto *Fn = MBB.getParent();
844
845 // Iterate over SuccBB's predecessor list.
846 for (MachineBasicBlock *Pred : SuccBB->predecessors())
847 if (!examinePred(*Pred, *SuccBB, RegDU, HasMultipleSuccs, BrMap))
848 return false;
849
850 // Do not allow moving instructions which have unallocatable register operands
851 // across basic block boundaries.
852 RegDU.setUnallocatableRegs(*Fn);
853
854 // Only allow moving loads from stack or constants if any of the SuccBB's
855 // predecessors have multiple successors.
856 if (HasMultipleSuccs) {
857 IM.reset(new LoadFromStackOrConst());
858 } else {
859 const MachineFrameInfo &MFI = Fn->getFrameInfo();
860 IM.reset(new MemDefsUses(&MFI));
861 }
862
863 if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot,
864 Filler))
865 return false;
866
867 insertDelayFiller(Filler, BrMap);
868 addLiveInRegs(Filler, *SuccBB);
869 Filler->eraseFromParent();
870
871 return true;
872}
873
875MipsDelaySlotFiller::selectSuccBB(MachineBasicBlock &B) const {
876 if (B.succ_empty())
877 return nullptr;
878
879 // Select the successor with the larget edge weight.
880 auto &Prob = getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
881 MachineBasicBlock *S = *std::max_element(
882 B.succ_begin(), B.succ_end(),
883 [&](const MachineBasicBlock *Dst0, const MachineBasicBlock *Dst1) {
884 return Prob.getEdgeProbability(&B, Dst0) <
885 Prob.getEdgeProbability(&B, Dst1);
886 });
887 return S->isEHPad() ? nullptr : S;
888}
889
890std::pair<MipsInstrInfo::BranchType, MachineInstr *>
891MipsDelaySlotFiller::getBranch(MachineBasicBlock &MBB,
892 const MachineBasicBlock &Dst) const {
893 const MipsInstrInfo *TII =
894 MBB.getParent()->getSubtarget<MipsSubtarget>().getInstrInfo();
895 MachineBasicBlock *TrueBB = nullptr, *FalseBB = nullptr;
898
900 TII->analyzeBranch(MBB, TrueBB, FalseBB, Cond, false, BranchInstrs);
901
903 return std::make_pair(R, nullptr);
904
906 if (!hasUnoccupiedSlot(BranchInstrs[0]))
907 return std::make_pair(MipsInstrInfo::BT_None, nullptr);
908
909 assert(((R != MipsInstrInfo::BT_Uncond) || (TrueBB == &Dst)));
910
911 return std::make_pair(R, BranchInstrs[0]);
912 }
913
914 assert((TrueBB == &Dst) || (FalseBB == &Dst));
915
916 // Examine the conditional branch. See if its slot is occupied.
917 if (hasUnoccupiedSlot(BranchInstrs[0]))
918 return std::make_pair(MipsInstrInfo::BT_Cond, BranchInstrs[0]);
919
920 // If that fails, try the unconditional branch.
921 if (hasUnoccupiedSlot(BranchInstrs[1]) && (FalseBB == &Dst))
922 return std::make_pair(MipsInstrInfo::BT_Uncond, BranchInstrs[1]);
923
924 return std::make_pair(MipsInstrInfo::BT_None, nullptr);
925}
926
927bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,
928 const MachineBasicBlock &Succ,
929 RegDefsUses &RegDU,
930 bool &HasMultipleSuccs,
931 BB2BrMap &BrMap) const {
932 std::pair<MipsInstrInfo::BranchType, MachineInstr *> P =
933 getBranch(Pred, Succ);
934
935 // Return if either getBranch wasn't able to analyze the branches or there
936 // were no branches with unoccupied slots.
937 if (P.first == MipsInstrInfo::BT_None)
938 return false;
939
940 if ((P.first != MipsInstrInfo::BT_Uncond) &&
941 (P.first != MipsInstrInfo::BT_NoBranch)) {
942 HasMultipleSuccs = true;
943 RegDU.addLiveOut(Pred, Succ);
944 }
945
946 BrMap[&Pred] = P.second;
947 return true;
948}
949
950bool MipsDelaySlotFiller::delayHasHazard(const MachineInstr &Candidate,
951 RegDefsUses &RegDU,
952 InspectMemInstr &IM) const {
953 assert(!Candidate.isKill() &&
954 "KILL instructions should have been eliminated at this point.");
955
956 bool HasHazard = Candidate.isImplicitDef();
957
958 HasHazard |= IM.hasHazard(Candidate);
959 HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
960
961 return HasHazard;
962}
963
964bool MipsDelaySlotFiller::terminateSearch(const MachineInstr &Candidate) const {
965 return (Candidate.isTerminator() || Candidate.isCall() ||
966 Candidate.isPosition() || Candidate.isInlineAsm() ||
967 Candidate.hasUnmodeledSideEffects());
968}
969
970/// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
971/// slots in Mips MachineFunctions
973 return new MipsDelaySlotFiller();
974}
aarch64 promote const
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
basic Basic Alias true
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:686
#define LLVM_DEBUG(...)
Definition: Debug.h:106
This file defines the DenseMap class.
bool End
Definition: ELF_riscv.cpp:480
static bool hasHazard(StateT State, function_ref< HazardFnResult(StateT &, const MachineInstr &)> IsHazard, function_ref< void(StateT &, const MachineInstr &)> UpdateState, const MachineBasicBlock *MBB, MachineBasicBlock::const_reverse_instr_iterator I, DenseSet< const MachineBasicBlock * > &Visited)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
static bool hasUnoccupiedSlot(const MachineInstr *MI)
static cl::opt< bool > DisableDelaySlotFiller("disable-mips-delay-filler", cl::init(false), cl::desc("Fill all delay slots with NOPs."), cl::Hidden)
static cl::opt< bool > DisableBackwardSearch("disable-mips-df-backward-search", cl::init(false), cl::desc("Disallow MIPS delay filler to search backward."), cl::Hidden)
static void addLiveInRegs(Iter Filler, MachineBasicBlock &MBB)
This function adds registers Filler defines to MBB's live-in register list.
static cl::opt< bool > DisableSuccBBSearch("disable-mips-df-succbb-search", cl::init(true), cl::desc("Disallow MIPS delay filler to search successor basic blocks."), cl::Hidden)
const BB2BrMap & BrMap
static cl::opt< bool > DisableForwardSearch("disable-mips-df-forward-search", cl::init(true), cl::desc("Disallow MIPS delay filler to search forward."), cl::Hidden)
static cl::opt< CompactBranchPolicy > MipsCompactBranchPolicy("mips-compact-branches", cl::Optional, cl::init(CB_Optimal), cl::desc("MIPS Specific: Compact branch policy."), cl::values(clEnumValN(CB_Never, "never", "Do not use compact branches if possible."), clEnumValN(CB_Optimal, "optimal", "Use compact branches where appropriate (default)."), clEnumValN(CB_Always, "always", "Always use compact branches if possible.")))
CompactBranchPolicy
@ CB_Never
The policy 'never' may in some circumstances or for some ISAs not be absolutely adhered to.
@ CB_Optimal
Optimal is the default and will produce compact branches when delay slots cannot be filled.
@ CB_Always
'always' may in some circumstances may not be absolutely adhered to there may not be a corresponding ...
static int getEquivalentCallShort(int Opcode)
#define DEBUG_TYPE
#define IsMFLOMFHI(instr)
Definition: Mips.h:20
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
This file defines the PointerUnion class, which is a discriminated union of pointer types.
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:166
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
bool test(unsigned Idx) const
Definition: BitVector.h:461
BitVector & set()
Definition: BitVector.h:351
BitVector & flip()
Definition: BitVector.h:431
iterator_range< const_set_bits_iterator > set_bits() const
Definition: BitVector.h:140
A debug info location.
Definition: DebugLoc.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:310
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
MCRegAliasIterator enumerates all registers aliasing Reg.
Helper class for constructing bundles of MachineInstrs.
MIBundleBuilder & append(MachineInstr *MI)
Insert MI into MBB by appending it to the instructions in the bundle.
bool isEHPad() const
Returns true if the block is a landing pad.
reverse_iterator rend()
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
void reset()
Reset the instance as if it was just created.
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
Definition: MachineInstr.h:69
bool isPosition() const
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
Definition: MachineInstr.h:980
bool isImplicitDef() const
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:956
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:578
bool isInlineAsm() const
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
bool isKill() const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
bool hasMips32r6() const
bool inMicroMipsMode() const
const MipsInstrInfo * getInstrInfo() const override
bool hasMips5() const
bool hasMips32() const
const MipsRegisterInfo * getRegisterInfo() const override
bool isTargetNaCl() const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
Special value supplied for machine level alias analysis.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC=nullptr) const
Returns a bitset indexed by register number indicating if a register is allocatable or not.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
LLVM Value Representation.
Definition: Value.h:74
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:711
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool isBasePlusOffsetMemoryAccess(unsigned Opcode, unsigned *AddrIdx, bool *IsStore=nullptr)
void initializeMipsDelaySlotFillerPass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
bool baseRegNeedsLoadStoreMask(unsigned Reg)
void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=6)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
FunctionPass * createMipsDelaySlotFillerPass()
createMipsDelaySlotFillerPass - Returns a pass that fills in delay slots in Mips MachineFunctions
bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.