Index: lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- lib/CodeGen/RegisterCoalescer.cpp +++ lib/CodeGen/RegisterCoalescer.cpp @@ -1338,6 +1338,12 @@ DEBUG(dbgs() << "Remat: " << NewMI); ++NumReMats; + // shrinkToUses has relative high cost. If there is other use of the SrcReg + // after CopyMI in MBB, it is unnecessary to update the live range. This + // can save a lot of compile time in some extreme cases. + if (SrcInt.liveAt(CopyIdx.getDeadSlot()) && !LIS->isLiveOutOfMBB(SrcInt, MBB)) + return true; + // The source interval can become smaller because we removed a use. shrinkToUses(&SrcInt, &DeadDefs); if (!DeadDefs.empty()) { Index: test/CodeGen/X86/only-necessary-shrink.mir =================================================================== --- test/CodeGen/X86/only-necessary-shrink.mir +++ test/CodeGen/X86/only-necessary-shrink.mir @@ -0,0 +1,86 @@ +# REQUIRES: asserts +# RUN: llc -run-pass simple-register-coalescing -mtriple=x86_64-gnu-unknown -debug-only=regalloc -o - %s 2>&1| FileCheck %s +--- | + target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + + declare void @hoo(i32) + + define internal void @foo() { + tail call void @hoo(i32 -343593632) + tail call void @hoo(i32 -343593632) + tail call void @hoo(i32 -343593632) + ret void + } + + define internal void @goo() { + %a = add i32 -343593632, 0 + br label %while.body + + while.body: ; preds = %while.body, %0 + tail call void @hoo(i32 -343593632) + br label %while.body + } + + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #0 + + attributes #0 = { nounwind } + +... +--- +name: foo +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } +frameInfo: + hasCalls: true +body: | + bb.0 (%ir-block.0): + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + %0:gr32 = MOV32ri -343593632 + $edi = COPY %0 + CALL64pcrel32 @hoo, csr_64, implicit $rsp, implicit $ssp, implicit killed $edi, implicit-def $rsp, implicit-def $ssp + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + $edi = COPY %0 + CALL64pcrel32 @hoo, csr_64, implicit $rsp, implicit $ssp, implicit killed $edi, implicit-def $rsp, implicit-def $ssp + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + $edi = COPY killed %0 + TCRETURNdi64 @hoo, 0, csr_64, implicit $rsp, implicit $ssp, implicit killed $edi + + ; Check only one shink operation happens and that shrink will lead to dead + ; def being deleted. + ; CHECK-LABEL: Function: foo + ; CHECK-NOT: Shrunk + ; CHECK: Shrunk + ; CHECK-NEXT: Deleting dead def + +... +--- +name: goo +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } +frameInfo: + hasCalls: true +body: | + bb.0 (%ir-block.0): + %0:gr32 = MOV32ri -343593632 + + bb.1.while.body: + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + $edi = COPY %0 + CALL64pcrel32 @hoo, csr_64, implicit $rsp, implicit $ssp, implicit killed $edi, implicit-def $rsp, implicit-def $ssp + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + JMP_1 %bb.1 + + ; Check one shink operation happens and that shrink will lead to dead + ; def being deleted. + ; CHECK-LABEL: Function: goo + ; CHECK-NOT: Shrunk + ; CHECK: Shrunk + ; CHECK-NEXT: Deleting dead def + +...