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