[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