From 4c46806b3940e7545204deb3144e92328cb4e1f1 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Mon, 10 Aug 2009 13:14:54 -0400 Subject: [PATCH] icode: iroutine knows its local registers iroutine inlining is also adapted to only duplicate local registers. Signed-off-by: Jean Privat --- src/icode/icode_base.nit | 3 +++ src/icode/icode_builder.nit | 4 +++- src/icode/icode_tools.nit | 35 +++++++++++++++++++++++------------ 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/icode/icode_base.nit b/src/icode/icode_base.nit index 5c265e6..f15b4a0 100644 --- a/src/icode/icode_base.nit +++ b/src/icode/icode_base.nit @@ -51,6 +51,9 @@ class IRoutine # The closure declared readable writable var _closure_decls: nullable Sequence[IClosureDecl] = null + # The local variables (excluding params and result) + readable var _registers: Set[IRegister] = new ArraySet[IRegister] + # The result of the routine readable var _result: nullable IRegister diff --git a/src/icode/icode_builder.nit b/src/icode/icode_builder.nit index c7cfe59..d1dd617 100644 --- a/src/icode/icode_builder.nit +++ b/src/icode/icode_builder.nit @@ -184,7 +184,9 @@ class ICodeBuilder # Get a new register fun new_register(s: MMType): IRegister do - return new IRegister(s) + var r = new IRegister(s) + iroutine.registers.add(r) + return r end # The module where classes and types are extracted diff --git a/src/icode/icode_tools.nit b/src/icode/icode_tools.nit index 349ed1a..0b48de9 100644 --- a/src/icode/icode_tools.nit +++ b/src/icode/icode_tools.nit @@ -97,37 +97,48 @@ redef class ICodeBuilder do var d = new ICodeDupContext assert args.length == routine.params.length + + # Fill register duplicate association + var dico = d._registers + var res = routine.result + if res != null then + var res2 = new_register(res.stype) + dico[res] = res2 + res = res2 + end + for reg in routine.registers do + assert not dico.has_key(reg) + dico[reg] = new_register(reg.stype) + end for i in [0..args.length[ do # FIXME The following assumes that params are readonly. # The alternative is safe but add one move :/ - d._registers[routine.params[i]] = args[i] - #seq.icodes.add(new IMove(d.dup_ireg(routine.params[i]), args[i])) + dico[routine.params[i]] = args[i] + #seq.icodes.add(new IMove(dico[routine.params[i]]), args[i])) end + + # Process inlining seq.icodes.add(routine.body.dup_with(d)) - var r = routine.result - if r != null then r = d.dup_ireg(r) - return r + return res end end # This class stores reference to allow correct duplication of icodes private class ICodeDupContext - # Duplicate one register - # Subsequent invocation will return the same register + # Return the correct register + # * a duplicate of the local register 'r' of the inlined iroutine + # * 'r' else (it is a register of the caller iroutine) fun dup_ireg(r: IRegister): IRegister do var rs = _registers if rs.has_key(r) then return rs[r] else - var r2 = new IRegister(r.stype) - rs[r] = r2 - return r2 + return r end end - # Duplicate a bunch of registers - # Subsequent invocation will return the same registers + # Return a correct bunch of registers fun dup_iregs(regs: Sequence[IRegister]): Sequence[IRegister] do var a = new Array[IRegister].with_capacity(regs.length) -- 1.7.9.5