value->type = MONO_VARIABLE_SUMMARIZED_VALUE;
value->value.variable.variable = ins->sreg1;
value->value.variable.delta = 0;
+ area->defs [ins->dreg] = ins;
+ break;
+ case OP_LDADDR:
+ /* The result is non-null */
+ result->relation = MONO_GT_RELATION;
+ value->type = MONO_CONSTANT_SUMMARIZED_VALUE;
+ value->value.constant.value = 0;
break;
/* FIXME: Add more opcodes */
if (ins->opcode == OP_NOT_NULL)
add_non_null (area, cfg, ins->sreg1, &check_relations);
+ /*
+ * FIXME: abcrem equates an array with its length,
+ * so a = new int [100] implies a != null, but a = new int [0] doesn't.
+ */
/*
* Eliminate MONO_INST_FAULT flags if possible.
*/
else
reg = ins->sreg1;
+ /*
+ * This doesn't work because LLVM can move the non-faulting loads before the faulting
+ * ones (test_0_llvm_moving_faulting_loads ()).
+ * So only do it if we know the load cannot be moved before the instruction which ensures it is not
+ * null (i.e. the def of its sreg).
+ */
+ if (area->defs [reg] && area->defs [reg]->opcode == OP_NEWARR) {
+ if (REPORT_ABC_REMOVAL)
+ printf ("ARRAY-ACCESS: removed MONO_INST_FAULT flag.\n");
+ ins->flags &= ~MONO_INST_FAULT;
+ }
+ /*
if (eval_non_null (area, reg)) {
if (REPORT_ABC_REMOVAL)
printf ("ARRAY-ACCESS: removed MONO_INST_FAULT flag.\n");
} else {
add_non_null (area, cfg, reg, &check_relations);
}
+ */
}
}
mono_mempool_alloc (cfg->mempool, sizeof (MonoRelationsEvaluationContext) * (cfg->next_vreg));
area.variable_value_kind = (MonoIntegerValueKind *)
mono_mempool_alloc (cfg->mempool, sizeof (MonoIntegerValueKind) * (cfg->next_vreg));
+ area.defs = mono_mempool_alloc (cfg->mempool, sizeof (MonoInst*) * cfg->next_vreg);
for (i = 0; i < cfg->next_vreg; i++) {
area.variable_value_kind [i] = MONO_UNKNOWN_INTEGER_VALUE;
area.relations [i].relation = MONO_EQ_RELATION;
area.relations [i].relation_is_static_definition = TRUE;
MAKE_VALUE_ANY (area.relations [i].related_value);
area.relations [i].next = NULL;
+ area.defs [i] = NULL;
}
for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {