HSAIL (tests) and inlining issue

Doug Simon doug.simon at oracle.com
Tue Jun 17 19:00:57 UTC 2014


On Jun 17, 2014, at 6:49 PM, Deneau, Tom <tom.deneau at amd.com> wrote:

> 
> 
>> -----Original Message-----
>> From: Doug Simon [mailto:doug.simon at oracle.com]
>> Sent: Tuesday, June 17, 2014 10:45 AM
>> To: Deneau, Tom
>> Cc: Caspole, Eric; graal-dev at openjdk.java.net
>> Subject: Re: HSAIL (tests) and inlining issue
>> 
>> 
>> On Jun 17, 2014, at 5:32 PM, Deneau, Tom <tom.deneau at amd.com> wrote:
>> 
>>> Doug --
>>> 
>>> I didn't understand the relation between resolving
>> StringIndexOutOfBoundsException and inlining String.equals().
>> 
>> In
>> com.oracle.graal.compiler.hsail.test.lambda.NewStringEqualsTest.runTest(
>> ) we have the following:
>> 
>>        dispatchLambdaKernel(NUM, (gid) -> {
>>            outArray[gid] = new String(chars, 0, 10 + (gid %
>> 3)).equals(base);
>>        });
>> 
>> The String(char[], int, int) constructor called above contains:
>> 
>>        if (count < 0) {
>>            throw new StringIndexOutOfBoundsException(count);
>>        }
>> 
>> When RemoveNeverExecutedCode == false, then the 'then' branch will be
>> compiled. If StringIndexOutOfBoundsException is unresolved, the
>> allocation of StringIndexOutOfBoundsException is converted to a deopt.
>> If it's resolved, then InlineEverything==true ensure it is inlined. This
>> constructor (indirectly) recursively calls String(char[], int, int). The
>> inliner performs recursive inlining until it hits
>> GraalOptions.MaximumDesiredSize which means it never gets to inline
>> String.equals.
>> 
>>> I'm trying to remember why we disabled RemoveNeverExecutedCode.  I
>> think it was because our junits often don't run enough times in java
>> mode to get valid profiling information so we might need code even if it
>> was previously never executed.
>> 
>> You could make the unit tests run in Java mode in a loop long enough to
>> get the desired profile.
>> 
> 
> Agreed. If the profile runs long enough, we can trust it and deopt on the paths that weren't executed and get rid of -G:-RemoveNeverExecutedCode.  And I guess if we do find something deopting we can always try to recompile.
> 
> We'll try to plan out some way to deal with this.
> 
>>> I need to think more about your suggestion of InlineOrDeopt.  While
>> this would allow a test to pass functionally, we wouldn't want to
>> actually offload a kernel where there was a deoptimization on the main
>> compilation path.
>> 
>> Won't the profile gathered for the kernel prior to compilation be
>> accurate in most cases?
> 
> Yes as mentioned above, if it runs long enough we should be able to trust it for removing never-executed code, etc.  But what about an actual recursive method in the main path?  We can't inline that, so we would deopt but it would be a poor offload candidate if it de-opted on the main code path.

This concern applies to normal (i.e. non-offloaded) code as well so whatever strategy the inliner takes for hot recursive calls should work as well for HSAIL code. That said, giving that the cost of deopting is higher for offload code, we may want to be able to parameterize the inlining strategy with a multiplier for the relative cost of an uncommon trap. Thomas is currently working on the new inlining implementation and may be able to comment on other ways recursive calls will be handled.

-Doug

>>>> -----Original Message-----
>>>> From: Doug Simon [mailto:doug.simon at oracle.com]
>>>> Sent: Tuesday, June 17, 2014 10:03 AM
>>>> To: Caspole, Eric; Deneau, Tom
>>>> Cc: graal-dev at openjdk.java.net
>>>> Subject: HSAIL (tests) and inlining issue
>>>> 
>>>> Eric, Tom,
>>>> 
>>>> We've had issues on our gate recently caused by intermittent failures
>>>> of NewStringEqualsTest (stack trace below). If
>>>> StringIndexOutOfBoundsException is resolved before this test is run,
>>>> then inlining exhausts its budget before getting to inline
>>>> String.equals which in turn leaves a direct call in the graph,
>>>> something that HSAIL cannot currently handle. The primary problem is
>>>> the use of InlineEverything and RemoveNeverExecutedCode in the HSAIL
>>>> tests. As we've seen, these don't actually guarantee everything will
>> be inlined.
>>>> 
>>>> For now, I've disabled NewStringEqualsTest and added a comment as to
>>>> why. I'm not sure what the longer term solution is. I'd at least like
>>>> to see RemoveNeverExecutedCode go away - do we really need it?
>>>> 
>>>> Now that HSAIL supports deopt, maybe we can change InlineEverything
>>>> to InlineEverythingOrDeopt - calls that cannot be inlined are replace
>>>> with DopetimizeNodes.
>>>> 
>>>> -Doug
>>>> 
>>>> 
>>>> 2)
>>>> testUsingLambdaMethod(com.oracle.graal.compiler.hsail.test.lambda.New
>>>> Str
>>>> ingEqualsTest)
>>>> com.oracle.graal.graph.GraalGraphInternalError:
>>>> com.oracle.graal.compiler.common.GraalInternalError: unimplemented:
>>>> direct call to java.lang.String.equals(Object)
>>>> 	at node: 110|Invoke#Direct#String.equals
>>>> 	at
>>>> com.oracle.graal.graph.GraalGraphInternalError.transformAndAddContext
>>>> (Gr
>>>> aalGraphInternalError.java:136)
>>>> 	at
>>>> com.oracle.graal.compiler.gen.NodeLIRBuilder.doBlock(NodeLIRBuilder.j
>>>> ava
>>>> :220)
>>>> 	at
>>>> com.oracle.graal.compiler.GraalCompiler.emitBlock(GraalCompiler.java:
>>>> 216
>>>> )
>>>> 	at
>>>> 
>> com.oracle.graal.compiler.GraalCompiler.emitLIR(GraalCompiler.java:250)
>>>> 	at
>>>> com.oracle.graal.compiler.GraalCompiler.emitBackEnd(GraalCompiler.jav
>>>> a:1
>>>> 98)
>>>> 	at
>>>> 
>> com.oracle.graal.compiler.GraalCompiler.compileGraph(GraalCompiler.java:
>>>> 141)
>>>> 	at
>>>> com.oracle.graal.hotspot.hsail.HSAILHotSpotBackend.compileKernel(HSAI
>>>> LHo
>>>> tSpotBackend.java:195)
>>>> 	at
>>>> com.oracle.graal.hotspot.hsail.HSAILHotSpotBackend.compileAndInstallK
>>>> ern
>>>> el(HSAILHotSpotBackend.java:153)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester.dispatch
>>>> Ker
>>>> nelOkra(GraalKernelTester.java:163)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.infra.KernelTester.dispatchLambd
>>>> aMe
>>>> thodKernelOkra(KernelTester.java:598)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.infra.KernelTester.dispatchLambd
>>>> aMe
>>>> thodKernel(KernelTester.java:279)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.infra.KernelTester.dispatchLambd
>>>> aKe
>>>> rnel(KernelTester.java:301)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.lambda.NewStringEqualsTest.runTe
>>>> st(
>>>> NewStringEqualsTest.java:55)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.infra.KernelTester.runOkraInstan
>>>> ce(
>>>> KernelTester.java:666)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.infra.KernelTester.assertOkraEqu
>>>> als
>>>> Seq(KernelTester.java:656)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.infra.KernelTester.testGenerated
>>>> Hsa
>>>> ilUsingLambdaMethod(KernelTester.java:683)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester.testGene
>>>> rat
>>>> edHsailUsingLambdaMethod(GraalKernelTester.java:206)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.test.lambda.NewStringEqualsTest.testU
>>>> sin
>>>> gLambdaMethod(NewStringEqualsTest.java:76)
>>>> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>> 	at
>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
>>>> jav
>>>> a:62)
>>>> 	at
>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
>>>> sor
>>>> Impl.java:43)
>>>> 	at java.lang.reflect.Method.invoke(Method.java:483)
>>>> 	at
>>>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(Framework
>>>> Met
>>>> hod.java:47)
>>>> 	at
>>>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCal
>>>> lab
>>>> le.java:12)
>>>> 	at
>>>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMe
>>>> tho
>>>> d.java:44)
>>>> 	at
>>>> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMet
>>>> hod
>>>> .java:17)
>>>> 	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
>>>> 	at
>>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRun
>>>> ner
>>>> .java:70)
>>>> 	at
>>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRun
>>>> ner
>>>> .java:50)
>>>> 	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
>>>> 	at
>>>> org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
>>>> 	at
>>>> org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
>>>> 	at
>>>> org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
>>>> 	at
>>>> org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
>>>> 	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
>>>> 	at org.junit.runners.Suite.runChild(Suite.java:127)
>>>> 	at org.junit.runners.Suite.runChild(Suite.java:26)
>>>> 	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
>>>> 	at
>>>> org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
>>>> 	at org.junit.runn
>>>> ers.ParentRunner.runChildren(ParentRunner.java:236)
>>>> 	at
>>>> org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
>>>> 	at
>>>> org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
>>>> 	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
>>>> 	at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
>>>> 	at org.junit.runner.JUnitCore.run(JUnitCore.java:138)
>>>> 	at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
>>>> 	at
>>>> com.oracle.graal.test.GraalJUnitCore.main(GraalJUnitCore.java:102)
>>>> 	at JUnitWrapper.main(JUnitWrapper.java:78)
>>>> Caused by: com.oracle.graal.compiler.common.GraalInternalError:
>>>> unimplemented: direct call to java.lang.String.equals(Object)
>>>> 	at
>>>> com.oracle.graal.compiler.common.GraalInternalError.unimplemented(Gra
>>>> alI
>>>> nternalError.java:40)
>>>> 	at
>>>> com.oracle.graal.compiler.hsail.HSAILNodeLIRBuilder.emitDirectCall(HS
>>>> AIL
>>>> NodeLIRBuilder.java:50)
>>>> 	at
>>>> com.oracle.graal.compiler.gen.NodeLIRBuilder.emitInvoke(NodeLIRBuilde
>>>> r.j
>>>> ava:472)
>>>> 	at
>>>> com.oracle.graal.nodes.InvokeNode.generate(InvokeNode.java:131)
>>>> 	at
>>>> com.oracle.graal.compiler.gen.NodeLIRBuilder.emitNode(NodeLIRBuilder.
>>>> jav
>>>> a:312)
>>>> 	at
>>>> com.oracle.graal.hotspot.hsail.HSAILHotSpotNodeLIRBuilder.emitNode(HS
>>>> AIL
>>>> HotSpotNodeLIRBuilder.java:56)
>>>> 	at
>>>> 
>> com.oracle.graal.compiler.gen.NodeLIRBuilder.doRoot(NodeLIRBuilder.java:
>>>> 303)
>>>> 	at
>>>> com.oracle.graal.compiler.gen.NodeLIRBuilder.doBlock(NodeLIRBuilder.j
>>>> ava
>>>> :218)
>>>> 	... 46 more
>>>> 
>>>> FAILURES!!!
>>>> Tests run: 4527,  Failures: 2



More information about the graal-dev mailing list