1279377Simp//===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===// 2279377Simp// 3279377Simp// The LLVM Compiler Infrastructure 4279377Simp// 5279377Simp// This file is distributed under the University of Illinois Open Source 6279377Simp// License. See LICENSE.TXT for details. 7279377Simp// 8279377Simp//===----------------------------------------------------------------------===// 9279377Simp// 10279377Simp// This file implements hazard recognizers for scheduling on PowerPC processors. 11279377Simp// 12279377Simp//===----------------------------------------------------------------------===// 13279377Simp 14279377Simp#define DEBUG_TYPE "pre-RA-sched" 15279377Simp#include "PPCHazardRecognizers.h" 16279377Simp#include "PPC.h" 17279377Simp#include "PPCInstrInfo.h" 18279377Simp#include "llvm/CodeGen/ScheduleDAG.h" 19279377Simp#include "llvm/Support/Debug.h" 20279377Simp#include "llvm/Support/ErrorHandling.h" 21279377Simp#include "llvm/Support/raw_ostream.h" 22279377Simpusing namespace llvm; 23279377Simp 24279377Simp//===----------------------------------------------------------------------===// 25279377Simp// PowerPC Scoreboard Hazard Recognizer 26279377Simpvoid PPCScoreboardHazardRecognizer::EmitInstruction(SUnit *SU) { 27279377Simp const MCInstrDesc *MCID = DAG->getInstrDesc(SU); 28279377Simp if (!MCID) 29279377Simp // This is a PPC pseudo-instruction. 30279377Simp return; 31279377Simp 32279377Simp ScoreboardHazardRecognizer::EmitInstruction(SU); 33279377Simp} 34279377Simp 35279377SimpScheduleHazardRecognizer::HazardType 36279377SimpPPCScoreboardHazardRecognizer::getHazardType(SUnit *SU, int Stalls) { 37279377Simp return ScoreboardHazardRecognizer::getHazardType(SU, Stalls); 38279377Simp} 39279377Simp 40279377Simpvoid PPCScoreboardHazardRecognizer::AdvanceCycle() { 41279377Simp ScoreboardHazardRecognizer::AdvanceCycle(); 42279377Simp} 43279377Simp 44279377Simpvoid PPCScoreboardHazardRecognizer::Reset() { 45279377Simp ScoreboardHazardRecognizer::Reset(); 46279377Simp} 47279377Simp 48279377Simp//===----------------------------------------------------------------------===// 49279377Simp// PowerPC 970 Hazard Recognizer 50279377Simp// 51279377Simp// This models the dispatch group formation of the PPC970 processor. Dispatch 52279377Simp// groups are bundles of up to five instructions that can contain various mixes 53279377Simp// of instructions. The PPC970 can dispatch a peak of 4 non-branch and one 54279377Simp// branch instruction per-cycle. 55279377Simp// 56279377Simp// There are a number of restrictions to dispatch group formation: some 57279377Simp// instructions can only be issued in the first slot of a dispatch group, & some 58279377Simp// instructions fill an entire dispatch group. Additionally, only branches can 59279377Simp// issue in the 5th (last) slot. 60279377Simp// 61279377Simp// Finally, there are a number of "structural" hazards on the PPC970. These 62279377Simp// conditions cause large performance penalties due to misprediction, recovery, 63279377Simp// and replay logic that has to happen. These cases include setting a CTR and 64279377Simp// branching through it in the same dispatch group, and storing to an address, 65279377Simp// then loading from the same address within a dispatch group. To avoid these 66279377Simp// conditions, we insert no-op instructions when appropriate. 67279377Simp// 68279377Simp// FIXME: This is missing some significant cases: 69279377Simp// 1. Modeling of microcoded instructions. 70279377Simp// 2. Handling of serialized operations. 71279377Simp// 3. Handling of the esoteric cases in "Resource-based Instruction Grouping". 72279377Simp// 73279377Simp 74279377SimpPPCHazardRecognizer970::PPCHazardRecognizer970(const TargetMachine &TM) 75279377Simp : TM(TM) { 76279377Simp EndDispatchGroup(); 77279377Simp} 78279377Simp 79279377Simpvoid PPCHazardRecognizer970::EndDispatchGroup() { 80279377Simp DEBUG(errs() << "=== Start of dispatch group\n"); 81279377Simp NumIssued = 0; 82279377Simp 83279377Simp // Structural hazard info. 84279377Simp HasCTRSet = false; 85279377Simp NumStores = 0; 86279377Simp} 87279377Simp 88279377Simp 89279377SimpPPCII::PPC970_Unit 90279377SimpPPCHazardRecognizer970::GetInstrType(unsigned Opcode, 91279377Simp bool &isFirst, bool &isSingle, 92279377Simp bool &isCracked, 93279377Simp bool &isLoad, bool &isStore) { 94279377Simp const MCInstrDesc &MCID = TM.getInstrInfo()->get(Opcode); 95279377Simp 96279377Simp isLoad = MCID.mayLoad(); 97279377Simp isStore = MCID.mayStore(); 98279377Simp 99279377Simp uint64_t TSFlags = MCID.TSFlags; 100279377Simp 101279377Simp isFirst = TSFlags & PPCII::PPC970_First; 102279377Simp isSingle = TSFlags & PPCII::PPC970_Single; 103279377Simp isCracked = TSFlags & PPCII::PPC970_Cracked; 104279377Simp return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask); 105279377Simp} 106279377Simp 107279377Simp/// isLoadOfStoredAddress - If we have a load from the previously stored pointer 108279377Simp/// as indicated by StorePtr1/StorePtr2/StoreSize, return true. 109279377Simpbool PPCHazardRecognizer970:: 110279377SimpisLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset, 111279377Simp const Value *LoadValue) const { 112279377Simp for (unsigned i = 0, e = NumStores; i != e; ++i) { 113279377Simp // Handle exact and commuted addresses. 114279377Simp if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i]) 115279377Simp return true; 116279377Simp 117279377Simp // Okay, we don't have an exact match, if this is an indexed offset, see if 118279377Simp // we have overlap (which happens during fp->int conversion for example). 119279377Simp if (StoreValue[i] == LoadValue) { 120279377Simp // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check 121279377Simp // to see if the load and store actually overlap. 122279377Simp if (StoreOffset[i] < LoadOffset) { 123279377Simp if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true; 124279377Simp } else { 125279377Simp if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true; 126279377Simp } 127279377Simp } 128279377Simp } 129279377Simp return false; 130279377Simp} 131279377Simp 132279377Simp/// getHazardType - We return hazard for any non-branch instruction that would 133279377Simp/// terminate the dispatch group. We turn NoopHazard for any 134279377Simp/// instructions that wouldn't terminate the dispatch group that would cause a 135279377Simp/// pipeline flush. 136279377SimpScheduleHazardRecognizer::HazardType PPCHazardRecognizer970:: 137279377SimpgetHazardType(SUnit *SU, int Stalls) { 138279377Simp assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead"); 139279377Simp 140279377Simp MachineInstr *MI = SU->getInstr(); 141279377Simp 142279377Simp if (MI->isDebugValue()) 143279377Simp return NoHazard; 144279377Simp 145279377Simp unsigned Opcode = MI->getOpcode(); 146279377Simp bool isFirst, isSingle, isCracked, isLoad, isStore; 147279377Simp PPCII::PPC970_Unit InstrType = 148279377Simp GetInstrType(Opcode, isFirst, isSingle, isCracked, 149279377Simp isLoad, isStore); 150279377Simp if (InstrType == PPCII::PPC970_Pseudo) return NoHazard; 151279377Simp 152279377Simp // We can only issue a PPC970_First/PPC970_Single instruction (such as 153279377Simp // crand/mtspr/etc) if this is the first cycle of the dispatch group. 154279377Simp if (NumIssued != 0 && (isFirst || isSingle)) 155279377Simp return Hazard; 156279377Simp 157279377Simp // If this instruction is cracked into two ops by the decoder, we know that 158279377Simp // it is not a branch and that it cannot issue if 3 other instructions are 159279377Simp // already in the dispatch group. 160279377Simp if (isCracked && NumIssued > 2) 161279377Simp return Hazard; 162279377Simp 163279377Simp switch (InstrType) { 164279377Simp default: llvm_unreachable("Unknown instruction type!"); 165279377Simp case PPCII::PPC970_FXU: 166279377Simp case PPCII::PPC970_LSU: 167279377Simp case PPCII::PPC970_FPU: 168279377Simp case PPCII::PPC970_VALU: 169279377Simp case PPCII::PPC970_VPERM: 170279377Simp // We can only issue a branch as the last instruction in a group. 171279377Simp if (NumIssued == 4) return Hazard; 172279377Simp break; 173279377Simp case PPCII::PPC970_CRU: 174279377Simp // We can only issue a CR instruction in the first two slots. 175279377Simp if (NumIssued >= 2) return Hazard; 176279377Simp break; 177279377Simp case PPCII::PPC970_BRU: 178279377Simp break; 179279377Simp } 180279377Simp 181279377Simp // Do not allow MTCTR and BCTRL to be in the same dispatch group. 182279377Simp if (HasCTRSet && Opcode == PPC::BCTRL) 183279377Simp return NoopHazard; 184279377Simp 185279377Simp // If this is a load following a store, make sure it's not to the same or 186279377Simp // overlapping address. 187279377Simp if (isLoad && NumStores && !MI->memoperands_empty()) { 188279377Simp MachineMemOperand *MO = *MI->memoperands_begin(); 189279377Simp if (isLoadOfStoredAddress(MO->getSize(), 190279377Simp MO->getOffset(), MO->getValue())) 191279377Simp return NoopHazard; 192279377Simp } 193279377Simp 194279377Simp return NoHazard; 195279377Simp} 196279377Simp 197279377Simpvoid PPCHazardRecognizer970::EmitInstruction(SUnit *SU) { 198279377Simp MachineInstr *MI = SU->getInstr(); 199279377Simp 200279377Simp if (MI->isDebugValue()) 201279377Simp return; 202279377Simp 203279377Simp unsigned Opcode = MI->getOpcode(); 204279377Simp bool isFirst, isSingle, isCracked, isLoad, isStore; 205279377Simp PPCII::PPC970_Unit InstrType = 206279377Simp GetInstrType(Opcode, isFirst, isSingle, isCracked, 207279377Simp isLoad, isStore); 208279377Simp if (InstrType == PPCII::PPC970_Pseudo) return; 209279377Simp 210279377Simp // Update structural hazard information. 211279377Simp if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true; 212279377Simp 213279377Simp // Track the address stored to. 214279377Simp if (isStore && NumStores < 4 && !MI->memoperands_empty()) { 215279377Simp MachineMemOperand *MO = *MI->memoperands_begin(); 216279377Simp StoreSize[NumStores] = MO->getSize(); 217279377Simp StoreOffset[NumStores] = MO->getOffset(); 218279377Simp StoreValue[NumStores] = MO->getValue(); 219279377Simp ++NumStores; 220279377Simp } 221279377Simp 222279377Simp if (InstrType == PPCII::PPC970_BRU || isSingle) 223279377Simp NumIssued = 4; // Terminate a d-group. 224279377Simp ++NumIssued; 225279377Simp 226279377Simp // If this instruction is cracked into two ops by the decoder, remember that 227279377Simp // we issued two pieces. 228279377Simp if (isCracked) 229279377Simp ++NumIssued; 230279377Simp 231279377Simp if (NumIssued == 5) 232279377Simp EndDispatchGroup(); 233279377Simp} 234279377Simp 235279377Simpvoid PPCHazardRecognizer970::AdvanceCycle() { 236279377Simp assert(NumIssued < 5 && "Illegal dispatch group!"); 237279377Simp ++NumIssued; 238279377Simp if (NumIssued == 5) 239279377Simp EndDispatchGroup(); 240279377Simp} 241279377Simp 242279377Simpvoid PPCHazardRecognizer970::Reset() { 243279377Simp EndDispatchGroup(); 244279377Simp} 245279377Simp 246279377Simp