use of com.jopdesign.common.code.SuperGraph.ContextCFG in project jop by jop-devel.
the class JavaOneProcessPerSupergraphTranslator method computeMethodNestingDepths.
private void computeMethodNestingDepths() throws BadGraphException {
this.methodMNDs = new HashMap<MethodInfo, Integer>();
/* for super graph nodes in topological order */
for (ContextCFG n : superGraph.topologicalOrderIterator().getTopologicalTraversal()) {
MethodInfo methodInvoked = n.getCfg().getMethodInfo();
int maxCaller = 0;
for (Pair<SuperGraph.SuperInvokeEdge, SuperGraph.SuperReturnEdge> callSite : superGraph.getCallSitesInvoking(n)) {
ControlFlowGraph.InvokeNode callSiteNode = callSite.first().getInvokeNode();
ControlFlowGraph cfgInvoker = callSiteNode.invokerFlowGraph();
int callerRootDepth = methodMNDs.get(cfgInvoker.getMethodInfo());
int nestingDepth = cfgInvoker.getLoopColoring().getLoopColor(callSiteNode).size();
maxCaller = Math.max(maxCaller, callerRootDepth + nestingDepth);
}
Integer oldValue = methodMNDs.get(methodInvoked);
if (oldValue == null)
oldValue = 0;
methodMNDs.put(methodInvoked, Math.max(oldValue, maxCaller));
}
if (config.debug)
MiscUtils.printMap(System.out, methodMNDs, 30, 0);
}
use of com.jopdesign.common.code.SuperGraph.ContextCFG in project jop by jop-devel.
the class Segment method synchronizedSegment.
/**
* Create an interprocedural segment for a synchronized block. Currently we do
* not split basic blocks here, so either you are happy with basic block granularity,
* or you split the basic block while loading.
* @param targetBlock The block containing the monitorenter instruction
* @param monitorEnter The monitor enter instruction
* @param callString The context for the method
* @param cfgProvider A control flow graph provider
* @param callStringLength Length of the callstrings
* @param infeasibles Information about infeasible edges (null if no information available)
*
* @return a segment representing executions of the synchronized block
*/
public static Segment synchronizedSegment(ContextCFG ccfg, CFGNode entryNode, InstructionHandle monitorEnter, CFGProvider cfgProvider, int callStringLength, InfeasibleEdgeProvider infeasibles) {
if (infeasibles == null) {
infeasibles = InfeasibleEdgeProvider.NO_INFEASIBLES;
}
ControlFlowGraph cfg = ccfg.getCfg();
SuperGraph superGraph = new SuperGraph(cfgProvider, cfg, ccfg.getCallString(), callStringLength, infeasibles);
ContextCFG rootMethod = superGraph.getRootNode();
/* lift entry edges */
Set<SuperGraphEdge> entryEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.liftCFGEdges(rootMethod, cfg.incomingEdgesOf(entryNode)));
/* find exit blocks (might also be in the same block) */
/* monitorenter followed bei monitorexit in same block => segment only contains this block */
Set<CFGEdge> monitorExitEdges = new HashSet<CFGEdge>();
CFGNode currentNode = entryNode;
int currentNestingLevel = 1;
Iterator<InstructionHandle> insIter = currentNode.getBasicBlock().getInstructions().iterator();
while (insIter.hasNext()) {
if (insIter.next() == monitorEnter)
break;
}
Stack<Pair<CFGNode, Integer>> todo = new Stack<Pair<CFGNode, Integer>>();
Set<CFGNode> visited = new HashSet<CFGNode>();
do {
boolean isExit = false;
while (insIter.hasNext()) {
InstructionHandle ih = insIter.next();
if (ih.getInstruction() instanceof MONITOREXIT) {
/* blocks outgoing edges terminate segment */
currentNestingLevel--;
if (currentNestingLevel == 0) {
isExit = true;
// If monitorexit is not implemented in Java, the outgoing edges of the
// basic block that contains monitorexit end the synchronized block.
// In order to avoid imprecision, it is advisable that monitorexit is the
// last statement in the basic block.
// We also handle the case when monitorexit is implemented in Java. In this case,
// currentNode will be a SpecialInvokeNode, urrentNode's only
// successor will be the corresponding ReturnNode, and the outgoing edges of
// the ReturnNode are the exit edges for the synchronized segment.
CFGNode onlySuccessor = Iterators.fromSingleton(cfg.getSuccessors(currentNode));
if (onlySuccessor != null && onlySuccessor instanceof ControlFlowGraph.ReturnNode) {
Iterators.addAll(monitorExitEdges, cfg.outgoingEdgesOf(onlySuccessor));
} else {
Iterators.addAll(monitorExitEdges, cfg.outgoingEdgesOf(currentNode));
}
break;
}
} else if (ih.getInstruction() instanceof MONITORENTER) {
currentNestingLevel++;
}
}
if (!isExit) {
for (CFGNode node : cfg.getSuccessors(currentNode)) {
todo.add(new Pair<CFGNode, Integer>(node, currentNestingLevel));
}
}
currentNode = null;
while (!todo.isEmpty()) {
Pair<CFGNode, Integer> nextPair = todo.pop();
CFGNode nextNode = nextPair.first();
if (!visited.contains(nextNode)) {
visited.add(nextNode);
if (cfg.outgoingEdgesOf(nextNode).isEmpty()) {
throw new AssertionError("Found monitor-exit free path from monitorenter to the end of a function. In: " + cfg);
} else if (nextNode.getBasicBlock() == null) {
for (CFGNode node : cfg.getSuccessors(nextNode)) {
todo.add(new Pair<CFGNode, Integer>(node, nextPair.second()));
}
} else {
currentNode = nextNode;
currentNestingLevel = nextPair.second();
insIter = currentNode.getBasicBlock().getInstructions().iterator();
break;
}
}
}
} while (currentNode != null);
Set<SuperGraphEdge> exitEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.liftCFGEdges(rootMethod, monitorExitEdges));
return new Segment(superGraph, entryEdges, exitEdges);
}
use of com.jopdesign.common.code.SuperGraph.ContextCFG in project jop by jop-devel.
the class MethodCacheAnalysis method findPersistenceSegmentCover.
/** Find a segment cover (i.e., a set of segments covering all execution paths)
* where each segment in the set is persistent (a cache persistence region (CPR))
*
* <h2>The simplest algorithm for a segment S (for acyclic callgraphs)</h2>
* <ul><li/>Check whether S itself is CPR; if so, return S
* <li/>Otherwise, create subsegments S' for each invoked method,
* <li/>and single node segments for each access
* </ul>
* @param segment the parent segment
* @param checks the strategy to use to determine whether a segment is a persistence region
* @param avoidOverlap whether overlapping segments should be avoided
* @param extraCostOut additional cost for edges which are considered as always-miss or not-cached
* @return
*/
protected Collection<Segment> findPersistenceSegmentCover(Segment segment, EnumSet<PersistenceCheck> checks, boolean avoidOverlap, Map<SuperGraphEdge, Long> extraCostOut) {
List<Segment> cover = new ArrayList<Segment>();
/* We currently only support entries to one CFG */
Set<ContextCFG> entryMethods = new HashSet<ContextCFG>();
for (SuperGraphEdge entryEdge : segment.getEntryEdges()) {
entryMethods.add(entryEdge.getTarget().getContextCFG());
}
if (entryMethods.size() != 1) {
throw new AssertionError("findPersistenceSegmentCover: only supporting segments with unique entry method");
}
if (this.isPersistenceRegion(segment, checks)) {
// System.err.println("Adding cover segment for: "+entryMethods);
cover.add(segment);
} else {
for (Pair<SuperInvokeEdge, SuperReturnEdge> invocation : segment.getCallSitesFrom(entryMethods.iterator().next())) {
ContextCFG callee = invocation.first().getCallee();
// System.err.println("Recursively analyzing: "+callee);
Segment subSegment = Segment.methodSegment(callee, segment.getSuperGraph());
Collection<Segment> subRegions = findPersistenceSegmentCover(subSegment, checks, avoidOverlap, extraCostOut);
cover.addAll(subRegions);
SuperReturnEdge rEdge = invocation.second();
MiscUtils.incrementBy(extraCostOut, rEdge, getMissCost(rEdge), 0);
}
}
return cover;
}
use of com.jopdesign.common.code.SuperGraph.ContextCFG in project jop by jop-devel.
the class ObjectCacheAnalysis method contextForSegment.
/**
* XXX: temporary helper to bridge gap between two representations (segment and scope)
* @param segment
* @return the corresponding execution context
* @throws RuntimeException if the conversion is impossible
*/
private ExecutionContext contextForSegment(Segment segment) {
ContextCFG entry;
Set<ContextCFG> entries = segment.getEntryCFGs();
if (entries.size() != 1) {
throw new RuntimeException("contextForSegment(): Currently we only support a single entry method");
}
entry = entries.iterator().next();
return new ExecutionContext(entry.getCfg().getMethodInfo(), entry.getCallString());
}
use of com.jopdesign.common.code.SuperGraph.ContextCFG in project jop by jop-devel.
the class GlobalAnalysis method getLoopBounds.
/**
* <p>Get all loop bounds for the given segment.</p>
* <p>For each loop bound B for loop H relative to marker M:</p>
* <p>sum(M) * B <= sum(continue-edges-of(H))</p>
*
* @param segment
* @return
* @throws InvalidFlowFactException
*/
private static Iterable<LinearConstraint<SuperGraphEdge>> getLoopBounds(WCETTool wcetTool, Segment segment) throws InvalidFlowFactException {
List<LinearConstraint<SuperGraphEdge>> constraints = new ArrayList<LinearConstraint<SuperGraphEdge>>();
// For all CFG instances
for (ContextCFG ccfg : segment.getCallGraphNodes()) {
ControlFlowGraph cfg = ccfg.getCfg();
// for all loops in the method
LoopColoring<CFGNode, ControlFlowGraph.CFGEdge> loops = cfg.getLoopColoring();
for (CFGNode hol : loops.getHeadOfLoops()) {
LoopBound loopBound = wcetTool.getLoopBound(hol, ccfg.getContext().getCallString());
if (loopBound == null) {
throw new AppInfoError("No loop bound record for head of loop: " + hol + " : " + cfg.buildLoopBoundMap());
}
addLoopConstraints(constraints, segment, ccfg, hol, loops, loopBound);
}
}
return constraints;
}
Aggregations