Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 1 | //===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
Chris Lattner | 4ee451d | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file implements hazard recognizers for scheduling on PowerPC processors. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Dale Johannesen | e7e7d0d | 2007-07-13 17:13:54 +0000 | [diff] [blame] | 14 | #define DEBUG_TYPE "pre-RA-sched" |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 15 | #include "PPCHazardRecognizers.h" |
| 16 | #include "PPC.h" |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 17 | #include "PPCInstrInfo.h" |
Dan Gohman | fc54c55 | 2009-01-15 22:18:12 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/ScheduleDAG.h" |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 19 | #include "llvm/Support/Debug.h" |
Torok Edwin | c25e758 | 2009-07-11 20:10:48 +0000 | [diff] [blame] | 20 | #include "llvm/Support/ErrorHandling.h" |
Chris Lattner | 893e1c9 | 2009-08-23 06:49:22 +0000 | [diff] [blame] | 21 | #include "llvm/Support/raw_ostream.h" |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 22 | using namespace llvm; |
| 23 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 24 | //===----------------------------------------------------------------------===// |
Hal Finkel | 5b00cea | 2012-03-31 14:45:15 +0000 | [diff] [blame] | 25 | // PowerPC Scoreboard Hazard Recognizer |
| 26 | void PPCScoreboardHazardRecognizer::EmitInstruction(SUnit *SU) { |
Hal Finkel | c6d08f1 | 2011-10-17 04:03:49 +0000 | [diff] [blame] | 27 | const MCInstrDesc *MCID = DAG->getInstrDesc(SU); |
Hal Finkel | 5b00cea | 2012-03-31 14:45:15 +0000 | [diff] [blame] | 28 | if (!MCID) |
Hal Finkel | c6d08f1 | 2011-10-17 04:03:49 +0000 | [diff] [blame] | 29 | // This is a PPC pseudo-instruction. |
Hal Finkel | c6d08f1 | 2011-10-17 04:03:49 +0000 | [diff] [blame] | 30 | return; |
Hal Finkel | c6d08f1 | 2011-10-17 04:03:49 +0000 | [diff] [blame] | 31 | |
| 32 | ScoreboardHazardRecognizer::EmitInstruction(SU); |
| 33 | } |
| 34 | |
Hal Finkel | 5b00cea | 2012-03-31 14:45:15 +0000 | [diff] [blame] | 35 | ScheduleHazardRecognizer::HazardType |
| 36 | PPCScoreboardHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { |
| 37 | return ScoreboardHazardRecognizer::getHazardType(SU, Stalls); |
| 38 | } |
| 39 | |
| 40 | void PPCScoreboardHazardRecognizer::AdvanceCycle() { |
| 41 | ScoreboardHazardRecognizer::AdvanceCycle(); |
| 42 | } |
| 43 | |
| 44 | void PPCScoreboardHazardRecognizer::Reset() { |
| 45 | ScoreboardHazardRecognizer::Reset(); |
| 46 | } |
| 47 | |
Hal Finkel | c6d08f1 | 2011-10-17 04:03:49 +0000 | [diff] [blame] | 48 | //===----------------------------------------------------------------------===// |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 49 | // PowerPC 970 Hazard Recognizer |
| 50 | // |
Chris Lattner | 7ce6485 | 2006-03-07 06:44:19 +0000 | [diff] [blame] | 51 | // This models the dispatch group formation of the PPC970 processor. Dispatch |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 52 | // groups are bundles of up to five instructions that can contain various mixes |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 53 | // of instructions. The PPC970 can dispatch a peak of 4 non-branch and one |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 54 | // branch instruction per-cycle. |
Chris Lattner | 7ce6485 | 2006-03-07 06:44:19 +0000 | [diff] [blame] | 55 | // |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 56 | // There are a number of restrictions to dispatch group formation: some |
| 57 | // instructions can only be issued in the first slot of a dispatch group, & some |
| 58 | // instructions fill an entire dispatch group. Additionally, only branches can |
| 59 | // issue in the 5th (last) slot. |
Chris Lattner | 7ce6485 | 2006-03-07 06:44:19 +0000 | [diff] [blame] | 60 | // |
| 61 | // Finally, there are a number of "structural" hazards on the PPC970. These |
| 62 | // conditions cause large performance penalties due to misprediction, recovery, |
| 63 | // and replay logic that has to happen. These cases include setting a CTR and |
| 64 | // branching through it in the same dispatch group, and storing to an address, |
| 65 | // then loading from the same address within a dispatch group. To avoid these |
| 66 | // conditions, we insert no-op instructions when appropriate. |
| 67 | // |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 68 | // FIXME: This is missing some significant cases: |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 69 | // 1. Modeling of microcoded instructions. |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 70 | // 2. Handling of serialized operations. |
| 71 | // 3. Handling of the esoteric cases in "Resource-based Instruction Grouping". |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 72 | // |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 73 | |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 74 | PPCHazardRecognizer970::PPCHazardRecognizer970(const TargetInstrInfo &tii) |
| 75 | : TII(tii) { |
Chris Lattner | b0d21ef | 2006-03-08 04:25:59 +0000 | [diff] [blame] | 76 | EndDispatchGroup(); |
| 77 | } |
| 78 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 79 | void PPCHazardRecognizer970::EndDispatchGroup() { |
Chris Lattner | 893e1c9 | 2009-08-23 06:49:22 +0000 | [diff] [blame] | 80 | DEBUG(errs() << "=== Start of dispatch group\n"); |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 81 | NumIssued = 0; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 82 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 83 | // Structural hazard info. |
| 84 | HasCTRSet = false; |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 85 | NumStores = 0; |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 89 | PPCII::PPC970_Unit |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 90 | PPCHazardRecognizer970::GetInstrType(unsigned Opcode, |
| 91 | bool &isFirst, bool &isSingle, |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 92 | bool &isCracked, |
| 93 | bool &isLoad, bool &isStore) { |
Evan Cheng | e837dea | 2011-06-28 19:10:37 +0000 | [diff] [blame] | 94 | const MCInstrDesc &MCID = TII.get(Opcode); |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 95 | |
Evan Cheng | e837dea | 2011-06-28 19:10:37 +0000 | [diff] [blame] | 96 | isLoad = MCID.mayLoad(); |
| 97 | isStore = MCID.mayStore(); |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 98 | |
Evan Cheng | e837dea | 2011-06-28 19:10:37 +0000 | [diff] [blame] | 99 | uint64_t TSFlags = MCID.TSFlags; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 100 | |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 101 | isFirst = TSFlags & PPCII::PPC970_First; |
| 102 | isSingle = TSFlags & PPCII::PPC970_Single; |
| 103 | isCracked = TSFlags & PPCII::PPC970_Cracked; |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 104 | return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask); |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 105 | } |
| 106 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 107 | /// isLoadOfStoredAddress - If we have a load from the previously stored pointer |
| 108 | /// as indicated by StorePtr1/StorePtr2/StoreSize, return true. |
| 109 | bool PPCHazardRecognizer970:: |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 110 | isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset, |
| 111 | const Value *LoadValue) const { |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 112 | for (unsigned i = 0, e = NumStores; i != e; ++i) { |
| 113 | // Handle exact and commuted addresses. |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 114 | if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i]) |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 115 | return true; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 116 | |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 117 | // Okay, we don't have an exact match, if this is an indexed offset, see if |
| 118 | // we have overlap (which happens during fp->int conversion for example). |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 119 | if (StoreValue[i] == LoadValue) { |
| 120 | // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check |
| 121 | // to see if the load and store actually overlap. |
| 122 | if (StoreOffset[i] < LoadOffset) { |
| 123 | if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true; |
| 124 | } else { |
| 125 | if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true; |
| 126 | } |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 127 | } |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 128 | } |
| 129 | return false; |
| 130 | } |
| 131 | |
| 132 | /// getHazardType - We return hazard for any non-branch instruction that would |
Dan Gohman | f451cb8 | 2010-02-10 16:03:48 +0000 | [diff] [blame] | 133 | /// terminate the dispatch group. We turn NoopHazard for any |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 134 | /// instructions that wouldn't terminate the dispatch group that would cause a |
| 135 | /// pipeline flush. |
Dan Gohman | fc54c55 | 2009-01-15 22:18:12 +0000 | [diff] [blame] | 136 | ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970:: |
Andrew Trick | 2da8bc8 | 2010-12-24 05:03:26 +0000 | [diff] [blame] | 137 | getHazardType(SUnit *SU, int Stalls) { |
| 138 | assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead"); |
| 139 | |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 140 | MachineInstr *MI = SU->getInstr(); |
| 141 | |
| 142 | if (MI->isDebugValue()) |
| 143 | return NoHazard; |
| 144 | |
| 145 | unsigned Opcode = MI->getOpcode(); |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 146 | bool isFirst, isSingle, isCracked, isLoad, isStore; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 147 | PPCII::PPC970_Unit InstrType = |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 148 | GetInstrType(Opcode, isFirst, isSingle, isCracked, |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 149 | isLoad, isStore); |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 150 | if (InstrType == PPCII::PPC970_Pseudo) return NoHazard; |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 151 | |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 152 | // We can only issue a PPC970_First/PPC970_Single instruction (such as |
| 153 | // crand/mtspr/etc) if this is the first cycle of the dispatch group. |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 154 | if (NumIssued != 0 && (isFirst || isSingle)) |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 155 | return Hazard; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 156 | |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 157 | // If this instruction is cracked into two ops by the decoder, we know that |
| 158 | // it is not a branch and that it cannot issue if 3 other instructions are |
| 159 | // already in the dispatch group. |
| 160 | if (isCracked && NumIssued > 2) |
| 161 | return Hazard; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 162 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 163 | switch (InstrType) { |
Torok Edwin | c23197a | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 164 | default: llvm_unreachable("Unknown instruction type!"); |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 165 | case PPCII::PPC970_FXU: |
| 166 | case PPCII::PPC970_LSU: |
| 167 | case PPCII::PPC970_FPU: |
| 168 | case PPCII::PPC970_VALU: |
| 169 | case PPCII::PPC970_VPERM: |
| 170 | // We can only issue a branch as the last instruction in a group. |
| 171 | if (NumIssued == 4) return Hazard; |
| 172 | break; |
| 173 | case PPCII::PPC970_CRU: |
| 174 | // We can only issue a CR instruction in the first two slots. |
| 175 | if (NumIssued >= 2) return Hazard; |
| 176 | break; |
| 177 | case PPCII::PPC970_BRU: |
| 178 | break; |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 179 | } |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 180 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 181 | // Do not allow MTCTR and BCTRL to be in the same dispatch group. |
Tilmann Scheller | 2a9ddfb | 2009-07-03 06:47:08 +0000 | [diff] [blame] | 182 | if (HasCTRSet && (Opcode == PPC::BCTRL_Darwin || Opcode == PPC::BCTRL_SVR4)) |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 183 | return NoopHazard; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 184 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 185 | // If this is a load following a store, make sure it's not to the same or |
| 186 | // overlapping address. |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 187 | if (isLoad && NumStores && !MI->memoperands_empty()) { |
| 188 | MachineMemOperand *MO = *MI->memoperands_begin(); |
| 189 | if (isLoadOfStoredAddress(MO->getSize(), |
| 190 | MO->getOffset(), MO->getValue())) |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 191 | return NoopHazard; |
| 192 | } |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 193 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 194 | return NoHazard; |
| 195 | } |
| 196 | |
Dan Gohman | fc54c55 | 2009-01-15 22:18:12 +0000 | [diff] [blame] | 197 | void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) { |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 198 | MachineInstr *MI = SU->getInstr(); |
| 199 | |
| 200 | if (MI->isDebugValue()) |
| 201 | return; |
| 202 | |
| 203 | unsigned Opcode = MI->getOpcode(); |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 204 | bool isFirst, isSingle, isCracked, isLoad, isStore; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 205 | PPCII::PPC970_Unit InstrType = |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 206 | GetInstrType(Opcode, isFirst, isSingle, isCracked, |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 207 | isLoad, isStore); |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 208 | if (InstrType == PPCII::PPC970_Pseudo) return; |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 209 | |
| 210 | // Update structural hazard information. |
Roman Divacky | 0c9b559 | 2011-06-03 15:47:49 +0000 | [diff] [blame] | 211 | if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 212 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 213 | // Track the address stored to. |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 214 | if (isStore && NumStores < 4 && !MI->memoperands_empty()) { |
| 215 | MachineMemOperand *MO = *MI->memoperands_begin(); |
| 216 | StoreSize[NumStores] = MO->getSize(); |
| 217 | StoreOffset[NumStores] = MO->getOffset(); |
| 218 | StoreValue[NumStores] = MO->getValue(); |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 219 | ++NumStores; |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 220 | } |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 221 | |
Chris Lattner | 88d211f | 2006-03-12 09:13:49 +0000 | [diff] [blame] | 222 | if (InstrType == PPCII::PPC970_BRU || isSingle) |
| 223 | NumIssued = 4; // Terminate a d-group. |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 224 | ++NumIssued; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 225 | |
Chris Lattner | 3faad49 | 2006-03-13 05:20:04 +0000 | [diff] [blame] | 226 | // If this instruction is cracked into two ops by the decoder, remember that |
| 227 | // we issued two pieces. |
| 228 | if (isCracked) |
| 229 | ++NumIssued; |
Andrew Trick | 6e8f4c4 | 2010-12-24 04:28:06 +0000 | [diff] [blame] | 230 | |
Chris Lattner | c664418 | 2006-03-07 06:32:48 +0000 | [diff] [blame] | 231 | if (NumIssued == 5) |
| 232 | EndDispatchGroup(); |
| 233 | } |
| 234 | |
| 235 | void PPCHazardRecognizer970::AdvanceCycle() { |
| 236 | assert(NumIssued < 5 && "Illegal dispatch group!"); |
| 237 | ++NumIssued; |
| 238 | if (NumIssued == 5) |
| 239 | EndDispatchGroup(); |
| 240 | } |
Hal Finkel | 64c34e2 | 2011-12-02 04:58:02 +0000 | [diff] [blame] | 241 | |
| 242 | void PPCHazardRecognizer970::Reset() { |
| 243 | EndDispatchGroup(); |
| 244 | } |
| 245 | |