respsect array and object length requests
This commit is contained in:
159
streamline.cm
159
streamline.cm
@@ -123,45 +123,45 @@ var streamline = function(ir, log) {
|
||||
var op = instr[0]
|
||||
var src_type = null
|
||||
if (op == "access") {
|
||||
slot_types[text(instr[1])] = access_value_type(instr[2])
|
||||
slot_types[instr[1]] = access_value_type(instr[2])
|
||||
} else if (op == "int") {
|
||||
slot_types[text(instr[1])] = T_INT
|
||||
slot_types[instr[1]] = T_INT
|
||||
} else if (op == "true" || op == "false") {
|
||||
slot_types[text(instr[1])] = T_BOOL
|
||||
slot_types[instr[1]] = T_BOOL
|
||||
} else if (op == "null") {
|
||||
slot_types[text(instr[1])] = T_NULL
|
||||
slot_types[instr[1]] = T_NULL
|
||||
} else if (op == "move") {
|
||||
src_type = slot_types[text(instr[2])]
|
||||
slot_types[text(instr[1])] = src_type != null ? src_type : T_UNKNOWN
|
||||
src_type = slot_types[instr[2]]
|
||||
slot_types[instr[1]] = src_type != null ? src_type : T_UNKNOWN
|
||||
} else if (op == "concat") {
|
||||
slot_types[text(instr[1])] = T_TEXT
|
||||
slot_types[instr[1]] = T_TEXT
|
||||
} else if (bool_result_ops[op] == true) {
|
||||
slot_types[text(instr[1])] = T_BOOL
|
||||
slot_types[instr[1]] = T_BOOL
|
||||
} else if (op == "load_field" || op == "load_index" || op == "load_dynamic") {
|
||||
slot_types[text(instr[1])] = T_UNKNOWN
|
||||
slot_types[instr[1]] = T_UNKNOWN
|
||||
} else if (op == "invoke" || op == "tail_invoke") {
|
||||
slot_types[text(instr[2])] = T_UNKNOWN
|
||||
slot_types[instr[2]] = T_UNKNOWN
|
||||
} else if (op == "pop" || op == "get") {
|
||||
slot_types[text(instr[1])] = T_UNKNOWN
|
||||
slot_types[instr[1]] = T_UNKNOWN
|
||||
} else if (op == "array") {
|
||||
slot_types[text(instr[1])] = T_ARRAY
|
||||
slot_types[instr[1]] = T_ARRAY
|
||||
} else if (op == "record") {
|
||||
slot_types[text(instr[1])] = T_RECORD
|
||||
slot_types[instr[1]] = T_RECORD
|
||||
} else if (op == "function") {
|
||||
slot_types[text(instr[1])] = T_FUNCTION
|
||||
slot_types[instr[1]] = T_FUNCTION
|
||||
} else if (op == "length") {
|
||||
slot_types[text(instr[1])] = T_INT
|
||||
slot_types[instr[1]] = T_INT
|
||||
} else if (op == "negate" || numeric_ops[op] == true) {
|
||||
slot_types[text(instr[1])] = T_UNKNOWN
|
||||
slot_types[instr[1]] = T_UNKNOWN
|
||||
} else if (op == "bitnot" || op == "bitand" || op == "bitor" ||
|
||||
op == "bitxor" || op == "shl" || op == "shr" || op == "ushr") {
|
||||
slot_types[text(instr[1])] = T_INT
|
||||
slot_types[instr[1]] = T_INT
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
var slot_is = function(slot_types, slot, typ) {
|
||||
var known = slot_types[text(slot)]
|
||||
var known = slot_types[slot]
|
||||
if (known == null) {
|
||||
return false
|
||||
}
|
||||
@@ -175,24 +175,22 @@ var streamline = function(ir, log) {
|
||||
}
|
||||
|
||||
var merge_backward = function(backward_types, slot, typ) {
|
||||
var sk = null
|
||||
var existing = null
|
||||
if (!is_number(slot)) {
|
||||
return null
|
||||
}
|
||||
sk = text(slot)
|
||||
existing = backward_types[sk]
|
||||
existing = backward_types[slot]
|
||||
if (existing == null) {
|
||||
backward_types[sk] = typ
|
||||
backward_types[slot] = typ
|
||||
} else if (existing != typ && existing != T_UNKNOWN) {
|
||||
if ((existing == T_INT || existing == T_FLOAT) && typ == T_NUM) {
|
||||
// Keep more specific
|
||||
} else if (existing == T_NUM && (typ == T_INT || typ == T_FLOAT)) {
|
||||
backward_types[sk] = typ
|
||||
backward_types[slot] = typ
|
||||
} else if ((existing == T_INT && typ == T_FLOAT) || (existing == T_FLOAT && typ == T_INT)) {
|
||||
backward_types[sk] = T_NUM
|
||||
backward_types[slot] = T_NUM
|
||||
} else {
|
||||
backward_types[sk] = T_UNKNOWN
|
||||
backward_types[slot] = T_UNKNOWN
|
||||
}
|
||||
}
|
||||
return null
|
||||
@@ -201,8 +199,8 @@ var streamline = function(ir, log) {
|
||||
var seed_params = function(slot_types, param_types, nr_args) {
|
||||
var j = 1
|
||||
while (j <= nr_args) {
|
||||
if (param_types[text(j)] != null) {
|
||||
slot_types[text(j)] = param_types[text(j)]
|
||||
if (param_types[j] != null) {
|
||||
slot_types[j] = param_types[j]
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
@@ -210,10 +208,11 @@ var streamline = function(ir, log) {
|
||||
}
|
||||
|
||||
var seed_writes = function(slot_types, write_types) {
|
||||
var keys = array(write_types)
|
||||
var k = 0
|
||||
while (k < length(keys)) {
|
||||
slot_types[keys[k]] = write_types[keys[k]]
|
||||
while (k < length(write_types)) {
|
||||
if (write_types[k] != null) {
|
||||
slot_types[k] = write_types[k]
|
||||
}
|
||||
k = k + 1
|
||||
}
|
||||
return null
|
||||
@@ -236,11 +235,11 @@ var streamline = function(ir, log) {
|
||||
var bt = null
|
||||
|
||||
if (instructions == null || nr_args == 0) {
|
||||
return {}
|
||||
return array(func.nr_slots)
|
||||
}
|
||||
|
||||
num_instr = length(instructions)
|
||||
backward_types = {}
|
||||
backward_types = array(func.nr_slots)
|
||||
i = 0
|
||||
while (i < num_instr) {
|
||||
instr = instructions[i]
|
||||
@@ -296,12 +295,12 @@ var streamline = function(ir, log) {
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
param_types = {}
|
||||
param_types = array(func.nr_slots)
|
||||
j = 1
|
||||
while (j <= nr_args) {
|
||||
bt = backward_types[text(j)]
|
||||
bt = backward_types[j]
|
||||
if (bt != null && bt != T_UNKNOWN) {
|
||||
param_types[text(j)] = bt
|
||||
param_types[j] = bt
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
@@ -319,22 +318,19 @@ var streamline = function(ir, log) {
|
||||
var nr_args = func.nr_args != null ? func.nr_args : 0
|
||||
var num_instr = 0
|
||||
var write_types = null
|
||||
var result = null
|
||||
var keys = null
|
||||
var i = 0
|
||||
var k = 0
|
||||
var instr = null
|
||||
var op = null
|
||||
var slot = 0
|
||||
var typ = null
|
||||
var wt = null
|
||||
|
||||
if (instructions == null) {
|
||||
return {}
|
||||
return array(func.nr_slots)
|
||||
}
|
||||
|
||||
num_instr = length(instructions)
|
||||
write_types = {}
|
||||
write_types = array(func.nr_slots)
|
||||
i = 0
|
||||
while (i < num_instr) {
|
||||
instr = instructions[i]
|
||||
@@ -410,17 +406,14 @@ var streamline = function(ir, log) {
|
||||
}
|
||||
|
||||
// Filter to only slots with known (non-unknown) types
|
||||
result = {}
|
||||
keys = array(write_types)
|
||||
k = 0
|
||||
while (k < length(keys)) {
|
||||
wt = write_types[keys[k]]
|
||||
if (wt != null && wt != T_UNKNOWN) {
|
||||
result[keys[k]] = wt
|
||||
while (k < length(write_types)) {
|
||||
if (write_types[k] == T_UNKNOWN) {
|
||||
write_types[k] = null
|
||||
}
|
||||
k = k + 1
|
||||
}
|
||||
return result
|
||||
return write_types
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
@@ -462,14 +455,14 @@ var streamline = function(ir, log) {
|
||||
num_instr = length(instructions)
|
||||
j = 1
|
||||
while (j <= nr_args) {
|
||||
if (param_types[text(j)] != null) {
|
||||
if (param_types[j] != null) {
|
||||
has_params = true
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
has_writes = length(array(write_types)) > 0
|
||||
has_writes = some(write_types, function(x) { return x != null })
|
||||
|
||||
slot_types = {}
|
||||
slot_types = array(func.nr_slots)
|
||||
if (has_params) {
|
||||
seed_params(slot_types, param_types, nr_args)
|
||||
}
|
||||
@@ -482,7 +475,7 @@ var streamline = function(ir, log) {
|
||||
instr = instructions[i]
|
||||
|
||||
if (is_text(instr)) {
|
||||
slot_types = {}
|
||||
slot_types = array(func.nr_slots)
|
||||
if (has_params) {
|
||||
seed_params(slot_types, param_types, nr_args)
|
||||
}
|
||||
@@ -525,14 +518,14 @@ var streamline = function(ir, log) {
|
||||
at: i,
|
||||
before: [instr, next],
|
||||
after: [instructions[i], instructions[i + 1]],
|
||||
why: {slot: src, known_type: slot_types[text(src)], checked_type: checked_type}
|
||||
why: {slot: src, known_type: slot_types[src], checked_type: checked_type}
|
||||
}
|
||||
}
|
||||
slot_types[text(dest)] = T_BOOL
|
||||
slot_types[dest] = T_BOOL
|
||||
i = i + 2
|
||||
continue
|
||||
}
|
||||
src_known = slot_types[text(src)]
|
||||
src_known = slot_types[src]
|
||||
if (src_known != null && src_known != T_UNKNOWN && src_known != checked_type) {
|
||||
if (checked_type == T_NUM && (src_known == T_INT || src_known == T_FLOAT)) {
|
||||
nc = nc + 1
|
||||
@@ -550,7 +543,7 @@ var streamline = function(ir, log) {
|
||||
why: {slot: src, known_type: src_known, checked_type: checked_type}
|
||||
}
|
||||
}
|
||||
slot_types[text(dest)] = T_BOOL
|
||||
slot_types[dest] = T_BOOL
|
||||
i = i + 2
|
||||
continue
|
||||
}
|
||||
@@ -569,12 +562,12 @@ var streamline = function(ir, log) {
|
||||
why: {slot: src, known_type: src_known, checked_type: checked_type}
|
||||
}
|
||||
}
|
||||
slot_types[text(dest)] = T_UNKNOWN
|
||||
slot_types[dest] = T_UNKNOWN
|
||||
i = i + 2
|
||||
continue
|
||||
}
|
||||
slot_types[text(dest)] = T_BOOL
|
||||
slot_types[text(src)] = checked_type
|
||||
slot_types[dest] = T_BOOL
|
||||
slot_types[src] = checked_type
|
||||
i = i + 2
|
||||
continue
|
||||
}
|
||||
@@ -594,14 +587,14 @@ var streamline = function(ir, log) {
|
||||
at: i,
|
||||
before: [instr, next],
|
||||
after: [instructions[i], instructions[i + 1]],
|
||||
why: {slot: src, known_type: slot_types[text(src)], checked_type: checked_type}
|
||||
why: {slot: src, known_type: slot_types[src], checked_type: checked_type}
|
||||
}
|
||||
}
|
||||
slot_types[text(dest)] = T_BOOL
|
||||
slot_types[dest] = T_BOOL
|
||||
i = i + 2
|
||||
continue
|
||||
}
|
||||
src_known = slot_types[text(src)]
|
||||
src_known = slot_types[src]
|
||||
if (src_known != null && src_known != T_UNKNOWN && src_known != checked_type) {
|
||||
if (checked_type == T_NUM && (src_known == T_INT || src_known == T_FLOAT)) {
|
||||
nc = nc + 1
|
||||
@@ -619,7 +612,7 @@ var streamline = function(ir, log) {
|
||||
why: {slot: src, known_type: src_known, checked_type: checked_type}
|
||||
}
|
||||
}
|
||||
slot_types[text(dest)] = T_BOOL
|
||||
slot_types[dest] = T_BOOL
|
||||
i = i + 2
|
||||
continue
|
||||
}
|
||||
@@ -638,17 +631,17 @@ var streamline = function(ir, log) {
|
||||
why: {slot: src, known_type: src_known, checked_type: checked_type}
|
||||
}
|
||||
}
|
||||
slot_types[text(dest)] = T_BOOL
|
||||
slot_types[dest] = T_BOOL
|
||||
i = i + 2
|
||||
continue
|
||||
}
|
||||
slot_types[text(dest)] = T_BOOL
|
||||
slot_types[dest] = T_BOOL
|
||||
i = i + 2
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
slot_types[text(dest)] = T_BOOL
|
||||
slot_types[dest] = T_BOOL
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
@@ -664,7 +657,7 @@ var streamline = function(ir, log) {
|
||||
pass: "eliminate_type_checks",
|
||||
rule: "dynamic_to_field",
|
||||
at: i, before: old_op, after: instr[0],
|
||||
why: {slot: instr[3], known_type: slot_types[text(instr[3])]}
|
||||
why: {slot: instr[3], known_type: slot_types[instr[3]]}
|
||||
}
|
||||
}
|
||||
} else if (slot_is(slot_types, instr[3], T_INT)) {
|
||||
@@ -675,11 +668,11 @@ var streamline = function(ir, log) {
|
||||
pass: "eliminate_type_checks",
|
||||
rule: "dynamic_to_index",
|
||||
at: i, before: old_op, after: instr[0],
|
||||
why: {slot: instr[3], known_type: slot_types[text(instr[3])]}
|
||||
why: {slot: instr[3], known_type: slot_types[instr[3]]}
|
||||
}
|
||||
}
|
||||
}
|
||||
slot_types[text(instr[1])] = T_UNKNOWN
|
||||
slot_types[instr[1]] = T_UNKNOWN
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
@@ -693,7 +686,7 @@ var streamline = function(ir, log) {
|
||||
pass: "eliminate_type_checks",
|
||||
rule: "dynamic_to_field",
|
||||
at: i, before: old_op, after: instr[0],
|
||||
why: {slot: instr[3], known_type: slot_types[text(instr[3])]}
|
||||
why: {slot: instr[3], known_type: slot_types[instr[3]]}
|
||||
}
|
||||
}
|
||||
} else if (slot_is(slot_types, instr[3], T_INT)) {
|
||||
@@ -704,7 +697,7 @@ var streamline = function(ir, log) {
|
||||
pass: "eliminate_type_checks",
|
||||
rule: "dynamic_to_index",
|
||||
at: i, before: old_op, after: instr[0],
|
||||
why: {slot: instr[3], known_type: slot_types[text(instr[3])]}
|
||||
why: {slot: instr[3], known_type: slot_types[instr[3]]}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -745,14 +738,14 @@ var streamline = function(ir, log) {
|
||||
}
|
||||
|
||||
num_instr = length(instructions)
|
||||
slot_values = {}
|
||||
slot_values = array(func.nr_slots)
|
||||
|
||||
i = 0
|
||||
while (i < num_instr) {
|
||||
instr = instructions[i]
|
||||
|
||||
if (is_text(instr)) {
|
||||
slot_values = {}
|
||||
slot_values = array(func.nr_slots)
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
@@ -766,19 +759,19 @@ var streamline = function(ir, log) {
|
||||
|
||||
// Track known constant values
|
||||
if (op == "int") {
|
||||
slot_values[text(instr[1])] = instr[2]
|
||||
slot_values[instr[1]] = instr[2]
|
||||
} else if (op == "access" && is_number(instr[2])) {
|
||||
slot_values[text(instr[1])] = instr[2]
|
||||
slot_values[instr[1]] = instr[2]
|
||||
} else if (op == "true") {
|
||||
slot_values[text(instr[1])] = true
|
||||
slot_values[instr[1]] = true
|
||||
} else if (op == "false") {
|
||||
slot_values[text(instr[1])] = false
|
||||
slot_values[instr[1]] = false
|
||||
} else if (op == "move") {
|
||||
sv = slot_values[text(instr[2])]
|
||||
sv = slot_values[instr[2]]
|
||||
if (sv != null) {
|
||||
slot_values[text(instr[1])] = sv
|
||||
slot_values[instr[1]] = sv
|
||||
} else {
|
||||
slot_values[text(instr[1])] = null
|
||||
slot_values[instr[1]] = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -797,7 +790,7 @@ var streamline = function(ir, log) {
|
||||
why: {op: op, slot: instr[2]}
|
||||
}
|
||||
}
|
||||
slot_values[text(instr[1])] = true
|
||||
slot_values[instr[1]] = true
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
@@ -814,7 +807,7 @@ var streamline = function(ir, log) {
|
||||
why: {op: op, slot: instr[2]}
|
||||
}
|
||||
}
|
||||
slot_values[text(instr[1])] = false
|
||||
slot_values[instr[1]] = false
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
@@ -822,7 +815,7 @@ var streamline = function(ir, log) {
|
||||
|
||||
// Clear value tracking for dest-producing ops (not reads-only)
|
||||
if (op == "invoke" || op == "tail_invoke") {
|
||||
slot_values[text(instr[2])] = null
|
||||
slot_values[instr[2]] = null
|
||||
} else if (op != "int" && op != "access" && op != "true" &&
|
||||
op != "false" && op != "move" && op != "null" &&
|
||||
op != "jump" && op != "jump_true" && op != "jump_false" &&
|
||||
@@ -830,7 +823,7 @@ var streamline = function(ir, log) {
|
||||
op != "store_field" && op != "store_index" &&
|
||||
op != "store_dynamic" && op != "push" && op != "setarg") {
|
||||
if (is_number(instr[1])) {
|
||||
slot_values[text(instr[1])] = null
|
||||
slot_values[instr[1]] = null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user