private class InlineMethodVisitor
special ICodeVisitor
var _pass: Int = 0
+ var _icb: ICodeBuilder
redef fun visit_icode(ic)
do
if ic isa ICall then
var m = ic.property
if m.iroutine != null and ic.is_inlinable then
+ var icb = _icb
var ir = m.iroutine.as(not null)
var seq = new ISeq
+ var old_seq = icb.seq
+ icb.seq = seq
current_icode.insert_before(seq)
- var e = ir.inline_in_seq(seq, ic.exprs)
+ var e = icb.inline_routine(ir, ic.exprs)
var r = ic.result
if r != null then
assert e != null
current_icode.insert_before(new IMove(r, e))
end
current_icode.delete
+ icb.seq = old_seq
visit_icode(seq)
end
end
super
end
+
+ init(m: MMModule, r: IRoutine)
+ do
+ _icb = new ICodeBuilder(m, r)
+ end
end
redef class ICall
redef class IRoutine
fun inline_methods(m: MMModule)
do
- var v = new InlineMethodVisitor
+ var v = new InlineMethodVisitor(m, self)
v.visit_iroutine(self)
end
end
var ir = p.iroutine
if ir == null then continue
# FIXME: Not compatible with sep compilation
- var e = ir.inline_in_seq(icb.seq, iselfa).as(not null)
+ var e = icb.inline_routine(ir, iselfa).as(not null)
icb.stmt(new IAttrWrite(p, iself, e))
end
end
# limitations under the License.
# Tools to manipulate intermediace nit code representation
-import icode_base
+import icode_builder
# A simple visitor to visit icode structures
class ICodeVisitor
end
end
-redef class IRoutine
- # Inline an iroutine in an icode sequence
- fun inline_in_seq(seq: ISeq, args: Sequence[IRegister]): nullable IRegister
+redef class ICodeBuilder
+ # Inline an iroutine in the current icode sequence
+ fun inline_routine(routine: IRoutine, args: Sequence[IRegister]): nullable IRegister
do
var d = new ICodeDupContext
- if args.length != params.length then print "{args.length} != {params.length}"
- assert args.length == params.length
+ assert args.length == routine.params.length
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[params[i]] = args[i]
- #seq.icodes.add(new IMove(d.dup_ireg(params[i]), args[i]))
+ d._registers[routine.params[i]] = args[i]
+ #seq.icodes.add(new IMove(d.dup_ireg(routine.params[i]), args[i]))
end
- seq.icodes.add(body.dup_with(d))
- var r = result
+ seq.icodes.add(routine.body.dup_with(d))
+ var r = routine.result
if r != null then r = d.dup_ireg(r)
return r
end