closure get type back inference
This commit is contained in:
@@ -457,6 +457,19 @@ var streamline = function(ir, log) {
|
|||||||
i = i + 1
|
i = i + 1
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if (op == "get" && func._closure_slot_types != null) {
|
||||||
|
slot = instr[1]
|
||||||
|
typ = T_UNKNOWN
|
||||||
|
src_typ = func._closure_slot_types[text(instr[2]) + "_" + text(instr[3])]
|
||||||
|
if (src_typ != null) {
|
||||||
|
typ = src_typ
|
||||||
|
}
|
||||||
|
if (slot > 0 && slot > nr_args) {
|
||||||
|
merge_backward(write_types, slot, typ)
|
||||||
|
}
|
||||||
|
i = i + 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
rule = write_rules[op]
|
rule = write_rules[op]
|
||||||
if (rule != null) {
|
if (rule != null) {
|
||||||
@@ -1966,6 +1979,71 @@ var streamline = function(ir, log) {
|
|||||||
}
|
}
|
||||||
fi = fi + 1
|
fi = fi + 1
|
||||||
}
|
}
|
||||||
|
ir._parent_of = parent_of
|
||||||
|
ir._parent_fc = fc
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================
|
||||||
|
// Resolve closure slot types from parent write_types.
|
||||||
|
// For each `get` in func, walk the parent chain and look up
|
||||||
|
// the ancestor's inferred write type for that closure slot.
|
||||||
|
// =========================================================
|
||||||
|
var resolve_closure_types = function(func, fi, ir) {
|
||||||
|
var parent_of = ir._parent_of
|
||||||
|
var fc = ir._parent_fc
|
||||||
|
var instructions = func.instructions
|
||||||
|
var num_instr = 0
|
||||||
|
var closure_types = null
|
||||||
|
var i = 0
|
||||||
|
var instr = null
|
||||||
|
var slot = 0
|
||||||
|
var depth = 0
|
||||||
|
var anc = 0
|
||||||
|
var j = 0
|
||||||
|
var target = null
|
||||||
|
var typ = null
|
||||||
|
var key = null
|
||||||
|
|
||||||
|
if (instructions == null || parent_of == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
num_instr = length(instructions)
|
||||||
|
closure_types = {}
|
||||||
|
i = 0
|
||||||
|
while (i < num_instr) {
|
||||||
|
instr = instructions[i]
|
||||||
|
if (is_array(instr) && instr[0] == "get") {
|
||||||
|
slot = instr[2]
|
||||||
|
depth = instr[3]
|
||||||
|
key = text(slot) + "_" + text(depth)
|
||||||
|
if (closure_types[key] == null) {
|
||||||
|
anc = fi
|
||||||
|
j = 0
|
||||||
|
while (j < depth && anc >= 0) {
|
||||||
|
anc = parent_of[anc]
|
||||||
|
j = j + 1
|
||||||
|
}
|
||||||
|
if (anc >= 0) {
|
||||||
|
if (anc == fc) {
|
||||||
|
target = ir.main
|
||||||
|
} else {
|
||||||
|
target = ir.functions[anc]
|
||||||
|
}
|
||||||
|
if (target != null && target._write_types != null) {
|
||||||
|
typ = target._write_types[slot]
|
||||||
|
if (typ != null) {
|
||||||
|
closure_types[key] = typ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = i + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func._closure_slot_types = closure_types
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2284,6 +2362,7 @@ var streamline = function(ir, log) {
|
|||||||
|
|
||||||
run_cycle("")
|
run_cycle("")
|
||||||
run_cycle("_2")
|
run_cycle("_2")
|
||||||
|
func._write_types = write_types
|
||||||
if (ir._warn) {
|
if (ir._warn) {
|
||||||
diagnose_function(func, {param_types: param_types, write_types: write_types}, ir)
|
diagnose_function(func, {param_types: param_types, write_types: write_types}, ir)
|
||||||
}
|
}
|
||||||
@@ -2305,11 +2384,12 @@ var streamline = function(ir, log) {
|
|||||||
optimize_function(ir.main, log)
|
optimize_function(ir.main, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process all sub-functions
|
// Process all sub-functions (resolve closure types from parent first)
|
||||||
var fi = 0
|
var fi = 0
|
||||||
if (ir.functions != null) {
|
if (ir.functions != null) {
|
||||||
fi = 0
|
fi = 0
|
||||||
while (fi < length(ir.functions)) {
|
while (fi < length(ir.functions)) {
|
||||||
|
resolve_closure_types(ir.functions[fi], fi, ir)
|
||||||
optimize_function(ir.functions[fi], log)
|
optimize_function(ir.functions[fi], log)
|
||||||
fi = fi + 1
|
fi = fi + 1
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user