Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
QueryR
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Julien Lopez
QueryR
Commits
d2f8ec90
Commit
d2f8ec90
authored
10 years ago
by
Gero Leinemann
Browse files
Options
Downloads
Patches
Plain Diff
RCallNode improvements from review
parent
959940b6
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
+56
-57
56 additions, 57 deletions
...es/src/com/oracle/truffle/r/nodes/function/RCallNode.java
with
56 additions
and
57 deletions
com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java
+
56
−
57
View file @
d2f8ec90
...
@@ -59,20 +59,20 @@ import com.oracle.truffle.r.runtime.data.*;
...
@@ -59,20 +59,20 @@ import com.oracle.truffle.r.runtime.data.*;
* {@link DirectCallNode} which is not as performant as the latter but has no further disadvantages.
* {@link DirectCallNode} which is not as performant as the latter but has no further disadvantages.
* But as the function changed its formal parameters changed, too, so a re-match has to be done as
* But as the function changed its formal parameters changed, too, so a re-match has to be done as
* well, which involves the creation of nodes and thus must happen on the {@link SlowPath}.<br/>
* well, which involves the creation of nodes and thus must happen on the {@link SlowPath}.<br/>
* Problem 2
however
is not that easy, too: It is solved by reading the values associated with "..."
* Problem 2 is not that easy, too: It is solved by reading the values associated with "..."
(which
*
(which
are Promises) and wrapping them in newly created {@link RNode}s. These nodes get inserted
* are Promises) and wrapping them in newly created {@link RNode}s. These nodes get inserted
into
*
into
the arguments list ({@link CallArgumentsNode#executeFlatten(VirtualFrame)}) - which needs to
* the arguments list ({@link CallArgumentsNode#executeFlatten(VirtualFrame)}) - which needs to
be
* be matched against the formal parameters again, as theses arguments may carry names as well which
* be matched against the formal parameters again, as theses arguments may carry names as well which
* may have an impact on argument order. As matching involves node creation, it has to happen on the
* may have an impact on argument order. As matching involves node creation, it has to happen on the
* {@link SlowPath}.
* {@link SlowPath}.
* </p>
* </p>
* To
cache those
node creations
, two interwoven PICs are implemented. The cache is constructed
* To
avoid repeated
node creations
as much as possible by caching two interwoven PICs are
* using the following classes:
*
implemented. The caches are constructed
using the following classes:
*
*
* <pre>
* <pre>
* U = {@link UninitializedCallNode}: Forms the uninitialized end of the function PIC
* U = {@link UninitializedCallNode}: Forms the uninitialized end of the function PIC
* D = {@link DispatchedCallNode}: Function fixed, no varargs
* D = {@link DispatchedCallNode}: Function fixed, no varargs
* G = {@link GenericCallNode}: Function
fixed
, no varargs (generic case)
* G = {@link GenericCallNode}: Function
arbitrary
, no varargs (generic case)
*
*
* UV = {@link UninitializedCallNode} with varargs,
* UV = {@link UninitializedCallNode} with varargs,
* UVC = {@link UninitializedVarArgsCacheCallNode} with varargs, for varargs cache
* UVC = {@link UninitializedVarArgsCacheCallNode} with varargs, for varargs cache
...
@@ -81,12 +81,12 @@ import com.oracle.truffle.r.runtime.data.*;
...
@@ -81,12 +81,12 @@ import com.oracle.truffle.r.runtime.data.*;
* GV = {@link GenericVarArgsCallNode}: Function arbitrary, with arbitrary varargs (generic case)
* GV = {@link GenericVarArgsCallNode}: Function arbitrary, with arbitrary varargs (generic case)
*
*
* (RB = {@link RBuiltinNode}: individual functions that are builtins are represented by this node
* (RB = {@link RBuiltinNode}: individual functions that are builtins are represented by this node
* which is not aware of caching)
* which is not aware of caching). Due to {@link CachedCallNode} (see below) this is transparent to
* the cache and just behaves like a D/DGV)
* </pre>
* </pre>
*
*
* As the function's identity is the primary id for this cache and as the property
* As the property "takes varargs as argument" is static for each call site, we effectively end up
* "takes varargs as argument" is static for each call site, we effectively end up with two separate
* with two separate cache structures. Some examples of each are depicted below:
* cache structures. Some examples of each are depicted below:
*
*
* <pre>
* <pre>
* non varargs, max depth:
* non varargs, max depth:
...
@@ -95,23 +95,31 @@ import com.oracle.truffle.r.runtime.data.*;
...
@@ -95,23 +95,31 @@ import com.oracle.truffle.r.runtime.data.*;
*
*
* no varargs, generic (if max depth is exceeded):
* no varargs, generic (if max depth is exceeded):
* |
* |
* G
*
D-D-D-D-
G
*
*
* varargs:
* varargs:
* |
* |
* DV-DV-UV
* DV-DV-UV
<- function identity level cache
* |
* |
* DV
* DV
* |
* |
* UVC
* UVC
<- varargs signature level cache
*
*
* varargs, max varargs depth exceeded:
* varargs, max varargs depth exceeded:
* |
* |
* DV-DGV-UV
* DV-DV-UV
* |
* DV
* |
* DV
* |
* DV
* |
* DGV
*
*
* varargs, max function depth exceeded:
* varargs, max function depth exceeded:
* |
* |
* GV
*
DV-DV-DV-DV-
GV
* </pre>
* </pre>
* <p>
* <p>
* In the diagrams above every horizontal connection "-" is in fact established by a separate node:
* In the diagrams above every horizontal connection "-" is in fact established by a separate node:
...
@@ -142,8 +150,6 @@ public abstract class RCallNode extends RNode {
...
@@ -142,8 +150,6 @@ public abstract class RCallNode extends RNode {
private
static
final
int
FUNCTION_INLINE_CACHE_SIZE
=
4
;
private
static
final
int
FUNCTION_INLINE_CACHE_SIZE
=
4
;
private
static
final
int
VARARGS_INLINE_CACHE_SIZE
=
4
;
private
static
final
int
VARARGS_INLINE_CACHE_SIZE
=
4
;
private
static
final
String
GENERIC_VARARGS_WARNING
=
"Warning: RCallNode varargs generic case!"
;
private
static
final
String
GENERIC_FUNCTION_WARNING
=
"Warning: RCallNode function generic case!"
;
protected
RCallNode
()
{
protected
RCallNode
()
{
}
}
...
@@ -264,7 +270,7 @@ public abstract class RCallNode extends RNode {
...
@@ -264,7 +270,7 @@ public abstract class RCallNode extends RNode {
}
}
/**
/**
* [C]
* [C]
Extracts the check for function identity away from the individual cache nodes
*
*
* @see RCallNode
* @see RCallNode
*/
*/
...
@@ -307,7 +313,7 @@ public abstract class RCallNode extends RNode {
...
@@ -307,7 +313,7 @@ public abstract class RCallNode extends RNode {
}
}
/**
/**
* [U]/[UV]
* [U]/[UV]
Forms the uninitialized end of the function PIC
*
*
* @see RCallNode
* @see RCallNode
*/
*/
...
@@ -347,20 +353,24 @@ public abstract class RCallNode extends RNode {
...
@@ -347,20 +353,24 @@ public abstract class RCallNode extends RNode {
private
RCallNode
specialize
(
VirtualFrame
frame
,
RFunction
function
)
{
private
RCallNode
specialize
(
VirtualFrame
frame
,
RFunction
function
)
{
CompilerAsserts
.
neverPartOfCompilation
();
CompilerAsserts
.
neverPartOfCompilation
();
if
(
depth
<
FUNCTION_INLINE_CACHE_SIZE
)
{
RCallNode
current
=
createCacheNode
(
frame
,
function
);
final
RCallNode
current
=
createCacheNode
(
frame
,
function
);
RootCallNode
next
=
createNextNode
();
final
RootCallNode
cachedNode
=
new
CachedCallNode
(
this
.
functionNode
,
current
,
new
UninitializedCallNode
(
this
),
function
);
RootCallNode
cachedNode
=
new
CachedCallNode
(
this
.
functionNode
,
current
,
next
,
function
);
current
.
onCreate
();
next
.
onCreate
();
this
.
replace
(
cachedNode
);
current
.
onCreate
();
return
cachedNode
;
this
.
replace
(
cachedNode
);
return
cachedNode
;
}
@SlowPath
protected
RootCallNode
createNextNode
()
{
if
(
depth
+
1
<
FUNCTION_INLINE_CACHE_SIZE
)
{
return
new
UninitializedCallNode
(
this
);
}
else
{
}
else
{
RootCallNode
topMost
=
(
RootCallNode
)
getTopNode
();
// 2 possible cases: G (Multiple functions, no varargs) or GV (Multiple function
// 2 possible cases: G (Multiple functions, no varargs) or GV (Multiple function
// arbitrary varargs)
// arbitrary varargs)
RCallNode
generic
=
args
.
containsVarArgsSymbol
()
?
new
GenericVarArgsCallNode
(
topMost
.
functionNode
,
args
)
:
new
GenericCallNode
(
topMost
.
functionNode
,
args
);
CallArgumentsNode
clonedArgs
=
getClonedArgs
();
generic
=
topMost
.
replace
(
generic
,
GENERIC_FUNCTION_WARNING
);
return
args
.
containsVarArgsSymbol
()
?
new
GenericVarArgsCallNode
(
functionNode
,
clonedArgs
)
:
new
GenericCallNode
(
functionNode
,
clonedArgs
);
generic
.
onCreate
();
return
generic
;
}
}
}
}
...
@@ -401,14 +411,6 @@ public abstract class RCallNode extends RNode {
...
@@ -401,14 +411,6 @@ public abstract class RCallNode extends RNode {
return
callNode
;
return
callNode
;
}
}
protected
Node
getTopNode
()
{
Node
parentNode
=
this
;
for
(
int
i
=
0
;
i
<
depth
;
i
++)
{
parentNode
=
parentNode
.
getParent
();
}
return
parentNode
;
}
public
CallArgumentsNode
getClonedArgs
()
{
public
CallArgumentsNode
getClonedArgs
()
{
return
NodeUtil
.
cloneNode
(
args
);
return
NodeUtil
.
cloneNode
(
args
);
}
}
...
@@ -514,29 +516,26 @@ public abstract class RCallNode extends RNode {
...
@@ -514,29 +516,26 @@ public abstract class RCallNode extends RNode {
return
specializeAndExecute
(
frame
,
function
,
varArgsSignature
);
return
specializeAndExecute
(
frame
,
function
,
varArgsSignature
);
}
}
@SlowPath
private
Object
specializeAndExecute
(
VirtualFrame
frame
,
RFunction
function
,
VarArgsSignature
varArgsSignature
)
{
private
Object
specializeAndExecute
(
VirtualFrame
frame
,
RFunction
function
,
VarArgsSignature
varArgsSignature
)
{
CompilerAsserts
.
neverPartOfCompilation
();
CompilerAsserts
.
neverPartOfCompilation
();
if
(
depth
<
VARARGS_INLINE_CACHE_SIZE
)
{
// Extend cache
// Extend cache
this
.
depth
+=
1
;
this
.
depth
+=
1
;
CallArgumentsNode
clonedArgs
=
NodeUtil
.
cloneNode
(
args
);
CallArgumentsNode
clonedArgs
=
NodeUtil
.
cloneNode
(
args
);
VarArgsCacheCallNode
next
=
createNextNode
(
function
);
DispatchedVarArgsCallNode
newCallNode
=
DispatchedVarArgsCallNode
.
create
(
frame
,
clonedArgs
,
this
,
getSourceSection
(),
function
,
varArgsSignature
,
false
);
DispatchedVarArgsCallNode
newCallNode
=
DispatchedVarArgsCallNode
.
create
(
frame
,
clonedArgs
,
next
,
getSourceSection
(),
function
,
varArgsSignature
,
false
);
return
replace
(
newCallNode
).
execute
(
frame
,
function
,
varArgsSignature
);
return
replace
(
newCallNode
).
execute
(
frame
,
function
,
varArgsSignature
);
}
else
{
// Add stable generic case
DispatchedGenericVarArgsCallNode
dgv
=
new
DispatchedGenericVarArgsCallNode
(
function
,
args
);
RCallNode
topMostVarargsCache
=
getTopMost
();
return
topMostVarargsCache
.
replace
(
dgv
,
GENERIC_VARARGS_WARNING
).
execute
(
frame
,
function
);
}
}
}
private
RCallNode
getTopMost
()
{
@SlowPath
Node
parent
=
this
;
private
VarArgsCacheCallNode
createNextNode
(
RFunction
function
)
{
for
(
int
i
=
0
;
i
<
depth
;
i
--)
{
if
(
depth
<
VARARGS_INLINE_CACHE_SIZE
)
{
parent
=
parent
.
getParent
();
return
this
;
}
else
{
CallArgumentsNode
clonedArgs
=
NodeUtil
.
cloneNode
(
args
);
return
new
DispatchedGenericVarArgsCallNode
(
function
,
clonedArgs
);
}
}
return
(
RCallNode
)
parent
;
}
}
}
}
...
@@ -612,7 +611,7 @@ public abstract class RCallNode extends RNode {
...
@@ -612,7 +611,7 @@ public abstract class RCallNode extends RNode {
*
*
* @see RCallNode
* @see RCallNode
*/
*/
private
static
final
class
DispatchedGenericVarArgsCallNode
extends
R
CallNode
{
private
static
final
class
DispatchedGenericVarArgsCallNode
extends
VarArgsCache
CallNode
{
@Child
private
DirectCallNode
call
;
@Child
private
DirectCallNode
call
;
@Child
private
CallArgumentsNode
suppliedArgs
;
@Child
private
CallArgumentsNode
suppliedArgs
;
...
@@ -627,7 +626,7 @@ public abstract class RCallNode extends RNode {
...
@@ -627,7 +626,7 @@ public abstract class RCallNode extends RNode {
@Override
@Override
@SlowPath
@SlowPath
p
ublic
Object
execute
(
VirtualFrame
frame
,
RFunction
currentFunction
)
{
p
rotected
Object
execute
(
VirtualFrame
frame
,
RFunction
currentFunction
,
VarArgsSignature
varArgsSignature
)
{
CompilerAsserts
.
neverPartOfCompilation
();
CompilerAsserts
.
neverPartOfCompilation
();
assert
function
==
currentFunction
;
assert
function
==
currentFunction
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment