
If a virtual register is not assigned preferred physical register, it means some COPY instructions will be changed to real register move instructions. In this case we can try to split the virtual register in colder blocks, if success, the original COPY instructions can be deleted, and the new COPY instructions in colder blocks will be generated as register move instructions. It results in fewer dynamic register move instructions executed. The new test case split-reg-with-hint.ll gives an example, the hot path contains 24 instructions without this patch, now it is only 4 instructions with this patch. Differential Revision: https://reviews.llvm.org/D156491
81 lines
2.9 KiB
LLVM
81 lines
2.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
|
|
; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s
|
|
|
|
; %ptr has a hint to %rdi in entry block, it also has a interference with %rdi
|
|
; in block if.then. It should be split in cold block if.then.
|
|
; Similarly %p2, %p3, %p4, %p5 and %p6 should also be split in cold block
|
|
; if.then.
|
|
|
|
define ptr @foo(ptr %ptr, i64 %p2, i64 %p3, i64 %p4, i64 %p5, i64 %p6) {
|
|
; CHECK-LABEL: foo:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: testq %rdi, %rdi
|
|
; CHECK-NEXT: je .LBB0_1
|
|
; CHECK-NEXT: # %bb.2: # %if.end
|
|
; CHECK-NEXT: incq %rdi
|
|
; CHECK-NEXT: jmp qux@PLT # TAILCALL
|
|
; CHECK-NEXT: .LBB0_1: # %if.then
|
|
; CHECK-NEXT: pushq %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: pushq %r14
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 24
|
|
; CHECK-NEXT: pushq %r13
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: pushq %r12
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 40
|
|
; CHECK-NEXT: pushq %rbx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-NEXT: .cfi_offset %rbx, -48
|
|
; CHECK-NEXT: .cfi_offset %r12, -40
|
|
; CHECK-NEXT: .cfi_offset %r13, -32
|
|
; CHECK-NEXT: .cfi_offset %r14, -24
|
|
; CHECK-NEXT: .cfi_offset %r15, -16
|
|
; CHECK-NEXT: movq %rsi, %rbx
|
|
; CHECK-NEXT: movq %rdx, %r14
|
|
; CHECK-NEXT: movq %rcx, %r15
|
|
; CHECK-NEXT: movq %r8, %r12
|
|
; CHECK-NEXT: movq %r9, %r13
|
|
; CHECK-NEXT: callq bar@PLT
|
|
; CHECK-NEXT: movq %rbx, %rsi
|
|
; CHECK-NEXT: movq %r14, %rdx
|
|
; CHECK-NEXT: movq %r15, %rcx
|
|
; CHECK-NEXT: movq %r12, %r8
|
|
; CHECK-NEXT: movq %r13, %r9
|
|
; CHECK-NEXT: movq %rax, %rdi
|
|
; CHECK-NEXT: popq %rbx
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 40
|
|
; CHECK-NEXT: popq %r12
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32
|
|
; CHECK-NEXT: popq %r13
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 24
|
|
; CHECK-NEXT: popq %r14
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: popq %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8
|
|
; CHECK-NEXT: .cfi_restore %rbx
|
|
; CHECK-NEXT: .cfi_restore %r12
|
|
; CHECK-NEXT: .cfi_restore %r13
|
|
; CHECK-NEXT: .cfi_restore %r14
|
|
; CHECK-NEXT: .cfi_restore %r15
|
|
; CHECK-NEXT: incq %rdi
|
|
; CHECK-NEXT: jmp qux@PLT # TAILCALL
|
|
entry:
|
|
%tobool.not = icmp eq ptr %ptr, null
|
|
br i1 %tobool.not, label %if.then, label %if.end, !prof !5
|
|
|
|
if.then: ; preds = %entry
|
|
%call = tail call ptr @bar(ptr %ptr, i64 %p2, i64 %p3, i64 %p4, i64 %p5, i64 %p6)
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %if.then, %entry
|
|
%ptr.addr.0 = phi ptr [ %call, %if.then ], [ %ptr, %entry ]
|
|
%incdec.ptr = getelementptr inbounds i8, ptr %ptr.addr.0, i64 1
|
|
%call2 = tail call ptr @qux(ptr %incdec.ptr, i64 %p2, i64 %p3, i64 %p4, i64 %p5, i64 %p6)
|
|
ret ptr %call2
|
|
}
|
|
|
|
!5 = !{!"branch_weights", i32 1, i32 2000}
|
|
|
|
declare ptr @bar(ptr, i64, i64, i64, i64, i64)
|
|
declare ptr @qux(ptr, i64, i64, i64, i64, i64)
|