-
Notifications
You must be signed in to change notification settings - Fork 326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve TCO in the presence of warnings #7116
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
import org.enso.interpreter.runtime.callable.atom.Atom; | ||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor; | ||
import org.enso.interpreter.runtime.callable.function.Function; | ||
import org.enso.interpreter.runtime.control.TailCallException; | ||
import org.enso.interpreter.runtime.error.DataflowError; | ||
import org.enso.interpreter.runtime.error.PanicException; | ||
import org.enso.interpreter.runtime.error.PanicSentinel; | ||
|
@@ -264,6 +265,15 @@ public Object invokeWarnings( | |
State state, | ||
Object[] arguments, | ||
@CachedLibrary(limit = "3") WarningsLibrary warnings) { | ||
|
||
Warning[] extracted; | ||
Object callable; | ||
try { | ||
extracted = warnings.getWarnings(warning, null); | ||
callable = warnings.removeWarnings(warning); | ||
} catch (UnsupportedMessageException e) { | ||
throw CompilerDirectives.shouldNotReachHere(e); | ||
} | ||
try { | ||
if (childDispatch == null) { | ||
CompilerDirectives.transferToInterpreterAndInvalidate(); | ||
|
@@ -277,7 +287,7 @@ public Object invokeWarnings( | |
invokeFunctionNode.getSchema(), | ||
invokeFunctionNode.getDefaultsExecutionMode(), | ||
invokeFunctionNode.getArgumentsExecutionMode())); | ||
childDispatch.setTailStatus(TailStatus.NOT_TAIL); | ||
childDispatch.setTailStatus(getTailStatus()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the test below... what node behavior this change affects? The warning in the test is attached to an argument, not to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh you mean why I change it in |
||
childDispatch.setId(invokeFunctionNode.getId()); | ||
notifyInserted(childDispatch); | ||
} | ||
|
@@ -287,21 +297,21 @@ public Object invokeWarnings( | |
} | ||
|
||
var result = childDispatch.execute( | ||
warnings.removeWarnings(warning), | ||
callable, | ||
callerFrame, | ||
state, | ||
arguments); | ||
|
||
Warning[] extracted = warnings.getWarnings(warning, null); | ||
|
||
if (result instanceof DataflowError) { | ||
return result; | ||
} else if (result instanceof WithWarnings withWarnings) { | ||
return withWarnings.append(EnsoContext.get(this), extracted); | ||
} else { | ||
return WithWarnings.wrap(EnsoContext.get(this), result, extracted); | ||
} | ||
} catch (UnsupportedMessageException e) { | ||
throw CompilerDirectives.shouldNotReachHere(e); | ||
} catch (TailCallException e) { | ||
throw new TailCallException(e, extracted); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,9 +15,12 @@ | |
import com.oracle.truffle.api.nodes.RepeatingNode; | ||
import org.enso.interpreter.node.callable.ExecuteCallNode; | ||
import org.enso.interpreter.node.callable.ExecuteCallNodeGen; | ||
import org.enso.interpreter.runtime.EnsoContext; | ||
import org.enso.interpreter.runtime.callable.CallerInfo; | ||
import org.enso.interpreter.runtime.callable.function.Function; | ||
import org.enso.interpreter.runtime.control.TailCallException; | ||
import org.enso.interpreter.runtime.error.Warning; | ||
import org.enso.interpreter.runtime.error.WithWarnings; | ||
import org.enso.interpreter.runtime.state.State; | ||
|
||
/** | ||
|
@@ -54,31 +57,78 @@ public static LoopingCallOptimiserNode build() { | |
* @param loopNode a cached instance of the loop node used by this node | ||
* @return the result of executing {@code function} using {@code arguments} | ||
*/ | ||
@Specialization | ||
public Object dispatch( | ||
@Specialization(guards = "warnings == null") | ||
public Object cachedDispatch( | ||
Function function, | ||
CallerInfo callerInfo, | ||
State state, | ||
Object[] arguments, | ||
Warning[] warnings, | ||
@Cached(value = "createLoopNode()") LoopNode loopNode) { | ||
return dispatch(function, callerInfo, state, arguments, loopNode); | ||
} | ||
|
||
@Specialization(guards = "warnings != null") | ||
public Object cachedDispatchWarnings( | ||
Function function, | ||
CallerInfo callerInfo, | ||
State state, | ||
Object[] arguments, | ||
Warning[] warnings, | ||
@Cached(value = "createLoopNode()") LoopNode loopNode) { | ||
Object result = dispatch(function, callerInfo, state, arguments, loopNode); | ||
return WithWarnings.appendTo(EnsoContext.get(this), result, warnings); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks correct. If there are warnings, remove them, handle all the tail calls and attach them again. Not sure how that can be triggered by the test however? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm not sure how to convince you other than running it with debugger attached and putting the breakpoint yourself. |
||
} | ||
|
||
private Object dispatch( | ||
Function function, | ||
CallerInfo callerInfo, | ||
State state, | ||
Object[] arguments, | ||
LoopNode loopNode) { | ||
RepeatedCallNode repeatedCallNode = (RepeatedCallNode) loopNode.getRepeatingNode(); | ||
VirtualFrame frame = repeatedCallNode.createFrame(); | ||
repeatedCallNode.setNextCall(frame, function, callerInfo, arguments); | ||
repeatedCallNode.setState(frame, state); | ||
loopNode.execute(frame); | ||
|
||
return repeatedCallNode.getResult(frame); | ||
} | ||
|
||
@Specialization(replaces = "dispatch") | ||
@Specialization(replaces = "cachedDispatch", guards = "warnings == null") | ||
@CompilerDirectives.TruffleBoundary | ||
public Object uncachedDispatch( | ||
MaterializedFrame frame, | ||
Function function, | ||
CallerInfo callerInfo, | ||
State state, | ||
Object[] arguments, | ||
Warning[] warnings, | ||
@Cached ExecuteCallNode executeCallNode) { | ||
return loopUntilCompletion(frame, function, callerInfo, state, arguments, executeCallNode); | ||
} | ||
|
||
@Specialization(replaces = "cachedDispatchWarnings", guards = "warnings != null") | ||
@CompilerDirectives.TruffleBoundary | ||
public Object uncachedDispatchWarnings( | ||
MaterializedFrame frame, | ||
Function function, | ||
CallerInfo callerInfo, | ||
State state, | ||
Object[] arguments, | ||
Warning[] warnings, | ||
@Cached ExecuteCallNode executeCallNode) { | ||
Object result = | ||
loopUntilCompletion(frame, function, callerInfo, state, arguments, executeCallNode); | ||
return WithWarnings.appendTo(EnsoContext.get(this), result, warnings); | ||
} | ||
|
||
private Object loopUntilCompletion( | ||
MaterializedFrame frame, | ||
Function function, | ||
CallerInfo callerInfo, | ||
State state, | ||
Object[] arguments, | ||
ExecuteCallNode executeCallNode) { | ||
while (true) { | ||
try { | ||
return executeCallNode.executeCall(frame, function, callerInfo, state, arguments); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a side note: Eventually, we should probably align the exceptions we are throwing from the nodes in the engine. In most places it is
IllegalStateException
, but sometimes it is alsoCompilerDirectives.shouldNotReachHere
. We should provide a proper wrapper for these exceptions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I've had the same observation a while ago ;)