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
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