X-Git-Url: http://nitlanguage.org diff --git a/src/analysis/inline_methods.nit b/src/analysis/inline_methods.nit index 80f0aac..875da44 100644 --- a/src/analysis/inline_methods.nit +++ b/src/analysis/inline_methods.nit @@ -20,29 +20,50 @@ package inline_methods import icode private class InlineMethodVisitor -special ICodeVisitor + super 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 ir = m.iroutine.as(not null) - var seq = new ISeq - current_icode.insert_before(seq) - var e = ir.inline_in_seq(seq, ic.exprs) - var r = ic.result - if r != null then - assert e != null - current_icode.insert_before(new IMove(r, e)) + var ir = m.iroutine + if ir != null and ic.is_inlinable then + var icb = _icb + if icb.iroutine == ir then + # We cannot inline ir + # So, at least transform the call to a static one + current_icode.delete + var icall = new IStaticCall(ic.property, ic.exprs) + icall.closure_defs = ic.closure_defs + icall.result = ic.result + current_icode.insert_before(icall) + current_icode.delete + else + var seq = new ISeq + var old_seq = icb.seq + icb.seq = seq + current_icode.insert_before(seq) + var e = icb.inline_routine(ir, ic.exprs, ic.closure_defs) + 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 - current_icode.delete - visit_icode(seq) end end super end + + init(m: MMModule, r: IRoutine) + do + _icb = new ICodeBuilder(m, r) + end end redef class ICall @@ -52,15 +73,17 @@ redef class ICall var mn = m.name var cn = m.local_class.name return (m.is_intern and cn != once ("Object".to_symbol)) or - (cn == (once ("Array".to_symbol)) and (mn == (once ("length".to_symbol)) or mn == (once ("[]".to_symbol)))) or - (cn == (once ("AbstractArrayRead".to_symbol)) and (mn == (once ("length".to_symbol)) or mn == (once ("[]".to_symbol)))) + (cn == (once ("Int".to_symbol)) and (mn == (once ("enumerate_to".to_symbol)) or mn == (once ("enumerate_before".to_symbol)))) or + (cn == (once ("Array".to_symbol)) and (mn == (once ("length".to_symbol)) or mn == (once ("[]".to_symbol)) or mn == (once ("iterate".to_symbol)))) or + (cn == (once ("AbstractArrayRead".to_symbol)) and (mn == (once ("length".to_symbol)) or mn == (once ("[]".to_symbol)))) or + (m.global.intro.local_class.name == (once ("Inline__".to_symbol))) end end redef class IRoutine - fun inline_methods + fun inline_methods(m: MMModule) do - var v = new InlineMethodVisitor + var v = new InlineMethodVisitor(m, self) v.visit_iroutine(self) end end