use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge 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.SuperGraphEdge in project jop by jop-devel.
the class Segment method exportDOT.
/**
* Export to DOT file
* @param dotFile
* @throws IOException
*/
public void exportDOT(File dotFile) throws IOException {
FileWriter dotWriter = new FileWriter(dotFile);
AdvancedDOTExporter.DOTNodeLabeller<SuperGraphNode> nodeLabeller = new AdvancedDOTExporter.DefaultNodeLabeller<SuperGraphNode>() {
@Override
public String getLabel(SuperGraphNode node) {
StringBuilder sb = new StringBuilder();
/* for entry nodes: method + call string */
if (node.getCFGNode().getId() == 0) {
sb.append(node.getContextCFG().getCfg().getMethodInfo().getFQMethodName() + "\n");
int i = 1;
for (InvokeSite is : node.getContextCFG().getCallString()) {
sb.append(" #" + i + " " + is.getInvoker().getFQMethodName() + " / " + is.getInstructionHandle().getPosition() + "\n");
i += 1;
}
} else /* for other nodes: basic block export */
{
sb.append(node.getCFGNode().toString());
}
return sb.toString();
}
};
DOTLabeller<SuperGraphEdge> edgeLabeller = new AdvancedDOTExporter.DefaultDOTLabeller<SuperGraphEdge>() {
@Override
public String getLabel(SuperGraphEdge edge) {
return "";
}
@Override
public boolean setAttributes(SuperGraphEdge edge, Map<String, String> ht) {
super.setAttributes(edge, ht);
if (edge instanceof SuperReturnEdge) {
ht.put("style", "dotted");
ht.put("arrowhead", "empty");
} else if (edge instanceof SuperInvokeEdge) {
ht.put("style", "dotted");
}
return true;
}
};
AdvancedDOTExporter<SuperGraphNode, SuperGraphEdge> de = new AdvancedDOTExporter<SuperGraphNode, SuperGraphEdge>(nodeLabeller, edgeLabeller);
de.exportDOTDiGraph(dotWriter, this.getNodes(), this.getEdges(), new AdvancedDOTExporter.GraphAdapter<SuperGraphNode, SuperGraphEdge>() {
@Override
public SuperGraphNode getEdgeSource(SuperGraphEdge e) {
return e.getSource();
}
@Override
public SuperGraphNode getEdgeTarget(SuperGraphEdge e) {
return e.getTarget();
}
});
dotWriter.close();
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge in project jop by jop-devel.
the class Segment method buildSegment.
/**
* Collect all supergraph edges which are part of the segment.
* As segments are allowed to be interprocedural, we require that
* control flow graphs have return edges, and that return edges
* are in the exit set if they are not part of the segment.
*/
private Set<SuperGraphEdge> buildSegment() {
nodes = new HashMap<SuperGraph.ContextCFG, List<SuperGraphNode>>();
edges = new HashSet<SuperGraphEdge>();
otherEntries = new HashSet<SuperGraphEdge>();
HashSet<SuperGraphEdge> actualExits = new HashSet<SuperGraphEdge>();
Stack<SuperGraphEdge> worklist = new Stack<SuperGraphEdge>();
/* push all targets of entry edges on the worklist */
worklist.addAll(entries);
while (!worklist.isEmpty()) {
SuperGraphEdge current = worklist.pop();
if (edges.contains(current))
continue;
/* continue if marked black */
edges.add(current);
/* If this is an exit egde, remember that it has been visited, and continue */
if (exits.contains(current)) {
actualExits.add(current);
continue;
}
/* Otherwise add the target node and push all successors on the worklist */
SuperGraphNode target = current.getTarget();
MiscUtils.addToList(nodes, target.getContextCFG(), target);
Iterators.addAll(worklist, sg.getSuccessorEdges(current));
}
exits = actualExits;
for (SuperGraphNode node : getNodes()) {
for (SuperGraphEdge edge : sg.incomingEdgesOf(node)) {
if (!edges.contains(edge)) {
otherEntries.add(edge);
}
}
}
/* for all nodes find entries which are not part of the segment; this are "otherEntries" */
return edges;
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge in project jop by jop-devel.
the class MethodCacheAnalysis method addMissOnceConstraints.
/**
* Add miss once constraints for all subsegments in the persistence cover of the given segment
* @param segment
* @param ipetSolver
* @return
*/
@Override
public Set<SuperGraphEdge> addMissOnceConstraints(Segment segment, IPETSolver<SuperGraphEdge> ipetSolver) {
Set<SuperGraphEdge> missEdges = new HashSet<SuperGraphEdge>();
Map<SuperGraphEdge, Long> extraCost = new HashMap<SuperGraphEdge, Long>();
Collection<Segment> cover = findPersistenceSegmentCover(segment, EnumSet.allOf(PersistenceCheck.class), false, extraCost);
int segmentCounter = 0;
for (Segment persistenceSegment : cover) {
/* we need to distinguish edges which are shared between persistence segments */
String key = KEY + "_" + (++segmentCounter);
missEdges.addAll(addPersistenceSegmentConstraints(persistenceSegment, getCacheAccessesByTag(persistenceSegment).entrySet(), ipetSolver, EDGE_MISS_COST, key));
}
for (Entry<SuperGraphEdge, Long> entry : extraCost.entrySet()) {
missEdges.add(fixedAdditionalCostEdge(entry.getKey(), KEY + "_am", 0, entry.getValue(), ipetSolver));
}
return missEdges;
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge in project jop by jop-devel.
the class MethodCacheAnalysis method addMissOnceCost.
/**
* Add miss once cost: for each method cache persistence segment, add maximum miss cost to the segment entries
* @param segment
* @param ipetSolver
* @param peristenceChecks which checks to perform
* @throws LpSolveException
* @throws InvalidFlowFactException
*/
@Override
public Set<SuperGraphEdge> addMissOnceCost(Segment segment, IPETSolver<SuperGraphEdge> ipetSolver, EnumSet<PersistenceCheck> checks) throws InvalidFlowFactException, LpSolveException {
Set<SuperGraphEdge> missEdges = new HashSet<SuperGraphEdge>();
Map<SuperGraphEdge, Long> extraCost = new HashMap<SuperGraphEdge, Long>();
Collection<Segment> cover = findPersistenceSegmentCover(segment, checks, true, extraCost);
int tag = 0;
for (Segment persistenceSegment : cover) {
tag++;
/* Collect all cache accesses */
long cost = computeMissOnceCost(persistenceSegment, getCacheAccessesByTag(persistenceSegment).entrySet(), EDGE_MISS_COST, true, KEY + ".addMissOnceCost", wcetTool);
F1<SuperGraphEdge, Long> costModel = MiscUtils.const1(cost);
Set<SuperGraphEdge> costEdges = addFixedCostEdges(persistenceSegment.getEntryEdges(), ipetSolver, costModel, KEY + "_miss_once", tag);
missEdges.addAll(costEdges);
}
for (Entry<SuperGraphEdge, Long> entry : extraCost.entrySet()) {
missEdges.add(fixedAdditionalCostEdge(entry.getKey(), KEY + "_am", 0, entry.getValue(), ipetSolver));
}
return missEdges;
}
Aggregations