getting newVariables in HSAILLIRGenerator

Deneau, Tom tom.deneau at
Sat Dec 7 10:10:33 PST 2013

Doug --

OK, I just assumed that a TEMP newVariable would never conflict with a USE variable in the same block.
So if I need a temp variable that never conflicts with any of the live variables in a block, how would I do that?
Would annotating the actionAndReason in this case as ALIVE solve my problem?

-- Tom

-----Original Message-----
From: Doug Simon [mailto:doug.simon at] 
Sent: Saturday, December 07, 2013 4:15 AM
To: Deneau, Tom
Cc: graal-dev at
Subject: Re: getting newVariables in HSAILLIRGenerator

Everything looks fine to me:

B22 <- B21,B20,B19,B18 [-1, -1]
_nr___st__instruction___________________________________________________________ (LIR)
 194      [] = LABEL align: false label: ?
 196      DEOPTIMIZE (x: -, actionAndReason: s0|i) {scratch64: d0|a, scratch32_1: s0|i, scratch32_2: s1|i} ...

s0|i is an input to DEOPTIMIZE and also a temp for the same instruction. This complies with the definition of @Use and @Temp (see OperandMode.USE and OperandMode.TEMP). You just need to ensure the usage of these registers in the code generated for DEOPTIMIZE always complies with this usage pattern.


On Dec 7, 2013, at 2:17 AM, Deneau, Tom <tom.deneau at> wrote:

> Doug --
> Here is the .cfg file.  B22 is the common deopt point, jumped to from B21, B19, B18, etc.  Each of those sets $s0 to a value corresponding to the actionAndReason.  The scratch register we allocate is also $s0.
> -- Tom
> -----Original Message-----
> From: Doug Simon [mailto:doug.simon at] 
> Sent: Friday, December 06, 2013 2:26 AM
> To: Deneau, Tom
> Cc: graal-dev at
> Subject: Re: getting newVariables in HSAILLIRGenerator
> Your use of the annotations for DeoptimizeOp look correct to me. What's makes you say that $s0 really is live at the deopt in your example? Unless the deopt takes the ClassCastException value as an input (which does not appear to be the case), then it's dead at the deopt (deopts are control flow sinks).
> If you're still having problems, please send me the c1visualizer log for the compilation of this method (i.e. -G:Dump= -G:MethodFilter=<qualified name of method>). You'll know what *.cfg file to send based on console output like this:
> CFGPrinter: Dumping method HotSpotMethod<String.hashCode()> to compilations-1386318229050_2.cfg
> -Doug
> On Dec 5, 2013, at 10:38 PM, Deneau, Tom <tom.deneau at> wrote:
>> We were playing around with hsail handling for a deoptimization node.
>> As part of the codegen for the deopt node, we needed a couple of scratch registers so in our LIRGenerator we have
>>   @Override
>>   public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) {
>>       Variable scratch64 = newVariable(Kind.Object); 
>>       Variable scratch32 = newVariable(Kind.Int); 
>>       append(new DeoptimizeOp(actionAndReason, deopting, getMetaAccess(), scratch64, scratch32));
>>   }
>> and inside our HSAIL DeooptimizeOp we have
>>       @Use({REG, CONST}) protected Value actionAndReason;
>>       protected DeoptimizingNode deopting;
>>       protected MetaAccessProvider metaAccessProvider;
>>       @Temp({REG}) private AllocatableValue scratch64;
>>       @Temp({REG}) private AllocatableValue scratch32;
>> However, maybe I am doing something wrong with the annotations because it seems that the register allocator will pick registers for scratch64, scratch32 that are really live.  For instance, sometimes the deopt node is jumped to from various locations with different codes as shown below. In this case, the compiler assigned scratch32 to be $s0, but that should be considered in use coming from the @L12 block.
>> @L12:
>> 	mov_b32 $s0, -35;	// ClassCastException
>> 	brn @L14;
>> @L14:
>> 	// Deoptimization for Variable Reason, scratch64=d0|a, scratch32=s0|i
>>      ... deoptimize codegen follows
>> -- Tom
> <>

More information about the graal-dev mailing list