[llvm] r212215 - R600/SI: Adjsut SGPR live ranges before register allocation

Vincent Lejeune vljn at ovi.com
Tue Jul 29 10:41:38 PDT 2014


Hi,

If you add "LI.verify();" at the end of the inner most loop, a lot of tests fail because two consecutiv intervals can't have the same value. I tried to fix it by using "LI.addSegment(Seg.end, Next.Start, Seg.valno);" but then other tests fails because of register live outness inconsistencies. And I didn't success to fix that by adding all MBB following register definition to liverange either...
I'm trying to implement a machine scheduler for SI but I have a lot of test failures because of range check.


Vincent



Le Mercredi 2 juillet 2014 23h07, Tom Stellard <thomas.stellard at amd.com> a écrit :
 

>
>
>Author: tstellar
>Date: Wed Jul  2 15:53:48 2014
>New Revision: 212215
>
>URL: http://llvm.org/viewvc/llvm-project?rev=212215&view=rev
>Log:
>R600/SI: Adjsut SGPR live ranges before register allocation
>
>SGPRs are written by instructions that sometimes will ignore control flow,
>which means if you have code like:
>
>if (VGPR0) {
>  SGPR0 = S_MOV_B32 0
>} else {
>  SGPR0 = S_MOV_B32 1
>}
>
>The value of SGPR0 will 1 no matter what the condition is.
>
>In order to deal with this situation correctly, we need to view the
>program as if it were a single basic block when we calculate the
>live ranges for the SGPRs.  They way we actually update the live
>range is by iterating over all of the segments in each LiveRange
>object and setting the end of each segment equal to the start of
>the next segment.  So a live range like:
>
>[3888r,9312r:0)[10032B,10384B:0)  0 at 3888r
>
>will become:
>
>[3888r,10032B:0)[10032B,10384B:0)  0 at 3888r
>
>This change will allow us to use SALU instructions within branches.
>
>Added:
>    llvm/trunk/lib/Target/R600/SIFixSGPRLiveRanges.cpp
>Modified:
>    llvm/trunk/lib/Target/R600/AMDGPU.h
>    llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp
>    llvm/trunk/lib/Target/R600/CMakeLists.txt
>
>Modified: llvm/trunk/lib/Target/R600/AMDGPU.h
>URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPU.h?rev=212215&r1=212214&r2=212215&view=diff
>==============================================================================
>--- llvm/trunk/lib/Target/R600/AMDGPU.h (original)
>+++ llvm/trunk/lib/Target/R600/AMDGPU.h Wed Jul  2 15:53:48 2014
>@@ -41,6 +41,7 @@ FunctionPass *createSIAnnotateControlFlo
>FunctionPass *createSILowerI1CopiesPass();
>FunctionPass *createSILowerControlFlowPass(TargetMachine &tm);
>FunctionPass *createSIFixSGPRCopiesPass(TargetMachine &tm);
>+FunctionPass *createSIFixSGPRLiveRangesPass();
>FunctionPass *createSICodeEmitterPass(formatted_raw_ostream &OS);
>FunctionPass *createSIInsertWaits(TargetMachine &tm);
>
>@@ -56,6 +57,10 @@ FunctionPass *createAMDGPUISelDag(Target
>ImmutablePass *
>createAMDGPUTargetTransformInfoPass(const AMDGPUTargetMachine *TM);
>
>+void initializeSIFixSGPRLiveRangesPass(PassRegistry&);
>+extern char &SIFixSGPRLiveRangesID;
>+
>+
>extern Target TheAMDGPUTarget;
>
>} // End namespace llvm
>
>Modified: llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp
>URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp?rev=212215&r1=212214&r2=212215&view=diff
>==============================================================================
>--- llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp (original)
>+++ llvm/trunk/lib/Target/R600/AMDGPUTargetMachine.cpp Wed Jul  2 15:53:48 2014
>@@ -174,6 +174,8 @@ bool AMDGPUPassConfig::addPreRegAlloc()
>     // SIFixSGPRCopies can generate a lot of duplicate instructions,
>     // so we need to run MachineCSE afterwards.
>     addPass(&MachineCSEID);
>+    initializeSIFixSGPRLiveRangesPass(*PassRegistry::getPassRegistry());
>+    insertPass(&RegisterCoalescerID, &SIFixSGPRLiveRangesID);
>   }
>   return false;
>}
>
>Modified: llvm/trunk/lib/Target/R600/CMakeLists.txt
>URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/CMakeLists.txt?rev=212215&r1=212214&r2=212215&view=diff
>==============================================================================
>--- llvm/trunk/lib/Target/R600/CMakeLists.txt (original)
>+++ llvm/trunk/lib/Target/R600/CMakeLists.txt Wed Jul  2 15:53:48 2014
>@@ -40,6 +40,7 @@ add_llvm_target(R600CodeGen
>   R600TextureIntrinsicsReplacer.cpp
>   SIAnnotateControlFlow.cpp
>   SIFixSGPRCopies.cpp
>+  SIFixSGPRLiveRanges.cpp
>   SIInsertWaits.cpp
>   SIInstrInfo.cpp
>   SIISelLowering.cpp
>
>Added: llvm/trunk/lib/Target/R600/SIFixSGPRLiveRanges.cpp
>URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIFixSGPRLiveRanges.cpp?rev=212215&view=auto
>==============================================================================
>--- llvm/trunk/lib/Target/R600/SIFixSGPRLiveRanges.cpp (added)
>+++ llvm/trunk/lib/Target/R600/SIFixSGPRLiveRanges.cpp Wed Jul  2 15:53:48 2014
>@@ -0,0 +1,110 @@
>+//===-- SIFixSGPRLiveRanges.cpp - Fix SGPR live ranges ----------------------===//
>+//
>+//                     The LLVM Compiler Infrastructure
>+//
>+// This file is distributed under the University of Illinois Open Source
>+// License. See LICENSE.TXT for details.
>+//
>+//===----------------------------------------------------------------------===//
>+//
>+/// \file
>+/// SALU instructions ignore control flow, so we need to modify the live ranges
>+/// of the registers they define.
>+///
>+/// The strategy is to view the entire program as if it were a single basic
>+/// block and calculate the intervals accordingly.  We implement this
>+/// by walking this list of segments for each LiveRange and setting the
>+/// end of each segment equal to the start of the segment that immediately
>+/// follows it.
>+
>+#include "AMDGPU.h"
>+#include "SIRegisterInfo.h"
>+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
>+#include "llvm/CodeGen/MachineFunctionPass.h"
>+#include "llvm/CodeGen/MachineRegisterInfo.h"
>+#include "llvm/Support/Debug.h"
>+#include "llvm/Target/TargetMachine.h"
>+
>+using namespace llvm;
>+
>+#define DEBUG_TYPE "si-fix-sgpr-live-ranges"
>+
>+namespace {
>+
>+class SIFixSGPRLiveRanges : public MachineFunctionPass {
>+public:
>+  static char ID;
>+
>+public:
>+  SIFixSGPRLiveRanges() : MachineFunctionPass(ID) {
>+    initializeSIFixSGPRLiveRangesPass(*PassRegistry::getPassRegistry());
>+  }
>+
>+  virtual bool runOnMachineFunction(MachineFunction &MF) override;
>+
>+  virtual const char *getPassName() const override {
>+    return "SI Fix SGPR live ranges";
>+  }
>+
>+  virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
>+    AU.addRequired<LiveIntervals>();
>+    AU.addPreserved<LiveIntervals>();
>+    AU.addPreserved<SlotIndexes>();
>+    AU.setPreservesCFG();
>+    MachineFunctionPass::getAnalysisUsage(AU);
>+  }
>+};
>+
>+} // End anonymous namespace.
>+
>+INITIALIZE_PASS_BEGIN(SIFixSGPRLiveRanges, DEBUG_TYPE,
>+                      "SI Fix SGPR Live Ranges", false, false)
>+INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
>+INITIALIZE_PASS_END(SIFixSGPRLiveRanges, DEBUG_TYPE,
>+                    "SI Fix SGPR Live Ranges", false, false)
>+
>+char SIFixSGPRLiveRanges::ID = 0;
>+
>+char &llvm::SIFixSGPRLiveRangesID = SIFixSGPRLiveRanges::ID;
>+
>+FunctionPass *llvm::createSIFixSGPRLiveRangesPass() {
>+  return new SIFixSGPRLiveRanges();
>+}
>+
>+bool SIFixSGPRLiveRanges::runOnMachineFunction(MachineFunction &MF) {
>+  MachineRegisterInfo &MRI = MF.getRegInfo();
>+  const SIRegisterInfo *TRI = static_cast<const SIRegisterInfo *>(
>+      MF.getTarget().getRegisterInfo());
>+  LiveIntervals *LIS = &getAnalysis<LiveIntervals>();
>+
>+  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
>+                                                  BI != BE; ++BI) {
>+
>+    MachineBasicBlock &MBB = *BI;
>+    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
>+                                                      I != E; ++I) {
>+      MachineInstr &MI = *I;
>+      MachineOperand *ExecUse = MI.findRegisterUseOperand(AMDGPU::EXEC);
>+      if (ExecUse)
>+        continue;
>+
>+      for (const MachineOperand &Def : MI.operands()) {
>+        if (!Def.isReg() || !Def.isDef() ||!TargetRegisterInfo::isVirtualRegister(Def.getReg()))
>+          continue;
>+
>+        const TargetRegisterClass *RC = MRI.getRegClass(Def.getReg());
>+
>+        if (!TRI->isSGPRClass(RC))
>+          continue;
>+        LiveInterval &LI = LIS->getInterval(Def.getReg());
>+        for (unsigned i = 0, e = LI.size() - 1; i != e; ++i) {
>+          LiveRange::Segment &Seg = LI.segments[i];
>+          LiveRange::Segment &Next = LI.segments[i + 1];
>+          Seg.end = Next.start;
>+        }
>+      }
>+    }
>+  }
>+
>+  return false;
>+}
>
>
>_______________________________________________
>llvm-commits mailing list
>llvm-commits at cs.uiuc.edu
>http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140729/cd869ab5/attachment.html>


More information about the llvm-commits mailing list