radeon/llvm: Use the VLIW Scheduler for R600->NI
authorTom Stellard <thomas.stellard@amd.com>
Tue, 19 Jun 2012 22:47:18 +0000 (18:47 -0400)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 21 Jun 2012 20:42:06 +0000 (20:42 +0000)
It's not optimal, but it's better than the register pressure scheduler
that was previously being used.  The VLIW scheduler currently ignores
all the complicated instruction groups restrictions and just tries to
fill the instruction groups with as many instructions as possible.
Though, it does know enough not to put two trans only instructions in
the same group.

We are able to ignore the instruction group restrictions in the LLVM
backend, because the finalizer in r600_asm.c will fix any illegal
instruction groups the backend generates.

Enabling the VLIW scheduler improved the run time for a sha1 compute
shader by about 50%.  I'm not sure what the impact will be for graphics
shaders.  I tested Lightsmark with the VLIW scheduler enabled and the
framerate was about the same, but it might help apps that use really
big shaders.

12 files changed:
src/gallium/drivers/radeon/AMDGPUInstructions.td
src/gallium/drivers/radeon/AMDGPUSubtarget.h [new file with mode: 0644]
src/gallium/drivers/radeon/AMDGPUTargetMachine.cpp
src/gallium/drivers/radeon/AMDGPUTargetMachine.h
src/gallium/drivers/radeon/AMDILBase.td
src/gallium/drivers/radeon/AMDILFormats.td
src/gallium/drivers/radeon/Makefile
src/gallium/drivers/radeon/Makefile.sources
src/gallium/drivers/radeon/R600ISelLowering.cpp
src/gallium/drivers/radeon/R600InstrInfo.cpp
src/gallium/drivers/radeon/R600InstrInfo.h
src/gallium/drivers/radeon/R600Schedule.td

index 9ec9c4d0356ec0108d9455892d26b26fbbe1e9e0..d6897d57060eaa400cc3f01b7548e8f60ca7657b 100644 (file)
@@ -21,6 +21,7 @@ class AMDGPUInst <dag outs, dag ins, string asm, list<dag> pattern> : Instructio
   let InOperandList = ins;
   let AsmString = asm;
   let Pattern = pattern;
+  let Itinerary = NullALU;
   let TSFlags{42-40} = Gen;
   let TSFlags{63-48} = AMDILOp;
 }
diff --git a/src/gallium/drivers/radeon/AMDGPUSubtarget.h b/src/gallium/drivers/radeon/AMDGPUSubtarget.h
new file mode 100644 (file)
index 0000000..96ace88
--- /dev/null
@@ -0,0 +1,36 @@
+//=====-- AMDGPUSubtarget.h - Define Subtarget for the AMDIL ---*- C++ -*-====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//==-----------------------------------------------------------------------===//
+//
+// This file declares the AMDGPU specific subclass of TargetSubtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _AMDGPUSUBTARGET_H_
+#define _AMDGPUSUBTARGET_H_
+#include "AMDILSubtarget.h"
+
+namespace llvm {
+
+class AMDGPUSubtarget : public AMDILSubtarget
+{
+  InstrItineraryData InstrItins;
+
+public:
+  AMDGPUSubtarget(StringRef TT, StringRef CPU, StringRef FS) :
+    AMDILSubtarget(TT, CPU, FS)
+  {
+    InstrItins = getInstrItineraryForCPU(CPU);
+  }
+
+  const InstrItineraryData &getInstrItineraryData() const { return InstrItins; }
+};
+
+} // End namespace llvm
+
+#endif // AMDGPUSUBTARGET_H_
index c6a2412f970c665142c389a9cdc4aa83896d81bb..7b199f170286ecd9a3c4b51098268daebfcfee4c 100644 (file)
@@ -50,6 +50,7 @@ AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT,
   FrameLowering(TargetFrameLowering::StackGrowsUp,
       Subtarget.device()->getStackAlignment(), 0),
   IntrinsicInfo(this),
+  InstrItins(&Subtarget.getInstrItineraryData()),
   mDump(false)
 
 {
index 84a1ea330d3fc18f2d019cca03d072a5690f0eb6..b419a6f33f2ec9db8f5363eeb7122cfe3d0deaaa 100644 (file)
@@ -15,9 +15,9 @@
 #define AMDGPU_TARGET_MACHINE_H
 
 #include "AMDGPUInstrInfo.h"
+#include "AMDGPUSubtarget.h"
 #include "AMDILFrameLowering.h"
 #include "AMDILIntrinsicInfo.h"
-#include "AMDILSubtarget.h"
 #include "R600ISelLowering.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/Target/TargetData.h"
@@ -28,12 +28,13 @@ MCAsmInfo* createMCAsmInfo(const Target &T, StringRef TT);
 
 class AMDGPUTargetMachine : public LLVMTargetMachine {
 
-  AMDILSubtarget Subtarget;
+  AMDGPUSubtarget Subtarget;
   const TargetData DataLayout;
   AMDILFrameLowering FrameLowering;
   AMDILIntrinsicInfo IntrinsicInfo;
   const AMDGPUInstrInfo * InstrInfo;
   AMDGPUTargetLowering * TLInfo;
+  const InstrItineraryData* InstrItins;
   bool mDump;
 
 public:
@@ -50,13 +51,16 @@ public:
      return &IntrinsicInfo;
    }
    virtual const AMDGPUInstrInfo *getInstrInfo() const {return InstrInfo;}
-   virtual const AMDILSubtarget *getSubtargetImpl() const {return &Subtarget; }
+   virtual const AMDGPUSubtarget *getSubtargetImpl() const {return &Subtarget; }
    virtual const AMDGPURegisterInfo *getRegisterInfo() const {
       return &InstrInfo->getRegisterInfo();
    }
    virtual AMDGPUTargetLowering * getTargetLowering() const {
       return TLInfo;
    }
+   virtual const InstrItineraryData* getInstrItineraryData() const {
+      return InstrItins;
+   }
    virtual const TargetData* getTargetData() const { return &DataLayout; }
    virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
    virtual bool addPassesToEmitFile(PassManagerBase &PM,
index 31ebed31d726f2ae33148af7c81b1102cb85f0be..8a2d34a63244108936a21ea5e89dbae5b0dc59ba 100644 (file)
 
 include "llvm/Target/Target.td"
 
+// Dummy Instruction itineraries for pseudo instructions
+def ALU_NULL : FuncUnit;
+def NullALU : InstrItinClass;
+
 //===----------------------------------------------------------------------===//
 // AMDIL Subtarget features.
 //===----------------------------------------------------------------------===//
index 25ca9a01019aa01fc85618462558dbccbe524444..5418c645a5352563b0538d350e1740a66384db72 100644 (file)
@@ -25,6 +25,7 @@ class ILFormat<ILOpCode op, dag outs, dag ins, string asmstr, list<dag> pattern>
      let Pattern = pattern;
      let AsmString = !strconcat(asmstr, "\n");
      let isPseudo = 1;
+     let Itinerary = NullALU;
      bit hasIEEEFlag = 0;
      bit hasZeroOpFlag = 0;
 }
index 955c41e575e0fa57d3c9fe721adf9514e7eb1921..ced202f331523edd63e33a1ac8752afafcb39fab 100644 (file)
@@ -65,6 +65,9 @@ AMDGPUGenIntrinsics.inc: *.td
 AMDGPUGenCodeEmitter.inc: *.td
        $(call tablegen, -gen-emitter, AMDGPU.td, $@)
 
+AMDGPUGenDFAPacketizer.inc: *.td
+       $(call tablegen, -gen-dfa-packetizer, AMDGPU.td, $@)
+
 LOADER_LIBS=$(shell llvm-config --libs bitreader asmparser)
 loader: loader.o libradeon.a
        gcc -o loader -L/usr/local/lib $(LDFLAGS) loader.o libradeon.a $(LLVM_LIBS) $(LOADER_LIBS) -lpthread -ldl -lstdc++ -lm
index b5665ce95f34cccd62deeed92731e9b0db531270..fc7b6520377d4e0082c34cc63316b9388191015d 100644 (file)
@@ -12,7 +12,8 @@ GENERATED_SOURCES := \
        AMDGPUGenSubtargetInfo.inc              \
        AMDGPUGenEDInfo.inc             \
        AMDGPUGenIntrinsics.inc         \
-       AMDGPUGenCodeEmitter.inc
+       AMDGPUGenCodeEmitter.inc        \
+       AMDGPUGenDFAPacketizer.inc
 
 CPP_SOURCES := \
        AMDIL7XXDevice.cpp              \
index bb034beeb33b454cd102dbb70a7683c77531df8f..3e021a23dbb37f85cd77c4d76b2db53964c196e3 100644 (file)
@@ -25,7 +25,6 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
     TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo()))
 {
   setOperationAction(ISD::MUL, MVT::i64, Expand);
-//  setSchedulingPreference(Sched::VLIW);
   addRegisterClass(MVT::v4f32, &AMDIL::R600_Reg128RegClass);
   addRegisterClass(MVT::f32, &AMDIL::R600_Reg32RegClass);
   addRegisterClass(MVT::v4i32, &AMDIL::R600_Reg128RegClass);
@@ -34,6 +33,7 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
 
   setOperationAction(ISD::FSUB, MVT::f32, Expand);
 
+  setSchedulingPreference(Sched::VLIW);
 }
 
 MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
index d1246d3e0ff279b00979fdfd9f8e88138a16d6e6..e11c0bd60f744cdceaa792ba366894126157a952 100644 (file)
 
 #include "R600InstrInfo.h"
 #include "AMDGPUTargetMachine.h"
+#include "AMDILSubtarget.h"
 #include "R600RegisterInfo.h"
 
+#define GET_INSTRINFO_CTOR
+#include "AMDGPUGenDFAPacketizer.inc"
+
 using namespace llvm;
 
 R600InstrInfo::R600InstrInfo(AMDGPUTargetMachine &tm)
@@ -92,3 +96,10 @@ bool R600InstrInfo::isMov(unsigned Opcode) const
     return true;
   }
 }
+
+DFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM,
+    const ScheduleDAG *DAG) const
+{
+  const InstrItineraryData *II = TM->getInstrItineraryData();
+  return TM->getSubtarget<AMDILSubtarget>().createDFAPacketizer(II);
+}
index f2a1098a40bbfbd042127673bae7543ec4d160b3..b9cbcc81a5e9e96aa24d6b1b3bfc387424f55792 100644 (file)
@@ -23,6 +23,8 @@
 namespace llvm {
 
   class AMDGPUTargetMachine;
+  class DFAPacketizer;
+  class ScheduleDAG;
   class MachineFunction;
   class MachineInstr;
   class MachineInstrBuilder;
@@ -52,6 +54,9 @@ namespace llvm {
 
   virtual unsigned getIEQOpcode() const;
   virtual bool isMov(unsigned Opcode) const;
+
+  DFAPacketizer *CreateTargetScheduleState(const TargetMachine *TM,
+                                           const ScheduleDAG *DAG) const;
 };
 
 } // End llvm namespace
index d1957903d879e19d8e6385042106e3ddec0d6dbb..7ede181c51dc9104e12aef1eb98b15affb9d280b 100644 (file)
@@ -20,17 +20,17 @@ def ALU_Z : FuncUnit;
 def ALU_W : FuncUnit;
 def TRANS : FuncUnit;
 
-
 def AnyALU : InstrItinClass;
 def VecALU : InstrItinClass;
 def TransALU : InstrItinClass;
 
 def R600_EG_Itin : ProcessorItineraries <
-  [ALU_X, ALU_Y, ALU_Z, ALU_W, TRANS],
+  [ALU_X, ALU_Y, ALU_Z, ALU_W, TRANS, ALU_NULL],
   [],
   [
     InstrItinData<AnyALU, [InstrStage<1, [ALU_X, ALU_Y, ALU_Z, ALU_W, TRANS]>]>,
     InstrItinData<VecALU, [InstrStage<1, [ALU_X, ALU_Y, ALU_X, ALU_W]>]>,
-    InstrItinData<TransALU, [InstrStage<1, [TRANS]>]>
+    InstrItinData<TransALU, [InstrStage<1, [TRANS]>]>,
+    InstrItinData<NullALU, [InstrStage<1, [ALU_NULL]>]>
   ]
 >;