// Reset value map if this instruction is the start/end of a basic block
Map<Operand,Operand> valueMap = new HashMap<Operand,Operand>();
Map<Variable,List<Variable>> simplificationMap = new HashMap<Variable,List<Variable>>();
while (instrs.hasNext()) {
Instr i = instrs.next();
Operation iop = i.getOperation();
if (preCFG && iop.startsBasicBlock()) {
valueMap = new HashMap<Operand,Operand>();
simplificationMap = new HashMap<Variable,List<Variable>>();
}
// Simplify instruction and record mapping between target variable and simplified value
// System.out.println("BEFORE: " + i);
Operand val = i.simplifyAndGetResult(s, valueMap);
// FIXME: This logic can be simplified based on the number of res != null checks only done if doesn't
Variable res = i instanceof ResultInstr ? ((ResultInstr) i).getResult() : null;
// System.out.println("AFTER: " + i + "; dst = " + res + "; val = " + val);
if (res != null && val != null) {
if (!res.equals(val)) {
recordSimplification(res, val, valueMap, simplificationMap);
}
if (!i.hasSideEffects()) {
if (i instanceof CopyInstr) {
if (res.equals(val) && i.canBeDeleted(s)) {
i.markDead();
instrs.remove();
}
} else {
instrs.set(new CopyInstr(res, val));
}
}
} else if (res != null && val == null) {
// If we didn't get a simplified value, remove any existing simplifications for the result
// to get rid of RAW hazards!
valueMap.remove(res);
}
// Purge all entries in valueMap that have 'res' as their simplified value to take care of RAW scenarios (because we aren't in SSA form yet!)
if (res != null && !res.equals(val)) {
List<Variable> simplifiedVars = simplificationMap.get(res);
if (simplifiedVars != null) {
for (Variable v: simplifiedVars) {
valueMap.remove(v);
}
simplificationMap.remove(res);
}
}
// If the call has been optimized away in the previous step, it is no longer a hard boundary for opts!
//
// Right now, calls are considered hard boundaries for optimization and
// information cannot be propagated across them!
//
// SSS FIXME: Rather than treat all calls with a broad brush, what we need
// is to capture different attributes about a call :
// - uses closures
// - known call target
// - can modify scope,
// - etc.
//
// This information is present in instruction flags on CallBase. Use it!
if ((preCFG && iop.endsBasicBlock()) || (iop.isCall() && !i.isDead())) {
valueMap = new HashMap<Operand,Operand>();
simplificationMap = new HashMap<Variable,List<Variable>>();
}
}
}