LLVM API Documentation
00001 //===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by Chris Lattner and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements hazard recognizers for scheduling on PowerPC processors. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #define DEBUG_TYPE "sched" 00015 #include "PPCHazardRecognizers.h" 00016 #include "PPC.h" 00017 #include "PPCInstrInfo.h" 00018 #include "llvm/Support/Debug.h" 00019 #include <iostream> 00020 using namespace llvm; 00021 00022 00023 //===----------------------------------------------------------------------===// 00024 // PowerPC 970 Hazard Recognizer 00025 // 00026 // This models the dispatch group formation of the PPC970 processor. Dispatch 00027 // groups are bundles of up to five instructions that can contain various mixes 00028 // of instructions. The PPC970 can dispatch a peak of 4 non-branch and one 00029 // branch instruction per-cycle. 00030 // 00031 // There are a number of restrictions to dispatch group formation: some 00032 // instructions can only be issued in the first slot of a dispatch group, & some 00033 // instructions fill an entire dispatch group. Additionally, only branches can 00034 // issue in the 5th (last) slot. 00035 // 00036 // Finally, there are a number of "structural" hazards on the PPC970. These 00037 // conditions cause large performance penalties due to misprediction, recovery, 00038 // and replay logic that has to happen. These cases include setting a CTR and 00039 // branching through it in the same dispatch group, and storing to an address, 00040 // then loading from the same address within a dispatch group. To avoid these 00041 // conditions, we insert no-op instructions when appropriate. 00042 // 00043 // FIXME: This is missing some significant cases: 00044 // 1. Modeling of microcoded instructions. 00045 // 2. Handling of serialized operations. 00046 // 3. Handling of the esoteric cases in "Resource-based Instruction Grouping". 00047 // 00048 00049 PPCHazardRecognizer970::PPCHazardRecognizer970(const TargetInstrInfo &tii) 00050 : TII(tii) { 00051 EndDispatchGroup(); 00052 } 00053 00054 void PPCHazardRecognizer970::EndDispatchGroup() { 00055 DEBUG(std::cerr << "=== Start of dispatch group\n"); 00056 NumIssued = 0; 00057 00058 // Structural hazard info. 00059 HasCTRSet = false; 00060 NumStores = 0; 00061 } 00062 00063 00064 PPCII::PPC970_Unit 00065 PPCHazardRecognizer970::GetInstrType(unsigned Opcode, 00066 bool &isFirst, bool &isSingle, 00067 bool &isCracked, 00068 bool &isLoad, bool &isStore) { 00069 if (Opcode < ISD::BUILTIN_OP_END) { 00070 isFirst = isSingle = isCracked = isLoad = isStore = false; 00071 return PPCII::PPC970_Pseudo; 00072 } 00073 Opcode -= ISD::BUILTIN_OP_END; 00074 00075 const TargetInstrDescriptor &TID = TII.get(Opcode); 00076 00077 isLoad = TID.Flags & M_LOAD_FLAG; 00078 isStore = TID.Flags & M_STORE_FLAG; 00079 00080 unsigned TSFlags = TID.TSFlags; 00081 00082 isFirst = TSFlags & PPCII::PPC970_First; 00083 isSingle = TSFlags & PPCII::PPC970_Single; 00084 isCracked = TSFlags & PPCII::PPC970_Cracked; 00085 return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask); 00086 } 00087 00088 /// isLoadOfStoredAddress - If we have a load from the previously stored pointer 00089 /// as indicated by StorePtr1/StorePtr2/StoreSize, return true. 00090 bool PPCHazardRecognizer970:: 00091 isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const { 00092 for (unsigned i = 0, e = NumStores; i != e; ++i) { 00093 // Handle exact and commuted addresses. 00094 if (Ptr1 == StorePtr1[i] && Ptr2 == StorePtr2[i]) 00095 return true; 00096 if (Ptr2 == StorePtr1[i] && Ptr1 == StorePtr2[i]) 00097 return true; 00098 00099 // Okay, we don't have an exact match, if this is an indexed offset, see if 00100 // we have overlap (which happens during fp->int conversion for example). 00101 if (StorePtr2[i] == Ptr2) { 00102 if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1[i])) 00103 if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) { 00104 // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check 00105 // to see if the load and store actually overlap. 00106 int StoreOffs = StoreOffset->getValue(); 00107 int LoadOffs = LoadOffset->getValue(); 00108 if (StoreOffs < LoadOffs) { 00109 if (int(StoreOffs+StoreSize[i]) > LoadOffs) return true; 00110 } else { 00111 if (int(LoadOffs+LoadSize) > StoreOffs) return true; 00112 } 00113 } 00114 } 00115 } 00116 return false; 00117 } 00118 00119 /// getHazardType - We return hazard for any non-branch instruction that would 00120 /// terminate terminate the dispatch group. We turn NoopHazard for any 00121 /// instructions that wouldn't terminate the dispatch group that would cause a 00122 /// pipeline flush. 00123 HazardRecognizer::HazardType PPCHazardRecognizer970:: 00124 getHazardType(SDNode *Node) { 00125 bool isFirst, isSingle, isCracked, isLoad, isStore; 00126 PPCII::PPC970_Unit InstrType = 00127 GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked, 00128 isLoad, isStore); 00129 if (InstrType == PPCII::PPC970_Pseudo) return NoHazard; 00130 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; 00131 00132 // We can only issue a PPC970_First/PPC970_Single instruction (such as 00133 // crand/mtspr/etc) if this is the first cycle of the dispatch group. 00134 if (NumIssued != 0 && (isFirst || isSingle)) 00135 return Hazard; 00136 00137 // If this instruction is cracked into two ops by the decoder, we know that 00138 // it is not a branch and that it cannot issue if 3 other instructions are 00139 // already in the dispatch group. 00140 if (isCracked && NumIssued > 2) 00141 return Hazard; 00142 00143 switch (InstrType) { 00144 default: assert(0 && "Unknown instruction type!"); 00145 case PPCII::PPC970_FXU: 00146 case PPCII::PPC970_LSU: 00147 case PPCII::PPC970_FPU: 00148 case PPCII::PPC970_VALU: 00149 case PPCII::PPC970_VPERM: 00150 // We can only issue a branch as the last instruction in a group. 00151 if (NumIssued == 4) return Hazard; 00152 break; 00153 case PPCII::PPC970_CRU: 00154 // We can only issue a CR instruction in the first two slots. 00155 if (NumIssued >= 2) return Hazard; 00156 break; 00157 case PPCII::PPC970_BRU: 00158 break; 00159 } 00160 00161 // Do not allow MTCTR and BCTRL to be in the same dispatch group. 00162 if (HasCTRSet && Opcode == PPC::BCTRL) 00163 return NoopHazard; 00164 00165 // If this is a load following a store, make sure it's not to the same or 00166 // overlapping address. 00167 if (isLoad && NumStores) { 00168 unsigned LoadSize; 00169 switch (Opcode) { 00170 default: assert(0 && "Unknown load!"); 00171 case PPC::LBZ: 00172 case PPC::LBZX: 00173 case PPC::LBZ8: 00174 case PPC::LBZX8: 00175 case PPC::LVEBX: 00176 LoadSize = 1; 00177 break; 00178 case PPC::LHA: 00179 case PPC::LHAX: 00180 case PPC::LHZ: 00181 case PPC::LHZX: 00182 case PPC::LVEHX: 00183 case PPC::LHBRX: 00184 case PPC::LHA8: 00185 case PPC::LHAX8: 00186 case PPC::LHZ8: 00187 case PPC::LHZX8: 00188 LoadSize = 2; 00189 break; 00190 case PPC::LFS: 00191 case PPC::LFSX: 00192 case PPC::LWZ: 00193 case PPC::LWZX: 00194 case PPC::LWZU: 00195 case PPC::LWA: 00196 case PPC::LWAX: 00197 case PPC::LVEWX: 00198 case PPC::LWBRX: 00199 case PPC::LWZ8: 00200 case PPC::LWZX8: 00201 LoadSize = 4; 00202 break; 00203 case PPC::LFD: 00204 case PPC::LFDX: 00205 case PPC::LD: 00206 case PPC::LDX: 00207 LoadSize = 8; 00208 break; 00209 case PPC::LVX: 00210 LoadSize = 16; 00211 break; 00212 } 00213 00214 if (isLoadOfStoredAddress(LoadSize, 00215 Node->getOperand(0), Node->getOperand(1))) 00216 return NoopHazard; 00217 } 00218 00219 return NoHazard; 00220 } 00221 00222 void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) { 00223 bool isFirst, isSingle, isCracked, isLoad, isStore; 00224 PPCII::PPC970_Unit InstrType = 00225 GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked, 00226 isLoad, isStore); 00227 if (InstrType == PPCII::PPC970_Pseudo) return; 00228 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; 00229 00230 // Update structural hazard information. 00231 if (Opcode == PPC::MTCTR) HasCTRSet = true; 00232 00233 // Track the address stored to. 00234 if (isStore) { 00235 unsigned ThisStoreSize; 00236 switch (Opcode) { 00237 default: assert(0 && "Unknown store instruction!"); 00238 case PPC::STB: 00239 case PPC::STBX: 00240 case PPC::STB8: 00241 case PPC::STBX8: 00242 case PPC::STVEBX: 00243 ThisStoreSize = 1; 00244 break; 00245 case PPC::STH: 00246 case PPC::STHX: 00247 case PPC::STH8: 00248 case PPC::STHX8: 00249 case PPC::STVEHX: 00250 case PPC::STHBRX: 00251 ThisStoreSize = 2; 00252 break; 00253 case PPC::STFS: 00254 case PPC::STFSX: 00255 case PPC::STWU: 00256 case PPC::STWX: 00257 case PPC::STWUX: 00258 case PPC::STW: 00259 case PPC::STW8: 00260 case PPC::STWX8: 00261 case PPC::STVEWX: 00262 case PPC::STFIWX: 00263 case PPC::STWBRX: 00264 ThisStoreSize = 4; 00265 break; 00266 case PPC::STD_32: 00267 case PPC::STDX_32: 00268 case PPC::STD: 00269 case PPC::STFD: 00270 case PPC::STFDX: 00271 case PPC::STDX: 00272 case PPC::STDUX: 00273 ThisStoreSize = 8; 00274 break; 00275 case PPC::STVX: 00276 ThisStoreSize = 16; 00277 break; 00278 } 00279 00280 StoreSize[NumStores] = ThisStoreSize; 00281 StorePtr1[NumStores] = Node->getOperand(1); 00282 StorePtr2[NumStores] = Node->getOperand(2); 00283 ++NumStores; 00284 } 00285 00286 if (InstrType == PPCII::PPC970_BRU || isSingle) 00287 NumIssued = 4; // Terminate a d-group. 00288 ++NumIssued; 00289 00290 // If this instruction is cracked into two ops by the decoder, remember that 00291 // we issued two pieces. 00292 if (isCracked) 00293 ++NumIssued; 00294 00295 if (NumIssued == 5) 00296 EndDispatchGroup(); 00297 } 00298 00299 void PPCHazardRecognizer970::AdvanceCycle() { 00300 assert(NumIssued < 5 && "Illegal dispatch group!"); 00301 ++NumIssued; 00302 if (NumIssued == 5) 00303 EndDispatchGroup(); 00304 } 00305 00306 void PPCHazardRecognizer970::EmitNoop() { 00307 AdvanceCycle(); 00308 }