Closed Quuxplusone closed 3 years ago
Bugzilla Link | PR46917 |
Status | RESOLVED FIXED |
Importance | P enhancement |
Reported by | listmail@philipreames.com |
Reported on | 2020-07-30 12:03:15 -0700 |
Last modified on | 2020-10-14 07:45:34 -0700 |
Version | trunk |
Hardware | PC Linux |
CC | dantrushin@gmail.com, llvm-bugs@lists.llvm.org |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
I've been assuming the following holds:
1. statepoint kills all OOPs; all pointers live across statepoint must be
relocated
2. gc.relocate relocate single pointer; in pair (base, derived) it relocates
second (derived) one.
From that I conclude that if base pointer is live across statepoint, it MUST
appear as (base, base) in gc args list.
I also think that all above means that from code generator point of view
(correctness),
in every single (base, derived) pair, base pointer is irrelevant to codegen.
It only is needed for (easier) generation of stack maps later.
All above means IMHO that
%1:gr64 = STATEPOINT 0, 0, 0, @foo, 2, 0, 2, 0, 2, 0, %0, %0(tied-def 0),
csr_64, implicit-def $rsp, implicit-def $ssp
is valid construct as long as tied operands are assigned to the same register
and that register is used past statepoint for %0. Even though I've never seen
this in practice,
I think it is OK for regalloc to assign untied %0 to something else (another
register or spill
slot) and possibly treat it read only, as you say.
Note that after SSA 'flattening' this will become
%0:gr64 = STATEPOINT 0, 0, 0, @foo, 2, 0, 2, 0, 2, 0, %0, %0(tied-def 0),
csr_64, implicit-def $rsp, implicit-def $ssp
I don't think regalloc is allowed to perform this assignment:
$r12 = STATEPOINT 0, 0, 0, @foo, 2, 0, 2, 0, 2, 0, $r12, $r13(tied-def 0),
csr_64, implicit-def $rsp, implicit-def $ssp
and this would be OK:
$r12 = STATEPOINT 0, 0, 0, @foo, 2, 0, 2, 0, 2, 0, $r13, $r12(tied-def 0),
csr_64, implicit-def $rsp, implicit-def $ssp
$r13 will (must) be dead after statepoint.
In practice, both %0 arguments are allocated to the same register.
As for
%1:gr64, %2:gr64 = STATEPOINT 0, 0, 0, @foo, 2, 0, 2, 0, 2, 0, %0(tied-def 0),
%0(tied-def 1), csr_64, implicit-def $rsp, implicit-def $ssp
how would it look like after regalloc?
I don't think the following is possible:
$r12, $r12 = STATEPOINT 0, 0, 0, @foo, 2, 0, 2, 0, 2, 0, $r12(tied-def 0),
$r12(tied-def 1), csr_64, implicit-def $rsp, implicit-def $ssp
(In reply to Denis Antrushin from comment #1)
> I also think that all above means that from code generator point of view
> (correctness),
> in every single (base, derived) pair, base pointer is irrelevant to codegen.
> It only is needed for (easier) generation of stack maps later.
This is the key mistake. This statement is false.
The base pointer must be available to the GC *during the call*. Think about a
dynamic trace which looks something like this:
call foo w/stackmap {reg, stackslot} // i.e. single base/derived
safepoint
safepoint
return from foo
At the safepoint, the GC will need to have available and update the base
pointer value. Without it, it can't correctly relocate the derived pointer.
D87154 fixes this problem by listing every pointer operand only once.
base/derived relation is enconded by following integer arguments (indices
into that pointer list)