PPCHazardRecognizers.cpp revision c6644188208d4aee9a9d6c428710ec1f69837944
1c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===//
2c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
3c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//                     The LLVM Compiler Infrastructure
4c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
5c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// This file was developed by Chris Lattner and is distributed under
6c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details.
7c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
8c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//===----------------------------------------------------------------------===//
9c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
10c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// This file implements hazard recognizers for scheduling on PowerPC processors.
11c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
12c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//===----------------------------------------------------------------------===//
13c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
14c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner#define DEBUG_TYPE "sched"
15c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner#include "PPCHazardRecognizers.h"
16c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner#include "PPC.h"
17c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner#include "llvm/Support/Debug.h"
18c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner#include <iostream>
19c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnerusing namespace llvm;
20c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
21c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
22c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//===----------------------------------------------------------------------===//
23c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// PowerPC 970 Hazard Recognizer
24c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
25c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// FIXME: This is missing some significant cases:
26c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//   0. Handling of instructions that must be the first/last in a group.
27c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//   1. Modeling of microcoded instructions.
28c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//   2. Handling of cracked instructions.
29c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//   3. Handling of serialized operations.
30c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//   4. Handling of the esoteric cases in "Resource-based Instruction Grouping",
31c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//      e.g. integer divides that only execute in the second slot.
32c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
33c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// Note: on the PPC970, logical CR operations are more expensive in their three
34c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// address form: ops that read/write the same register are half as expensive as
35c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
36c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
37c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnervoid PPCHazardRecognizer970::EndDispatchGroup() {
38c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  DEBUG(std::cerr << "=== Start of dispatch group\n");
39c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Pipeline units.
40c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  NumFXU = NumLSU = NumFPU = 0;
41c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  HasCR = HasVALU = HasVPERM = false;
42c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  NumIssued = 0;
43c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
44c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Structural hazard info.
45c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  HasCTRSet = false;
46c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  StorePtr1 = StorePtr2 = SDOperand();
47c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  StoreSize = 0;
48c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
49c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
50c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
51c6644188208d4aee9a9d6c428710ec1f69837944Chris LattnerPPCHazardRecognizer970::PPC970InstrType
52c6644188208d4aee9a9d6c428710ec1f69837944Chris LattnerPPCHazardRecognizer970::GetInstrType(unsigned Opcode) {
53c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (Opcode < ISD::BUILTIN_OP_END)
54c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return PseudoInst;
55c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  Opcode -= ISD::BUILTIN_OP_END;
56c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
57c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  switch (Opcode) {
58c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case PPC::FMRSD: return PseudoInst;  // Usually coallesced away.
59c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case PPC::BCTRL:
60c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case PPC::BL:
61c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case PPC::BLA:
62c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return BR;
63c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case PPC::LFS:
64c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case PPC::LWZ:
65c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return LSU_LD;
66c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case PPC::STFD:
67c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return LSU_ST;
68c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case PPC::FADDS:
69c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case PPC::FCTIWZ:
70c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return FPU;
71c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
72c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
73c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  return FXU;
74c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
75c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
76c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
77c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// StartBasicBlock - Initiate a new dispatch group.
78c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnervoid PPCHazardRecognizer970::StartBasicBlock() {
79c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  EndDispatchGroup();
80c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
81c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
82c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// isLoadOfStoredAddress - If we have a load from the previously stored pointer
83c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
84c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnerbool PPCHazardRecognizer970::
85c6644188208d4aee9a9d6c428710ec1f69837944Chris LattnerisLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const {
86c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Handle exact and commuted addresses.
87c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (Ptr1 == StorePtr1 && Ptr2 == StorePtr2)
88c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return true;
89c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (Ptr2 == StorePtr1 && Ptr1 == StorePtr2)
90c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return true;
91c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
92c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Okay, we don't have an exact match, if this is an indexed offset, see if we
93c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // have overlap (which happens during fp->int conversion for example).
94c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (StorePtr2 == Ptr2) {
95c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1))
96c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner      if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) {
97c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner        // Okay the base pointers match, so we have [c1+r] vs [c2+r].  Check to
98c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner        // see if the load and store actually overlap.
99c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner        int StoreOffs = StoreOffset->getValue();
100c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner        int LoadOffs  = LoadOffset->getValue();
101c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner        if (StoreOffs < LoadOffs) {
102c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner          if (int(StoreOffs+StoreSize) > LoadOffs) return true;
103c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner        } else {
104c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner          if (int(LoadOffs+LoadSize) > StoreOffs) return true;
105c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner        }
106c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner      }
107c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
108c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  return false;
109c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
110c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
111c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// getHazardType - We return hazard for any non-branch instruction that would
112c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// terminate terminate the dispatch group.  We turn NoopHazard for any
113c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// instructions that wouldn't terminate the dispatch group that would cause a
114c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// pipeline flush.
115c6644188208d4aee9a9d6c428710ec1f69837944Chris LattnerHazardRecognizer::HazardType PPCHazardRecognizer970::
116c6644188208d4aee9a9d6c428710ec1f69837944Chris LattnergetHazardType(SDNode *Node) {
117c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
118c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (InstrType == PseudoInst) return NoHazard;
119c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
120c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
121c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  switch (InstrType) {
122c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  default: assert(0 && "Unknown instruction type!");
123c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case FXU:    if (NumFXU  == 2) return Hazard;
124c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case LSU_ST:
125c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case LSU_LD: if (NumLSU  == 2) return Hazard;
126c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case FPU:    if (NumFPU  == 2) return Hazard;
127c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case CR:     if (HasCR) return Hazard;
128c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case VALU:   if (HasVALU) return Hazard;
129c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case VPERM:  if (HasVPERM) return Hazard;
130c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case BR:    break;
131c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
132c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
133c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // We can only issue a branch as the last instruction in a group.
134c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (NumIssued == 4 && InstrType != BR)
135c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return Hazard;
136c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
137c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Do not allow MTCTR and BCTRL to be in the same dispatch group.
138c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (HasCTRSet && Opcode == PPC::BCTRL)
139c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return NoopHazard;
140c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
141c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // If this is a load following a store, make sure it's not to the same or
142c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // overlapping address.
143c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (InstrType == LSU_LD && StoreSize) {
144c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    unsigned LoadSize;
145c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    switch (Opcode) {
146c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    default: assert(0 && "Unknown load!");
147c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    case PPC::LFS:
148c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    case PPC::LWZ: LoadSize = 4; break;
149c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    }
150c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
151c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    if (isLoadOfStoredAddress(LoadSize,
152c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner                              Node->getOperand(0), Node->getOperand(1)))
153c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner      return NoopHazard;
154c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
155c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
156c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  return NoHazard;
157c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
158c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
159c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnervoid PPCHazardRecognizer970::EmitInstruction(SDNode *Node) {
160c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
161c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (InstrType == PseudoInst) return;
162c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
163c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
164c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Update structural hazard information.
165c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (Opcode == PPC::MTCTR) HasCTRSet = true;
166c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
167c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Track the address stored to.
168c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (InstrType == LSU_ST) {
169c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    StorePtr1 = Node->getOperand(1);
170c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    StorePtr2 = Node->getOperand(2);
171c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    switch (Opcode) {
172c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    default: assert(0 && "Unknown store instruction!");
173c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    case PPC::STFD: StoreSize = 8; break;
174c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    }
175c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
176c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
177c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  switch (InstrType) {
178c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  default: assert(0 && "Unknown instruction type!");
179c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case FXU:    ++NumFXU; break;
180c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case LSU_LD:
181c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case LSU_ST: ++NumLSU; break;
182c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case FPU:    ++NumFPU; break;
183c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case CR:     HasCR    = true; break;
184c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case VALU:   HasVALU  = true; break;
185c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case VPERM:  HasVPERM = true; break;
186c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  case BR:     NumIssued = 4; return;  // ends a d-group.
187c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
188c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  ++NumIssued;
189c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
190c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (NumIssued == 5)
191c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    EndDispatchGroup();
192c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
193c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
194c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnervoid PPCHazardRecognizer970::AdvanceCycle() {
195c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  assert(NumIssued < 5 && "Illegal dispatch group!");
196c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  ++NumIssued;
197c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (NumIssued == 5)
198c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    EndDispatchGroup();
199c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
200c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
201c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnervoid PPCHazardRecognizer970::EmitNoop() {
202c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  AdvanceCycle();
203c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
204