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 { public ConstantAnalysis(ControlFlowGraph cfg) { super(cfg, true, false); } @Override protected MaybeC 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> 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 valueOpt = cte.calc(ast.right()); MaybeC mc = state.get(symbol); if (valueOpt.isPresent()) { state.put(symbol, MaybeC.value(valueOpt.get())); } else { mc.setNotConstant(); } } } } }