Mesa (master): radeon/llvm: Eliminate CFGStructurizer dependency on AMDIL instructions

Tom Stellard tstellar at kemper.freedesktop.org
Fri Jun 1 16:24:55 UTC 2012


Module: Mesa
Branch: master
Commit: d6c2d3722d795381d3cdf11fe00f63780ad0725a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d6c2d3722d795381d3cdf11fe00f63780ad0725a

Author: Tom Stellard <thomas.stellard at amd.com>
Date:   Thu May 31 20:35:18 2012 -0400

radeon/llvm: Eliminate CFGStructurizer dependency on AMDIL instructions

Add some hooks to the R600,SI InstrInfo and RegisterInfo classes, so
that the CFGStructurizer pass can run without any relying on AMDIL
instructions.

---

 .../drivers/radeon/AMDILCFGStructurizer.cpp        |   93 +++++++++++---------
 src/gallium/drivers/radeon/AMDILInstrInfo.h        |    5 +
 src/gallium/drivers/radeon/AMDILRegisterInfo.h     |    5 +
 src/gallium/drivers/radeon/R600InstrInfo.cpp       |   16 ++++
 src/gallium/drivers/radeon/R600InstrInfo.h         |    6 +-
 src/gallium/drivers/radeon/R600RegisterInfo.cpp    |    8 ++
 src/gallium/drivers/radeon/R600RegisterInfo.h      |    4 +
 src/gallium/drivers/radeon/SIInstrInfo.cpp         |   11 +++
 src/gallium/drivers/radeon/SIInstrInfo.h           |    5 +
 src/gallium/drivers/radeon/SIRegisterInfo.cpp      |    8 ++
 src/gallium/drivers/radeon/SIRegisterInfo.h        |    4 +
 11 files changed, 124 insertions(+), 41 deletions(-)

diff --git a/src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp b/src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp
index e47c2d8..26559a0 100644
--- a/src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp
+++ b/src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp
@@ -11,6 +11,7 @@
 #define DEBUG_TYPE "structcfg"
 
 #include "AMDIL.h"
+#include "AMDILInstrInfo.h"
 #include "AMDILRegisterInfo.h"
 #include "AMDILUtilityFunctions.h"
 #include "llvm/ADT/SCCIterator.h"
@@ -295,10 +296,10 @@ public:
   ~CFGStructurizer();
 
   /// Perform the CFG structurization
-  bool run(FuncT &Func, PassT &Pass);
+  bool run(FuncT &Func, PassT &Pass, const AMDILRegisterInfo *tri);
 
   /// Perform the CFG preparation
-  bool prepare(FuncT &Func, PassT &Pass);
+  bool prepare(FuncT &Func, PassT &Pass, const AMDILRegisterInfo *tri);
 
 private:
   void   orderBlocks();
@@ -402,6 +403,7 @@ private:
   BlockInfoMap blockInfoMap;
   LoopLandInfoMap loopLandInfoMap;
   SmallVector<BlockT *, DEFAULT_VEC_SLOTS> orderedBlks;
+  const AMDILRegisterInfo *TRI;
 
 };  //template class CFGStructurizer
 
@@ -417,9 +419,11 @@ template<class PassT> CFGStructurizer<PassT>::~CFGStructurizer() {
 }
 
 template<class PassT>
-bool CFGStructurizer<PassT>::prepare(FuncT &func, PassT &pass) {
+bool CFGStructurizer<PassT>::prepare(FuncT &func, PassT &pass,
+                                     const AMDILRegisterInfo * tri) {
   passRep = &pass;
   funcRep = &func;
+  TRI = tri;
 
   bool changed = false;
   //func.RenumberBlocks();
@@ -504,9 +508,11 @@ bool CFGStructurizer<PassT>::prepare(FuncT &func, PassT &pass) {
 } //CFGStructurizer::prepare
 
 template<class PassT>
-bool CFGStructurizer<PassT>::run(FuncT &func, PassT &pass) {
+bool CFGStructurizer<PassT>::run(FuncT &func, PassT &pass,
+    const AMDILRegisterInfo * tri) {
   passRep = &pass;
   funcRep = &func;
+  TRI = tri;
 
   //func.RenumberBlocks();
 
@@ -1333,8 +1339,10 @@ int CFGStructurizer<PassT>::improveSimpleJumpintoIf(BlockT *headBlk,
   //      if (initReg !=2) {...}
   //
   // add initReg = initVal to headBlk
+
+  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
   unsigned initReg =
-    funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass);
+    funcRep->getRegInfo().createVirtualRegister(I32RC);
   if (!migrateTrue || !migrateFalse) {
     int initVal = migrateTrue ? 0 : 1;
     CFGTraits::insertAssignInstrBefore(headBlk, passRep, initReg, initVal);
@@ -1370,10 +1378,10 @@ int CFGStructurizer<PassT>::improveSimpleJumpintoIf(BlockT *headBlk,
 
   if (landBlkHasOtherPred) {
     unsigned immReg =
-      funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass);
+      funcRep->getRegInfo().createVirtualRegister(I32RC);
     CFGTraits::insertAssignInstrBefore(insertPos, passRep, immReg, 2);
     unsigned cmpResReg =
-      funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass);
+      funcRep->getRegInfo().createVirtualRegister(I32RC);
 
     CFGTraits::insertCompareInstrBefore(landBlk, insertPos, passRep, cmpResReg,
                                         initReg, immReg);
@@ -1439,11 +1447,12 @@ void CFGStructurizer<PassT>::handleLoopbreak(BlockT *exitingBlk,
     errs() << "Trying to break loop-depth = " << getLoopDepth(exitLoop)
            << " from loop-depth = " << getLoopDepth(exitingLoop) << "\n";
   }
+  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
 
   RegiT initReg = INVALIDREGNUM;
   if (exitingLoop != exitLoop) {
     initReg = static_cast<int>
-      (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass));
+      (funcRep->getRegInfo().createVirtualRegister(I32RC));
     assert(initReg != INVALIDREGNUM);
     addLoopBreakInitReg(exitLoop, initReg);
     while (exitingLoop != exitLoop && exitingLoop) {
@@ -1472,9 +1481,10 @@ void CFGStructurizer<PassT>::handleLoopcontBlock(BlockT *contingBlk,
   }
 
   RegiT initReg = INVALIDREGNUM;
+  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
   if (contingLoop != contLoop) {
     initReg = static_cast<int>
-      (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass));
+      (funcRep->getRegInfo().createVirtualRegister(I32RC));
     assert(initReg != INVALIDREGNUM);
     addLoopContInitReg(contLoop, initReg);
     while (contingLoop && contingLoop->getParentLoop() != contLoop) {
@@ -1862,10 +1872,12 @@ typename CFGStructurizer<PassT>::BlockT *
 CFGStructurizer<PassT>::addLoopEndbranchBlock(LoopT *loopRep,
                                               BlockTSmallerVector &exitingBlks,
                                               BlockTSmallerVector &exitBlks) {
-  const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
+  const AMDILInstrInfo *tii =
+             static_cast<const AMDILInstrInfo *>(passRep->getTargetInstrInfo());
+  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
 
   RegiT endBranchReg = static_cast<int>
-    (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass));
+    (funcRep->getRegInfo().createVirtualRegister(I32RC));
   assert(endBranchReg >= 0);
 
   // reg = 0 before entering the loop
@@ -1925,14 +1937,16 @@ CFGStructurizer<PassT>::addLoopEndbranchBlock(LoopT *loopRep,
 
   DebugLoc DL;
   RegiT preValReg = static_cast<int>
-    (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass));
-  BuildMI(preBranchBlk, DL, tii->get(AMDIL::LOADCONST_i32), preValReg)
-    .addImm(i - 1); //preVal
+    (funcRep->getRegInfo().createVirtualRegister(I32RC));
+
+  preBranchBlk->insert(preBranchBlk->begin(),
+                       tii->getMovImmInstr(preBranchBlk->getParent(), preValReg,
+                       i - 1));
 
   // condResReg = (endBranchReg == preValReg)
     RegiT condResReg = static_cast<int>
-      (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass));
-    BuildMI(preBranchBlk, DL, tii->get(AMDIL::IEQ), condResReg)
+      (funcRep->getRegInfo().createVirtualRegister(I32RC));
+    BuildMI(preBranchBlk, DL, tii->get(tii->getIEQOpcode()), condResReg)
       .addReg(endBranchReg).addReg(preValReg);
 
     BuildMI(preBranchBlk, DL, tii->get(AMDIL::BRANCH_COND_i32))
@@ -2136,6 +2150,7 @@ CFGStructurizer<PassT>::normalizeInfiniteLoopExit(LoopT* LoopRep) {
   loopHeader = LoopRep->getHeader();
   loopLatch = LoopRep->getLoopLatch();
   BlockT *dummyExitBlk = NULL;
+  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
   if (loopHeader!=NULL && loopLatch!=NULL) {
     InstrT *branchInstr = CFGTraits::getLoopendBlockBranchInstr(loopLatch);
     if (branchInstr!=NULL && CFGTraits::isUncondBranch(branchInstr)) {
@@ -2148,7 +2163,7 @@ CFGStructurizer<PassT>::normalizeInfiniteLoopExit(LoopT* LoopRep) {
       typename BlockT::iterator insertPos =
         CFGTraits::getInstrPos(loopLatch, branchInstr);
       unsigned immReg =
-        funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass);
+        funcRep->getRegInfo().createVirtualRegister(I32RC);
       CFGTraits::insertAssignInstrBefore(insertPos, passRep, immReg, 1);
       InstrT *newInstr = 
         CFGTraits::insertInstrBefore(insertPos, AMDIL::BRANCH_COND_i32, passRep);
@@ -2615,12 +2630,11 @@ public:
   typedef MachinePostDominatorTree  PostDominatortreeType;
   typedef MachineDomTreeNode        DomTreeNodeType;
   typedef MachineLoop               LoopType;
-//private:
+
+protected:
   TargetMachine &TM;
   const TargetInstrInfo *TII;
-
-//public:
-//  static char ID;
+  const AMDILRegisterInfo *TRI;
 
 public:
   AMDILCFGStructurizer(char &pid, TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
@@ -2635,7 +2649,9 @@ private:
 } //end of namespace llvm
 AMDILCFGStructurizer::AMDILCFGStructurizer(char &pid, TargetMachine &tm
                                            AMDIL_OPT_LEVEL_DECL)
-: MachineFunctionPass(pid), TM(tm), TII(tm.getInstrInfo()) {
+: MachineFunctionPass(pid), TM(tm), TII(tm.getInstrInfo()),
+  TRI(static_cast<const AMDILRegisterInfo *>(tm.getRegisterInfo())
+  ) {
 }
 
 const TargetInstrInfo *AMDILCFGStructurizer::getTargetInstrInfo() const {
@@ -3071,14 +3087,11 @@ struct CFGStructTraits<AMDILCFGStructurizer>
                                       AMDILCFGStructurizer *passRep,
                                       RegiT regNum, int regVal) {
     MachineInstr *oldInstr = &(*instrPos);
-    const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
+    const AMDILInstrInfo *tii =
+             static_cast<const AMDILInstrInfo *>(passRep->getTargetInstrInfo());
     MachineBasicBlock *blk = oldInstr->getParent();
-    MachineInstr *newInstr =
-      blk->getParent()->CreateMachineInstr(tii->get(AMDIL::LOADCONST_i32),
-                                           DebugLoc());
-    MachineInstrBuilder(newInstr).addReg(regNum, RegState::Define); //set target
-    MachineInstrBuilder(newInstr).addImm(regVal); //set src value
-
+    MachineInstr *newInstr = tii->getMovImmInstr(blk->getParent(), regNum,
+                                                 regVal);
     blk->insert(instrPos, newInstr);
 
     SHOWNEWINSTR(newInstr);
@@ -3087,14 +3100,11 @@ struct CFGStructTraits<AMDILCFGStructurizer>
   static void insertAssignInstrBefore(MachineBasicBlock *blk,
                                       AMDILCFGStructurizer *passRep,
                                       RegiT regNum, int regVal) {
-    const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
-
-    MachineInstr *newInstr =
-      blk->getParent()->CreateMachineInstr(tii->get(AMDIL::LOADCONST_i32),
-                                           DebugLoc());
-    MachineInstrBuilder(newInstr).addReg(regNum, RegState::Define); //set target
-    MachineInstrBuilder(newInstr).addImm(regVal); //set src value
+    const AMDILInstrInfo *tii =
+             static_cast<const AMDILInstrInfo *>(passRep->getTargetInstrInfo());
 
+    MachineInstr *newInstr = tii->getMovImmInstr(blk->getParent(), regNum,
+                                                 regVal);
     if (blk->begin() != blk->end()) {
       blk->insert(blk->begin(), newInstr);
     } else {
@@ -3110,9 +3120,10 @@ struct CFGStructTraits<AMDILCFGStructurizer>
                                        AMDILCFGStructurizer *passRep,
                                        RegiT dstReg, RegiT src1Reg,
                                        RegiT src2Reg) {
-    const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
+    const AMDILInstrInfo *tii =
+             static_cast<const AMDILInstrInfo *>(passRep->getTargetInstrInfo());
     MachineInstr *newInstr =
-      blk->getParent()->CreateMachineInstr(tii->get(AMDIL::IEQ), DebugLoc());
+      blk->getParent()->CreateMachineInstr(tii->get(tii->getIEQOpcode()), DebugLoc());
 
     MachineInstrBuilder(newInstr).addReg(dstReg, RegState::Define); //set target
     MachineInstrBuilder(newInstr).addReg(src1Reg); //set src value
@@ -3212,7 +3223,8 @@ FunctionPass *llvm::createAMDILCFGPreparationPass(TargetMachine &tm
 
 bool AMDILCFGPrepare::runOnMachineFunction(MachineFunction &func) {
   return llvmCFGStruct::CFGStructurizer<AMDILCFGStructurizer>().prepare(func,
-                                                                        *this);
+                                                                        *this,
+                                                                        TRI);
 }
 
 // createAMDILCFGStructurizerPass- Returns a pass
@@ -3223,7 +3235,8 @@ FunctionPass *llvm::createAMDILCFGStructurizerPass(TargetMachine &tm
 
 bool AMDILCFGPerform::runOnMachineFunction(MachineFunction &func) {
   return llvmCFGStruct::CFGStructurizer<AMDILCFGStructurizer>().run(func,
-                                                                    *this);
+                                                                    *this,
+                                                                    TRI);
 }
 
 //end of file newline goes below
diff --git a/src/gallium/drivers/radeon/AMDILInstrInfo.h b/src/gallium/drivers/radeon/AMDILInstrInfo.h
index 6aa03e7..211c881 100644
--- a/src/gallium/drivers/radeon/AMDILInstrInfo.h
+++ b/src/gallium/drivers/radeon/AMDILInstrInfo.h
@@ -147,6 +147,11 @@ public:
   bool isLocalAtomic(llvm::MachineInstr *MI) const;
   bool isGlobalAtomic(llvm::MachineInstr *MI) const;
   bool isArenaAtomic(llvm::MachineInstr *MI) const;
+
+  virtual MachineInstr * getMovImmInstr(MachineFunction *MF, unsigned DstReg,
+                                        int64_t Imm) const = 0;
+
+  virtual unsigned getIEQOpcode() const = 0;
 };
 
 }
diff --git a/src/gallium/drivers/radeon/AMDILRegisterInfo.h b/src/gallium/drivers/radeon/AMDILRegisterInfo.h
index 7627bde..4bfb9a7 100644
--- a/src/gallium/drivers/radeon/AMDILRegisterInfo.h
+++ b/src/gallium/drivers/radeon/AMDILRegisterInfo.h
@@ -80,6 +80,11 @@ namespace llvm
 
     int64_t
       getStackSize() const;
+
+    virtual const TargetRegisterClass * getCFGStructurizerRegClass(MVT VT)
+                                                                      const {
+      return AMDIL::GPRI32RegisterClass;
+    }
     private:
     mutable int64_t baseOffset;
     mutable int64_t nextFuncOffset;
diff --git a/src/gallium/drivers/radeon/R600InstrInfo.cpp b/src/gallium/drivers/radeon/R600InstrInfo.cpp
index 9915357..05c291f 100644
--- a/src/gallium/drivers/radeon/R600InstrInfo.cpp
+++ b/src/gallium/drivers/radeon/R600InstrInfo.cpp
@@ -100,3 +100,19 @@ unsigned R600InstrInfo::getLSHRop() const
     return AMDIL::LSHR_eg;
   }
 }
+
+MachineInstr * R600InstrInfo::getMovImmInstr(MachineFunction *MF,
+                                             unsigned DstReg, int64_t Imm) const
+{
+  MachineInstr * MI = MF->CreateMachineInstr(get(AMDIL::MOV), DebugLoc());
+  MachineInstrBuilder(MI).addReg(DstReg, RegState::Define);
+  MachineInstrBuilder(MI).addReg(AMDIL::ALU_LITERAL_X);
+  MachineInstrBuilder(MI).addImm(Imm);
+
+  return MI;
+}
+
+unsigned R600InstrInfo::getIEQOpcode() const
+{
+  return AMDIL::SETE_INT;
+}
diff --git a/src/gallium/drivers/radeon/R600InstrInfo.h b/src/gallium/drivers/radeon/R600InstrInfo.h
index 9dca483..2b5e5c4 100644
--- a/src/gallium/drivers/radeon/R600InstrInfo.h
+++ b/src/gallium/drivers/radeon/R600InstrInfo.h
@@ -47,7 +47,11 @@ namespace llvm {
   unsigned getLSHRop() const;
   unsigned getASHRop() const;
 
-  };
+  virtual MachineInstr * getMovImmInstr(MachineFunction *MF, unsigned DstReg,
+                                        int64_t Imm) const;
+
+  virtual unsigned getIEQOpcode() const;
+};
 
 } // End llvm namespace
 
diff --git a/src/gallium/drivers/radeon/R600RegisterInfo.cpp b/src/gallium/drivers/radeon/R600RegisterInfo.cpp
index de559bd..ad6deab 100644
--- a/src/gallium/drivers/radeon/R600RegisterInfo.cpp
+++ b/src/gallium/drivers/radeon/R600RegisterInfo.cpp
@@ -94,4 +94,12 @@ unsigned R600RegisterInfo::getHWRegChan(unsigned reg) const
   }
 }
 
+const TargetRegisterClass * R600RegisterInfo::getCFGStructurizerRegClass(
+                                                                   MVT VT) const
+{
+  switch(VT.SimpleTy) {
+  default:
+  case MVT::i32: return AMDIL::R600_TReg32RegisterClass;
+  }
+}
 #include "R600HwRegInfo.include"
diff --git a/src/gallium/drivers/radeon/R600RegisterInfo.h b/src/gallium/drivers/radeon/R600RegisterInfo.h
index 7525a97..4ed831a 100644
--- a/src/gallium/drivers/radeon/R600RegisterInfo.h
+++ b/src/gallium/drivers/radeon/R600RegisterInfo.h
@@ -42,6 +42,10 @@ struct R600RegisterInfo : public AMDGPURegisterInfo
   /// getHWRegChan - get the HW encoding for a register's channel.
   unsigned getHWRegChan(unsigned reg) const;
 
+  /// getCFGStructurizerRegClass - get the register class of the specified
+  /// type to use in the CFGStructurizer
+  virtual const TargetRegisterClass * getCFGStructurizerRegClass(MVT VT) const;
+
 private:
   /// getHWRegIndexGen - Generated function returns a register's encoding
   unsigned getHWRegIndexGen(unsigned reg) const;
diff --git a/src/gallium/drivers/radeon/SIInstrInfo.cpp b/src/gallium/drivers/radeon/SIInstrInfo.cpp
index 4ee3e5d..cd4e227 100644
--- a/src/gallium/drivers/radeon/SIInstrInfo.cpp
+++ b/src/gallium/drivers/radeon/SIInstrInfo.cpp
@@ -105,3 +105,14 @@ unsigned SIInstrInfo::getISAOpcode(unsigned AMDILopcode) const
   default: return AMDILopcode;
   }
 }
+
+MachineInstr * SIInstrInfo::getMovImmInstr(MachineFunction *MF, unsigned DstReg,
+                                           int64_t Imm) const
+{
+  MachineInstr * MI = MF->CreateMachineInstr(get(AMDIL::V_MOV_IMM), DebugLoc());
+  MachineInstrBuilder(MI).addReg(DstReg, RegState::Define);
+  MachineInstrBuilder(MI).addImm(Imm);
+
+  return MI;
+
+}
diff --git a/src/gallium/drivers/radeon/SIInstrInfo.h b/src/gallium/drivers/radeon/SIInstrInfo.h
index 0614638..996dcee 100644
--- a/src/gallium/drivers/radeon/SIInstrInfo.h
+++ b/src/gallium/drivers/radeon/SIInstrInfo.h
@@ -51,6 +51,11 @@ public:
   /// returns an equivalent SI opcode.
   virtual unsigned getISAOpcode(unsigned AMDILopcode) const;
 
+  virtual MachineInstr * getMovImmInstr(MachineFunction *MF, unsigned DstReg,
+                                        int64_t Imm) const;
+
+  virtual unsigned getIEQOpcode() const { assert(!"Implement"); return 0;}
+
   };
 
 } // End namespace llvm
diff --git a/src/gallium/drivers/radeon/SIRegisterInfo.cpp b/src/gallium/drivers/radeon/SIRegisterInfo.cpp
index 04e2e17..2abe688 100644
--- a/src/gallium/drivers/radeon/SIRegisterInfo.cpp
+++ b/src/gallium/drivers/radeon/SIRegisterInfo.cpp
@@ -53,4 +53,12 @@ SIRegisterInfo::getISARegClass(const TargetRegisterClass * rc) const
   }
 }
 
+const TargetRegisterClass * SIRegisterInfo::getCFGStructurizerRegClass(
+                                                                   MVT VT) const
+{
+  switch(VT.SimpleTy) {
+    default:
+    case MVT::i32: return AMDIL::VReg_32RegisterClass;
+  }
+}
 #include "SIRegisterGetHWRegNum.inc"
diff --git a/src/gallium/drivers/radeon/SIRegisterInfo.h b/src/gallium/drivers/radeon/SIRegisterInfo.h
index 949a1e2..99005cb 100644
--- a/src/gallium/drivers/radeon/SIRegisterInfo.h
+++ b/src/gallium/drivers/radeon/SIRegisterInfo.h
@@ -43,6 +43,10 @@ struct SIRegisterInfo : public AMDGPURegisterInfo
   /// a register
   unsigned getHWRegNum(unsigned reg) const;
 
+  /// getCFGStructurizerRegClass - get the register class of the specified
+  /// type to use in the CFGStructurizer
+  virtual const TargetRegisterClass * getCFGStructurizerRegClass(MVT VT) const;
+
 };
 
 } // End namespace llvm




More information about the mesa-commit mailing list