makeAddress and large frame sizes

Tom Rodriguez tom.rodriguez at oracle.com
Tue Apr 29 17:38:26 UTC 2014


C2 has a bailout when emitting the spill.

    // Better yet would be some mechanism to handle variable-size matches correctly
    if (!Assembler::is_simm13(offset + STACK_BIAS)) {
      ra_->C->record_method_not_compilable("unable to handle large constant offsets");

C2’s register allocator allocates stack slots as if they were registers so the frames don’t tend to be as large because there’s a lot of reuse.  In 64 bit, I think biasing of SP also gives you greater effective reach, at least for the interesting part of the frame.

Interestingly the aarch64.ad doesn’t seem to have equivalent code.  http://hg.openjdk.java.net/aarch64-port/jdk8/hotspot/file/9d641fdeea4d/src/cpu/aarch64/vm/aarch64.ad  I can’t see where it’s handled at all.

That’s a pretty limited reach.  It can be hard to do a backend without at least one scratch register for reasons like this.  The hotspot aarch port has two.

// r8 is used for indirect result location return
// we use it and r9 as scratch registers
REGISTER_DECLARATION(Register, rscratch1, r8);
REGISTER_DECLARATION(Register, rscratch2, r9);

Have you managed to not have any scratch registers?

Actually I not sure it’s possible in general to do it without a scratch register.  If you allow every register to be used and you need to spill something to give you a temporary then where would its temporary come from?

tom

On Apr 29, 2014, at 9:39 AM, Doug Simon <doug.simon at oracle.com> wrote:

> How does C1 and C2 on SPARC handle this?
> 
> On Apr 29, 2014, at 4:49 PM, D.Sturm <D.Sturm42 at gmail.com> wrote:
> 
>> Hi,
>> This is a bit complicated, but I hope I can make the problem
>> comprehensible.
>> 
>> The Aarch64 ISA only allows a 9-bit signed unscaled offset added to a
>> register for memory accesses. Consequently for stacks that are larger than
>> 2^8 byte we have a problem when using AbstractAssembler.makeAddress to
>> access something on the stack with an offset larger than 256 bytes. (SPARC
>> seems to have the same problem and seems to just ignore the problem -
>> 13-bit signed offsets work fine for all JTT tests I guess)
>> 
>> I can solve that problem when loading values from the stack since I can use
>> the result register as a scratch register (and don't
>> use CompilationResultBuilder.asAddress but compute the stack offset myself).
>> 
>> But when storing values *into* the stack I really need to allocate a
>> temporary register if the offset is too large. Always allocating a scratch
>> register even if I only need it in case of a large stack and worse even for
>> reg->reg moves since I don't know whether the register allocator will
>> actually use a register for the destination and not a stackslot when
>> generating LIR instructions seems like a really unfortunate solution.
>> 
>> I was thinking I could specify a scratch register for all moves and then
>> in beforeRegisterAllocation() remove the load if I can guarantee that the
>> stack won't be too large (hard since I don't know how many registers the
>> register allocator will have to spill? some heuristic seems necessary).
>> 
>> Sounds reasonable or any problems with that approach? Or maybe some
>> completely different solution?
>> 
>> 
>> --Daniel
> 



More information about the graal-dev mailing list