if r != null and r.slot_index != null then
assert s != null
v.add_assignment(v.register(r), s)
- else if s != null and not self isa IMove then
+ else if s != null and not is_pure then
+ # ICode with side effects must be evaluated
+ # even if the result is not wanted
v.add_instr(s + ";")
end
end
# The location of the icode (if any)
readable writable var _location: nullable Location = null
+
+ # Is the icode side effect free?
+ fun is_pure: Bool do return false
end
# An icode that uses no registers (no args)
super(e)
_code = c
end
+
+ redef readable writable var _is_pure: Bool = false
end
# A register assigment
super(e)
_result = r
end
+
+ redef fun is_pure do return true
end
# An attribute read access
super(r)
_property = p
end
+
+ redef fun is_pure do return true
end
# An attribute assignment
super(r)
_property = p
end
+
+ redef fun is_pure do return true
end
# A type check
super(e)
_stype = t
end
+
+ redef fun is_pure do return true
end
# The 'is' operator
do
super
end
+
+ redef fun is_pure do return true
end
# The unary 'not' operation
do
super
end
+
+ redef fun is_pure do return true
end
# Evaluate body once them return the same value again and again
do
_closure_decl = c
end
+
+ redef fun is_pure do return true
end
#################################################
fun lit_true_reg: IRegister
do
var e = new INative("TAG_Bool(true)", null)
+ e.is_pure = true
return expr(e, module.type_bool)
end
fun lit_false_reg: IRegister
do
var e = new INative("TAG_Bool(false)", null)
+ e.is_pure = true
return expr(e, module.type_bool)
end
redef class INative
redef fun inner_dup_with(d)
do
- return new INative(code, d.dup_iregs(exprs))
+ var c2 = new INative(code, d.dup_iregs(exprs))
+ c2.is_pure = is_pure
+ return c2
end
end