|
36 | 36 | ///
|
37 | 37 | /// Regarding compact branch hazard prevention:
|
38 | 38 | ///
|
39 |
| -/// Hazards handled: forbidden slots for MIPSR6, FPU slots for MIPS3 and below. |
| 39 | +/// Hazards handled: forbidden slots for MIPSR6, FPU slots for MIPS3 and below, |
| 40 | +/// load delay slots for MIPS1. |
40 | 41 | ///
|
41 | 42 | /// A forbidden slot hazard occurs when a compact branch instruction is executed
|
42 | 43 | /// and the adjacent instruction in memory is a control transfer instruction
|
@@ -164,6 +165,7 @@ class MipsBranchExpansion : public MachineFunctionPass {
|
164 | 165 | bool handleSlot(Pred Predicate, Safe SafeInSlot);
|
165 | 166 | bool handleForbiddenSlot();
|
166 | 167 | bool handleFPUDelaySlot();
|
| 168 | + bool handleLoadDelaySlot(); |
167 | 169 | bool handlePossibleLongBranch();
|
168 | 170 |
|
169 | 171 | const MipsSubtarget *STI;
|
@@ -762,7 +764,6 @@ bool MipsBranchExpansion::handleSlot(Pred Predicate, Safe SafeInSlot) {
|
762 | 764 | }
|
763 | 765 |
|
764 | 766 | if (LastInstInFunction || !SafeInSlot(*IInSlot, *I)) {
|
765 |
| - |
766 | 767 | MachineBasicBlock::instr_iterator Iit = I->getIterator();
|
767 | 768 | if (std::next(Iit) == FI->end() ||
|
768 | 769 | std::next(Iit)->getOpcode() != Mips::NOP) {
|
@@ -801,6 +802,18 @@ bool MipsBranchExpansion::handleFPUDelaySlot() {
|
801 | 802 | });
|
802 | 803 | }
|
803 | 804 |
|
| 805 | +bool MipsBranchExpansion::handleLoadDelaySlot() { |
| 806 | + // Load delay slot hazards are only for MIPS1. |
| 807 | + if (STI->hasMips2()) |
| 808 | + return false; |
| 809 | + |
| 810 | + return handleSlot( |
| 811 | + [this](auto &I) -> bool { return TII->HasLoadDelaySlot(I); }, |
| 812 | + [this](auto &IInSlot, auto &I) -> bool { |
| 813 | + return TII->SafeInLoadDelaySlot(IInSlot, I); |
| 814 | + }); |
| 815 | +} |
| 816 | + |
804 | 817 | bool MipsBranchExpansion::handlePossibleLongBranch() {
|
805 | 818 | if (STI->inMips16Mode() || !STI->enableLongBranchPass())
|
806 | 819 | return false;
|
@@ -877,19 +890,21 @@ bool MipsBranchExpansion::runOnMachineFunction(MachineFunction &MF) {
|
877 | 890 | MFp = &MF;
|
878 | 891 |
|
879 | 892 | ForceLongBranchFirstPass = ForceLongBranch;
|
880 |
| - // Run these two at least once |
| 893 | + // Run these at least once. |
881 | 894 | bool longBranchChanged = handlePossibleLongBranch();
|
882 | 895 | bool forbiddenSlotChanged = handleForbiddenSlot();
|
883 | 896 | bool fpuDelaySlotChanged = handleFPUDelaySlot();
|
| 897 | + bool loadDelaySlotChanged = handleLoadDelaySlot(); |
884 | 898 |
|
885 |
| - bool Changed = |
886 |
| - longBranchChanged || forbiddenSlotChanged || fpuDelaySlotChanged; |
| 899 | + bool Changed = longBranchChanged || forbiddenSlotChanged || |
| 900 | + fpuDelaySlotChanged || loadDelaySlotChanged; |
887 | 901 |
|
888 |
| - // Then run them alternatively while there are changes |
| 902 | + // Then run them alternatively while there are changes. |
889 | 903 | while (forbiddenSlotChanged) {
|
890 | 904 | longBranchChanged = handlePossibleLongBranch();
|
891 | 905 | fpuDelaySlotChanged = handleFPUDelaySlot();
|
892 |
| - if (!longBranchChanged && !fpuDelaySlotChanged) |
| 906 | + loadDelaySlotChanged = handleLoadDelaySlot(); |
| 907 | + if (!longBranchChanged && !fpuDelaySlotChanged && !loadDelaySlotChanged) |
893 | 908 | break;
|
894 | 909 | forbiddenSlotChanged = handleForbiddenSlot();
|
895 | 910 | }
|
|
0 commit comments