use of com.jopdesign.common.MethodInfo in project jop by jop-devel.
the class MethodCacheAnalysis method updateNodes.
private void updateNodes(SimpleDirectedGraph<ExecutionContext, ContextEdge> closure, Set<ExecutionContext> nodes, boolean reuseResults) {
for (ExecutionContext node : nodes) {
if (node.getMethodInfo().isNative())
continue;
// We could make this more memory efficient, because in many cases we do not need a
// separate set for each node, but this would be more complicated to calculate
Set<MethodInfo> reachable = new LinkedHashSet<MethodInfo>();
reachable.add(node.getMethodInfo());
// we only need to add all children to the set, no need to go down the graph
for (ContextEdge edge : closure.outgoingEdgesOf(node)) {
ExecutionContext target = edge.getTarget();
if (target.getMethodInfo().isNative())
continue;
if (reuseResults && !nodes.contains(target)) {
reachable.addAll(reachableMethods.get(target));
} else {
reachable.add(target.getMethodInfo());
}
}
reachableMethods.put(node, reachable);
}
MethodCache cache = jcopter.getMethodCache();
// now we can sum up the cache blocks for all nodes in the graph
for (ExecutionContext node : nodes) {
if (node.getMethodInfo().isNative())
continue;
Set<MethodInfo> reachable = reachableMethods.get(node);
int blocks = 0;
for (MethodInfo method : reachable) {
int size = MiscUtils.bytesToWords(getMethodSize(method));
blocks += cache.requiredNumberOfBlocks(size);
}
cacheBlocks.put(node, blocks);
}
}
use of com.jopdesign.common.MethodInfo in project jop by jop-devel.
the class MethodCacheAnalysis method inline.
public void inline(CodeModification modification, InvokeSite invokeSite, MethodInfo invokee) {
if (analysisType == AnalysisType.ALWAYS_HIT || analysisType == AnalysisType.ALWAYS_MISS)
return;
Set<ExecutionContext> nodes = new LinkedHashSet<ExecutionContext>();
// We need to go down first, find all new nodes
MethodInfo invoker = invokeSite.getInvoker();
LinkedList<ExecutionContext> queue = new LinkedList<ExecutionContext>(callGraph.getNodes(invoker));
// TODO if the callgraph is compressed, we need to go down all callstring-length long paths
while (!queue.isEmpty()) {
ExecutionContext node = queue.remove();
for (ExecutionContext child : callGraph.getChildren(node)) {
if (!cacheBlocks.containsKey(child) && !nodes.contains(child)) {
nodes.add(child);
queue.add(child);
}
}
}
// update reachable set and codesize for all new nodes
updateNewNodes(nodes);
// To get the old size, use any execution node ..
ExecutionContext node = callGraph.getNodes(invoker).iterator().next();
// this includes all reachable methods, so we need to subtract them
int oldBlocks = cacheBlocks.get(node);
for (MethodInfo m : reachableMethods.get(node)) {
int size = MiscUtils.bytesToWords(getMethodSize(m));
oldBlocks -= cache.requiredNumberOfBlocks(size);
}
int size = MiscUtils.bytesToWords(getMethodSize(invoker));
int newBlocks = cache.requiredNumberOfBlocks(size);
// not using CodeModification codesize delta because it might be an estimation
int deltaBlocks = newBlocks - oldBlocks;
// now go up from the modified method, remove invokee from reachable sets if last invoke was inlined
// and update block counts
findClassificationChanges(invoker, deltaBlocks, modification.getRemovedInvokees(), true);
}
use of com.jopdesign.common.MethodInfo in project jop by jop-devel.
the class WCAInvoker method updateWCEP.
private void updateWCEP() {
if (!provideWCAExecCount)
return;
execCounts.clear();
for (MethodInfo root : getWcaTargets()) {
execCounts.put(root, 1L);
}
NodeVisitor<ExecutionContext> visitor = new NodeVisitor<ExecutionContext>() {
@Override
public boolean visitNode(ExecutionContext context) {
MethodInfo method = context.getMethodInfo();
MethodCode code = method.getCode();
long ec = getExecCount(method);
// skip methods which are not on the WCET path.. we can ship iterating over the childs too..
if (ec == 0)
return false;
// iterate over all blocks in the CFG, find all invokes and add block execution counts to invokees
ControlFlowGraph cfg = method.getCode().getControlFlowGraph(false);
for (CFGNode node : cfg.getGraph().vertexSet()) {
if (node instanceof InvokeNode) {
InvokeNode inv = (InvokeNode) node;
long ef = getExecFrequency(method, node);
for (MethodInfo invokee : inv.getImplementingMethods()) {
addExecCount(invokee, ec * ef);
}
} else if (node instanceof BasicBlockNode) {
// check if we have a JVM invoke here (or an invoke not in a dedicated node..)
for (InstructionHandle ih : node.getBasicBlock().getInstructions()) {
if (!code.isInvokeSite(ih))
continue;
long ef = getExecFrequency(method, node);
for (MethodInfo invokee : method.getAppInfo().findImplementations(code.getInvokeSite(ih))) {
addExecCount(invokee, ec * ef);
}
}
}
}
return true;
}
};
TopologicalTraverser<ExecutionContext, ContextEdge> topOrder = new TopologicalTraverser<ExecutionContext, ContextEdge>(wcetTool.getCallGraph().getGraph(), visitor);
topOrder.traverse();
}
use of com.jopdesign.common.MethodInfo in project jop by jop-devel.
the class WCAInvoker method updateWCA.
///////////////////////////////////////////////////////////////////////////////
// Update results
///////////////////////////////////////////////////////////////////////////////
/**
* Update the WCA results after a set of methods have been changed. The changesets of analyses
* in the AnalysisManager are checked for changes too.
*
* @param changedMethods a set of methods of which the code has been modified.
* @return a set of all methods for which the path may have changed.
*/
public Set<MethodInfo> updateWCA(Collection<MethodInfo> changedMethods) {
// Now we need to clear all results for all callers of the modified methods as well as the modified methods,
// and recalculate all results
CallGraph callGraph = wcetTool.getCallGraph();
final Set<ExecutionContext> rootNodes = new LinkedHashSet<ExecutionContext>();
for (MethodInfo root : changedMethods) {
rootNodes.addAll(callGraph.getNodes(root));
}
// we also need to recalculate for new nodes.. we simply go down callstring-length from the changed methods
final int callstringLength = AppInfo.getSingleton().getCallstringLength();
DFSVisitor<ExecutionContext, ContextEdge> visitor = new EmptyDFSVisitor<ExecutionContext, ContextEdge>() {
@Override
public boolean visitNode(ExecutionContext parent, ContextEdge edge, ExecutionContext node, DFSEdgeType type, Collection<ContextEdge> outEdges, int depth) {
if (type.isFirstVisit() && !wcaNodeFlow.containsKey(node)) {
rootNodes.add(node);
}
return depth <= callstringLength;
}
};
DFSTraverser<ExecutionContext, ContextEdge> traverser = new DFSTraverser<ExecutionContext, ContextEdge>(visitor);
traverser.traverse(callGraph.getGraph(), new ArrayList<ExecutionContext>(rootNodes));
// classification changed too
for (MethodInfo method : analyses.getMethodCacheAnalysis().getClassificationChangeSet()) {
rootNodes.addAll(callGraph.getNodes(method));
}
Set<MethodInfo> changed = runAnalysis(wcetTool.getCallGraph().createInvokeGraph(rootNodes, true));
updateWCEP();
return changed;
}
use of com.jopdesign.common.MethodInfo in project jop by jop-devel.
the class SimpleInliner method analyzeCodeSize.
/**
* Check if the resulting code will not be larger than the older code.
* @param invokeSite the invokesite to inline.
* @param invokee the invoked method.
* @param inlineData the map to store the analyzer results
* @return true if the new code will not violate any size constrains
*/
private boolean analyzeCodeSize(InvokeSite invokeSite, MethodInfo invokee, InlineData inlineData) {
ProcessorModel pm = AppInfo.getSingleton().getProcessorModel();
MethodInfo invoker = invokeSite.getInvoker();
// delta = new prologue + inlined code + epilogue - old prologue - invokesite
int delta = 0;
InstructionHandle[] il = invokee.getCode().getInstructionList().getInstructionHandles();
InstructionHandle ih = il[inlineData.getInlineStart()];
while (ih != null) {
Instruction instr = ih.getInstruction();
if (instr instanceof ReturnInstruction) {
break;
}
delta += pm.getNumberOfBytes(invokee, instr);
ih = ih.getNext();
}
for (InstructionHandle instr : inlineData.getPrologue().getInstructionHandles()) {
delta += pm.getNumberOfBytes(invoker, instr.getInstruction());
}
for (InstructionHandle instr : inlineData.getEpilogue().getInstructionHandles()) {
delta += pm.getNumberOfBytes(invoker, instr.getInstruction());
}
ih = invokeSite.getInstructionHandle();
for (int i = 0; i <= inlineData.getOldPrologueLength(); i++) {
Instruction instr = ih.getInstruction();
delta -= pm.getNumberOfBytes(invoker, instr);
ih = ih.getPrev();
}
// TODO we could allow for some slack, especially if we decreased the codesize before..
return delta <= 0;
}
Aggregations