[llvm] r339912 - [RegisterCoalescer] Shrink to uses if needed after removeCopyByCommutingDef
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 16 11:02:59 PDT 2018
Author: kparzysz
Date: Thu Aug 16 11:02:59 2018
New Revision: 339912
URL: http://llvm.org/viewvc/llvm-project?rev=339912&view=rev
Log:
[RegisterCoalescer] Shrink to uses if needed after removeCopyByCommutingDef
Added:
llvm/trunk/test/CodeGen/SystemZ/subregliveness-05.ll
Modified:
llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
Modified: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp?rev=339912&r1=339911&r2=339912&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Thu Aug 16 11:02:59 2018
@@ -226,8 +226,12 @@ namespace {
/// If the source value number is defined by a commutable instruction and
/// its other operand is coalesced to the copy dest register, see if we
/// can transform the copy into a noop by commuting the definition.
- /// This returns true if an interval was modified.
- bool removeCopyByCommutingDef(const CoalescerPair &CP,MachineInstr *CopyMI);
+ /// This returns a pair of two flags:
+ /// - the first element is true if an interval was modified,
+ /// - the second element is true if the destination interval needs
+ /// to be shrunk after deleting the copy.
+ std::pair<bool,bool> removeCopyByCommutingDef(const CoalescerPair &CP,
+ MachineInstr *CopyMI);
/// We found a copy which can be moved to its less frequent predecessor.
bool removePartialRedundancy(const CoalescerPair &CP, MachineInstr &CopyMI);
@@ -686,20 +690,32 @@ bool RegisterCoalescer::hasOtherReaching
/// Copy segments with value number @p SrcValNo from liverange @p Src to live
/// range @Dst and use value number @p DstValNo there.
-static bool addSegmentsWithValNo(LiveRange &Dst, VNInfo *DstValNo,
- const LiveRange &Src, const VNInfo *SrcValNo) {
+static std::pair<bool,bool>
+addSegmentsWithValNo(LiveRange &Dst, VNInfo *DstValNo, const LiveRange &Src,
+ const VNInfo *SrcValNo) {
bool Changed = false;
+ bool MergedWithDead = false;
for (const LiveRange::Segment &S : Src.segments) {
if (S.valno != SrcValNo)
continue;
- Dst.addSegment(LiveRange::Segment(S.start, S.end, DstValNo));
+ // This is adding a segment from Src that ends in a copy that is about
+ // to be removed. This segment is going to be merged with a pre-existing
+ // segment in Dst. This works, except in cases when the corresponding
+ // segment in Dst is dead. For example: adding [192r,208r:1) from Src
+ // to [208r,208d:1) in Dst would create [192r,208d:1) in Dst.
+ // Recognized such cases, so that the segments can be shrunk.
+ LiveRange::Segment Added = LiveRange::Segment(S.start, S.end, DstValNo);
+ LiveRange::Segment &Merged = *Dst.addSegment(Added);
+ if (Merged.end.isDead())
+ MergedWithDead = true;
Changed = true;
}
- return Changed;
+ return std::make_pair(Changed, MergedWithDead);
}
-bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
- MachineInstr *CopyMI) {
+std::pair<bool,bool>
+RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
+ MachineInstr *CopyMI) {
assert(!CP.isPhys());
LiveInterval &IntA =
@@ -737,19 +753,19 @@ bool RegisterCoalescer::removeCopyByComm
VNInfo *AValNo = IntA.getVNInfoAt(CopyIdx.getRegSlot(true));
assert(AValNo && !AValNo->isUnused() && "COPY source not live");
if (AValNo->isPHIDef())
- return false;
+ return { false, false };
MachineInstr *DefMI = LIS->getInstructionFromIndex(AValNo->def);
if (!DefMI)
- return false;
+ return { false, false };
if (!DefMI->isCommutable())
- return false;
+ return { false, false };
// If DefMI is a two-address instruction then commuting it will change the
// destination register.
int DefIdx = DefMI->findRegisterDefOperandIdx(IntA.reg);
assert(DefIdx != -1);
unsigned UseOpIdx;
if (!DefMI->isRegTiedToUseOperand(DefIdx, &UseOpIdx))
- return false;
+ return { false, false };
// FIXME: The code below tries to commute 'UseOpIdx' operand with some other
// commutable operand which is expressed by 'CommuteAnyOperandIndex'value
@@ -762,17 +778,17 @@ bool RegisterCoalescer::removeCopyByComm
// op#2<->op#3) of commute transformation should be considered/tried here.
unsigned NewDstIdx = TargetInstrInfo::CommuteAnyOperandIndex;
if (!TII->findCommutedOpIndices(*DefMI, UseOpIdx, NewDstIdx))
- return false;
+ return { false, false };
MachineOperand &NewDstMO = DefMI->getOperand(NewDstIdx);
unsigned NewReg = NewDstMO.getReg();
if (NewReg != IntB.reg || !IntB.Query(AValNo->def).isKill())
- return false;
+ return { false, false };
// Make sure there are no other definitions of IntB that would reach the
// uses which the new definition can reach.
if (hasOtherReachingDefs(IntA, IntB, AValNo, BValNo))
- return false;
+ return { false, false };
// If some of the uses of IntA.reg is already coalesced away, return false.
// It's not possible to determine whether it's safe to perform the coalescing.
@@ -785,7 +801,7 @@ bool RegisterCoalescer::removeCopyByComm
continue;
// If this use is tied to a def, we can't rewrite the register.
if (UseMI->isRegTiedToDefOperand(OpNo))
- return false;
+ return { false, false };
}
LLVM_DEBUG(dbgs() << "\tremoveCopyByCommutingDef: " << AValNo->def << '\t'
@@ -797,11 +813,11 @@ bool RegisterCoalescer::removeCopyByComm
MachineInstr *NewMI =
TII->commuteInstruction(*DefMI, false, UseOpIdx, NewDstIdx);
if (!NewMI)
- return false;
+ return { false, false };
if (TargetRegisterInfo::isVirtualRegister(IntA.reg) &&
TargetRegisterInfo::isVirtualRegister(IntB.reg) &&
!MRI->constrainRegClass(IntB.reg, MRI->getRegClass(IntA.reg)))
- return false;
+ return { false, false };
if (NewMI != DefMI) {
LIS->ReplaceMachineInstrInMaps(*DefMI, *NewMI);
MachineBasicBlock::iterator Pos = DefMI;
@@ -875,6 +891,7 @@ bool RegisterCoalescer::removeCopyByComm
// Extend BValNo by merging in IntA live segments of AValNo. Val# definition
// is updated.
+ bool ShrinkB = false;
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
if (IntA.hasSubRanges() || IntB.hasSubRanges()) {
if (!IntA.hasSubRanges()) {
@@ -890,26 +907,30 @@ bool RegisterCoalescer::removeCopyByComm
assert(ASubValNo != nullptr);
IntB.refineSubRanges(Allocator, SA.LaneMask,
- [&Allocator,&SA,CopyIdx,ASubValNo](LiveInterval::SubRange &SR) {
+ [&Allocator,&SA,CopyIdx,ASubValNo,&ShrinkB]
+ (LiveInterval::SubRange &SR) {
VNInfo *BSubValNo = SR.empty()
? SR.getNextValue(CopyIdx, Allocator)
: SR.getVNInfoAt(CopyIdx);
assert(BSubValNo != nullptr);
- if (addSegmentsWithValNo(SR, BSubValNo, SA, ASubValNo))
+ auto P = addSegmentsWithValNo(SR, BSubValNo, SA, ASubValNo);
+ ShrinkB |= P.second;
+ if (P.first)
BSubValNo->def = ASubValNo->def;
});
}
}
BValNo->def = AValNo->def;
- addSegmentsWithValNo(IntB, BValNo, IntA, AValNo);
+ auto P = addSegmentsWithValNo(IntB, BValNo, IntA, AValNo);
+ ShrinkB |= P.second;
LLVM_DEBUG(dbgs() << "\t\textended: " << IntB << '\n');
LIS->removeVRegDefAt(IntA, AValNo->def);
LLVM_DEBUG(dbgs() << "\t\ttrimmed: " << IntA << '\n');
++numCommutes;
- return true;
+ return { true, ShrinkB };
}
/// For copy B = A in BB2, if A is defined by A = B in BB0 which is a
@@ -1795,9 +1816,18 @@ bool RegisterCoalescer::joinCopy(Machine
// If we can eliminate the copy without merging the live segments, do so
// now.
if (!CP.isPartial() && !CP.isPhys()) {
- if (adjustCopiesBackFrom(CP, CopyMI) ||
- removeCopyByCommutingDef(CP, CopyMI)) {
+ bool Changed = adjustCopiesBackFrom(CP, CopyMI);
+ bool Shrink = false;
+ if (!Changed)
+ std::tie(Changed, Shrink) = removeCopyByCommutingDef(CP, CopyMI);
+ if (Changed) {
deleteInstr(CopyMI);
+ if (Shrink) {
+ unsigned DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg();
+ LiveInterval &DstLI = LIS->getInterval(DstReg);
+ shrinkToUses(&DstLI);
+ LLVM_DEBUG(dbgs() << "\t\tshrunk: " << DstLI << '\n');
+ }
LLVM_DEBUG(dbgs() << "\tTrivial!\n");
return true;
}
Added: llvm/trunk/test/CodeGen/SystemZ/subregliveness-05.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/subregliveness-05.ll?rev=339912&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/subregliveness-05.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/subregliveness-05.ll Thu Aug 16 11:02:59 2018
@@ -0,0 +1,48 @@
+; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z10 -verify-machineinstrs -systemz-subreg-liveness < %s | FileCheck %s
+
+; Check for successful compilation.
+; CHECK: lgfrl %r1, g_65
+
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"
+target triple = "s390x-ibm-linux"
+
+ at g_65 = external global i32, align 4
+
+; Function Attrs: nounwind
+define void @main() #0 {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb
+ %tmp = load i32, i32* @g_65, align 4
+ %tmp2 = sext i32 %tmp to i64
+ %tmp3 = shl i32 %tmp, 16
+ %tmp4 = ashr exact i32 %tmp3, 16
+ %tmp5 = shl i32 %tmp4, 0
+ %tmp6 = zext i32 %tmp5 to i64
+ %tmp7 = shl i64 %tmp6, 48
+ %tmp8 = ashr exact i64 %tmp7, 48
+ br i1 undef, label %bb12, label %bb9
+
+bb9: ; preds = %bb1
+ %tmp10 = select i1 undef, i64 0, i64 %tmp2
+ %tmp11 = add nsw i64 %tmp10, %tmp8
+ br label %bb12
+
+bb12: ; preds = %bb9, %bb1
+ %tmp13 = phi i64 [ %tmp11, %bb9 ], [ %tmp8, %bb1 ]
+ %tmp14 = trunc i64 %tmp13 to i32
+ %tmp15 = and i32 %tmp14, 255
+ %tmp16 = shl i32 %tmp15, 0
+ %tmp17 = trunc i32 %tmp16 to i8
+ %tmp18 = icmp eq i8 %tmp17, 0
+ br i1 %tmp18, label %bb20, label %bb19
+
+bb19: ; preds = %bb12
+ unreachable
+
+bb20: ; preds = %bb12
+ unreachable
+}
+
+attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="z10" "unsafe-fp-math"="false" "use-soft-float"="false" }
More information about the llvm-commits
mailing list