1 //===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This file implements hazard recognizers for scheduling on PowerPC processors.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "sched"
15 #include "PPCHazardRecognizers.h"
17 #include "llvm/Support/Debug.h"
22 //===----------------------------------------------------------------------===//
23 // PowerPC 970 Hazard Recognizer
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.
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.
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.
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.
53 void PPCHazardRecognizer970::EndDispatchGroup() {
54 DEBUG(std::cerr << "=== Start of dispatch group\n");
56 NumFXU = NumLSU = NumFPU = 0;
57 HasCR = HasSPR = HasVALU = HasVPERM = false;
60 // Structural hazard info.
62 StorePtr1 = StorePtr2 = SDOperand();
67 PPCHazardRecognizer970::PPC970InstrType
68 PPCHazardRecognizer970::GetInstrType(unsigned Opcode) {
69 if (Opcode < ISD::BUILTIN_OP_END)
71 Opcode -= ISD::BUILTIN_OP_END;
74 case PPC::FMRSD: return PseudoInst; // Usually coallesced away.
121 /// StartBasicBlock - Initiate a new dispatch group.
122 void PPCHazardRecognizer970::StartBasicBlock() {
126 /// isLoadOfStoredAddress - If we have a load from the previously stored pointer
127 /// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
128 bool PPCHazardRecognizer970::
129 isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const {
130 // Handle exact and commuted addresses.
131 if (Ptr1 == StorePtr1 && Ptr2 == StorePtr2)
133 if (Ptr2 == StorePtr1 && Ptr1 == StorePtr2)
136 // Okay, we don't have an exact match, if this is an indexed offset, see if we
137 // have overlap (which happens during fp->int conversion for example).
138 if (StorePtr2 == Ptr2) {
139 if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1))
140 if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) {
141 // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check to
142 // see if the load and store actually overlap.
143 int StoreOffs = StoreOffset->getValue();
144 int LoadOffs = LoadOffset->getValue();
145 if (StoreOffs < LoadOffs) {
146 if (int(StoreOffs+StoreSize) > LoadOffs) return true;
148 if (int(LoadOffs+LoadSize) > StoreOffs) return true;
155 /// getHazardType - We return hazard for any non-branch instruction that would
156 /// terminate terminate the dispatch group. We turn NoopHazard for any
157 /// instructions that wouldn't terminate the dispatch group that would cause a
159 HazardRecognizer::HazardType PPCHazardRecognizer970::
160 getHazardType(SDNode *Node) {
161 PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
162 if (InstrType == PseudoInst) return NoHazard;
163 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
166 default: assert(0 && "Unknown instruction type!");
168 case FXU_FIRST: if (NumFXU == 2) return Hazard;
170 case LSU_LD: if (NumLSU == 2) return Hazard;
171 case FPU: if (NumFPU == 2) return Hazard;
172 case CR: if (HasCR) return Hazard;
173 case SPR: if (HasSPR) return Hazard;
174 case VALU: if (HasVALU) return Hazard;
175 case VPERM: if (HasVPERM) return Hazard;
179 // We can only issue a CR or SPR instruction, or an FXU instruction that needs
180 // to lead a dispatch group as the first instruction in the group.
181 if (NumIssued != 0 &&
182 (InstrType == CR || InstrType == SPR || InstrType == FXU_FIRST))
185 // We can only issue a branch as the last instruction in a group.
186 if (NumIssued == 4 && InstrType != BR)
189 // Do not allow MTCTR and BCTRL to be in the same dispatch group.
190 if (HasCTRSet && Opcode == PPC::BCTRL)
193 // If this is a load following a store, make sure it's not to the same or
194 // overlapping address.
195 if (InstrType == LSU_LD && StoreSize) {
198 default: assert(0 && "Unknown load!");
199 case PPC::LBZ: LoadSize = 1; break;
201 case PPC::LHZ: LoadSize = 2; break;
206 case PPC::LWZ: LoadSize = 4; break;
207 case PPC::LFD: LoadSize = 8; break;
210 if (isLoadOfStoredAddress(LoadSize,
211 Node->getOperand(0), Node->getOperand(1)))
218 void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) {
219 PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
220 if (InstrType == PseudoInst) return;
221 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
223 // Update structural hazard information.
224 if (Opcode == PPC::MTCTR) HasCTRSet = true;
226 // Track the address stored to.
227 if (InstrType == LSU_ST) {
228 StorePtr1 = Node->getOperand(1);
229 StorePtr2 = Node->getOperand(2);
231 default: assert(0 && "Unknown store instruction!");
232 case PPC::STB: StoreSize = 1; break;
233 case PPC::STH: StoreSize = 2; break;
236 case PPC::STW: StoreSize = 4; break;
237 case PPC::STFD: StoreSize = 8; break;
242 default: assert(0 && "Unknown instruction type!");
244 case FXU_FIRST: ++NumFXU; break;
246 case LSU_ST: ++NumLSU; break;
247 case FPU: ++NumFPU; break;
248 case CR: HasCR = true; break;
249 case SPR: HasSPR = true; break;
250 case VALU: HasVALU = true; break;
251 case VPERM: HasVPERM = true; break;
252 case BR: NumIssued = 4; return; // ends a d-group.
260 void PPCHazardRecognizer970::AdvanceCycle() {
261 assert(NumIssued < 5 && "Illegal dispatch group!");
267 void PPCHazardRecognizer970::EmitNoop() {