PPCHazardRecognizers.cpp revision 3acbe5d4f0d6163cb761368692c830c1a4f27e31
1//===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements hazard recognizers for scheduling on PowerPC processors. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "sched" 15#include "PPCHazardRecognizers.h" 16#include "PPC.h" 17#include "llvm/Support/Debug.h" 18#include <iostream> 19using namespace llvm; 20 21 22//===----------------------------------------------------------------------===// 23// PowerPC 970 Hazard Recognizer 24// 25// This models the dispatch group formation of the PPC970 processor. Dispatch 26// groups are bundles of up to five instructions that can contain up to two ALU 27// (aka FXU) ops, two FPU ops, two Load/Store ops, one CR op, one VALU op, one 28// VPERM op, and one BRANCH op. If the code contains more instructions in a 29// sequence than the dispatch group can contain (e.g. three loads in a row) the 30// processor terminates the dispatch group early, wasting execution resources. 31// 32// In addition to these restrictions, there are a number of other restrictions: 33// some instructions, e.g. branches, are required to be the last instruction in 34// a group. Additionally, only branches can issue in the 5th (last) slot. 35// 36// Finally, there are a number of "structural" hazards on the PPC970. These 37// conditions cause large performance penalties due to misprediction, recovery, 38// and replay logic that has to happen. These cases include setting a CTR and 39// branching through it in the same dispatch group, and storing to an address, 40// then loading from the same address within a dispatch group. To avoid these 41// conditions, we insert no-op instructions when appropriate. 42// 43// FIXME: This is missing some significant cases: 44// -1. Handle all of the instruction types in GetInstrType. 45// 0. Handling of instructions that must be the first/last in a group. 46// 1. Modeling of microcoded instructions. 47// 2. Handling of cracked instructions. 48// 3. Handling of serialized operations. 49// 4. Handling of the esoteric cases in "Resource-based Instruction Grouping", 50// e.g. integer divides that only execute in the second slot. 51// 52 53void PPCHazardRecognizer970::EndDispatchGroup() { 54 DEBUG(std::cerr << "=== Start of dispatch group\n"); 55 // Pipeline units. 56 NumFXU = NumLSU = NumFPU = 0; 57 HasCR = HasSPR = HasVALU = HasVPERM = false; 58 NumIssued = 0; 59 60 // Structural hazard info. 61 HasCTRSet = false; 62 StorePtr1 = StorePtr2 = SDOperand(); 63 StoreSize = 0; 64} 65 66 67PPCHazardRecognizer970::PPC970InstrType 68PPCHazardRecognizer970::GetInstrType(unsigned Opcode) { 69 if (Opcode < ISD::BUILTIN_OP_END) 70 return PseudoInst; 71 Opcode -= ISD::BUILTIN_OP_END; 72 73 switch (Opcode) { 74 case PPC::FMRSD: return PseudoInst; // Usually coallesced away. 75 case PPC::BCTRL: 76 case PPC::BL: 77 case PPC::BLA: 78 return BR; 79 case PPC::MCRF: 80 case PPC::MFCR: 81 case PPC::MFOCRF: 82 return CR; 83 case PPC::MFLR: 84 case PPC::MFCTR: 85 case PPC::MTLR: 86 case PPC::MTCTR: 87 return SPR; 88 case PPC::LFS: 89 case PPC::LFD: 90 case PPC::LWZ: 91 case PPC::LFSX: 92 case PPC::LWZX: 93 return LSU_LD; 94 case PPC::STFD: 95 case PPC::STW: 96 return LSU_ST; 97 case PPC::DIVW: 98 case PPC::DIVWU: 99 case PPC::DIVD: 100 case PPC::DIVDU: 101 return FXU_FIRST; 102 case PPC::FADDS: 103 case PPC::FCTIWZ: 104 case PPC::FRSP: 105 case PPC::FSUB: 106 return FPU; 107 } 108 109 return FXU; 110} 111 112 113/// StartBasicBlock - Initiate a new dispatch group. 114void PPCHazardRecognizer970::StartBasicBlock() { 115 EndDispatchGroup(); 116} 117 118/// isLoadOfStoredAddress - If we have a load from the previously stored pointer 119/// as indicated by StorePtr1/StorePtr2/StoreSize, return true. 120bool PPCHazardRecognizer970:: 121isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const { 122 // Handle exact and commuted addresses. 123 if (Ptr1 == StorePtr1 && Ptr2 == StorePtr2) 124 return true; 125 if (Ptr2 == StorePtr1 && Ptr1 == StorePtr2) 126 return true; 127 128 // Okay, we don't have an exact match, if this is an indexed offset, see if we 129 // have overlap (which happens during fp->int conversion for example). 130 if (StorePtr2 == Ptr2) { 131 if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1)) 132 if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) { 133 // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check to 134 // see if the load and store actually overlap. 135 int StoreOffs = StoreOffset->getValue(); 136 int LoadOffs = LoadOffset->getValue(); 137 if (StoreOffs < LoadOffs) { 138 if (int(StoreOffs+StoreSize) > LoadOffs) return true; 139 } else { 140 if (int(LoadOffs+LoadSize) > StoreOffs) return true; 141 } 142 } 143 } 144 return false; 145} 146 147/// getHazardType - We return hazard for any non-branch instruction that would 148/// terminate terminate the dispatch group. We turn NoopHazard for any 149/// instructions that wouldn't terminate the dispatch group that would cause a 150/// pipeline flush. 151HazardRecognizer::HazardType PPCHazardRecognizer970:: 152getHazardType(SDNode *Node) { 153 PPC970InstrType InstrType = GetInstrType(Node->getOpcode()); 154 if (InstrType == PseudoInst) return NoHazard; 155 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; 156 157 switch (InstrType) { 158 default: assert(0 && "Unknown instruction type!"); 159 case FXU: 160 case FXU_FIRST: if (NumFXU == 2) return Hazard; 161 case LSU_ST: 162 case LSU_LD: if (NumLSU == 2) return Hazard; 163 case FPU: if (NumFPU == 2) return Hazard; 164 case CR: if (HasCR) return Hazard; 165 case SPR: if (HasSPR) return Hazard; 166 case VALU: if (HasVALU) return Hazard; 167 case VPERM: if (HasVPERM) return Hazard; 168 case BR: break; 169 } 170 171 // We can only issue a CR or SPR instruction, or an FXU instruction that needs 172 // to lead a dispatch group as the first instruction in the group. 173 if (NumIssued != 0 && 174 (InstrType == CR || InstrType == SPR || InstrType == FXU_FIRST)) 175 return Hazard; 176 177 // We can only issue a branch as the last instruction in a group. 178 if (NumIssued == 4 && InstrType != BR) 179 return Hazard; 180 181 // Do not allow MTCTR and BCTRL to be in the same dispatch group. 182 if (HasCTRSet && Opcode == PPC::BCTRL) 183 return NoopHazard; 184 185 // If this is a load following a store, make sure it's not to the same or 186 // overlapping address. 187 if (InstrType == LSU_LD && StoreSize) { 188 unsigned LoadSize; 189 switch (Opcode) { 190 default: assert(0 && "Unknown load!"); 191 case PPC::LFSX: 192 case PPC::LFS: 193 case PPC::LWZX: 194 case PPC::LWZ: LoadSize = 4; break; 195 case PPC::LFD: LoadSize = 8; break; 196 } 197 198 if (isLoadOfStoredAddress(LoadSize, 199 Node->getOperand(0), Node->getOperand(1))) 200 return NoopHazard; 201 } 202 203 return NoHazard; 204} 205 206void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) { 207 PPC970InstrType InstrType = GetInstrType(Node->getOpcode()); 208 if (InstrType == PseudoInst) return; 209 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; 210 211 // Update structural hazard information. 212 if (Opcode == PPC::MTCTR) HasCTRSet = true; 213 214 // Track the address stored to. 215 if (InstrType == LSU_ST) { 216 StorePtr1 = Node->getOperand(1); 217 StorePtr2 = Node->getOperand(2); 218 switch (Opcode) { 219 default: assert(0 && "Unknown store instruction!"); 220 case PPC::STFD: StoreSize = 8; break; 221 case PPC::STW: StoreSize = 4; break; 222 } 223 } 224 225 switch (InstrType) { 226 default: assert(0 && "Unknown instruction type!"); 227 case FXU: 228 case FXU_FIRST: ++NumFXU; break; 229 case LSU_LD: 230 case LSU_ST: ++NumLSU; break; 231 case FPU: ++NumFPU; break; 232 case CR: HasCR = true; break; 233 case SPR: HasSPR = true; break; 234 case VALU: HasVALU = true; break; 235 case VPERM: HasVPERM = true; break; 236 case BR: NumIssued = 4; return; // ends a d-group. 237 } 238 ++NumIssued; 239 240 if (NumIssued == 5) 241 EndDispatchGroup(); 242} 243 244void PPCHazardRecognizer970::AdvanceCycle() { 245 assert(NumIssued < 5 && "Illegal dispatch group!"); 246 ++NumIssued; 247 if (NumIssued == 5) 248 EndDispatchGroup(); 249} 250 251void PPCHazardRecognizer970::EmitNoop() { 252 AdvanceCycle(); 253} 254