use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge in project jop by jop-devel.
the class Segment method methodSegment.
/**
* Create an interprocedural segment for a method
* @param targetMethod The method to build a segment for
* @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 method (not including the virtual entry and exit nodes)
*/
public static Segment methodSegment(MethodInfo targetMethod, CallString callString, CFGProvider cfgProvider, int callStringLength, InfeasibleEdgeProvider infeasibles) {
if (infeasibles == null) {
infeasibles = InfeasibleEdgeProvider.NO_INFEASIBLES;
}
SuperGraph superGraph = new SuperGraph(cfgProvider, cfgProvider.getFlowGraph(targetMethod), callString, callStringLength, infeasibles);
ContextCFG rootMethod = superGraph.getRootNode();
Set<SuperGraphEdge> entryEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.getCFGEntryEdges(rootMethod)), exitEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.getCFGExitEdges(rootMethod));
return new Segment(superGraph, entryEdges, exitEdges);
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge in project jop by jop-devel.
the class SegmentTest method main.
public static void main(String[] args) {
TestFramework testFramework = new TestFramework();
AppSetup setup = testFramework.setupAppSetup("java/tools/test/test/cg1.zip", null);
AppInfo appInfo = testFramework.setupAppInfo("wcet.devel.CallGraph1.run", true);
SegmentTest testInst = new SegmentTest();
testInst.appInfo = appInfo;
MethodInfo mainMethod = appInfo.getMainMethod();
/* count total number of CFG nodes */
SuperGraph superGraph = new SuperGraph(testInst, testInst.getFlowGraph(mainMethod), 2);
Segment segment = Segment.methodSegment(mainMethod, CallString.EMPTY, testInst, 2, superGraph.getInfeasibleEdgeProvider());
int count = 0;
for (ContextCFG cgNode : superGraph.getCallGraphNodes()) {
try {
cgNode.getCfg().exportDOT(new File("/tmp/cfg-" + cgNode.getCfg().getMethodInfo().getClassName() + "_" + cgNode.getCfg().getMethodInfo().getShortName() + ".dot"));
} catch (IOException e) {
}
count += cgNode.getCfg().vertexSet().size();
}
checkEquals("[Segment 1] Expected node count", (count - 2), Iterators.size(segment.getNodes()));
try {
segment.exportDOT(new File("/tmp/cg1-segment.dot"));
} catch (IOException e) {
e.printStackTrace();
}
/* root */
ContextCFG root = superGraph.getRootNode();
/* Build a segment cuts all invokes in those methods invoked by run() */
Segment segment2;
/* root entries */
Set<SuperGraphEdge> entries = new HashSet<SuperGraphEdge>();
Iterators.addAll(entries, superGraph.liftCFGEdges(root, root.getCfg().outgoingEdgesOf(root.getCfg().getEntry())));
Set<SuperGraphEdge> exits = new HashSet<SuperGraphEdge>();
int cfgNodeCandidateCount = root.getCfg().vertexSet().size();
/* find callees */
for (SuperEdge superEdge : superGraph.getCallGraph().outgoingEdgesOf(root)) {
if (!(superEdge instanceof SuperInvokeEdge))
continue;
ContextCFG callee1 = superGraph.getCallGraph().getEdgeTarget(superEdge);
cfgNodeCandidateCount += callee1.getCfg().vertexSet().size();
/* find all edges from invoke nodes */
for (CFGNode cfgNode : callee1.getCfg().vertexSet()) {
if (cfgNode instanceof InvokeNode) {
Iterators.addAll(exits, superGraph.outgoingEdgesOf(new SuperGraphNode(callee1, cfgNode)));
}
}
}
segment2 = new Segment(superGraph, entries, exits);
exits = segment2.getExitEdges();
/* reachable exits */
try {
segment2.exportDOT(new File("/tmp/cg1-segment2.dot"));
} catch (IOException e) {
e.printStackTrace();
}
checkEquals("[Segment 2] Expected node count", 14, Iterators.size(segment2.getNodes()) + 2);
checkLessEqual("[Segment 2] Expected node count <= |root + directly invoked|", Iterators.size(segment2.getNodes()) + 2, cfgNodeCandidateCount);
/* Another segment, with entries the exits of the last segment, and exits all invokes in methods the entries */
Segment segment3;
entries = segment2.getExitEdges();
exits = new HashSet<SuperGraphEdge>();
cfgNodeCandidateCount = 0;
for (SuperGraphEdge superEdge : entries) {
SuperGraphNode node1 = superEdge.getTarget();
for (SuperEdge superEdge2 : superGraph.getCallGraph().outgoingEdgesOf(node1.getContextCFG())) {
if (!(superEdge2 instanceof SuperInvokeEdge))
continue;
ContextCFG callee2 = superGraph.getCallGraph().getEdgeTarget(superEdge2);
/* find all edges from invoke nodes */
for (CFGNode cfgNode : callee2.getCfg().vertexSet()) {
if (cfgNode instanceof InvokeNode) {
Iterators.addAll(exits, superGraph.outgoingEdgesOf(new SuperGraphNode(callee2, cfgNode)));
}
}
}
}
segment3 = new Segment(superGraph, entries, exits);
try {
segment3.exportDOT(new File("/tmp/cg1-segment3.dot"));
} catch (IOException e) {
e.printStackTrace();
}
checkEquals("[Segment 2] 3 exits", 3, segment2.getExitEdges().size());
checkEquals("[Segment 3] 3 entries", 3, segment3.getEntryEdges().size());
checkEquals("[Segment 3] 4 exits", 4, segment3.getExitEdges().size());
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge in project jop by jop-devel.
the class ObjectCacheAnalysis 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 alwaysMissNodes additional node set considered to be always miss
* @return
* @throws LpSolveException
* @throws InvalidFlowFactException
*/
protected Collection<Segment> findPersistenceSegmentCover(Segment segment, EnumSet<PersistenceCheck> checks, boolean avoidOverlap, Set<SuperGraphNode> alwaysMissNodes) throws InvalidFlowFactException, LpSolveException {
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());
}
ContextCFG entryMethod;
if (entryMethods.size() != 1) {
throw new AssertionError("findPersistenceSegmentCover: only supporting segments with unique entry method");
} else {
entryMethod = entryMethods.iterator().next();
}
if (this.isPersistenceRegion(segment, checks)) {
cover.add(segment);
} else {
/* method sub segments */
for (Pair<SuperInvokeEdge, SuperReturnEdge> invocation : segment.getCallSitesFrom(entryMethod)) {
ContextCFG callee = invocation.first().getCallee();
// System.err.println("Recursively analyzing: "+callee);
Segment subSegment = Segment.methodSegment(callee, segment.getSuperGraph());
cover.addAll(findPersistenceSegmentCover(subSegment, checks, avoidOverlap, alwaysMissNodes));
}
/* always miss nodes (not covered) */
alwaysMissNodes.addAll(segment.getNodes(entryMethod));
}
return cover;
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge in project jop by jop-devel.
the class ObjectCacheAnalysis 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 checks
* @throws LpSolveException
* @throws InvalidFlowFactException
*/
@Override
public Set<SuperGraphEdge> addMissOnceCost(Segment segment, IPETSolver<SuperGraphEdge> ipetSolver, EnumSet<PersistenceCheck> checks) throws InvalidFlowFactException, LpSolveException {
Set<SuperGraphEdge> missCostEdges = new HashSet<SuperGraphEdge>();
Set<SuperGraphNode> alwaysMissNodes = new HashSet<SuperGraphNode>();
Collection<Segment> cover = findPersistenceSegmentCover(segment, EnumSet.allOf(PersistenceCheck.class), false, alwaysMissNodes);
int tag = 0;
for (Segment persistenceSegment : cover) {
tag++;
/* Compute cost for persistence segment */
HashSet<SymbolicAddress> usedSetOut = new HashSet<SymbolicAddress>();
ObjectCacheCost cost = computeCacheCost(persistenceSegment, getUsedRefs(persistenceSegment), objectCache.getCostModel(), usedSetOut);
WCETTool.logger.info("O$-addMissOnceCost: " + cost.toString());
F1<SuperGraphEdge, Long> costModel = MiscUtils.const1(cost.getCost());
Set<SuperGraphEdge> costEdges = addFixedCostEdges(persistenceSegment.getEntryEdges(), ipetSolver, costModel, KEY + "_miss_once", tag);
missCostEdges.addAll(costEdges);
}
AccessCostInfo alwaysMissAccessInfo = extractAccessesAndCosts(alwaysMissNodes, null, objectCache.getCostModel());
missCostEdges.addAll(addStaticCost(segment, alwaysMissAccessInfo, ipetSolver));
return missCostEdges;
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphEdge in project jop by jop-devel.
the class ObjectCacheAnalysis method addMissOnceConstraints.
/**
* Add miss once constraints for all subsegments in the persistence cover of the given segment
* @param segment
* @param ipetSolver
* @return
* @throws LpSolveException
* @throws InvalidFlowFactException
*/
@Override
public Set<SuperGraphEdge> addMissOnceConstraints(Segment segment, IPETSolver<SuperGraphEdge> ipetSolver) throws InvalidFlowFactException, LpSolveException {
Set<SuperGraphEdge> missEdges = new HashSet<SuperGraphEdge>();
Set<SuperGraphNode> alwaysMissNodes = new HashSet<SuperGraphNode>();
Collection<Segment> cover = findPersistenceSegmentCover(segment, EnumSet.allOf(PersistenceCheck.class), false, alwaysMissNodes);
int segmentCounter = 0;
for (Segment persistenceSegment : cover) {
/* we need to distinguish edges which are shared between persistence segments */
String key = KEY + "_" + (++segmentCounter);
LocalPointsToResult usedRefs = getUsedRefs(persistenceSegment);
/* Compute worst-case cost */
HashSet<SymbolicAddress> usedObjectsSet = new HashSet<SymbolicAddress>();
ObjectCacheIPETModel ocim = addObjectCacheCostEdges(persistenceSegment, usedRefs, objectCache.getCostModel(), ipetSolver);
missEdges.addAll(ocim.staticCostEdges);
missEdges.addAll(ocim.refMissEdges);
missEdges.addAll(ocim.blockMissEdges);
}
AccessCostInfo alwaysMissAccessInfo = extractAccessesAndCosts(alwaysMissNodes, null, objectCache.getCostModel());
missEdges.addAll(addStaticCost(segment, alwaysMissAccessInfo, ipetSolver));
return missEdges;
}
Aggregations