From: Krzysztof Parzyszek Date: Thu, 16 Aug 2018 18:02:59 +0000 (+0000) Subject: [RegisterCoalescer] Shrink to uses if needed after removeCopyByCommutingDef X-Git-Tag: llvmorg-8.0.0-rc1~10841 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=17143f6111af47146ff1782729ec4f74fc2733f6;p=platform%2Fupstream%2Fllvm.git [RegisterCoalescer] Shrink to uses if needed after removeCopyByCommutingDef llvm-svn: 339912 --- diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index e33429b..a9cec3f 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -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 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::hasOtherReachingDefs(LiveInterval &IntA, /// 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 +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 +RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP, + MachineInstr *CopyMI) { assert(!CP.isPhys()); LiveInterval &IntA = @@ -737,19 +753,19 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP, 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::removeCopyByCommutingDef(const CoalescerPair &CP, // 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::removeCopyByCommutingDef(const CoalescerPair &CP, 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::removeCopyByCommutingDef(const CoalescerPair &CP, 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::removeCopyByCommutingDef(const CoalescerPair &CP, // 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::removeCopyByCommutingDef(const CoalescerPair &CP, 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(MachineInstr *CopyMI, bool &Again) { // 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; } diff --git a/llvm/test/CodeGen/SystemZ/subregliveness-05.ll b/llvm/test/CodeGen/SystemZ/subregliveness-05.ll new file mode 100644 index 0000000..9aba18f --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/subregliveness-05.ll @@ -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" + +@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" }