use of com.jopdesign.dfa.framework.FlowEdge in project jop by jop-devel.
the class LoopBounds method getInfeasibleEdges.
public Set<FlowEdge> getInfeasibleEdges(InstructionHandle stmt, CallString cs) {
ContextMap<CallString, Set<FlowEdge>> map = infeasibles.get(stmt);
Set<FlowEdge> retval = new LinkedHashSet<FlowEdge>();
if (map == null) {
// no infeasibility information here
return retval;
}
for (CallString c : map.keySet()) {
if (c.hasSuffix(cs)) {
Set<FlowEdge> f = map.get(c);
retval.addAll(f);
}
}
return retval;
}
use of com.jopdesign.dfa.framework.FlowEdge in project jop by jop-devel.
the class DFATool method buildPrologue.
private MethodInfo buildPrologue(MethodInfo mainMethod, List<InstructionHandle> statements, Flow flow, List<ClassInfo> clinits) {
// we use a prologue sequence for startup
InstructionList prologue = new InstructionList();
ConstantPoolGen prologueCP = mainMethod.getConstantPoolGen();
Instruction instr;
int idx;
// add magic initializers to prologue sequence
if (!analyzeBootMethod) {
instr = new ICONST(0);
prologue.append(instr);
instr = new ICONST(0);
prologue.append(instr);
idx = prologueCP.addMethodref("com.jopdesign.sys.GC", "init", "(II)V");
instr = new INVOKESTATIC(idx);
prologue.append(instr);
}
// add class initializers
for (ClassInfo clinit : clinits) {
MemberID cSig = appInfo.getClinitSignature(clinit.getClassName());
idx = prologueCP.addMethodref(cSig.getClassName(), cSig.getMemberName(), cSig.getDescriptor().toString());
instr = new INVOKESTATIC(idx);
prologue.append(instr);
}
if (analyzeBootMethod) {
// Let's just analyze the full boot method, so that the callgraph-builder is happy.
// Doing this after clinit, so that we have DFA infos on fields in JVMHelp.init()
idx = prologueCP.addMethodref("com.jopdesign.sys.Startup", "boot", "()V");
instr = new INVOKESTATIC(idx);
prologue.append(instr);
}
// add main method
instr = new ACONST_NULL();
prologue.append(instr);
idx = prologueCP.addMethodref(mainMethod.getClassName(), mainMethod.getShortName(), mainMethod.getDescriptor().toString());
instr = new INVOKESTATIC(idx);
prologue.append(instr);
// // invoke startMission() to ensure analysis of threads
// idx = prologueCP.addMethodref("joprt.RtThread", "startMission", "()V");
// instr = new INVOKESTATIC(idx);
// prologue.append(instr);
instr = new NOP();
prologue.append(instr);
prologue.setPositions(true);
// add prologue to program structure
for (Iterator l = prologue.iterator(); l.hasNext(); ) {
InstructionHandle handle = (InstructionHandle) l.next();
statements.add(handle);
if (handle.getInstruction() instanceof GOTO) {
GOTO g = (GOTO) handle.getInstruction();
flow.addEdge(new FlowEdge(handle, g.getTarget(), FlowEdge.NORMAL_EDGE));
} else if (handle.getNext() != null) {
flow.addEdge(new FlowEdge(handle, handle.getNext(), FlowEdge.NORMAL_EDGE));
}
}
MemberID pSig = new MemberID(prologueName, Descriptor.parse(prologueSig));
MethodInfo mi = mainMethod.getClassInfo().createMethod(pSig, null, prologue);
mi.setAccessType(AccessType.ACC_PRIVATE);
return mi;
}
use of com.jopdesign.dfa.framework.FlowEdge in project jop by jop-devel.
the class DFATool method loadMethod.
private void loadMethod(MethodInfo method) {
MethodCode mcode = method.getCode();
// TODO is there a better way to get an instruction handle? Do we need to keep the list somehow?
InstructionHandle exit;
exit = (InstructionHandle) method.getCustomValue(KEY_NOP);
// we reuse the NOP if it exists, so that we can have multiple DFAs running at the same time
if (exit == null) {
exit = new InstructionList(new NOP()).getStart();
// We do not really want to modify the REAL instruction list and append exit
// (SH) Fixed :) Yep, we need the NOP somewhere, else doInvoke() will collect the wrong result state.
// But we can eliminate the NOP by adding the instruction not to the list, but instead to the
// MethodInfo, and also retrieve it from there.
method.setCustomValue(KEY_NOP, exit);
}
this.getStatements().add(exit);
// We do not modify the code, so we leave existing CFGs alone, just make sure the instruction list is uptodate
InstructionList il = mcode.getInstructionList(true, false);
// we need correct positions for the DFA cache serialization stuff
il.setPositions();
for (Iterator<?> l = il.iterator(); l.hasNext(); ) {
InstructionHandle handle = (InstructionHandle) l.next();
this.getStatements().add(handle);
Instruction instr = handle.getInstruction();
if (instr instanceof BranchInstruction) {
if (instr instanceof Select) {
Select s = (Select) instr;
InstructionHandle[] target = s.getTargets();
for (InstructionHandle aTarget : target) {
this.getFlow().addEdge(new FlowEdge(handle, aTarget, FlowEdge.TRUE_EDGE));
}
this.getFlow().addEdge(new FlowEdge(handle, s.getTarget(), FlowEdge.FALSE_EDGE));
} else {
BranchInstruction b = (BranchInstruction) instr;
this.getFlow().addEdge(new FlowEdge(handle, b.getTarget(), FlowEdge.TRUE_EDGE));
}
}
if (handle.getNext() != null && !(instr instanceof UnconditionalBranch || instr instanceof Select || instr instanceof ReturnInstruction)) {
if (instr instanceof BranchInstruction) {
this.getFlow().addEdge(new FlowEdge(handle, handle.getNext(), FlowEdge.FALSE_EDGE));
} else {
this.getFlow().addEdge(new FlowEdge(handle, handle.getNext(), FlowEdge.NORMAL_EDGE));
}
}
if (instr instanceof ReturnInstruction) {
this.getFlow().addEdge(new FlowEdge(handle, exit, FlowEdge.NORMAL_EDGE));
}
}
}
use of com.jopdesign.dfa.framework.FlowEdge in project jop by jop-devel.
the class LoopBounds method copyResults.
@Override
public void copyResults(MethodInfo newContainer, Map<InstructionHandle, InstructionHandle> newHandles) {
for (Map.Entry<InstructionHandle, InstructionHandle> entry : newHandles.entrySet()) {
InstructionHandle oldHandle = entry.getKey();
InstructionHandle newHandle = entry.getValue();
if (newHandle == null)
continue;
// TODO support updating the callstrings too
// TODO this does NOT update stackPtr,.. in the new context!
ContextMap<CallString, Pair<ValueMapping, ValueMapping>> value = bounds.get(oldHandle);
if (value != null)
bounds.put(newHandle, value.copy(newContainer));
ContextMap<CallString, Interval> value1 = arrayIndices.get(oldHandle);
if (value1 != null)
arrayIndices.put(newHandle, value1.copy(newContainer));
ContextMap<CallString, Integer> value2 = scopes.get(oldHandle);
if (value2 != null)
scopes.put(newHandle, value2.copy(newContainer));
ContextMap<CallString, Interval[]> value3 = sizes.get(oldHandle);
if (value3 != null)
sizes.put(newHandle, value3.copy(newContainer));
ContextMap<CallString, Set<FlowEdge>> old = infeasibles.get(oldHandle);
if (old != null) {
Map<CallString, Set<FlowEdge>> map = new LinkedHashMap<CallString, Set<FlowEdge>>(old.size());
for (CallString cs : old.keySet()) {
Set<FlowEdge> newSet = new LinkedHashSet<FlowEdge>();
for (FlowEdge edge : old.get(cs)) {
InstructionHandle newHead = newHandles.get(edge.getHead());
InstructionHandle newTail = newHandles.get(edge.getTail());
if (newHead != null && newTail != null) {
Context ctx = new Context(edge.getContext());
ctx.setMethodInfo(newContainer);
newSet.add(new FlowEdge(newTail, newHead, edge.getType(), ctx));
}
}
map.put(cs, newSet);
}
Context c = old.getContext();
c.setMethodInfo(newContainer);
ContextMap<CallString, Set<FlowEdge>> edges = new ContextMap<CallString, Set<FlowEdge>>(c, map);
infeasibles.put(newHandle, edges);
}
}
}
use of com.jopdesign.dfa.framework.FlowEdge in project jop by jop-devel.
the class WCETTool method dfaInfeasibleEdge.
/**
* Get infeasible edges for certain basic block call string
* @param cfg the CFG containing the block
* @param block get infeasible outgoing edges for the block
* @param cs the callstring
* @return The infeasible edges for this basic block
*/
private List<CFGEdge> dfaInfeasibleEdge(ControlFlowGraph cfg, BasicBlock block, CallString cs) {
List<CFGEdge> retval = new LinkedList<CFGEdge>();
if (getDfaLoopBounds() != null) {
LoopBounds lbs = getDfaLoopBounds();
Set<FlowEdge> edges = lbs.getInfeasibleEdges(block.getLastInstruction(), cs);
for (FlowEdge e : edges) {
BasicBlockNode head = cfg.getHandleNode(e.getHead());
BasicBlockNode tail = cfg.getHandleNode(e.getTail());
CFGEdge edge = cfg.getEdge(tail, head);
if (edge != null) {
retval.add(edge);
} else {
// edge does was removed from the CFG
// logger.warn("The infeasible edge between "+head+" and "+tail+" does not exist");
}
}
}
return retval;
}
Aggregations