use of com.jopdesign.common.MethodCode 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.common.MethodCode in project jop by jop-devel.
the class WCETEventHandler method loadLoopAnnotations.
/**
* load annotations for the flow graph.
*
* @param cfg the control flow graph of the method
* @throws BadAnnotationException if an annotations is missing
*/
public void loadLoopAnnotations(ControlFlowGraph cfg) throws BadAnnotationException {
SourceAnnotations wcaMap;
MethodInfo method = cfg.getMethodInfo();
MethodCode code = method.getCode();
ExecutionContext eCtx = new ExecutionContext(cfg.getMethodInfo());
for (CFGNode n : cfg.getLoopColoring().getHeadOfLoops()) {
BasicBlockNode headOfLoop = (BasicBlockNode) n;
BasicBlock block = headOfLoop.getBasicBlock();
// check if loopbound has already been loaded
if (block.getLoopBound() != null) {
// or at least check if the source-annotation is tighter than what is currently set?
continue;
}
Set<LoopBound> bounds = new HashSet<LoopBound>(2);
InstructionHandle first = block.getFirstInstruction();
InstructionHandle last = first;
ClassInfo sourceInfo = method.getCode().getSourceClassInfo(block.getFirstInstruction());
for (InstructionHandle ih : block.getInstructions()) {
ClassInfo cls = method.getCode().getSourceClassInfo(ih);
boolean isLast = ih.equals(block.getLastInstruction());
if (!cls.equals(sourceInfo) || isLast) {
try {
wcaMap = getAnnotations(method.getCode().getSourceClassInfo(block.getFirstInstruction()));
} catch (IOException e) {
throw new BadAnnotationException("IO Error reading annotation: " + e.getMessage(), e);
}
if (isLast) {
last = ih;
}
// search for loop annotation in range
int sourceRangeStart = code.getLineNumber(first);
int sourceRangeStop = code.getLineNumber(last);
bounds.addAll(wcaMap.annotationsForLineRange(sourceRangeStart, sourceRangeStop + 1));
first = ih;
}
last = ih;
}
if (bounds.size() > 1) {
String reason = "Ambiguous Annotation [" + bounds + "]";
throw new BadAnnotationException(reason, code, block);
}
LoopBound loopAnnot = null;
if (bounds.size() == 1) {
loopAnnot = bounds.iterator().next();
}
// if we have loop bounds from DFA analysis, use them
loopAnnot = dfaLoopBound(block, eCtx, loopAnnot);
if (loopAnnot == null) {
// Bit of a hack: if we load CFGs before the callgraph is constructed, this will log errors anyway
if (ignoreMissingLoopBounds) {
logger.trace("No loop bound annotation: " + method + ":" + n + " " + getLineRangeText(code, block) + ".\nApproximating with " + DEFAULT_LOOP_BOUND + ", but result is not safe anymore.");
} else if (project.getCallGraph() != null && !project.getCallGraph().containsMethod(method)) {
logger.debug("No loop bound annotation for non-WCET method: " + method + ":" + n + " " + getLineRangeText(code, block) + ".\nApproximating with " + DEFAULT_LOOP_BOUND);
} else {
logger.error("No loop bound annotation: " + method + ":" + n + " " + getLineRangeText(code, block) + ".\nApproximating with " + DEFAULT_LOOP_BOUND + ", but result is not safe anymore.");
}
loopAnnot = LoopBound.defaultBound(DEFAULT_LOOP_BOUND);
}
block.setLoopBound(loopAnnot);
}
}
use of com.jopdesign.common.MethodCode in project jop by jop-devel.
the class InlineHelper method checkConstraints.
/**
* Check if inlining is possible under the target code restrictions. This check depends on the caller code,
* so this check can turn to false if other invokes in the caller are inlined.
* <p>
* This does not check the application code size, this must be done by the optimization.
* </p>
*
* @param invoker the method into which the invokee is inlined.
* @param invokeSite The invoke site. Does not need to refer to an invoke instruction, and does not need to
* refer to the method which will actually contain the invocation (in case of recursive inlining).
* @param invokee the devirtualized invokee.
* @param deltaCode size of code inserted or removed from the caller in addition to the inlined method.
* This can include nullpointer checks, other invokes which will be inlined in the caller but have
* not yet been inlined or code to save the stack. This does not include the current invoke instruction
* or the code to be inlined (i.e. if only the invokesite is replaced by the invokee code, this is 0).
* @param numLocals the number of (live) local variable slots in the caller at the invokesite. This code
* does not check if a local variable assignment is actually possible, i.e. it might be possible
* that although enough slots are available, inlining is not possible due to fragmentation of the
* unused slots in the caller if the callee uses double or long values, so you either need to
* check this yourself or simply pass largest live slot number. Pass 0 to skip this test.
* @param stackSize Used slots on the stack before the invoke site.
* @return true if no target size constraints are violated.
*/
public boolean checkConstraints(MethodInfo invoker, InvokeSite invokeSite, MethodInfo invokee, int deltaCode, int numLocals, int stackSize) {
MethodCode code = invokee.getCode();
// TODO needed to make sure maxLocals and maxStack is uptodate.. Maybe we can skip this and require the analysis to do that?
code.compile();
int codeSize = invoker.getCode().getNumberOfBytes() + code.getNumberOfBytes() + deltaCode;
if ((maxCodesize > 0 && codeSize > maxCodesize)) {
return false;
}
// check if we have enough local variables available
if (maxLocals > 0 && numLocals + code.getMaxLocals() > maxLocals) {
return false;
}
if (maxStacksize > 0 && stackSize + code.getMaxStack() > maxStacksize) {
return false;
}
return true;
}
use of com.jopdesign.common.MethodCode in project jop by jop-devel.
the class InlineOptimizer method findCandidates.
@Override
public Collection<Candidate> findCandidates(MethodInfo method, AnalysisManager analyses, StacksizeAnalysis stacksize, int maxLocals, InstructionHandle start, InstructionHandle end) {
List<Candidate> candidates = new LinkedList<Candidate>();
MethodCode code = method.getCode();
InstructionHandle next = end.getNext();
for (InstructionHandle ih = start; ih != next; ih = ih.getNext()) {
if (code.isInvokeSite(ih)) {
InvokeSite site = code.getInvokeSite(ih);
// since we update the appInfo callgraph, the callstring only contains the invokesite and no
// inlined methods
CallString cs = new CallString(site);
countInvokeSites++;
MethodInfo invokee = helper.devirtualize(cs);
if (invokee == null)
continue;
countDevirtualized++;
// for the initial check and the DFA lookup we need the old callstring
cs = getInlineCallString(code, ih).push(site);
Candidate candidate = checkInvoke(code, cs, site, invokee, maxLocals);
if (candidate == null) {
continue;
}
// initial check for locals and stack, calculate gain and codesize
if (!candidate.recalculate(analyses, stacksize)) {
continue;
}
candidates.add(candidate);
}
}
return candidates;
}
use of com.jopdesign.common.MethodCode in project jop by jop-devel.
the class HashTest method main.
public static void main(String[] args) {
TestFramework test = new TestFramework();
AppSetup setup = test.setupAppSetup();
AppInfo appInfo = test.setupAppInfo("common.code.HashTest", false);
ClassInfo testClass = appInfo.loadClass("common.TestFramework");
MethodInfo mainMethod = appInfo.getMainMethod();
MethodCode code = mainMethod.getCode();
InstructionHandle[] ih = code.getInstructionList().getInstructionHandles();
InvokeSite i1 = code.getInvokeSite(ih[1]);
InvokeSite i2 = code.getInvokeSite(ih[2]);
InvokeSite i3 = code.getInvokeSite(ih[3]);
InvokeSite i11 = code.getInvokeSite(ih[1]);
check(i1 == i11);
CallString c1 = new CallString(i1);
CallString c2 = new CallString(i2);
CallString c11 = new CallString(i1);
check(c1.equals(c11));
check(!c1.equals(c2));
ExecutionContext e1 = new ExecutionContext(mainMethod, c1);
ExecutionContext e2 = new ExecutionContext(mainMethod, c2);
ExecutionContext e11 = new ExecutionContext(mainMethod, c11);
check(e1.equals(e11));
check(!e1.equals(e2));
// TODO put stuff into maps, check contains() and get()
// modify instruction list, check if everything still works
InstructionList il = code.getInstructionList();
il.insert(new ILOAD(0));
il.insert(ih[2], new ILOAD(1));
ih = il.getInstructionHandles();
InvokeSite i12 = code.getInvokeSite(ih[2]);
InvokeSite i22 = code.getInvokeSite(ih[4]);
check(i12 == i1);
check(i22 == i2);
check(e1.equals(e11));
check(!e1.equals(e2));
il.setPositions();
check(c1.equals(c11));
check(!c1.equals(c2));
check(e1.equals(e11));
check(!e1.equals(e2));
}
Aggregations