1155192Srwatson//===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===// 2180701Srwatson// 3155192Srwatson// The LLVM Compiler Infrastructure 4155192Srwatson// 5155192Srwatson// This file is distributed under the University of Illinois Open Source 6155192Srwatson// License. See LICENSE.TXT for details. 7155192Srwatson// 8155192Srwatson//===----------------------------------------------------------------------===// 9155192Srwatson// 10155192Srwatson// This file implements hazard recognizers for scheduling on PowerPC processors. 11155192Srwatson// 12155192Srwatson//===----------------------------------------------------------------------===// 13180701Srwatson 14155192Srwatson#define DEBUG_TYPE "pre-RA-sched" 15155192Srwatson#include "PPCHazardRecognizers.h" 16155192Srwatson#include "PPC.h" 17155192Srwatson#include "PPCInstrInfo.h" 18155192Srwatson#include "llvm/CodeGen/ScheduleDAG.h" 19155192Srwatson#include "llvm/Support/Debug.h" 20155192Srwatson#include "llvm/Support/ErrorHandling.h" 21155192Srwatson#include "llvm/Support/raw_ostream.h" 22155192Srwatsonusing namespace llvm; 23155192Srwatson 24155192Srwatson//===----------------------------------------------------------------------===// 25155192Srwatson// PowerPC Scoreboard Hazard Recognizer 26155192Srwatsonvoid PPCScoreboardHazardRecognizer::EmitInstruction(SUnit *SU) { 27155192Srwatson const MCInstrDesc *MCID = DAG->getInstrDesc(SU); 28155192Srwatson if (!MCID) 29155192Srwatson // This is a PPC pseudo-instruction. 30178186Srwatson return; 31178186Srwatson 32178186Srwatson ScoreboardHazardRecognizer::EmitInstruction(SU); 33155192Srwatson} 34155192Srwatson 35155192SrwatsonScheduleHazardRecognizer::HazardType 36155192SrwatsonPPCScoreboardHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { 37155192Srwatson return ScoreboardHazardRecognizer::getHazardType(SU, Stalls); 38155192Srwatson} 39155192Srwatson 40160136Swsalamonvoid PPCScoreboardHazardRecognizer::AdvanceCycle() { 41155192Srwatson ScoreboardHazardRecognizer::AdvanceCycle(); 42155192Srwatson} 43155192Srwatson 44155192Srwatsonvoid PPCScoreboardHazardRecognizer::Reset() { 45155192Srwatson ScoreboardHazardRecognizer::Reset(); 46155192Srwatson} 47155192Srwatson 48155192Srwatson//===----------------------------------------------------------------------===// 49155192Srwatson// PowerPC 970 Hazard Recognizer 50155192Srwatson// 51155192Srwatson// This models the dispatch group formation of the PPC970 processor. Dispatch 52155192Srwatson// groups are bundles of up to five instructions that can contain various mixes 53155192Srwatson// of instructions. The PPC970 can dispatch a peak of 4 non-branch and one 54155192Srwatson// branch instruction per-cycle. 55155192Srwatson// 56155192Srwatson// There are a number of restrictions to dispatch group formation: some 57155192Srwatson// instructions can only be issued in the first slot of a dispatch group, & some 58155192Srwatson// instructions fill an entire dispatch group. Additionally, only branches can 59155192Srwatson// issue in the 5th (last) slot. 60155192Srwatson// 61155192Srwatson// Finally, there are a number of "structural" hazards on the PPC970. These 62155192Srwatson// conditions cause large performance penalties due to misprediction, recovery, 63155192Srwatson// and replay logic that has to happen. These cases include setting a CTR and 64155192Srwatson// branching through it in the same dispatch group, and storing to an address, 65155192Srwatson// then loading from the same address within a dispatch group. To avoid these 66155192Srwatson// conditions, we insert no-op instructions when appropriate. 67155192Srwatson// 68155192Srwatson// FIXME: This is missing some significant cases: 69155192Srwatson// 1. Modeling of microcoded instructions. 70155192Srwatson// 2. Handling of serialized operations. 71155192Srwatson// 3. Handling of the esoteric cases in "Resource-based Instruction Grouping". 72155192Srwatson// 73156889Srwatson 74156889SrwatsonPPCHazardRecognizer970::PPCHazardRecognizer970(const TargetMachine &TM) 75156889Srwatson : TM(TM) { 76180706Srwatson EndDispatchGroup(); 77156889Srwatson} 78156889Srwatson 79155192Srwatsonvoid PPCHazardRecognizer970::EndDispatchGroup() { 80156889Srwatson DEBUG(errs() << "=== Start of dispatch group\n"); 81155192Srwatson NumIssued = 0; 82156889Srwatson 83155192Srwatson // Structural hazard info. 84162466Srwatson HasCTRSet = false; 85155192Srwatson NumStores = 0; 86155192Srwatson} 87155192Srwatson 88155192Srwatson 89155192SrwatsonPPCII::PPC970_Unit 90155192SrwatsonPPCHazardRecognizer970::GetInstrType(unsigned Opcode, 91155192Srwatson bool &isFirst, bool &isSingle, 92155192Srwatson bool &isCracked, 93155192Srwatson bool &isLoad, bool &isStore) { 94156889Srwatson const MCInstrDesc &MCID = TM.getInstrInfo()->get(Opcode); 95155192Srwatson 96155192Srwatson isLoad = MCID.mayLoad(); 97155192Srwatson isStore = MCID.mayStore(); 98155192Srwatson 99155192Srwatson uint64_t TSFlags = MCID.TSFlags; 100155192Srwatson 101155192Srwatson isFirst = TSFlags & PPCII::PPC970_First; 102155192Srwatson isSingle = TSFlags & PPCII::PPC970_Single; 103155192Srwatson isCracked = TSFlags & PPCII::PPC970_Cracked; 104155192Srwatson return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask); 105155192Srwatson} 106155192Srwatson 107155192Srwatson/// isLoadOfStoredAddress - If we have a load from the previously stored pointer 108155192Srwatson/// as indicated by StorePtr1/StorePtr2/StoreSize, return true. 109155192Srwatsonbool PPCHazardRecognizer970:: 110155192SrwatsonisLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset, 111155192Srwatson const Value *LoadValue) const { 112155192Srwatson for (unsigned i = 0, e = NumStores; i != e; ++i) { 113155192Srwatson // Handle exact and commuted addresses. 114155192Srwatson if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i]) 115155192Srwatson return true; 116156889Srwatson 117161635Srwatson // Okay, we don't have an exact match, if this is an indexed offset, see if 118162466Srwatson // we have overlap (which happens during fp->int conversion for example). 119170196Srwatson if (StoreValue[i] == LoadValue) { 120162466Srwatson // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check 121162466Srwatson // to see if the load and store actually overlap. 122162466Srwatson if (StoreOffset[i] < LoadOffset) { 123162466Srwatson if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true; 124155192Srwatson } else { 125162466Srwatson if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true; 126162466Srwatson } 127155192Srwatson } 128162466Srwatson } 129162466Srwatson return false; 130162466Srwatson} 131162466Srwatson 132162466Srwatson/// getHazardType - We return hazard for any non-branch instruction that would 133155192Srwatson/// terminate the dispatch group. We turn NoopHazard for any 134155192Srwatson/// instructions that wouldn't terminate the dispatch group that would cause a 135155192Srwatson/// pipeline flush. 136155192SrwatsonScheduleHazardRecognizer::HazardType PPCHazardRecognizer970:: 137156889SrwatsongetHazardType(SUnit *SU, int Stalls) { 138156889Srwatson assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead"); 139155192Srwatson 140155192Srwatson MachineInstr *MI = SU->getInstr(); 141155192Srwatson 142155192Srwatson if (MI->isDebugValue()) 143155192Srwatson return NoHazard; 144155192Srwatson 145156889Srwatson unsigned Opcode = MI->getOpcode(); 146155192Srwatson bool isFirst, isSingle, isCracked, isLoad, isStore; 147155192Srwatson PPCII::PPC970_Unit InstrType = 148155192Srwatson GetInstrType(Opcode, isFirst, isSingle, isCracked, 149155192Srwatson isLoad, isStore); 150156889Srwatson if (InstrType == PPCII::PPC970_Pseudo) return NoHazard; 151155192Srwatson 152155192Srwatson // We can only issue a PPC970_First/PPC970_Single instruction (such as 153156889Srwatson // crand/mtspr/etc) if this is the first cycle of the dispatch group. 154155192Srwatson if (NumIssued != 0 && (isFirst || isSingle)) 155155192Srwatson return Hazard; 156155192Srwatson 157155192Srwatson // If this instruction is cracked into two ops by the decoder, we know that 158155192Srwatson // it is not a branch and that it cannot issue if 3 other instructions are 159170196Srwatson // already in the dispatch group. 160180704Srwatson if (isCracked && NumIssued > 2) 161155192Srwatson return Hazard; 162155192Srwatson 163155192Srwatson switch (InstrType) { 164155192Srwatson default: llvm_unreachable("Unknown instruction type!"); 165180708Srwatson case PPCII::PPC970_FXU: 166155192Srwatson case PPCII::PPC970_LSU: 167155192Srwatson case PPCII::PPC970_FPU: 168155192Srwatson case PPCII::PPC970_VALU: 169155192Srwatson case PPCII::PPC970_VPERM: 170155192Srwatson // We can only issue a branch as the last instruction in a group. 171155192Srwatson if (NumIssued == 4) return Hazard; 172180708Srwatson break; 173155192Srwatson case PPCII::PPC970_CRU: 174155192Srwatson // We can only issue a CR instruction in the first two slots. 175155192Srwatson if (NumIssued >= 2) return Hazard; 176155192Srwatson break; 177155192Srwatson case PPCII::PPC970_BRU: 178155192Srwatson break; 179180708Srwatson } 180180709Srwatson 181155192Srwatson // Do not allow MTCTR and BCTRL to be in the same dispatch group. 182155192Srwatson if (HasCTRSet && Opcode == PPC::BCTRL) 183155192Srwatson return NoopHazard; 184155192Srwatson 185155192Srwatson // If this is a load following a store, make sure it's not to the same or 186180708Srwatson // overlapping address. 187180709Srwatson if (isLoad && NumStores && !MI->memoperands_empty()) { 188155192Srwatson MachineMemOperand *MO = *MI->memoperands_begin(); 189155192Srwatson if (isLoadOfStoredAddress(MO->getSize(), 190180709Srwatson MO->getOffset(), MO->getValue())) 191155192Srwatson return NoopHazard; 192155192Srwatson } 193155192Srwatson 194155192Srwatson return NoHazard; 195155192Srwatson} 196180708Srwatson 197180709Srwatsonvoid PPCHazardRecognizer970::EmitInstruction(SUnit *SU) { 198155192Srwatson MachineInstr *MI = SU->getInstr(); 199155192Srwatson 200155192Srwatson if (MI->isDebugValue()) 201155192Srwatson return; 202155192Srwatson 203180711Srwatson unsigned Opcode = MI->getOpcode(); 204155192Srwatson bool isFirst, isSingle, isCracked, isLoad, isStore; 205155192Srwatson PPCII::PPC970_Unit InstrType = 206155192Srwatson GetInstrType(Opcode, isFirst, isSingle, isCracked, 207155192Srwatson isLoad, isStore); 208155192Srwatson if (InstrType == PPCII::PPC970_Pseudo) return; 209155192Srwatson 210155192Srwatson // Update structural hazard information. 211155192Srwatson if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true; 212155192Srwatson 213156889Srwatson // Track the address stored to. 214156889Srwatson if (isStore && NumStores < 4 && !MI->memoperands_empty()) { 215155192Srwatson MachineMemOperand *MO = *MI->memoperands_begin(); 216155192Srwatson StoreSize[NumStores] = MO->getSize(); 217155192Srwatson StoreOffset[NumStores] = MO->getOffset(); 218155192Srwatson StoreValue[NumStores] = MO->getValue(); 219155192Srwatson ++NumStores; 220180708Srwatson } 221159277Srwatson 222159277Srwatson if (InstrType == PPCII::PPC970_BRU || isSingle) 223172915Scsjp NumIssued = 4; // Terminate a d-group. 224159277Srwatson ++NumIssued; 225159277Srwatson 226159277Srwatson // If this instruction is cracked into two ops by the decoder, remember that 227172915Scsjp // we issued two pieces. 228159277Srwatson if (isCracked) 229159277Srwatson ++NumIssued; 230159277Srwatson 231159277Srwatson if (NumIssued == 5) 232155192Srwatson EndDispatchGroup(); 233180712Srwatson} 234155192Srwatson 235180711Srwatsonvoid PPCHazardRecognizer970::AdvanceCycle() { 236160136Swsalamon assert(NumIssued < 5 && "Illegal dispatch group!"); 237160136Swsalamon ++NumIssued; 238160136Swsalamon if (NumIssued == 5) 239160136Swsalamon EndDispatchGroup(); 240160136Swsalamon} 241160136Swsalamon 242160136Swsalamonvoid PPCHazardRecognizer970::Reset() { 243160136Swsalamon EndDispatchGroup(); 244160136Swsalamon} 245160136Swsalamon 246160136Swsalamon