iroutine inlining is also adapted to only duplicate local registers.
Signed-off-by: Jean Privat <jean@pryen.org>
# The closure declared
readable writable var _closure_decls: nullable Sequence[IClosureDecl] = null
# 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
# The result of the routine
readable var _result: nullable IRegister
# Get a new register
fun new_register(s: MMType): IRegister
do
# 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
end
# The module where classes and types are extracted
do
var d = new ICodeDupContext
assert args.length == routine.params.length
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 :/
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]))
seq.icodes.add(routine.body.dup_with(d))
seq.icodes.add(routine.body.dup_with(d))
- var r = routine.result
- if r != null then r = d.dup_ireg(r)
- return r
end
end
# This class stores reference to allow correct duplication of icodes
private class ICodeDupContext
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
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
- # 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)
fun dup_iregs(regs: Sequence[IRegister]): Sequence[IRegister]
do
var a = new Array[IRegister].with_capacity(regs.length)