Change the interface for getting a target HazardRecognizer to be more clean.
[oota-llvm.git] / lib / Target / PowerPC / PPCHazardRecognizers.cpp
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>
19 using 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
53 PPCHazardRecognizer970::PPCHazardRecognizer970() {
54   EndDispatchGroup();
55 }
56
57 void PPCHazardRecognizer970::EndDispatchGroup() {
58   DEBUG(std::cerr << "=== Start of dispatch group\n");
59   // Pipeline units.
60   NumFXU = NumLSU = NumFPU = 0;
61   HasCR = HasSPR = HasVALU = HasVPERM = false;
62   NumIssued = 0;
63   
64   // Structural hazard info.
65   HasCTRSet = false;
66   StorePtr1 = StorePtr2 = SDOperand();
67   StoreSize = 0;
68 }
69
70
71 PPCHazardRecognizer970::PPC970InstrType
72 PPCHazardRecognizer970::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;
83   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;
92   case PPC::LFS:
93   case PPC::LFD:
94   case PPC::LWZ:
95   case PPC::LFSX:
96   case PPC::LWZX:
97   case PPC::LBZ:
98   case PPC::LHA:
99   case PPC::LHZ:
100   case PPC::LWZU:
101     return LSU_LD;
102   case PPC::STFS:
103   case PPC::STFD:
104   case PPC::STW:
105   case PPC::STB:
106   case PPC::STH:
107   case PPC::STWU:
108     return LSU_ST;
109   case PPC::DIVW:
110   case PPC::DIVWU:
111   case PPC::DIVD:
112   case PPC::DIVDU:
113     return FXU_FIRST;
114   case PPC::FADDS:
115   case PPC::FCTIWZ:
116   case PPC::FRSP:
117   case PPC::FSUB:
118     return FPU;
119   }
120   
121   return FXU;
122 }
123
124 /// isLoadOfStoredAddress - If we have a load from the previously stored pointer
125 /// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
126 bool PPCHazardRecognizer970::
127 isLoadOfStoredAddress(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.
157 HazardRecognizer::HazardType PPCHazardRecognizer970::
158 getHazardType(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!");
165   case FXU:
166   case FXU_FIRST: if (NumFXU  == 2) return Hazard;
167   case LSU_ST:
168   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;
175   }
176   
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   
183   // 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!");
197     case PPC::LBZ: LoadSize = 1; break;
198     case PPC::LHA:
199     case PPC::LHZ: LoadSize = 2; break;
200     case PPC::LWZU:
201     case PPC::LFSX:
202     case PPC::LFS:
203     case PPC::LWZX:
204     case PPC::LWZ: LoadSize = 4; break;
205     case PPC::LFD: LoadSize = 8; break;
206     }
207     
208     if (isLoadOfStoredAddress(LoadSize, 
209                               Node->getOperand(0), Node->getOperand(1)))
210       return NoopHazard;
211   }
212   
213   return NoHazard;
214 }
215
216 void 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!");
230     case PPC::STB:  StoreSize = 1; break;
231     case PPC::STH:  StoreSize = 2; break;
232     case PPC::STFS:
233     case PPC::STWU:
234     case PPC::STW:  StoreSize = 4; break;
235     case PPC::STFD: StoreSize = 8; break;
236     }
237   }
238   
239   switch (InstrType) {
240   default: assert(0 && "Unknown instruction type!");
241   case FXU:
242   case FXU_FIRST: ++NumFXU; break;
243   case LSU_LD:
244   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.
251   }
252   ++NumIssued;
253   
254   if (NumIssued == 5)
255     EndDispatchGroup();
256 }
257
258 void PPCHazardRecognizer970::AdvanceCycle() {
259   assert(NumIssued < 5 && "Illegal dispatch group!");
260   ++NumIssued;
261   if (NumIssued == 5)
262     EndDispatchGroup();
263 }
264
265 void PPCHazardRecognizer970::EmitNoop() {
266   AdvanceCycle();
267 }