closure get type back inference
This commit is contained in:
@@ -457,6 +457,19 @@ var streamline = function(ir, log) {
|
||||
i = i + 1
|
||||
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]
|
||||
if (rule != null) {
|
||||
@@ -1966,6 +1979,71 @@ var streamline = function(ir, log) {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -2284,6 +2362,7 @@ var streamline = function(ir, log) {
|
||||
|
||||
run_cycle("")
|
||||
run_cycle("_2")
|
||||
func._write_types = write_types
|
||||
if (ir._warn) {
|
||||
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)
|
||||
}
|
||||
|
||||
// Process all sub-functions
|
||||
// Process all sub-functions (resolve closure types from parent first)
|
||||
var fi = 0
|
||||
if (ir.functions != null) {
|
||||
fi = 0
|
||||
while (fi < length(ir.functions)) {
|
||||
resolve_closure_types(ir.functions[fi], fi, ir)
|
||||
optimize_function(ir.functions[fi], log)
|
||||
fi = fi + 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user