blob: 203f116135b63eb90afcf800ff590dc0430cd9c2 [file] [log] [blame]
Chris Lattnerc6644182006-03-07 06:32:48 +00001//===-- 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//
Chris Lattner7ce64852006-03-07 06:44:19 +000025// 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//
Chris Lattnerc6644182006-03-07 06:32:48 +000043// FIXME: This is missing some significant cases:
Chris Lattner20463712006-03-07 07:14:55 +000044// -1. Handle all of the instruction types in GetInstrType.
Chris Lattnerc6644182006-03-07 06:32:48 +000045// 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//
Chris Lattnerc6644182006-03-07 06:32:48 +000052
Chris Lattnerb0d21ef2006-03-08 04:25:59 +000053PPCHazardRecognizer970::PPCHazardRecognizer970() {
54 EndDispatchGroup();
55}
56
Chris Lattnerc6644182006-03-07 06:32:48 +000057void PPCHazardRecognizer970::EndDispatchGroup() {
58 DEBUG(std::cerr << "=== Start of dispatch group\n");
59 // Pipeline units.
60 NumFXU = NumLSU = NumFPU = 0;
Nate Begeman3acbe5d2006-03-07 08:30:27 +000061 HasCR = HasSPR = HasVALU = HasVPERM = false;
Chris Lattnerc6644182006-03-07 06:32:48 +000062 NumIssued = 0;
63
64 // Structural hazard info.
65 HasCTRSet = false;
66 StorePtr1 = StorePtr2 = SDOperand();
67 StoreSize = 0;
68}
69
70
71PPCHazardRecognizer970::PPC970InstrType
72PPCHazardRecognizer970::GetInstrType(unsigned Opcode) {
73 if (Opcode < ISD::BUILTIN_OP_END)
74 return PseudoInst;
75 Opcode -= ISD::BUILTIN_OP_END;
76
77 switch (Opcode) {
78 case PPC::FMRSD: return PseudoInst; // Usually coallesced away.
79 case PPC::BCTRL:
80 case PPC::BL:
81 case PPC::BLA:
82 return BR;
Nate Begeman3acbe5d2006-03-07 08:30:27 +000083 case PPC::MCRF:
84 case PPC::MFCR:
85 case PPC::MFOCRF:
86 return CR;
87 case PPC::MFLR:
88 case PPC::MFCTR:
89 case PPC::MTLR:
90 case PPC::MTCTR:
91 return SPR;
Chris Lattnerc6644182006-03-07 06:32:48 +000092 case PPC::LFS:
Chris Lattner20463712006-03-07 07:14:55 +000093 case PPC::LFD:
Chris Lattnerc6644182006-03-07 06:32:48 +000094 case PPC::LWZ:
Chris Lattner20463712006-03-07 07:14:55 +000095 case PPC::LFSX:
96 case PPC::LWZX:
Chris Lattnerab5801c2006-03-07 16:19:46 +000097 case PPC::LBZ:
98 case PPC::LHA:
99 case PPC::LHZ:
100 case PPC::LWZU:
Chris Lattnerc6644182006-03-07 06:32:48 +0000101 return LSU_LD;
Chris Lattnerb84225b2006-03-07 16:26:48 +0000102 case PPC::STFS:
Chris Lattnerc6644182006-03-07 06:32:48 +0000103 case PPC::STFD:
Chris Lattner20463712006-03-07 07:14:55 +0000104 case PPC::STW:
Chris Lattnerab5801c2006-03-07 16:19:46 +0000105 case PPC::STB:
106 case PPC::STH:
107 case PPC::STWU:
Chris Lattnerc6644182006-03-07 06:32:48 +0000108 return LSU_ST;
Nate Begeman3acbe5d2006-03-07 08:30:27 +0000109 case PPC::DIVW:
110 case PPC::DIVWU:
111 case PPC::DIVD:
112 case PPC::DIVDU:
113 return FXU_FIRST;
Chris Lattnerc6644182006-03-07 06:32:48 +0000114 case PPC::FADDS:
115 case PPC::FCTIWZ:
Chris Lattner20463712006-03-07 07:14:55 +0000116 case PPC::FRSP:
117 case PPC::FSUB:
Chris Lattnerc6644182006-03-07 06:32:48 +0000118 return FPU;
119 }
120
121 return FXU;
122}
123
Chris Lattnerc6644182006-03-07 06:32:48 +0000124/// isLoadOfStoredAddress - If we have a load from the previously stored pointer
125/// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
126bool PPCHazardRecognizer970::
127isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const {
128 // Handle exact and commuted addresses.
129 if (Ptr1 == StorePtr1 && Ptr2 == StorePtr2)
130 return true;
131 if (Ptr2 == StorePtr1 && Ptr1 == StorePtr2)
132 return true;
133
134 // Okay, we don't have an exact match, if this is an indexed offset, see if we
135 // have overlap (which happens during fp->int conversion for example).
136 if (StorePtr2 == Ptr2) {
137 if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1))
138 if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) {
139 // Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check to
140 // see if the load and store actually overlap.
141 int StoreOffs = StoreOffset->getValue();
142 int LoadOffs = LoadOffset->getValue();
143 if (StoreOffs < LoadOffs) {
144 if (int(StoreOffs+StoreSize) > LoadOffs) return true;
145 } else {
146 if (int(LoadOffs+LoadSize) > StoreOffs) return true;
147 }
148 }
149 }
150 return false;
151}
152
153/// getHazardType - We return hazard for any non-branch instruction that would
154/// terminate terminate the dispatch group. We turn NoopHazard for any
155/// instructions that wouldn't terminate the dispatch group that would cause a
156/// pipeline flush.
157HazardRecognizer::HazardType PPCHazardRecognizer970::
158getHazardType(SDNode *Node) {
159 PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
160 if (InstrType == PseudoInst) return NoHazard;
161 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
162
163 switch (InstrType) {
164 default: assert(0 && "Unknown instruction type!");
Nate Begeman3acbe5d2006-03-07 08:30:27 +0000165 case FXU:
166 case FXU_FIRST: if (NumFXU == 2) return Hazard;
Chris Lattnerc6644182006-03-07 06:32:48 +0000167 case LSU_ST:
Nate Begeman3acbe5d2006-03-07 08:30:27 +0000168 case LSU_LD: if (NumLSU == 2) return Hazard;
169 case FPU: if (NumFPU == 2) return Hazard;
170 case CR: if (HasCR) return Hazard;
171 case SPR: if (HasSPR) return Hazard;
172 case VALU: if (HasVALU) return Hazard;
173 case VPERM: if (HasVPERM) return Hazard;
174 case BR: break;
Chris Lattnerc6644182006-03-07 06:32:48 +0000175 }
Nate Begeman3acbe5d2006-03-07 08:30:27 +0000176
177 // We can only issue a CR or SPR instruction, or an FXU instruction that needs
178 // to lead a dispatch group as the first instruction in the group.
179 if (NumIssued != 0 &&
180 (InstrType == CR || InstrType == SPR || InstrType == FXU_FIRST))
181 return Hazard;
182
Chris Lattnerc6644182006-03-07 06:32:48 +0000183 // We can only issue a branch as the last instruction in a group.
184 if (NumIssued == 4 && InstrType != BR)
185 return Hazard;
186
187 // Do not allow MTCTR and BCTRL to be in the same dispatch group.
188 if (HasCTRSet && Opcode == PPC::BCTRL)
189 return NoopHazard;
190
191 // If this is a load following a store, make sure it's not to the same or
192 // overlapping address.
193 if (InstrType == LSU_LD && StoreSize) {
194 unsigned LoadSize;
195 switch (Opcode) {
196 default: assert(0 && "Unknown load!");
Chris Lattnerab5801c2006-03-07 16:19:46 +0000197 case PPC::LBZ: LoadSize = 1; break;
198 case PPC::LHA:
199 case PPC::LHZ: LoadSize = 2; break;
200 case PPC::LWZU:
Chris Lattner20463712006-03-07 07:14:55 +0000201 case PPC::LFSX:
Chris Lattnerc6644182006-03-07 06:32:48 +0000202 case PPC::LFS:
Chris Lattner20463712006-03-07 07:14:55 +0000203 case PPC::LWZX:
Chris Lattnerc6644182006-03-07 06:32:48 +0000204 case PPC::LWZ: LoadSize = 4; break;
Chris Lattner20463712006-03-07 07:14:55 +0000205 case PPC::LFD: LoadSize = 8; break;
Chris Lattnerc6644182006-03-07 06:32:48 +0000206 }
207
208 if (isLoadOfStoredAddress(LoadSize,
209 Node->getOperand(0), Node->getOperand(1)))
210 return NoopHazard;
211 }
212
213 return NoHazard;
214}
215
216void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) {
217 PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
218 if (InstrType == PseudoInst) return;
219 unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
220
221 // Update structural hazard information.
222 if (Opcode == PPC::MTCTR) HasCTRSet = true;
223
224 // Track the address stored to.
225 if (InstrType == LSU_ST) {
226 StorePtr1 = Node->getOperand(1);
227 StorePtr2 = Node->getOperand(2);
228 switch (Opcode) {
229 default: assert(0 && "Unknown store instruction!");
Chris Lattnerab5801c2006-03-07 16:19:46 +0000230 case PPC::STB: StoreSize = 1; break;
231 case PPC::STH: StoreSize = 2; break;
Chris Lattnerb84225b2006-03-07 16:26:48 +0000232 case PPC::STFS:
Chris Lattnerab5801c2006-03-07 16:19:46 +0000233 case PPC::STWU:
Chris Lattner20463712006-03-07 07:14:55 +0000234 case PPC::STW: StoreSize = 4; break;
Chris Lattnerab5801c2006-03-07 16:19:46 +0000235 case PPC::STFD: StoreSize = 8; break;
Chris Lattnerc6644182006-03-07 06:32:48 +0000236 }
237 }
238
239 switch (InstrType) {
240 default: assert(0 && "Unknown instruction type!");
Nate Begeman3acbe5d2006-03-07 08:30:27 +0000241 case FXU:
242 case FXU_FIRST: ++NumFXU; break;
Chris Lattnerc6644182006-03-07 06:32:48 +0000243 case LSU_LD:
Nate Begeman3acbe5d2006-03-07 08:30:27 +0000244 case LSU_ST: ++NumLSU; break;
245 case FPU: ++NumFPU; break;
246 case CR: HasCR = true; break;
247 case SPR: HasSPR = true; break;
248 case VALU: HasVALU = true; break;
249 case VPERM: HasVPERM = true; break;
250 case BR: NumIssued = 4; return; // ends a d-group.
Chris Lattnerc6644182006-03-07 06:32:48 +0000251 }
252 ++NumIssued;
253
254 if (NumIssued == 5)
255 EndDispatchGroup();
256}
257
258void PPCHazardRecognizer970::AdvanceCycle() {
259 assert(NumIssued < 5 && "Illegal dispatch group!");
260 ++NumIssued;
261 if (NumIssued == 5)
262 EndDispatchGroup();
263}
264
265void PPCHazardRecognizer970::EmitNoop() {
266 AdvanceCycle();
267}