Re: guardIfConstant, the constant sniffer combinator

2019-04-11 Thread Remi Forax
- Mail original -
> De: "John Rose" 
> À: "Da Vinci Machine Project" 
> Cc: "valhalla-dev" 
> Envoyé: Jeudi 11 Avril 2019 00:08:07
> Objet: Re: guardIfConstant, the constant sniffer combinator

> This is very similar to a "growable switch" combinator,
> which would call the provider for each distinct selector
> value.  A key difference is that non-constant values
> go through the fallback, where a "growable switch"
> doesn't need a fallback, since the provider MH is
> always free to just return a standard fallback as
> its result (as is the case with your combinator).
> 
> I wonder if the concepts can be combined somehow?

They are clearly related.
I'm trying to avoid the shared pairs of constant/target you need to maintain 
for a "growable switch" combinator by pushing these states neare to the 
generated assembly code where the inlining tree is resolved. 

> 
> Here's a test question:  When the JIT, after heroic
> effort, discovers that an argument is constant, can
> it run the provider (in the compiler thread???) to
> determine a custom handler for the newly discovered
> branch of constant code?  The answer is probably,
> "sorry, no", although the JIT might set up an uncommon
> trap (and/or an execution counter) that can revisit
> the question at some point.

yes,
the idea is to revisit later, my hope is that it can work well with tiered 
compilation or if there is only one JIT, to force a recompilation after some 
time.

> 
> Here's a close point of correspondence between the
> idea of a growable switch and your combinator:  Both
> need a memory.  Both want to remember the appearance
> of constants, so a later optimization phase can use the
> full historical knowledge.

yes !
and my hope is that we don't need a shared memory for that.   

> 
> — John

Rémi

> 
>> On Apr 10, 2019, at 2:47 PM, Remi Forax  wrote:
>> 
>> The problem is the following,
>> with the java compiler intrinsic of amber, String.format() is optimized using
>> invokedynamic in the case the format (the first argument) is constant (and 
>> some
>> other conditions on the format), this is great, perf are like 25x in simple
>> benchmarks, and that all because in a lot of code, the format is not constant
>> for the Java compiler.
>> 
>> By example,
>>  class Logger {
>>public static void log(String format, String message) {
>>  System.err.println(String.format(format, message));
>>}
>>  }
>>  ...
>>  logger.log("%s", "hello");
>> 
>> The format is not a constant inside Logger::log for the Java compiler but 
>> when
>> the code is JITed, due to inlining, logger.log("hello") calls String.format()
>> with a constant.
>> 
>> 
>> I propose a way to fix that, by providing a method handle combiner
>> (guardIfConstant) that detects if an argument is a constant and do something
>> different if it's a constant or not.
>> It's a little more complex than that, we don't only want to have a separate 
>> path
>> if the argument is a constant, we also want to be able to build a method 
>> handle
>> tree depending on the value of that constant.
>> 
>>  MethodHandle guardIfConstant(int argument, MethodHandle targetProvider,
>>  MethodHandle fallback)
>> 
>> the semantics: if the nth argument is a constant, the target provider is 
>> called
>> with that argument and the return value, a method handle, is called with all
>> the arguments, otherwise the fallback is called.
>> 
>> in term of method type:
>>  - the method type of the return value of guardIfConstant is the same as 
>> fallback
>>  - the method type of targetProvider returns a MethodHandle and takes a 
>> single
>>  parameter which is the nth parameter type of the fallback method type,
>>the returned method handle as to have the same method type as the 
>> fallback.
>> 
>> Rémi
>> 
>> ___
>> mlvm-dev mailing list
>> mlvm-dev@openjdk.java.net
> > https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: guardIfConstant, the constant sniffer combinator

2019-04-10 Thread John Rose
This is very similar to a "growable switch" combinator,
which would call the provider for each distinct selector
value.  A key difference is that non-constant values
go through the fallback, where a "growable switch"
doesn't need a fallback, since the provider MH is
always free to just return a standard fallback as
its result (as is the case with your combinator).

I wonder if the concepts can be combined somehow?

Here's a test question:  When the JIT, after heroic
effort, discovers that an argument is constant, can
it run the provider (in the compiler thread???) to
determine a custom handler for the newly discovered
branch of constant code?  The answer is probably,
"sorry, no", although the JIT might set up an uncommon
trap (and/or an execution counter) that can revisit
the question at some point.

Here's a close point of correspondence between the
idea of a growable switch and your combinator:  Both
need a memory.  Both want to remember the appearance
of constants, so a later optimization phase can use the
full historical knowledge.

— John

> On Apr 10, 2019, at 2:47 PM, Remi Forax  wrote:
> 
> The problem is the following,
> with the java compiler intrinsic of amber, String.format() is optimized using 
> invokedynamic in the case the format (the first argument) is constant (and 
> some other conditions on the format), this is great, perf are like 25x in 
> simple benchmarks, and that all because in a lot of code, the format is not 
> constant for the Java compiler. 
> 
> By example,
>  class Logger {
>public static void log(String format, String message) {
>  System.err.println(String.format(format, message));
>}
>  }
>  ...
>  logger.log("%s", "hello");
> 
> The format is not a constant inside Logger::log for the Java compiler but 
> when the code is JITed, due to inlining, logger.log("hello") calls 
> String.format() with a constant.
> 
> 
> I propose a way to fix that, by providing a method handle combiner 
> (guardIfConstant) that detects if an argument is a constant and do something 
> different if it's a constant or not.
> It's a little more complex than that, we don't only want to have a separate 
> path if the argument is a constant, we also want to be able to build a method 
> handle tree depending on the value of that constant.
> 
>  MethodHandle guardIfConstant(int argument, MethodHandle targetProvider, 
> MethodHandle fallback)
> 
> the semantics: if the nth argument is a constant, the target provider is 
> called with that argument and the return value, a method handle, is called 
> with all the arguments, otherwise the fallback is called.
> 
> in term of method type:
>  - the method type of the return value of guardIfConstant is the same as 
> fallback
>  - the method type of targetProvider returns a MethodHandle and takes a 
> single parameter which is the nth parameter type of the fallback method type,
>the returned method handle as to have the same method type as the fallback.
> 
> Rémi
> 
> ___
> mlvm-dev mailing list
> mlvm-dev@openjdk.java.net
> https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


guardIfConstant, the constant sniffer combinator

2019-04-10 Thread Remi Forax
The problem is the following,
with the java compiler intrinsic of amber, String.format() is optimized using 
invokedynamic in the case the format (the first argument) is constant (and some 
other conditions on the format), this is great, perf are like 25x in simple 
benchmarks, and that all because in a lot of code, the format is not constant 
for the Java compiler. 

By example,
  class Logger {
public static void log(String format, String message) {
  System.err.println(String.format(format, message));
}
  }
  ...
  logger.log("%s", "hello");

The format is not a constant inside Logger::log for the Java compiler but when 
the code is JITed, due to inlining, logger.log("hello") calls String.format() 
with a constant.


I propose a way to fix that, by providing a method handle combiner 
(guardIfConstant) that detects if an argument is a constant and do something 
different if it's a constant or not.
It's a little more complex than that, we don't only want to have a separate 
path if the argument is a constant, we also want to be able to build a method 
handle tree depending on the value of that constant.

  MethodHandle guardIfConstant(int argument, MethodHandle targetProvider, 
MethodHandle fallback)

the semantics: if the nth argument is a constant, the target provider is called 
with that argument and the return value, a method handle, is called with all 
the arguments, otherwise the fallback is called.

in term of method type:
  - the method type of the return value of guardIfConstant is the same as 
fallback
  - the method type of targetProvider returns a MethodHandle and takes a single 
parameter which is the nth parameter type of the fallback method type,
the returned method handle as to have the same method type as the fallback.

Rémi

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev