[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp PPCHazardRecognizers.h PPCISelDAGToDAG.cpp

Chris Lattner lattner at cs.uiuc.edu
Mon Mar 6 22:33:01 PST 2006



Changes in directory llvm/lib/Target/PowerPC:

PPCHazardRecognizers.cpp added (r1.1)
PPCHazardRecognizers.h added (r1.1)
PPCISelDAGToDAG.cpp updated: 1.161 -> 1.162
---
Log message:

Implement a very very simple hazard recognizer for LSU rejects and ctr set/read
flushes


---
Diffs of the changes:  (+292 -2)

 PPCHazardRecognizers.cpp |  203 +++++++++++++++++++++++++++++++++++++++++++++++
 PPCHazardRecognizers.h   |   79 ++++++++++++++++++
 PPCISelDAGToDAG.cpp      |   12 ++
 3 files changed, 292 insertions(+), 2 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp
diff -c /dev/null llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.1
*** /dev/null	Tue Mar  7 00:32:58 2006
--- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp	Tue Mar  7 00:32:48 2006
***************
*** 0 ****
--- 1,203 ----
+ //===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Chris Lattner and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file implements hazard recognizers for scheduling on PowerPC processors.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #define DEBUG_TYPE "sched"
+ #include "PPCHazardRecognizers.h"
+ #include "PPC.h"
+ #include "llvm/Support/Debug.h"
+ #include <iostream>
+ using namespace llvm;
+ 
+ 
+ //===----------------------------------------------------------------------===//
+ // PowerPC 970 Hazard Recognizer
+ //
+ // FIXME: This is missing some significant cases:
+ //   0. Handling of instructions that must be the first/last in a group.
+ //   1. Modeling of microcoded instructions.
+ //   2. Handling of cracked instructions.
+ //   3. Handling of serialized operations.
+ //   4. Handling of the esoteric cases in "Resource-based Instruction Grouping",
+ //      e.g. integer divides that only execute in the second slot.
+ //
+ // Note: on the PPC970, logical CR operations are more expensive in their three
+ // address form: ops that read/write the same register are half as expensive as
+ //
+ 
+ void PPCHazardRecognizer970::EndDispatchGroup() {
+   DEBUG(std::cerr << "=== Start of dispatch group\n");
+   // Pipeline units.
+   NumFXU = NumLSU = NumFPU = 0;
+   HasCR = HasVALU = HasVPERM = false;
+   NumIssued = 0;
+   
+   // Structural hazard info.
+   HasCTRSet = false;
+   StorePtr1 = StorePtr2 = SDOperand();
+   StoreSize = 0;
+ }
+ 
+ 
+ PPCHazardRecognizer970::PPC970InstrType
+ PPCHazardRecognizer970::GetInstrType(unsigned Opcode) {
+   if (Opcode < ISD::BUILTIN_OP_END)
+     return PseudoInst;
+   Opcode -= ISD::BUILTIN_OP_END;
+   
+   switch (Opcode) {
+   case PPC::FMRSD: return PseudoInst;  // Usually coallesced away.
+   case PPC::BCTRL:
+   case PPC::BL:
+   case PPC::BLA:
+     return BR;
+   case PPC::LFS:
+   case PPC::LWZ:
+     return LSU_LD;
+   case PPC::STFD:
+     return LSU_ST;
+   case PPC::FADDS:
+   case PPC::FCTIWZ:
+     return FPU;
+   }
+   
+   return FXU;
+ }
+ 
+ 
+ /// StartBasicBlock - Initiate a new dispatch group.
+ void PPCHazardRecognizer970::StartBasicBlock() {
+   EndDispatchGroup();
+ }
+ 
+ /// isLoadOfStoredAddress - If we have a load from the previously stored pointer
+ /// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
+ bool PPCHazardRecognizer970::
+ isLoadOfStoredAddress(unsigned LoadSize, SDOperand Ptr1, SDOperand Ptr2) const {
+   // Handle exact and commuted addresses.
+   if (Ptr1 == StorePtr1 && Ptr2 == StorePtr2)
+     return true;
+   if (Ptr2 == StorePtr1 && Ptr1 == StorePtr2)
+     return true;
+   
+   // Okay, we don't have an exact match, if this is an indexed offset, see if we
+   // have overlap (which happens during fp->int conversion for example).
+   if (StorePtr2 == Ptr2) {
+     if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1))
+       if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) {
+         // Okay the base pointers match, so we have [c1+r] vs [c2+r].  Check to
+         // see if the load and store actually overlap.
+         int StoreOffs = StoreOffset->getValue();
+         int LoadOffs  = LoadOffset->getValue();
+         if (StoreOffs < LoadOffs) {
+           if (int(StoreOffs+StoreSize) > LoadOffs) return true;
+         } else {
+           if (int(LoadOffs+LoadSize) > StoreOffs) return true;
+         }
+       }
+   }
+   return false;
+ }
+ 
+ /// getHazardType - We return hazard for any non-branch instruction that would
+ /// terminate terminate the dispatch group.  We turn NoopHazard for any
+ /// instructions that wouldn't terminate the dispatch group that would cause a
+ /// pipeline flush.
+ HazardRecognizer::HazardType PPCHazardRecognizer970::
+ getHazardType(SDNode *Node) {
+   PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
+   if (InstrType == PseudoInst) return NoHazard;  
+   unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
+ 
+   switch (InstrType) {
+   default: assert(0 && "Unknown instruction type!");
+   case FXU:    if (NumFXU  == 2) return Hazard;
+   case LSU_ST:
+   case LSU_LD: if (NumLSU  == 2) return Hazard;
+   case FPU:    if (NumFPU  == 2) return Hazard;
+   case CR:     if (HasCR) return Hazard;
+   case VALU:   if (HasVALU) return Hazard;
+   case VPERM:  if (HasVPERM) return Hazard;
+   case BR:    break;
+   }
+ 
+   // We can only issue a branch as the last instruction in a group.
+   if (NumIssued == 4 && InstrType != BR)
+     return Hazard;
+   
+   // Do not allow MTCTR and BCTRL to be in the same dispatch group.
+   if (HasCTRSet && Opcode == PPC::BCTRL)
+     return NoopHazard;
+   
+   // If this is a load following a store, make sure it's not to the same or
+   // overlapping address.
+   if (InstrType == LSU_LD && StoreSize) {
+     unsigned LoadSize;
+     switch (Opcode) {
+     default: assert(0 && "Unknown load!");
+     case PPC::LFS:
+     case PPC::LWZ: LoadSize = 4; break;
+     }
+     
+     if (isLoadOfStoredAddress(LoadSize, 
+                               Node->getOperand(0), Node->getOperand(1)))
+       return NoopHazard;
+   }
+   
+   return NoHazard;
+ }
+ 
+ void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) {
+   PPC970InstrType InstrType = GetInstrType(Node->getOpcode());
+   if (InstrType == PseudoInst) return;
+   unsigned Opcode = Node->getOpcode()-ISD::BUILTIN_OP_END;
+ 
+   // Update structural hazard information.
+   if (Opcode == PPC::MTCTR) HasCTRSet = true;
+   
+   // Track the address stored to.
+   if (InstrType == LSU_ST) {
+     StorePtr1 = Node->getOperand(1);
+     StorePtr2 = Node->getOperand(2);
+     switch (Opcode) {
+     default: assert(0 && "Unknown store instruction!");
+     case PPC::STFD: StoreSize = 8; break;
+     }
+   }
+   
+   switch (InstrType) {
+   default: assert(0 && "Unknown instruction type!");
+   case FXU:    ++NumFXU; break;
+   case LSU_LD:
+   case LSU_ST: ++NumLSU; break;
+   case FPU:    ++NumFPU; break;
+   case CR:     HasCR    = true; break;
+   case VALU:   HasVALU  = true; break;
+   case VPERM:  HasVPERM = true; break;
+   case BR:     NumIssued = 4; return;  // ends a d-group.
+   }
+   ++NumIssued;
+   
+   if (NumIssued == 5)
+     EndDispatchGroup();
+ }
+ 
+ void PPCHazardRecognizer970::AdvanceCycle() {
+   assert(NumIssued < 5 && "Illegal dispatch group!");
+   ++NumIssued;
+   if (NumIssued == 5)
+     EndDispatchGroup();
+ }
+ 
+ void PPCHazardRecognizer970::EmitNoop() {
+   AdvanceCycle();
+ }


Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.h
diff -c /dev/null llvm/lib/Target/PowerPC/PPCHazardRecognizers.h:1.1
*** /dev/null	Tue Mar  7 00:33:01 2006
--- llvm/lib/Target/PowerPC/PPCHazardRecognizers.h	Tue Mar  7 00:32:48 2006
***************
*** 0 ****
--- 1,79 ----
+ //===-- PPCHazardRecognizers.h - PowerPC Hazard Recognizers -----*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Chris Lattner and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file defines hazard recognizers for scheduling on PowerPC processors.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef PPCHAZRECS_H
+ #define PPCHAZRECS_H
+ 
+ #include "llvm/CodeGen/ScheduleDAG.h"
+ 
+ namespace llvm {
+   
+ /// PPCHazardRecognizer970 - This class defines a finite state automata that
+ /// models the dispatch logic on the PowerPC 970 (aka G5) processor.  This
+ /// promotes good dispatch group formation and implements noop insertion to
+ /// avoid structural hazards that cause significant performance penalties (e.g.
+ /// setting the CTR register then branching through it within a dispatch group),
+ /// or storing then loading from the same address within a dispatch group.
+ class PPCHazardRecognizer970 : public HazardRecognizer {
+   unsigned NumIssued;  // Number of insts issued, including advanced cycles.
+   
+   // Number of various types of instructions in the current dispatch group.
+   unsigned NumFXU;     // Number of Fixed Point (integer) instructions
+   unsigned NumLSU;     // Number of Load/Store instructions
+   unsigned NumFPU;     // Number of Floating Point instructions
+   bool     HasCR;      // True if Condition Register instruction issued
+   bool     HasVALU;    // True if Vector Arithmetic instruction issued
+   bool     HasVPERM;   // True if Vector Permute instruction issued
+   
+   // Various things that can cause a structural hazard.
+   
+   // HasCTRSet - If the CTR register is set in this group, disallow BCTRL.
+   bool HasCTRSet;
+   
+   // StoredPtr - Keep track of the address of any store.  If we see a load from
+   // the same address (or one that aliases it), disallow the store.  We only
+   // need one pointer here, because there can only be two LSU operations and we
+   // only get an LSU reject if the first is a store and the second is a load.
+   //
+   // This is null if we haven't seen a store yet.  We keep track of both
+   // operands of the store here, since we support [r+r] and [r+i] addressing.
+   SDOperand StorePtr1, StorePtr2;
+   unsigned  StoreSize;
+   
+ public:
+   virtual void StartBasicBlock();
+   virtual HazardType getHazardType(SDNode *Node);
+   virtual void EmitInstruction(SDNode *Node);
+   virtual void AdvanceCycle();
+   virtual void EmitNoop();
+   
+ private:
+   /// EndDispatchGroup - Called when we are finishing a new dispatch group.
+   ///
+   void EndDispatchGroup();
+   
+   enum PPC970InstrType {
+     FXU, LSU_LD, LSU_ST, FPU, CR, VALU, VPERM, BR, PseudoInst
+   };
+   
+   /// GetInstrType - Classify the specified powerpc opcode according to its
+   /// pipeline.
+   PPC970InstrType GetInstrType(unsigned Opcode);
+   
+   bool isLoadOfStoredAddress(unsigned LoadSize,
+                              SDOperand Ptr1, SDOperand Ptr2) const;
+ };
+ 
+ } // end namespace llvm
+ 
+ #endif
\ No newline at end of file


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.161 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.162
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.161	Wed Mar  1 01:14:48 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp	Tue Mar  7 00:32:48 2006
@@ -15,6 +15,7 @@
 #include "PPC.h"
 #include "PPCTargetMachine.h"
 #include "PPCISelLowering.h"
+#include "PPCHazardRecognizers.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/SSARegMap.h"
@@ -40,6 +41,7 @@
   class PPCDAGToDAGISel : public SelectionDAGISel {
     PPCTargetLowering PPCLowering;
     unsigned GlobalBaseReg;
+    PPCHazardRecognizer970 PPC970HR;
   public:
     PPCDAGToDAGISel(TargetMachine &TM)
       : SelectionDAGISel(PPCLowering), PPCLowering(TM) {}
@@ -122,13 +124,19 @@
     virtual const char *getPassName() const {
       return "PowerPC DAG->DAG Pattern Instruction Selection";
     } 
+    
+    /// GetTargetHazardRecognizer - Return the hazard recognizer to use for this
+    /// target when scheduling the DAG.
+    virtual HazardRecognizer &GetTargetHazardRecognizer() {
+      // Should use subtarget info to pick the right hazard recognizer.  For
+      // now, always return a PPC970 recognizer.
+      return PPC970HR; 
+    }
 
 // Include the pieces autogenerated from the target description.
 #include "PPCGenDAGISel.inc"
     
 private:
-    SDOperand SelectADD_PARTS(SDOperand Op);
-    SDOperand SelectSUB_PARTS(SDOperand Op);
     SDOperand SelectSETCC(SDOperand Op);
     SDOperand SelectCALL(SDOperand Op);
   };






More information about the llvm-commits mailing list