diff --git a/aeneas/src/ir/SsaNormalizer.v3 b/aeneas/src/ir/SsaNormalizer.v3 index fd92991f5..95f6e2ff7 100644 --- a/aeneas/src/ir/SsaNormalizer.v3 +++ b/aeneas/src/ir/SsaNormalizer.v3 @@ -28,6 +28,12 @@ class SsaRaNormalizer extends SsaRebuilder { var opt = SsaOptimizer.new(context); opt.optGraph(); context.printSsa("Norm Optimized"); + if (context.compiler.LoadOptimize) { + // Perform load elimination. + if (SsaLoadOptimizer.new(context).optimize()) { + context.printSsa("Load Optimized"); + } + } //TODO SsaGraphVerifier.new(context).verify(); } } diff --git a/aeneas/src/main/Version.v3 b/aeneas/src/main/Version.v3 index 59cc613a8..c1379f9de 100644 --- a/aeneas/src/main/Version.v3 +++ b/aeneas/src/main/Version.v3 @@ -3,6 +3,6 @@ // Updated by VCS scripts. DO NOT EDIT. component Version { - def version: string = "III-7.1760"; + def version: string = "III-7.1761"; var buildData: string; } diff --git a/aeneas/src/ssa/SsaOptimizer.v3 b/aeneas/src/ssa/SsaOptimizer.v3 index 66e546a44..55a3b0188 100644 --- a/aeneas/src/ssa/SsaOptimizer.v3 +++ b/aeneas/src/ssa/SsaOptimizer.v3 @@ -280,6 +280,7 @@ class SsaInstrReducer(context: SsaContext) extends SsaInstrMatcher { var optimize_nullchecks = true; // activates null check elimination var optimize_inits = false; // activates init elimination var optimize_bounds = true; + var remove_pure_ops = true; var graph: SsaGraph; var prev: SsaLink; // instruction before the current instruction var next: SsaLink; // instruction after the current instruction @@ -375,6 +376,7 @@ class SsaInstrReducer(context: SsaContext) extends SsaInstrMatcher { def PURE_LOAD = Fact.O_NO_NULL_CHECK | Fact.O_PURE; def ZERO_NON_ZERO = Fact.V_ZERO | Fact.V_NON_ZERO; def ABOVE_BELOW_ZERO = Fact.V_NON_ZERO | Fact.V_NON_NEGATIVE | Fact.V_BELOW_ZERO; + if (remove_pure_ops && i.facts.O_PURE && i.useList == null) return killUnused(i); match (i.op.opcode) { BoolEq, IntEq, @@ -730,6 +732,7 @@ class SsaInstrReducer(context: SsaContext) extends SsaInstrMatcher { } i.setFactIf(Fact.O_NO_NULL_CHECK, Fact.O_PURE); i.facts |= Fact.F_VALUE; + if (remove_pure_ops && i.facts.O_PURE && i.useList == null) return killUnused(i); return lookupField(i, receiver, field); } } @@ -1232,6 +1235,11 @@ class SsaInstrReducer(context: SsaContext) extends SsaInstrMatcher { prev = i; return i; } + def killUnused(i_old: SsaInstr) -> SsaInstr { + i_old.kill(); + i_old.remove(); + return graph.nop(); + } } // Performs control flow optimizations on a completed SsaGraph. @@ -1911,15 +1919,23 @@ class SsaLoadOptimizer(context: SsaContext) { pure.length = 0; impure.length = 0; var i = block.next; + for (i = block.next; SsaInstr.?(i); ()) { + var next = i.next; + match (i) { + instr: SsaApplyOp => { + var repl = optInstr(instr); + if (repl != null) { + any = true; + instr.replace(repl); + instr.remove(); + } + } + } + i = next; + } while (SsaApplyOp.?(i)) { var instr = SsaApplyOp.!(i); var next = instr.next; - var repl = optInstr(instr); - if (repl != null) { - any = true; - instr.replace(repl); - instr.remove(); - } i = next; } } diff --git a/aeneas/test/SsaInstrReducerTest.v3 b/aeneas/test/SsaInstrReducerTest.v3 index 61a04db74..1ead48012 100644 --- a/aeneas/test/SsaInstrReducerTest.v3 +++ b/aeneas/test/SsaInstrReducerTest.v3 @@ -199,6 +199,7 @@ private class SsaInstrReducerTester(t: Tester) { opt.optimize_nullchecks = optimize_nullchecks; opt.optimize_inits = optimize_inits; opt.optimize_bounds = optimize_bounds; + opt.remove_pure_ops = false; // TODO: test with removal of pure operations return opt; } def recordConst(rtype: Type, vals: Array) -> SsaConst { diff --git a/test/core/opt_load12.v3 b/test/core/opt_load12.v3 new file mode 100644 index 000000000..5ae48c416 --- /dev/null +++ b/test/core/opt_load12.v3 @@ -0,0 +1,10 @@ +//@execute -1=33; 2=55 +class Foo(x: (int, int)) { } + +var f1 = Foo.new(33, 44); +var f2 = Foo.new(55, 66); + +def main(a: int) -> int { + var f = if(a < 0, f1, f2); + return f.x.0; +}