Commit 2a40171d authored by Yudi Zheng's avatar Yudi Zheng

Introduce MethodAnalysisContext, which will cache the analysis result for methods.

Now the BasicBlockStaticContext will not generate control flow graph for each Shadow.
parent 2534c634
......@@ -3,16 +3,15 @@ package ch.usi.dag.disl.staticcontext;
import java.util.List;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.util.cfg.CtrlFlowGraph;
import ch.usi.dag.disl.util.cfg.LoopAnalyzer;
public class BasicBlockStaticContext extends AbstractStaticContext {
public class BasicBlockStaticContext extends
MethodAnalysisContext<CtrlFlowGraph> {
public int getTotBBs() {
CtrlFlowGraph cfg = new CtrlFlowGraph(
staticContextData.getMethodNode());
return cfg.getNodes().size();
return thisAnalysis.getNodes().size();
}
public int getBBSize() {
......@@ -37,15 +36,11 @@ public class BasicBlockStaticContext extends AbstractStaticContext {
}
public int getBBindex() {
CtrlFlowGraph cfg = new CtrlFlowGraph(
staticContextData.getMethodNode());
return cfg.getIndex(staticContextData.getRegionStart());
return thisAnalysis.getIndex(staticContextData.getRegionStart());
}
public boolean isFirstOfLoop() {
return LoopAnalyzer.isEntryOfLoop(staticContextData.getMethodNode(),
staticContextData.getRegionStart());
@Override
public CtrlFlowGraph analysis(MethodNode method) {
return new CtrlFlowGraph(method);
}
}
package ch.usi.dag.disl.util.cfg;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
public class LoopAnalyzer {
// compute dominators
private static Map<BasicBlock, Set<BasicBlock>> computeDominators(
CtrlFlowGraph cfg, MethodNode method) {
// initialization
Set<BasicBlock> entries = new HashSet<BasicBlock>();
entries.add(cfg.getBB(method.instructions.getFirst()));
for (TryCatchBlockNode tcb : method.tryCatchBlocks) {
entries.add(cfg.getBB(tcb.handler));
}
Map<BasicBlock, Set<BasicBlock>> dominatormapping = new HashMap<BasicBlock, Set<BasicBlock>>();
for (BasicBlock bb : cfg.getNodes()) {
Set<BasicBlock> dominators = new HashSet<BasicBlock>();
if (entries.contains(bb)) {
dominators.add(bb);
} else {
dominators.addAll(cfg.getNodes());
}
dominatormapping.put(bb, dominators);
}
// whether the dominators of any basic block is changed
boolean changed;
// loop until no more changes
do {
changed = false;
for (BasicBlock bb : cfg.getNodes()) {
if (entries.contains(bb)) {
continue;
}
Set<BasicBlock> dominators = dominatormapping.get(bb);
dominators.remove(bb);
// update the dominators of current basic block,
// contains only the dominators of its predecessors
for (BasicBlock predecessor : bb.getPredecessors()) {
if (dominators.retainAll(dominatormapping.get(predecessor))) {
changed = true;
}
}
dominators.add(bb);
}
} while (changed);
return dominatormapping;
}
public static boolean isEntryOfLoop(MethodNode method,
AbstractInsnNode instr) {
CtrlFlowGraph cfg = CtrlFlowGraph.build(method);
cfg.visit(method.instructions.getFirst());
Map<BasicBlock, Set<BasicBlock>> dominatormapping = computeDominators(
cfg, method);
BasicBlock entry = cfg.getBB(instr);
for (BasicBlock bb : entry.getPredecessors()) {
if (dominatormapping.get(bb).contains(entry)) {
return true;
}
}
return false;
}
}
package ch.usi.dag.disl.staticcontext;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import ch.usi.dag.disl.util.cfg.BasicBlock;
import ch.usi.dag.disl.util.cfg.CtrlFlowGraph;
public class LoopStaticContext extends BasicBlockStaticContext {
private Map<BasicBlock, Set<BasicBlock>> dominatormapping;
@Override
public CtrlFlowGraph analysis(MethodNode method) {
CtrlFlowGraph cfg = CtrlFlowGraph.build(method);
dominatormapping = new HashMap<BasicBlock, Set<BasicBlock>>();
Set<BasicBlock> entries = new HashSet<BasicBlock>();
entries.add(cfg.getBB(method.instructions.getFirst()));
for (TryCatchBlockNode tcb : method.tryCatchBlocks) {
entries.add(cfg.getBB(tcb.handler));
}
for (BasicBlock bb : cfg.getNodes()) {
Set<BasicBlock> dominators = new HashSet<BasicBlock>();
if (entries.contains(bb)) {
dominators.add(bb);
} else {
dominators.addAll(cfg.getNodes());
}
dominatormapping.put(bb, dominators);
}
// whether the dominators of any basic block is changed
boolean changed;
// loop until no more changes
do {
changed = false;
for (BasicBlock bb : cfg.getNodes()) {
if (entries.contains(bb)) {
continue;
}
Set<BasicBlock> dominators = dominatormapping.get(bb);
dominators.remove(bb);
// update the dominators of current basic block,
// contains only the dominators of its predecessors
for (BasicBlock predecessor : bb.getPredecessors()) {
if (dominators.retainAll(dominatormapping.get(predecessor))) {
changed = true;
}
}
dominators.add(bb);
}
} while (changed);
return cfg;
}
public boolean isFirstOfLoop() {
BasicBlock entry = thisAnalysis.getBB(staticContextData
.getRegionStart());
for (BasicBlock bb : entry.getPredecessors()) {
if (dominatormapping.get(bb).contains(entry)) {
return true;
}
}
return false;
}
}
package ch.usi.dag.disl.staticcontext;
import java.util.HashMap;
import java.util.Map;
import org.objectweb.asm.tree.MethodNode;
import ch.usi.dag.disl.snippet.Shadow;
import ch.usi.dag.disl.staticcontext.AbstractStaticContext;
public abstract class MethodAnalysisContext<V> extends AbstractStaticContext {
private Map<MethodNode, V> analysisCache = new HashMap<MethodNode, V>();
protected V thisAnalysis;
public void staticContextData(Shadow sa) {
staticContextData = sa;
MethodNode method = sa.getMethodNode();
thisAnalysis = analysisCache.get(method);
if (thisAnalysis == null) {
thisAnalysis = analysis(method);
analysisCache.put(method, thisAnalysis);
}
}
public abstract V analysis(MethodNode method);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment