PPCHazardRecognizers.cpp revision 2046371e70e90d4435fcdf1b2ebeb64a2e5b2626
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 = 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::LFS: 80 case PPC::LFD: 81 case PPC::LWZ: 82 case PPC::LFSX: 83 case PPC::LWZX: 84 return LSU_LD; 85 case PPC::STFD: 86 case PPC::STW: 87 return LSU_ST; 88 case PPC::FADDS: 89 case PPC::FCTIWZ: 90 case PPC::FRSP: 91 case PPC::FSUB: 92 return FPU; 93 } 94 95 return FXU; 96} 97 98 99/// StartBasicBlock - Initiate a new dispatch group. 100void PPCHazardRecognizer970::StartBasicBlock() { 101 EndDispatchGroup(); 102} 103 104/// isLoadOfStoredAddress - If we have a load from the previously stored pointer 105/// as indicated by StorePtr1/StorePtr2/StoreSize, return true. 106bool PPCHazardRecognizer970:: 107isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const { 108 // Handle exact and commuted addresses. 109 if (Ptr1 == StorePtr1 && Ptr2 == StorePtr2) 110 return true; 111 if (Ptr2 == StorePtr1 && Ptr1 == StorePtr2) 112 return true; 113 114 // Okay, we don't have an exact match, if this is an indexed offset, see if we 115 // have overlap (which happens during fp->int conversion for example). 116 if (StorePtr2 == Ptr2) { 117 if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1)) 118 if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) { 119 // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check to 120 // see if the load and store actually overlap. 121 int StoreOffs = StoreOffset->getValue(); 122 int LoadOffs = LoadOffset->getValue(); 123 if (StoreOffs < LoadOffs) { 124 if (int(StoreOffs+StoreSize) > LoadOffs) return true; 125 } else { 126 if (int(LoadOffs+LoadSize) > StoreOffs) return true; 127 } 128 } 129 } 130 return false; 131} 132 133/// getHazardType - We return hazard for any non-branch instruction that would 134/// terminate terminate the dispatch group. We turn NoopHazard for any 135/// instructions that wouldn't terminate the dispatch group that would cause a 136/// pipeline flush. 137HazardRecognizer::HazardType PPCHazardRecognizer970:: 138getHazardType(SDNode *Node) { 139 PPC970InstrType InstrType = GetInstrType(Node->getOpcode()); 140 if (InstrType == PseudoInst) return NoHazard; 141 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; 142 143 switch (InstrType) { 144 default: assert(0 && "Unknown instruction type!"); 145 case FXU: if (NumFXU == 2) return Hazard; 146 case LSU_ST: 147 case LSU_LD: if (NumLSU == 2) return Hazard; 148 case FPU: if (NumFPU == 2) return Hazard; 149 case CR: if (HasCR) return Hazard; 150 case VALU: if (HasVALU) return Hazard; 151 case VPERM: if (HasVPERM) return Hazard; 152 case BR: break; 153 } 154 155 // We can only issue a branch as the last instruction in a group. 156 if (NumIssued == 4 && InstrType != BR) 157 return Hazard; 158 159 // Do not allow MTCTR and BCTRL to be in the same dispatch group. 160 if (HasCTRSet && Opcode == PPC::BCTRL) 161 return NoopHazard; 162 163 // If this is a load following a store, make sure it's not to the same or 164 // overlapping address. 165 if (InstrType == LSU_LD && StoreSize) { 166 unsigned LoadSize; 167 switch (Opcode) { 168 default: assert(0 && "Unknown load!"); 169 case PPC::LFSX: 170 case PPC::LFS: 171 case PPC::LWZX: 172 case PPC::LWZ: LoadSize = 4; break; 173 case PPC::LFD: LoadSize = 8; break; 174 } 175 176 if (isLoadOfStoredAddress(LoadSize, 177 Node->getOperand(0), Node->getOperand(1))) 178 return NoopHazard; 179 } 180 181 return NoHazard; 182} 183 184void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) { 185 PPC970InstrType InstrType = GetInstrType(Node->getOpcode()); 186 if (InstrType == PseudoInst) return; 187 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END; 188 189 // Update structural hazard information. 190 if (Opcode == PPC::MTCTR) HasCTRSet = true; 191 192 // Track the address stored to. 193 if (InstrType == LSU_ST) { 194 StorePtr1 = Node->getOperand(1); 195 StorePtr2 = Node->getOperand(2); 196 switch (Opcode) { 197 default: assert(0 && "Unknown store instruction!"); 198 case PPC::STFD: StoreSize = 8; break; 199 case PPC::STW: StoreSize = 4; break; 200 } 201 } 202 203 switch (InstrType) { 204 default: assert(0 && "Unknown instruction type!"); 205 case FXU: ++NumFXU; break; 206 case LSU_LD: 207 case LSU_ST: ++NumLSU; break; 208 case FPU: ++NumFPU; break; 209 case CR: HasCR = true; break; 210 case VALU: HasVALU = true; break; 211 case VPERM: HasVPERM = true; break; 212 case BR: NumIssued = 4; return; // ends a d-group. 213 } 214 ++NumIssued; 215 216 if (NumIssued == 5) 217 EndDispatchGroup(); 218} 219 220void PPCHazardRecognizer970::AdvanceCycle() { 221 assert(NumIssued < 5 && "Illegal dispatch group!"); 222 ++NumIssued; 223 if (NumIssued == 5) 224 EndDispatchGroup(); 225} 226 227void PPCHazardRecognizer970::EmitNoop() { 228 AdvanceCycle(); 229} 230