Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RegAllocFast] properly handle STATEPOINT instruction.
STATEPOINT is a fancy and complex pseudo instruction which has both tied defs and regmask operand. Basic FastRA algorithm is as follows: 1. Mark registers used by defs as free 2. If instruction has regmask operand displace clobbered registers according to regmask. 3. Assign registers for use operands. In case of tied defs step 1 is replaced with allocation of registers for them. But regmask is still processed, which may displace already allocated registers. As a result, tied use and def will get assigned to different registers. This patch makes FastRA to process instruction's RegMask (if any) when checking for physical registers interference. That way tied operands won't get registers clobbered by regmask. Reviewed By: arsenm, skatkov Differential Revision: https://reviews.llvm.org/D99284
- Loading branch information
1 parent
3b87383
commit df47368
Showing
2 changed files
with
66 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# RUN: llc -mtriple=x86_64-- -run-pass=regallocfast -o - %s | FileCheck %s | ||
|
||
# Check that fastregalloc does not displace register assigned to tied def when | ||
# RegMask operand is present. STATEPOINT is an example of such instruction. | ||
# Tied def/use must be assigned to the same register. | ||
--- | ||
name: test_relocate | ||
tracksRegLiveness: true | ||
body: | | ||
bb.0.entry: | ||
liveins: $rdi | ||
; CHECK: renamable [[REG:\$[a-z0-9]+]] = STATEPOINT 0, 0, 0, target-flags(x86-plt) 0, 2, 0, 2, 0, 2, 0, 2, 1, renamable [[REG]](tied-def 0) | ||
%1:gr64 = COPY $rdi | ||
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp | ||
%1:gr64 = STATEPOINT 0, 0, 0, target-flags(x86-plt) 0, 2, 0, 2, 0, 2, 0, 2, 1, %1(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, 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 | ||
$rax = COPY %1 | ||
RET 0, killed $rax | ||
... | ||
|
||
# Same as above but with multiple RegMask operands per instruction. | ||
# These regmasks have no real meaning and chosen to allow only single register to be assignable ($r12) | ||
--- | ||
name: test_relocate_multi_regmasks | ||
tracksRegLiveness: true | ||
body: | | ||
bb.0.entry: | ||
liveins: $rdi | ||
; CHECK: renamable $r12 = STATEPOINT 0, 0, 0, target-flags(x86-plt) 0, 2, 0, 2, 0, 2, 0, 2, 1, renamable $r12(tied-def 0) | ||
%1:gr64 = COPY $rdi | ||
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp | ||
%1:gr64 = STATEPOINT 0, 0, 0, target-flags(x86-plt) 0, 2, 0, 2, 0, 2, 0, 2, 1, %1(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64_rt_allregs, csr_64_hhvm, 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 | ||
$rax = COPY %1 | ||
RET 0, killed $rax | ||
... |