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