50 lines
1.3 KiB
Java
Executable file
50 lines
1.3 KiB
Java
Executable file
package cd.transform.analysis;
|
|
|
|
|
|
import cd.ir.Ast;
|
|
import cd.ir.Ast.Assign;
|
|
import cd.ir.Ast.Var;
|
|
import cd.ir.ControlFlowGraph;
|
|
import cd.ir.Symbol.VariableSymbol;
|
|
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
|
|
/**
|
|
* This class implements constant propagation:
|
|
* remember variables that have constant values
|
|
* no need evaluate them at runtime, save movl instruction
|
|
*/
|
|
public class ConstantAnalysis extends MaybeFlowAnalysis<Integer> {
|
|
public ConstantAnalysis(ControlFlowGraph cfg) {
|
|
super(cfg, true, false);
|
|
}
|
|
|
|
@Override
|
|
protected MaybeC<Integer> defaultInit(VariableSymbol varSym) {
|
|
if (varSym.kind == VariableSymbol.Kind.LOCAL)
|
|
return MaybeC.value(0);
|
|
else
|
|
return MaybeC.notConstant();
|
|
}
|
|
|
|
@Override
|
|
public void transferStmt(Ast.Stmt stmt, Map<VariableSymbol, MaybeC<Integer>> state) {
|
|
if (stmt instanceof Assign) {
|
|
Assign ast = (Assign) stmt;
|
|
if (ast.left() instanceof Var) {
|
|
VariableSymbol symbol = ((Var) ast.left()).sym;
|
|
if (!state.containsKey(symbol)) return;
|
|
|
|
// Obtain value and previous MaybeConstant
|
|
Optional<Integer> valueOpt = cte.calc(ast.right());
|
|
MaybeC<Integer> mc = state.get(symbol);
|
|
if (valueOpt.isPresent()) {
|
|
state.put(symbol, MaybeC.value(valueOpt.get()));
|
|
} else {
|
|
mc.setNotConstant();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|