Skip to content
Snippets Groups Projects
Commit 4cd6a927 authored by Mick Jordan's avatar Mick Jordan
Browse files

clean up sourceSection assignment for function body/stmts nodes; instrument...

clean up sourceSection assignment for function body/stmts nodes; instrument all wrappers with source
parent 54787c76
No related branches found
No related tags found
No related merge requests found
......@@ -135,8 +135,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> {
ASTNode astBody = func.getBody();
FunctionStatementsNode statements;
if (astBody != null) {
// TODO fix
statements = new FunctionStatementsNode(func.getSource(), astBody.accept(this));
statements = new FunctionStatementsNode(astBody.accept(this));
} else {
statements = new FunctionStatementsNode(RNode.EMTPY_RNODE_ARRAY);
}
......
......@@ -214,7 +214,7 @@ public class SequenceNode extends RNode {
total += sequence.timing[i];
}
}
if (total > 1000000000L) {
if (total > 0L) {
int startLine = sequence.getSourceSection().getStartLine();
int endLine = startLine + sequence.getSourceSection().getCode().split("\n").length - 1;
RPerfStats.out().println("File " + source.getName() + " lines " + startLine + "-" + endLine + ", total: " + (total / 1000000) + "ms");
......
......@@ -23,6 +23,7 @@
package com.oracle.truffle.r.nodes.function;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.r.nodes.*;
import com.oracle.truffle.r.runtime.*;
import com.oracle.truffle.r.runtime.env.REnvironment;
......@@ -33,6 +34,8 @@ import com.oracle.truffle.r.runtime.env.REnvironment;
*
* Children are typed as {@link RNode} to avoid a custom instrumentation wrapper node.
*
* The {@link SourceSection} is that of the {@link FunctionStatementsNode} as the
* {@link SaveArgumentsNode} is not part of the syntax.
*/
public class FunctionBodyNode extends RNode {
......@@ -42,11 +45,13 @@ public class FunctionBodyNode extends RNode {
public FunctionBodyNode(SaveArgumentsNode saveArgs, FunctionStatementsNode statements) {
this.saveArgs = saveArgs;
this.statements = statements;
assignSourceSection(statements.getSourceSection());
}
private FunctionBodyNode(RNode saveArgs, RNode statements) {
this.saveArgs = saveArgs;
this.statements = statements;
assignSourceSection(statements.getSourceSection());
}
@Override
......
......@@ -30,19 +30,19 @@ import com.oracle.truffle.r.runtime.env.REnvironment;
/**
* Encapsulates the sequence of statements (expressions) of a function. Has no specific execute
* behavior but is an important placeholder for debugging instrumentation.
*
* The {@link SourceSection} for a non-empty sequence is that of the sequence itself.
*/
public class FunctionStatementsNode extends SequenceNode {
public FunctionStatementsNode(RNode[] sequence) {
// TODO revisit what this variant is really for
super(sequence);
}
public FunctionStatementsNode(SourceSection src, RNode sequence) {
super(src, sequence);
}
public FunctionStatementsNode(RNode node) {
super(node);
public FunctionStatementsNode(RNode sequence) {
super(sequence);
assignSourceSection(sequence.getSourceSection());
}
@Override
......
......@@ -31,6 +31,7 @@ import com.oracle.truffle.r.nodes.*;
import com.oracle.truffle.r.nodes.control.*;
import com.oracle.truffle.r.nodes.function.*;
import com.oracle.truffle.r.options.FastROptions;
import com.oracle.truffle.r.runtime.*;
/**
* A visitor which traverses a completely parsed R AST (presumed not yet executed) and attaches
......@@ -57,8 +58,14 @@ public final class RASTProber implements ASTProber {
public void probeAST(Node node) {
FunctionBodyNode body = (FunctionBodyNode) node;
FunctionDefinitionNode fdn = (FunctionDefinitionNode) body.getParent();
if (fdn.getSourceSection() == null) {
// Can't instrument ASTs without a SourceSection
if (body.getSourceSection() == null) {
// Can't instrument AST (bodies) without a SourceSection
if (FastROptions.debugMatches("RASTProberNoSource")) {
RDeparse.State state = RDeparse.State.createPrintableState();
fdn.deparse(state);
System.out.printf("No source sections for %s, can't instrument%n", fdn);
System.out.println(state.toString());
}
return;
}
RInstrument.registerFunctionDefinition(fdn);
......@@ -67,7 +74,7 @@ public final class RASTProber implements ASTProber {
body.probe().tagAs(RSyntaxTag.FUNCTION_BODY, uid);
stmts.probe().tagAs(START_METHOD, uid);
TagSyntaxNodeVisitor visitor = new TagSyntaxNodeVisitor(uid);
if (FastROptions.debugMatches("astprober")) {
if (FastROptions.debugMatches("RASTProberTag")) {
System.out.printf("Tagging function %s%n", uid);
}
body.accept(visitor);
......@@ -111,7 +118,7 @@ public final class RASTProber implements ASTProber {
protected boolean callback(RNode node) {
RInstrument.NodeId nodeId = new RInstrument.NodeId(uid, node);
node.probe().tagAs(STATEMENT, new RInstrument.NodeId(uid, node));
if (FastROptions.debugMatches("astprober")) {
if (FastROptions.debugMatches("RASTProberTag")) {
System.out.printf("Tagged %s as STATEMENT: %s%n", node.toString(), nodeId.toString());
}
return true;
......
......@@ -124,15 +124,15 @@ public class RNodeTimer {
private static class PerfHandler implements RPerfStats.Handler {
static final String NAME = "timing";
private boolean expand;
private boolean stmts;
private int threshold;
public void initialize(String optionText) {
if (optionText.length() > 0) {
String[] subOptions = optionText.split(":");
for (String subOption : subOptions) {
if (subOption.equals("expand")) {
expand = true;
if (subOption.equals("stmts")) {
stmts = true;
} else if (subOption.startsWith("threshold")) {
threshold = Integer.parseInt(subOption.substring(subOption.indexOf('=') + 1)) * 1000;
}
......@@ -169,17 +169,25 @@ public class RNodeTimer {
TimingData[] sortedData = new TimingData[values.size()];
values.toArray(sortedData);
Arrays.sort(sortedData);
long totalTime = 0;
for (TimingData t : sortedData) {
totalTime += t.time;
}
for (TimingData t : sortedData) {
if (t.time > 0) {
if (t.time > threshold) {
FunctionIdentification fdi = RInstrument.getFunctionIdentification(t.functionUID);
RPerfStats.out().println("==========");
RPerfStats.out().printf("%d ms: %s, %s%n", t.time, fdi.name, fdi.origin);
if (expand) {
RPerfStats.out().printf("%d ms (%.2f%%): %s, %s%n", t.time, percent(t.time, totalTime), fdi.name, fdi.origin);
if (stmts) {
SourceSection ss = fdi.node.getSourceSection();
if (ss == null) {
RPerfStats.out().println("no source available");
// wrapper
ss = fdi.node.getBody().getSourceSection();
if (ss == null) {
RPerfStats.out().println("no source available");
}
} else {
long[] time = createLineTimes(fdi);
int startLine = ss.getStartLine();
......@@ -196,12 +204,16 @@ public class RNodeTimer {
}
}
private static double percent(long a, long b) {
return ((double) a * 100) / b;
}
private static class LineTimesNodeVisitor extends RASTProber.SyntaxNodeVisitor {
private final long[] time;
private final long[] times;
LineTimesNodeVisitor(FunctionUID uid, long[] time) {
super(uid);
this.time = time;
this.times = time;
}
@Override
......@@ -211,7 +223,10 @@ public class RNodeTimer {
NodeId nodeId = new NodeId(uid, node);
Statement stmt = (Statement) timerMap.get(nodeId);
if (stmt != null) {
time[ss.getStartLine()] += millis(stmt.cumulativeTime);
assert ss.getStartLine() != 0;
long stmtTime = millis(stmt.cumulativeTime);
times[0] += stmtTime;
times[ss.getStartLine()] += stmtTime;
} else {
/*
* This happens because default arguments are not visited during the AST
......@@ -241,11 +256,11 @@ public class RNodeTimer {
/*
* Although only those lines occupied by the function will actually have entries in the
* array, addressing is easier if we allocate an array that is as long as the entire
* source.
* source. Since there is never a line 0, we use that to compute the total.
*/
final long[] time = new long[fdi.source.getLineCount() + 1];
fdi.node.getBody().accept(new LineTimesNodeVisitor(fdi.node.getUID(), time));
return time;
final long[] times = new long[fdi.source.getLineCount() + 1];
fdi.node.getBody().accept(new LineTimesNodeVisitor(fdi.node.getUID(), times));
return times;
}
public static boolean enabled() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment