Commit 515cda12 authored by Zhang Zijing's avatar Zhang Zijing
Browse files

backup: dom info, ipa, paa, dec in progress

Showing with 839 additions and 0 deletions
+839 -0
......@@ -31,4 +31,12 @@ public class AllocaInst extends Instruction {
public String getOpString() {
return "alloca " + ty.toString();
}
public Type getType() {
return ty;
}
public Type getReturnType() {
return type;
}
}
......@@ -8,11 +8,18 @@ public class BasicBlock {
public String label;
public List<Instruction> insts;
public BasicBlockValue val;
public List<BasicBlock> domers; // 谁支配我
public List<BasicBlock> idoms; // 我直接支配谁
public List<BasicBlock> domiFrontier; // 支配边界
public BasicBlock idomer; // 谁直接支配我
public Integer domLevel;
public BasicBlock(String name) {
label = name;
insts = new ArrayList<>();
val = new BasicBlockValue(this);
domers = new ArrayList<>();
idoms = new ArrayList<>();
}
public BasicBlockValue getValue() {
......
......@@ -24,6 +24,10 @@ public class CallInst extends Instruction {
}
}
public Func target(){
return ((FuncValue)oprands.get(0).value).func;
}
public boolean isVariadic() {
FuncValue fv = (FuncValue) oprands.get(0).value;
return fv.func.isVariadic;
......
package ssa.ds;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
......@@ -14,6 +15,12 @@ public class Func {
public FuncType retType;
public List<ParamValue> argType;
// filled after IPA
public List<Func> callers = new ArrayList<>();
public List<Func> callees = new ArrayList<>();
public boolean hasSideEffect = true;
public boolean usingGlobs = true;
public Func(String name, FuncType retTy, List<ParamValue> argTy) {
this.name = name;
this.retType = retTy;
......@@ -91,4 +98,8 @@ public class Func {
builder.append(sj.toString());
return builder.toString();
}
public BasicBlock entry() {
return bbs.get(0);
}
}
......@@ -45,6 +45,14 @@ public class StoreInst extends Instruction {
}
}
public Value getPtr() {
return oprands.get(1).value;
}
public Value getVal() {
return oprands.get(0).value;
}
public static boolean checkType(Type val, Type ptr) {
// 必须 store 到地址
if (!ptr.isPointer){
......
package ssa.pass;
import ssa.ds.Func;
import ssa.ds.Module;
public class DCE {
Module ssaModule;
public DCE(Module ssaModule) {
this.ssaModule = ssaModule;
}
public static void process(Module ssaModule) {
var dce = new DCE(ssaModule);
dce.execute();
}
private void execute() {
ssaModule.funcs.forEach(func -> this.executeOnFunc(func));
}
private void executeOnFunc(Func func) {
}
}
package ssa.pass;
import ssa.ds.BasicBlock;
import ssa.ds.Func;
import java.util.ArrayList;
import java.util.BitSet;
public class DomInfo {
public static void computeDominanceInfo(Func function) {
// TODO bbs[0] 一定是 entry 吗?
BasicBlock entry = function.entry();
int numNode = function.bbs.size();
ArrayList<BitSet> domers = new ArrayList<>(numNode);
ArrayList<BasicBlock> bbList = new ArrayList<>();
int index = 0;
// 初始化
for (var bb : function.bbs) {
bb.domers.clear();
bb.idoms.clear();
bbList.add(bb);
domers.add(new BitSet());
domers.get(index).set(index);
index++;
}
// 计算支配者
boolean unstable = true;
while (unstable) {
unstable = false;
index = 0;
for (var bb : function.bbs) {
// no need to consider entry node
if (bb != entry) {
BitSet temp = new BitSet();
temp.set(0, numNode);
// temp <- {index} \cup (\Bigcap_{j \in preds(index)} domer(j) )
for (BasicBlock pre_bb : bb.pred()) {
int preIndex = bbList.indexOf(pre_bb);
temp.and(domers.get(preIndex));
}
temp.set(index);
if (!temp.equals(domers.get(index))) {
// replace domers[index] with temp
domers.get(index).clear();
domers.get(index).or(temp);
unstable = true;
}
}
index++;
}
}
for (int i = 0; i < numNode; i++) {
BasicBlock bb = bbList.get(i);
BitSet domerInfo = domers.get(i);
for (int domerIndex = domerInfo.nextSetBit(0); domerIndex >= 0; domerIndex = domerInfo
.nextSetBit(domerIndex + 1)) {
BasicBlock domerbb = bbList.get(domerIndex);
bb.domers.add(domerbb);
}
}
// calculate doms and idom
for (int i = 0; i < numNode; i++) {
BasicBlock bb = bbList.get(i);
for (BasicBlock maybeIdomerbb : bb.domers) {
if (maybeIdomerbb != bb) {
boolean isIdom = true;
for (BasicBlock domerbb : bb.domers) {
if (domerbb != bb && domerbb != maybeIdomerbb && domerbb.domers
.contains(maybeIdomerbb)) {
isIdom = false;
break;
}
}
if (isIdom) {
bb.idomer = maybeIdomerbb;
maybeIdomerbb.idoms.add(bb);
break;
}
}
}
}
// calculate dom level
computeDominanceLevel(entry, 0);
}
public static void computeDominanceFrontier(Func function) {
for (var bb : function.bbs) {
bb.domiFrontier.clear();
}
for (var a : function.bbs) {
for (BasicBlock b : a.succ()) {
BasicBlock x = a;
while (x == b || !b.domers.contains(x)) {
if (!x.domiFrontier.contains(b)) {
// maybe better to design the data structure of dominance frontier as a set
x.domiFrontier.add(b);
}
x = x.idomer;
}
}
}
}
public static void computeDominanceLevel(BasicBlock bb, Integer domLevel) {
bb.domLevel = domLevel;
for (BasicBlock succ : bb.idoms) {
computeDominanceLevel(succ, domLevel + 1);
}
}
}
package ssa.pass;
import ssa.ds.BasicBlock;
import ssa.ds.CallInst;
import ssa.ds.Func;
import ssa.ds.Instruction;
import ssa.ds.LoadInst;
import ssa.ds.Module;
public class IPA {
Module module;
public IPA(Module module) {
this.module = module;
}
public static void process(Module module) {
var ipa = new IPA(module);
ipa.executeInit();
ipa.executeCallingAnalysis();
}
private void executeCallingAnalysis() {
for(var func: module.funcs) {
for(var block: func.bbs) {
for(var inst: block.insts) {
this.analysisOnInst(func, block, inst);
}
}
}
}
private void analysisOnInst(Func func, BasicBlock block, Instruction inst) {
if(inst instanceof CallInst) {
var callInst = (CallInst) inst;
var target = callInst.target();
func.callees.add(target);
target.callers.add(func);
return;
}
if(inst instanceof LoadInst) {
var loadInst = (LoadInst) inst;
var target = loadInst.getPtr();
func.readVars.add(target);
target.readers.add(func);
return;
}
}
private void executeInit() {
module.funcs.forEach(func -> {
func.callers.clear();
func.callees.clear();
func.hasSideEffect = false;
func.usingGlobs = false;
});
module.builtins.forEach(func -> {
func.callers.clear();
func.callees.clear();
func.hasSideEffect = true;
func.usingGlobs = true;
});
}
}
This diff is collapsed.
Supports Markdown
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