use of com.jopdesign.common.code.SuperGraph.SuperGraphNode in project jop by jop-devel.
the class MethodCacheAnalysis method getMissCost.
/**
* Get miss cost for an edge accessing the method cache
* @param accessEdge either a SuperInvoke or SuperReturn edge, or an entry edge of the segment analyzed
* @return maximum miss penalty (in cycles)
*/
private long getMissCost(SuperGraphEdge accessEdge) {
SuperGraphNode accessed = accessEdge.getTarget();
ControlFlowGraph cfg = accessed.getCfg();
if (accessEdge instanceof SuperReturnEdge) {
/* return edge: return cost */
Type returnType = accessEdge.getSource().getCfg().getMethodInfo().getType();
return methodCache.getMissPenaltyOnReturn(cfg.getNumberOfWords(), returnType);
} else if (accessEdge instanceof SuperInvokeEdge) {
InstructionHandle invokeIns = ((SuperInvokeEdge) accessEdge).getInvokeNode().getInvokeSite().getInstructionHandle();
return methodCache.getMissPenaltyOnInvoke(cfg.getNumberOfWords(), invokeIns.getInstruction());
} else {
/* entry edge of the segment: can be invoke or return cost */
return methodCache.getMissPenalty(cfg.getNumberOfWords(), false);
}
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphNode 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.SuperGraphNode in project jop by jop-devel.
the class ObjectCacheAnalysis method extractAccessesAndCosts.
/** Traverse vertex set.
* <p>Add vertex to access set of referenced addresses
* For references whose type cannot be fully resolved, add a
* cost of 1.</p>
* <p>FIXME: We should deal with subtyping (or better use storage based alias-analysis)</p>
*
* @param nodes
* @param usedRefs the results of the local points-to analysis, or {@code null} for always miss costs
* @param costModel
*/
private AccessCostInfo extractAccessesAndCosts(Iterable<SuperGraphNode> nodes, LocalPointsToResult usedRefs, ObjectCacheCostModel costModel) {
AccessCostInfo aci = new AccessCostInfo();
for (SuperGraphNode node : nodes) {
/* Compute cost for basic block */
BasicBlock bb = node.getCFGNode().getBasicBlock();
if (bb == null)
continue;
long bypassCost = 0;
long alwaysMissCost = 0;
CallString cs = node.getContextCFG().getCallString();
for (InstructionHandle ih : bb.getInstructions()) {
String handleType = getHandleType(project, node.getCfg(), ih);
if (handleType == null)
continue;
/* No getfield/handle access */
int fieldIndex = getFieldIndex(project, node.getCfg(), ih);
int blockIndex = getBlockIndex(fieldIndex);
if (fieldIndex > this.maxCachedFieldIndex) {
bypassCost += costModel.getFieldAccessCostBypass();
continue;
}
BoundedSet<SymbolicAddress> refs = null;
if (usedRefs != null) {
if (!usedRefs.containsKey(ih)) {
usedRefs = null;
WCETTool.logger.error("No DFA results for: " + ih.getInstruction() + " with field " + ((FieldInstruction) ih.getInstruction()).getFieldName(bb.cpg()));
} else {
refs = usedRefs.get(ih, cs);
if (refs.isSaturated())
refs = null;
}
}
if (refs == null) {
alwaysMissCost += costModel.getReplaceLineCost() + costModel.getLoadCacheBlockCost();
} else {
for (SymbolicAddress ref : refs.getSet()) {
aci.addRefAccess(ref, node);
aci.addBlockAccess(ref.accessArray(blockIndex), node);
// Handle getfield_long / getfield_double
if (getCachedType(project, node.getCfg(), ih) == Type.LONG || getCachedType(project, node.getCfg(), ih) == Type.DOUBLE) {
if (blockIndex + 1 > this.maxCachedFieldIndex) {
bypassCost += costModel.getFieldAccessCostBypass();
} else {
aci.addBlockAccess(ref.accessArray(blockIndex + 1), node);
}
}
}
}
}
aci.putBypassCost(node, bypassCost);
aci.putStaticCost(node, bypassCost + alwaysMissCost);
}
return aci;
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphNode 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;
}
use of com.jopdesign.common.code.SuperGraph.SuperGraphNode in project jop by jop-devel.
the class ObjectCacheAnalysis method extractCost.
/**
*
* @param segment the segment analyzed
* @param lpCost the lp objective value
* @param flowMap the lp assignment for variables
* @param accessCostInfo information on object cache cost edges
* @param costModel the object cache cost model
* @param refMissEdges the object cache cost edges for references
* @param blockMissEdges the object cache cost edges for blocks
* @return
*/
private ObjectCache.ObjectCacheCost extractCost(Segment segment, long lpCost, Map<SuperGraphEdge, Long> flowMap, AccessCostInfo accessCostInfo, ObjectCacheCostModel costModel, Set<SuperGraphEdge> refMissEdges, Set<SuperGraphEdge> blockMissEdges) {
long missCount = 0;
/* miss count */
long totalMissCost = 0;
/* has to be equal to (cost - bypass cost) */
long bypassAccesses = 0;
/* bypassed fields accesses */
long fieldAccesses = 0;
/* cached fields accessed */
long totalBypassCost = 0;
for (SuperGraphEdge edge : segment.getEdges()) {
long edgeFreq = flowMap.get(edge);
SuperGraphNode node = edge.getTarget();
/* Compute cost for basic block */
BasicBlock bb = node.getCFGNode().getBasicBlock();
if (bb == null)
continue;
long missCost = accessCostInfo.getMissCost(node) * edgeFreq;
totalMissCost += missCost;
totalBypassCost += accessCostInfo.getBypassCost(node) * edgeFreq;
/* Calculate number of unpredictable always-miss accesses, and record them */
long alwaysMissCost = costModel.getReplaceLineCost() + costModel.getLoadCacheBlockCost();
if (alwaysMissCost > 0) {
missCount += missCost / alwaysMissCost;
}
/* count normal and bypass accesses in the basic block */
for (InstructionHandle ih : bb.getInstructions()) {
String handleType = getHandleType(project, node.getCfg(), ih);
if (handleType == null)
continue;
/* No getfield/handle access */
if (!isFieldCached(project, node.getCfg(), ih, maxCachedFieldIndex)) {
bypassAccesses += edgeFreq;
} else {
fieldAccesses += edgeFreq;
}
}
}
/* For each miss edge, there is an associated cost; moreover
* fill-word & single-field: missCount = sum of miss block variables
* fill-line: missCount = sum of miss object reference variables
*/
long totalRefMisses = 0;
for (SuperGraphEdge refMissEdge : refMissEdges) {
totalRefMisses += flowMap.get(refMissEdge);
}
totalMissCost += costModel.getReplaceLineCost() * totalRefMisses;
long totalBlockMisses = 0;
for (SuperGraphEdge blockMissEdge : blockMissEdges) {
totalBlockMisses += flowMap.get(blockMissEdge);
}
totalMissCost += costModel.getLoadCacheBlockCost() * totalBlockMisses;
missCount += totalBlockMisses;
if (totalMissCost + totalBypassCost != lpCost) {
WCETTool.logger.warn(String.format("Error in calculating missCost in all fit-area (misscount = %d): %d but should be %d (%d - %d)", missCount, totalMissCost, lpCost - totalBypassCost, lpCost, totalBypassCost));
}
ObjectCache.ObjectCacheCost ocCost = new ObjectCache.ObjectCacheCost(missCount, totalMissCost, bypassAccesses, totalBypassCost, fieldAccesses);
return ocCost;
}
Aggregations