1 //===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements hazard recognizers for scheduling on PowerPC processors. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "PPCHazardRecognizers.h" 15 #include "PPC.h" 16 #include "PPCInstrInfo.h" 17 #include "PPCTargetMachine.h" 18 #include "llvm/CodeGen/ScheduleDAG.h" 19 #include "llvm/Support/Debug.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/raw_ostream.h" 22 using namespace llvm; 23 24 #define DEBUG_TYPE "pre-RA-sched" 25 26 bool PPCDispatchGroupSBHazardRecognizer::isLoadAfterStore(SUnit *SU) { 27 // FIXME: Move this. 28 if (isBCTRAfterSet(SU)) 29 return true; 30 31 const MCInstrDesc *MCID = DAG->getInstrDesc(SU); 32 if (!MCID) 33 return false; 34 35 if (!MCID->mayLoad()) 36 return false; 37 38 // SU is a load; for any predecessors in this dispatch group, that are stores, 39 // and with which we have an ordering dependency, return true. 40 for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) { 41 const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit()); 42 if (!PredMCID || !PredMCID->mayStore()) 43 continue; 44 45 if (!SU->Preds[i].isNormalMemory() && !SU->Preds[i].isBarrier()) 46 continue; 47 48 for (unsigned j = 0, je = CurGroup.size(); j != je; ++j) 49 if (SU->Preds[i].getSUnit() == CurGroup[j]) 50 return true; 51 } 52 53 return false; 54 } 55 56 bool PPCDispatchGroupSBHazardRecognizer::isBCTRAfterSet(SUnit *SU) { 57 const MCInstrDesc *MCID = DAG->getInstrDesc(SU); 58 if (!MCID) 59 return false; 60 61 if (!MCID->isBranch()) 62 return false; 63 64 // SU is a branch; for any predecessors in this dispatch group, with which we 65 // have a data dependence and set the counter register, return true. 66 for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) { 67 const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit()); 68 if (!PredMCID || PredMCID->getSchedClass() != PPC::Sched::IIC_SprMTSPR) 69 continue; 70 71 if (SU->Preds[i].isCtrl()) 72 continue; 73 74 for (unsigned j = 0, je = CurGroup.size(); j != je; ++j) 75 if (SU->Preds[i].getSUnit() == CurGroup[j]) 76 return true; 77 } 78 79 return false; 80 } 81 82 // FIXME: Remove this when we don't need this: 83 namespace llvm { namespace PPC { extern int getNonRecordFormOpcode(uint16_t); } } 84 85 // FIXME: A lot of code in PPCDispatchGroupSBHazardRecognizer is P7 specific. 86 87 bool PPCDispatchGroupSBHazardRecognizer::mustComeFirst(const MCInstrDesc *MCID, 88 unsigned &NSlots) { 89 // FIXME: Indirectly, this information is contained in the itinerary, and 90 // we should derive it from there instead of separately specifying it 91 // here. 92 unsigned IIC = MCID->getSchedClass(); 93 switch (IIC) { 94 default: 95 NSlots = 1; 96 break; 97 case PPC::Sched::IIC_IntDivW: 98 case PPC::Sched::IIC_IntDivD: 99 case PPC::Sched::IIC_LdStLoadUpd: 100 case PPC::Sched::IIC_LdStLDU: 101 case PPC::Sched::IIC_LdStLFDU: 102 case PPC::Sched::IIC_LdStLFDUX: 103 case PPC::Sched::IIC_LdStLHA: 104 case PPC::Sched::IIC_LdStLHAU: 105 case PPC::Sched::IIC_LdStLWA: 106 case PPC::Sched::IIC_LdStSTDU: 107 case PPC::Sched::IIC_LdStSTFDU: 108 NSlots = 2; 109 break; 110 case PPC::Sched::IIC_LdStLoadUpdX: 111 case PPC::Sched::IIC_LdStLDUX: 112 case PPC::Sched::IIC_LdStLHAUX: 113 case PPC::Sched::IIC_LdStLWARX: 114 case PPC::Sched::IIC_LdStLDARX: 115 case PPC::Sched::IIC_LdStSTDUX: 116 case PPC::Sched::IIC_LdStSTDCX: 117 case PPC::Sched::IIC_LdStSTWCX: 118 case PPC::Sched::IIC_BrMCRX: // mtcr 119 // FIXME: Add sync/isync (here and in the itinerary). 120 NSlots = 4; 121 break; 122 } 123 124 // FIXME: record-form instructions need a different itinerary class. 125 if (NSlots == 1 && PPC::getNonRecordFormOpcode(MCID->getOpcode()) != -1) 126 NSlots = 2; 127 128 switch (IIC) { 129 default: 130 // All multi-slot instructions must come first. 131 return NSlots > 1; 132 case PPC::Sched::IIC_BrCR: // cr logicals 133 case PPC::Sched::IIC_SprMFCR: 134 case PPC::Sched::IIC_SprMFCRF: 135 case PPC::Sched::IIC_SprMTSPR: 136 return true; 137 } 138 } 139 140 ScheduleHazardRecognizer::HazardType 141 PPCDispatchGroupSBHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { 142 if (Stalls == 0 && isLoadAfterStore(SU)) 143 return NoopHazard; 144 145 return ScoreboardHazardRecognizer::getHazardType(SU, Stalls); 146 } 147 148 bool PPCDispatchGroupSBHazardRecognizer::ShouldPreferAnother(SUnit *SU) { 149 const MCInstrDesc *MCID = DAG->getInstrDesc(SU); 150 unsigned NSlots; 151 if (MCID && mustComeFirst(MCID, NSlots) && CurSlots) 152 return true; 153 154 return ScoreboardHazardRecognizer::ShouldPreferAnother(SU); 155 } 156 157 unsigned PPCDispatchGroupSBHazardRecognizer::PreEmitNoops(SUnit *SU) { 158 // We only need to fill out a maximum of 5 slots here: The 6th slot could 159 // only be a second branch, and otherwise the next instruction will start a 160 // new group. 161 if (isLoadAfterStore(SU) && CurSlots < 6) { 162 unsigned Directive = 163 DAG->MF.getSubtarget<PPCSubtarget>().getDarwinDirective(); 164 // If we're using a special group-terminating nop, then we need only one. 165 // FIXME: the same for P9 as previous gen until POWER9 scheduling is ready 166 if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 || 167 Directive == PPC::DIR_PWR8 || Directive == PPC::DIR_PWR9) 168 return 1; 169 170 return 5 - CurSlots; 171 } 172 173 return ScoreboardHazardRecognizer::PreEmitNoops(SU); 174 } 175 176 void PPCDispatchGroupSBHazardRecognizer::EmitInstruction(SUnit *SU) { 177 const MCInstrDesc *MCID = DAG->getInstrDesc(SU); 178 if (MCID) { 179 if (CurSlots == 5 || (MCID->isBranch() && CurBranches == 1)) { 180 CurGroup.clear(); 181 CurSlots = CurBranches = 0; 182 } else { 183 LLVM_DEBUG(dbgs() << "**** Adding to dispatch group: "); 184 LLVM_DEBUG(DAG->dumpNode(*SU)); 185 186 unsigned NSlots; 187 bool MustBeFirst = mustComeFirst(MCID, NSlots); 188 189 // If this instruction must come first, but does not, then it starts a 190 // new group. 191 if (MustBeFirst && CurSlots) { 192 CurSlots = CurBranches = 0; 193 CurGroup.clear(); 194 } 195 196 CurSlots += NSlots; 197 CurGroup.push_back(SU); 198 199 if (MCID->isBranch()) 200 ++CurBranches; 201 } 202 } 203 204 return ScoreboardHazardRecognizer::EmitInstruction(SU); 205 } 206 207 void PPCDispatchGroupSBHazardRecognizer::AdvanceCycle() { 208 return ScoreboardHazardRecognizer::AdvanceCycle(); 209 } 210 211 void PPCDispatchGroupSBHazardRecognizer::RecedeCycle() { 212 llvm_unreachable("Bottom-up scheduling not supported"); 213 } 214 215 void PPCDispatchGroupSBHazardRecognizer::Reset() { 216 CurGroup.clear(); 217 CurSlots = CurBranches = 0; 218 return ScoreboardHazardRecognizer::Reset(); 219 } 220 221 void PPCDispatchGroupSBHazardRecognizer::EmitNoop() { 222 unsigned Directive = 223 DAG->MF.getSubtarget<PPCSubtarget>().getDarwinDirective(); 224 // If the group has now filled all of its slots, or if we're using a special 225 // group-terminating nop, the group is complete. 226 // FIXME: the same for P9 as previous gen until POWER9 scheduling is ready 227 if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 || 228 Directive == PPC::DIR_PWR8 || Directive == PPC::DIR_PWR9 || 229 CurSlots == 6) { 230 CurGroup.clear(); 231 CurSlots = CurBranches = 0; 232 } else { 233 CurGroup.push_back(nullptr); 234 ++CurSlots; 235 } 236 } 237 238 //===----------------------------------------------------------------------===// 239 // PowerPC 970 Hazard Recognizer 240 // 241 // This models the dispatch group formation of the PPC970 processor. Dispatch 242 // groups are bundles of up to five instructions that can contain various mixes 243 // of instructions. The PPC970 can dispatch a peak of 4 non-branch and one 244 // branch instruction per-cycle. 245 // 246 // There are a number of restrictions to dispatch group formation: some 247 // instructions can only be issued in the first slot of a dispatch group, & some 248 // instructions fill an entire dispatch group. Additionally, only branches can 249 // issue in the 5th (last) slot. 250 // 251 // Finally, there are a number of "structural" hazards on the PPC970. These 252 // conditions cause large performance penalties due to misprediction, recovery, 253 // and replay logic that has to happen. These cases include setting a CTR and 254 // branching through it in the same dispatch group, and storing to an address, 255 // then loading from the same address within a dispatch group. To avoid these 256 // conditions, we insert no-op instructions when appropriate. 257 // 258 // FIXME: This is missing some significant cases: 259 // 1. Modeling of microcoded instructions. 260 // 2. Handling of serialized operations. 261 // 3. Handling of the esoteric cases in "Resource-based Instruction Grouping". 262 // 263 264 PPCHazardRecognizer970::PPCHazardRecognizer970(const ScheduleDAG &DAG) 265 : DAG(DAG) { 266 EndDispatchGroup(); 267 } 268 269 void PPCHazardRecognizer970::EndDispatchGroup() { 270 LLVM_DEBUG(errs() << "=== Start of dispatch group\n"); 271 NumIssued = 0; 272 273 // Structural hazard info. 274 HasCTRSet = false; 275 NumStores = 0; 276 } 277 278 279 PPCII::PPC970_Unit 280 PPCHazardRecognizer970::GetInstrType(unsigned Opcode, 281 bool &isFirst, bool &isSingle, 282 bool &isCracked, 283 bool &isLoad, bool &isStore) { 284 const MCInstrDesc &MCID = DAG.TII->get(Opcode); 285 286 isLoad = MCID.mayLoad(); 287 isStore = MCID.mayStore(); 288 289 uint64_t TSFlags = MCID.TSFlags; 290 291 isFirst = TSFlags & PPCII::PPC970_First; 292 isSingle = TSFlags & PPCII::PPC970_Single; 293 isCracked = TSFlags & PPCII::PPC970_Cracked; 294 return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask); 295 } 296 297 /// isLoadOfStoredAddress - If we have a load from the previously stored pointer 298 /// as indicated by StorePtr1/StorePtr2/StoreSize, return true. 299 bool PPCHazardRecognizer970:: 300 isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset, 301 const Value *LoadValue) const { 302 for (unsigned i = 0, e = NumStores; i != e; ++i) { 303 // Handle exact and commuted addresses. 304 if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i]) 305 return true; 306 307 // Okay, we don't have an exact match, if this is an indexed offset, see if 308 // we have overlap (which happens during fp->int conversion for example). 309 if (StoreValue[i] == LoadValue) { 310 // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check 311 // to see if the load and store actually overlap. 312 if (StoreOffset[i] < LoadOffset) { 313 if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true; 314 } else { 315 if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true; 316 } 317 } 318 } 319 return false; 320 } 321 322 /// getHazardType - We return hazard for any non-branch instruction that would 323 /// terminate the dispatch group. We turn NoopHazard for any 324 /// instructions that wouldn't terminate the dispatch group that would cause a 325 /// pipeline flush. 326 ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970:: 327 getHazardType(SUnit *SU, int Stalls) { 328 assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead"); 329 330 MachineInstr *MI = SU->getInstr(); 331 332 if (MI->isDebugInstr()) 333 return NoHazard; 334 335 unsigned Opcode = MI->getOpcode(); 336 bool isFirst, isSingle, isCracked, isLoad, isStore; 337 PPCII::PPC970_Unit InstrType = 338 GetInstrType(Opcode, isFirst, isSingle, isCracked, 339 isLoad, isStore); 340 if (InstrType == PPCII::PPC970_Pseudo) return NoHazard; 341 342 // We can only issue a PPC970_First/PPC970_Single instruction (such as 343 // crand/mtspr/etc) if this is the first cycle of the dispatch group. 344 if (NumIssued != 0 && (isFirst || isSingle)) 345 return Hazard; 346 347 // If this instruction is cracked into two ops by the decoder, we know that 348 // it is not a branch and that it cannot issue if 3 other instructions are 349 // already in the dispatch group. 350 if (isCracked && NumIssued > 2) 351 return Hazard; 352 353 switch (InstrType) { 354 default: llvm_unreachable("Unknown instruction type!"); 355 case PPCII::PPC970_FXU: 356 case PPCII::PPC970_LSU: 357 case PPCII::PPC970_FPU: 358 case PPCII::PPC970_VALU: 359 case PPCII::PPC970_VPERM: 360 // We can only issue a branch as the last instruction in a group. 361 if (NumIssued == 4) return Hazard; 362 break; 363 case PPCII::PPC970_CRU: 364 // We can only issue a CR instruction in the first two slots. 365 if (NumIssued >= 2) return Hazard; 366 break; 367 case PPCII::PPC970_BRU: 368 break; 369 } 370 371 // Do not allow MTCTR and BCTRL to be in the same dispatch group. 372 if (HasCTRSet && Opcode == PPC::BCTRL) 373 return NoopHazard; 374 375 // If this is a load following a store, make sure it's not to the same or 376 // overlapping address. 377 if (isLoad && NumStores && !MI->memoperands_empty()) { 378 MachineMemOperand *MO = *MI->memoperands_begin(); 379 if (isLoadOfStoredAddress(MO->getSize(), 380 MO->getOffset(), MO->getValue())) 381 return NoopHazard; 382 } 383 384 return NoHazard; 385 } 386 387 void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) { 388 MachineInstr *MI = SU->getInstr(); 389 390 if (MI->isDebugInstr()) 391 return; 392 393 unsigned Opcode = MI->getOpcode(); 394 bool isFirst, isSingle, isCracked, isLoad, isStore; 395 PPCII::PPC970_Unit InstrType = 396 GetInstrType(Opcode, isFirst, isSingle, isCracked, 397 isLoad, isStore); 398 if (InstrType == PPCII::PPC970_Pseudo) return; 399 400 // Update structural hazard information. 401 if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true; 402 403 // Track the address stored to. 404 if (isStore && NumStores < 4 && !MI->memoperands_empty()) { 405 MachineMemOperand *MO = *MI->memoperands_begin(); 406 StoreSize[NumStores] = MO->getSize(); 407 StoreOffset[NumStores] = MO->getOffset(); 408 StoreValue[NumStores] = MO->getValue(); 409 ++NumStores; 410 } 411 412 if (InstrType == PPCII::PPC970_BRU || isSingle) 413 NumIssued = 4; // Terminate a d-group. 414 ++NumIssued; 415 416 // If this instruction is cracked into two ops by the decoder, remember that 417 // we issued two pieces. 418 if (isCracked) 419 ++NumIssued; 420 421 if (NumIssued == 5) 422 EndDispatchGroup(); 423 } 424 425 void PPCHazardRecognizer970::AdvanceCycle() { 426 assert(NumIssued < 5 && "Illegal dispatch group!"); 427 ++NumIssued; 428 if (NumIssued == 5) 429 EndDispatchGroup(); 430 } 431 432 void PPCHazardRecognizer970::Reset() { 433 EndDispatchGroup(); 434 } 435 436