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 info for the Branch.
567 if (ToErase->shouldUpdateAdditionalCallInfo())
568 ToErase->getMF()->moveAdditionalCallInfo(ToErase,
569 cast<MachineInstr>(&*Branch));
570 ToErase->eraseFromParent();
571 return Branch;
572}
573
574// For given opcode returns opcode of corresponding instruction with short
575// delay slot.
576// For the pseudo TAILCALL*_MM instructions return the short delay slot
577// form. Unfortunately, TAILCALL<->b16 is denied as b16 has a limited range
578// that is too short to make use of for tail calls.
579static int getEquivalentCallShort(int Opcode) {
580 switch (Opcode) {
581 case Mips::BGEZAL:
582 return Mips::BGEZALS_MM;
583 case Mips::BLTZAL:
584 return Mips::BLTZALS_MM;
585 case Mips::JAL:
586 case Mips::JAL_MM:
587 return Mips::JALS_MM;
588 case Mips::JALR:
589 return Mips::JALRS_MM;
590 case Mips::JALR16_MM:
591 return Mips::JALRS16_MM;
592 case Mips::TAILCALL_MM:
593 llvm_unreachable("Attempting to shorten the TAILCALL_MM pseudo!");
594 case Mips::TAILCALLREG:
595 return Mips::JR16_MM;
596 default:
597 llvm_unreachable("Unexpected call instruction for microMIPS.");
598 }
599}
600
601/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
602/// We assume there is only one delay slot per delayed instruction.
603bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
604 bool Changed = false;
606 bool InMicroMipsMode = STI.inMicroMipsMode();
607 const MipsInstrInfo *TII = STI.getInstrInfo();
608
609 for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
610 if (!hasUnoccupiedSlot(&*I))
611 continue;
612
613 // Delay slot filling is disabled at -O0, or in microMIPS32R6.
615 (TM->getOptLevel() != CodeGenOptLevel::None) &&
616 !(InMicroMipsMode && STI.hasMips32r6())) {
617
618 bool Filled = false;
619
620 if (MipsCompactBranchPolicy.getValue() != CB_Always ||
621 !TII->getEquivalentCompactForm(I)) {
622 if (searchBackward(MBB, *I)) {
623 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
624 " in backwards search.\n");
625 Filled = true;
626 } else if (I->isTerminator()) {
627 if (searchSuccBBs(MBB, I)) {
628 Filled = true;
629 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
630 " in successor BB search.\n");
631 }
632 } else if (searchForward(MBB, I)) {
633 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"
634 " in forwards search.\n");
635 Filled = true;
636 }
637 }
638
639 if (Filled) {
640 // Get instruction with delay slot.
641 MachineBasicBlock::instr_iterator DSI = I.getInstrIterator();
642
643 if (InMicroMipsMode && TII->getInstSizeInBytes(*std::next(DSI)) == 2 &&
644 DSI->isCall()) {
645 // If instruction in delay slot is 16b change opcode to
646 // corresponding instruction with short delay slot.
647
648 // TODO: Implement an instruction mapping table of 16bit opcodes to
649 // 32bit opcodes so that an instruction can be expanded. This would
650 // save 16 bits as a TAILCALL_MM pseudo requires a fullsized nop.
651 // TODO: Permit b16 when branching backwards to the same function
652 // if it is in range.
653 DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode())));
654 }
655 ++FilledSlots;
656 Changed = true;
657 continue;
658 }
659 }
660
661 // For microMIPS if instruction is BEQ or BNE with one ZERO register, then
662 // instead of adding NOP replace this instruction with the corresponding
663 // compact branch instruction, i.e. BEQZC or BNEZC. Additionally
664 // PseudoReturn and PseudoIndirectBranch are expanded to JR_MM, so they can
665 // be replaced with JRC16_MM.
666
667 // For MIPSR6 attempt to produce the corresponding compact (no delay slot)
668 // form of the CTI. For indirect jumps this will not require inserting a
669 // NOP and for branches will hopefully avoid requiring a NOP.
670 if ((InMicroMipsMode ||
672 TII->getEquivalentCompactForm(I)) {
673 I = replaceWithCompactBranch(MBB, I, I->getDebugLoc());
674 Changed = true;
675 continue;
676 }
677
678 // Bundle the NOP to the instruction with the delay slot.
679 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": could not fill delay slot for ";
680 I->dump());
681 TII->insertNop(MBB, std::next(I), I->getDebugLoc());
682 MIBundleBuilder(MBB, I, std::next(I, 2));
683 ++FilledSlots;
684 Changed = true;
685 }
686
687 return Changed;
688}
689
690template <typename IterTy>
691bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
692 IterTy End, RegDefsUses &RegDU,
693 InspectMemInstr &IM, Iter Slot,
694 IterTy &Filler) const {
695 for (IterTy I = Begin; I != End;) {
696 IterTy CurrI = I;
697 ++I;
698 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": checking instruction: "; CurrI->dump());
699 // skip debug value
700 if (CurrI->isDebugInstr()) {
701 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": ignoring debug instruction: ";
702 CurrI->dump());
703 continue;
704 }
705
706 if (CurrI->isBundle()) {
707 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": ignoring BUNDLE instruction: ";
708 CurrI->dump());
709 // However, we still need to update the register def-use information.
710 RegDU.update(*CurrI, 0, CurrI->getNumOperands());
711 continue;
712 }
713
714 if (terminateSearch(*CurrI)) {
715 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": should terminate search: ";
716 CurrI->dump());
717 break;
718 }
719
720 assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) &&
721 "Cannot put calls, returns or branches in delay slot.");
722
723 if (CurrI->isKill()) {
724 CurrI->eraseFromParent();
725 continue;
726 }
727
728 if (delayHasHazard(*CurrI, RegDU, IM))
729 continue;
730
732 if (STI.isTargetNaCl()) {
733 // In NaCl, instructions that must be masked are forbidden in delay slots.
734 // We only check for loads, stores and SP changes. Calls, returns and
735 // branches are not checked because non-NaCl targets never put them in
736 // delay slots.
737 unsigned AddrIdx;
738 if ((isBasePlusOffsetMemoryAccess(CurrI->getOpcode(), &AddrIdx) &&
739 baseRegNeedsLoadStoreMask(CurrI->getOperand(AddrIdx).getReg())) ||
740 CurrI->modifiesRegister(Mips::SP, STI.getRegisterInfo()))
741 continue;
742 }
743
744 bool InMicroMipsMode = STI.inMicroMipsMode();
745 const MipsInstrInfo *TII = STI.getInstrInfo();
746 unsigned Opcode = (*Slot).getOpcode();
747
748 // In mips1-4, should not put mflo into the delay slot for the return.
749 if ((IsMFLOMFHI(CurrI->getOpcode())) &&
750 (!STI.hasMips32() && !STI.hasMips5()))
751 continue;
752
753 // This is complicated by the tail call optimization. For non-PIC code
754 // there is only a 32bit sized unconditional branch which can be assumed
755 // to be able to reach the target. b16 only has a range of +/- 1 KB.
756 // It's entirely possible that the target function is reachable with b16
757 // but we don't have enough information to make that decision.
758 if (InMicroMipsMode && TII->getInstSizeInBytes(*CurrI) == 2 &&
759 (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||
760 Opcode == Mips::PseudoIndirectBranch_MM ||
761 Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL))
762 continue;
763 // Instructions LWP/SWP and MOVEP should not be in a delay slot as that
764 // results in unpredictable behaviour
765 if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM ||
766 Opcode == Mips::MOVEP_MM))
767 continue;
768
769 Filler = CurrI;
770 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot: ";
771 CurrI->dump());
772
773 return true;
774 }
775
776 return false;
777}
778
779bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB,
780 MachineInstr &Slot) const {
782 return false;
783
784 auto *Fn = MBB.getParent();
785 RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo());
786 MemDefsUses MemDU(&Fn->getFrameInfo());
787 ReverseIter Filler;
788
789 RegDU.init(Slot);
790
792 if (!searchRange(MBB, ++SlotI.getReverse(), MBB.rend(), RegDU, MemDU, Slot,
793 Filler)) {
794 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
795 "slot using backwards search.\n");
796 return false;
797 }
798
799 MBB.splice(std::next(SlotI), &MBB, Filler.getReverse());
800 MIBundleBuilder(MBB, SlotI, std::next(SlotI, 2));
801 ++UsefulSlots;
802 return true;
803}
804
805bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB,
806 Iter Slot) const {
807 // Can handle only calls.
808 if (DisableForwardSearch || !Slot->isCall())
809 return false;
810
811 RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo());
812 NoMemInstr NM;
813 Iter Filler;
814
815 RegDU.setCallerSaved(*Slot);
816
817 if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) {
818 LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "
819 "slot using forwards search.\n");
820 return false;
821 }
822
823 MBB.splice(std::next(Slot), &MBB, Filler);
824 MIBundleBuilder(MBB, Slot, std::next(Slot, 2));
825 ++UsefulSlots;
826 return true;
827}
828
829bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB,
830 Iter Slot) const {
832 return false;
833
834 MachineBasicBlock *SuccBB = selectSuccBB(MBB);
835
836 if (!SuccBB)
837 return false;
838
839 RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo());
840 bool HasMultipleSuccs = false;
841 BB2BrMap BrMap;
842 std::unique_ptr<InspectMemInstr> IM;
843 Iter Filler;
844 auto *Fn = MBB.getParent();
845
846 // Iterate over SuccBB's predecessor list.
847 for (MachineBasicBlock *Pred : SuccBB->predecessors())
848 if (!examinePred(*Pred, *SuccBB, RegDU, HasMultipleSuccs, BrMap))
849 return false;
850
851 // Do not allow moving instructions which have unallocatable register operands
852 // across basic block boundaries.
853 RegDU.setUnallocatableRegs(*Fn);
854
855 // Only allow moving loads from stack or constants if any of the SuccBB's
856 // predecessors have multiple successors.
857 if (HasMultipleSuccs) {
858 IM.reset(new LoadFromStackOrConst());
859 } else {
860 const MachineFrameInfo &MFI = Fn->getFrameInfo();
861 IM.reset(new MemDefsUses(&MFI));
862 }
863
864 if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot,
865 Filler))
866 return false;
867
868 insertDelayFiller(Filler, BrMap);
869 addLiveInRegs(Filler, *SuccBB);
870 Filler->eraseFromParent();
871
872 return true;
873}
874
876MipsDelaySlotFiller::selectSuccBB(MachineBasicBlock &B) const {
877 if (B.succ_empty())
878 return nullptr;
879
880 // Select the successor with the larget edge weight.
881 auto &Prob = getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
882 MachineBasicBlock *S = *std::max_element(
883 B.succ_begin(), B.succ_end(),
884 [&](const MachineBasicBlock *Dst0, const MachineBasicBlock *Dst1) {
885 return Prob.getEdgeProbability(&B, Dst0) <
886 Prob.getEdgeProbability(&B, Dst1);
887 });
888 return S->isEHPad() ? nullptr : S;
889}
890
891std::pair<MipsInstrInfo::BranchType, MachineInstr *>
892MipsDelaySlotFiller::getBranch(MachineBasicBlock &MBB,
893 const MachineBasicBlock &Dst) const {
894 const MipsInstrInfo *TII =
895 MBB.getParent()->getSubtarget<MipsSubtarget>().getInstrInfo();
896 MachineBasicBlock *TrueBB = nullptr, *FalseBB = nullptr;
899
901 TII->analyzeBranch(MBB, TrueBB, FalseBB, Cond, false, BranchInstrs);
902
904 return std::make_pair(R, nullptr);
905
907 if (!hasUnoccupiedSlot(BranchInstrs[0]))
908 return std::make_pair(MipsInstrInfo::BT_None, nullptr);
909
910 assert(((R != MipsInstrInfo::BT_Uncond) || (TrueBB == &Dst)));
911
912 return std::make_pair(R, BranchInstrs[0]);
913 }
914
915 assert((TrueBB == &Dst) || (FalseBB == &Dst));
916
917 // Examine the conditional branch. See if its slot is occupied.
918 if (hasUnoccupiedSlot(BranchInstrs[0]))
919 return std::make_pair(MipsInstrInfo::BT_Cond, BranchInstrs[0]);
920
921 // If that fails, try the unconditional branch.
922 if (hasUnoccupiedSlot(BranchInstrs[1]) && (FalseBB == &Dst))
923 return std::make_pair(MipsInstrInfo::BT_Uncond, BranchInstrs[1]);
924
925 return std::make_pair(MipsInstrInfo::BT_None, nullptr);
926}
927
928bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,
929 const MachineBasicBlock &Succ,
930 RegDefsUses &RegDU,
931 bool &HasMultipleSuccs,
932 BB2BrMap &BrMap) const {
933 std::pair<MipsInstrInfo::BranchType, MachineInstr *> P =
934 getBranch(Pred, Succ);
935
936 // Return if either getBranch wasn't able to analyze the branches or there
937 // were no branches with unoccupied slots.
938 if (P.first == MipsInstrInfo::BT_None)
939 return false;
940
941 if ((P.first != MipsInstrInfo::BT_Uncond) &&
942 (P.first != MipsInstrInfo::BT_NoBranch)) {
943 HasMultipleSuccs = true;
944 RegDU.addLiveOut(Pred, Succ);
945 }
946
947 BrMap[&Pred] = P.second;
948 return true;
949}
950
951bool MipsDelaySlotFiller::delayHasHazard(const MachineInstr &Candidate,
952 RegDefsUses &RegDU,
953 InspectMemInstr &IM) const {
954 assert(!Candidate.isKill() &&
955 "KILL instructions should have been eliminated at this point.");
956
957 bool HasHazard = Candidate.isImplicitDef();
958
959 HasHazard |= IM.hasHazard(Candidate);
960 HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
961
962 return HasHazard;
963}
964
965bool MipsDelaySlotFiller::terminateSearch(const MachineInstr &Candidate) const {
966 return (Candidate.isTerminator() || Candidate.isCall() ||
967 Candidate.isPosition() || Candidate.isInlineAsm() ||
968 Candidate.hasUnmodeledSideEffects());
969}
970
971/// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
972/// slots in Mips MachineFunctions
974 return new MipsDelaySlotFiller();
975}
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:981
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.