Build mono runtime under none desktop Windows API family, adjustments and cleanup.
[mono.git] / mono / mini / abcremoval.c
index 508d28ae61429ce892935c5245e8e7d3bb537bb9..c4c00645c1630884ba75ec654fc47124dcd2a379 100644 (file)
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/mempool.h>
 #include <mono/metadata/opcodes.h>
+#include <mono/metadata/mempool-internals.h>
+#include <mono/utils/mono-compiler.h>
+
+#include <config.h>
 
 #ifndef DISABLE_JIT
 
@@ -25,7 +29,7 @@
 
 
 #define TRACE_ABC_REMOVAL (verbose_level > 2)
-#define REPORT_ABC_REMOVAL (verbose_level > 0)
+#define REPORT_ABC_REMOVAL (verbose_level > 1)
 
 /*
  * A little hack for the verbosity level.
@@ -59,8 +63,8 @@ static int verbose_level;
                (r)->next = NULL;\
        } while (0)
 
-#define MONO_NEGATED_RELATION(r) ((~(r))&MONO_ANY_RELATION)
-#define MONO_SYMMETRIC_RELATION(r) (((r)&MONO_EQ_RELATION)|(((r)&MONO_LT_RELATION)<<1)|((r&MONO_GT_RELATION)>>1))
+#define MONO_NEGATED_RELATION(r) ((MonoValueRelation)((~(r))&MONO_ANY_RELATION))
+#define MONO_SYMMETRIC_RELATION(r) ((MonoValueRelation)(((r)&MONO_EQ_RELATION)|(((r)&MONO_LT_RELATION)<<1)|((r&MONO_GT_RELATION)>>1)))
 
 
 
@@ -180,10 +184,9 @@ print_evaluation_context_ranges (MonoRelationsEvaluationRanges *ranges) {
 }
 
 static void
-print_evaluation_context (MonoRelationsEvaluationContext *context) {
-       printf ("Context status: ");
-       print_evaluation_context_status (context->status);
-       if (context->status & (MONO_RELATIONS_EVALUATION_IN_PROGRESS|MONO_RELATIONS_EVALUATION_COMPLETED)) {
+print_evaluation_context (MonoRelationsEvaluationContext *context, MonoRelationsEvaluationStatus status) {
+       print_evaluation_context_status (status);
+       if (status & (MONO_RELATIONS_EVALUATION_IN_PROGRESS|MONO_RELATIONS_EVALUATION_COMPLETED)) {
                print_evaluation_context_ranges (&(context->ranges));
        }
        printf ("\n");
@@ -212,27 +215,6 @@ print_evaluation_area_contexts (MonoVariableRelationsEvaluationArea *area) {
 }
 #endif
 
-static inline GSList*
-g_slist_append_mempool (MonoMemPool *mp, GSList *list, gpointer data)
-{
-       GSList *new_list;
-       GSList *last;
-       
-       new_list = mono_mempool_alloc (mp, sizeof (GSList));
-       new_list->data = data;
-       new_list->next = NULL;
-       
-       if (list) {
-               last = list;
-               while (last->next)
-                       last = last->next;
-               last->next = new_list;
-               
-               return list;
-       } else
-               return new_list;
-}
-
 /*
  * Check if the delta of an integer variable value is safe with respect
  * to the variable size in bytes and its kind (signed or unsigned).
@@ -293,6 +275,12 @@ get_relation_from_ins (MonoVariableRelationsEvaluationArea *area, MonoInst *ins,
                value->value.variable.variable = ins->sreg1;
                value->value.variable.delta = 0;
                break;
+       case OP_SEXT_I4:
+               value->type = MONO_VARIABLE_SUMMARIZED_VALUE;
+               value->value.variable.variable = ins->sreg1;
+               value->value.variable.delta = 0;
+               value_kind = MONO_INTEGER_VALUE_SIZE_8;
+               break;
        case OP_PHI:
                value->type = MONO_PHI_SUMMARIZED_VALUE;
                value->value.phi.number_of_alternatives = *(ins->inst_phi_args);
@@ -308,7 +296,7 @@ get_relation_from_ins (MonoVariableRelationsEvaluationArea *area, MonoInst *ins,
        case OP_ISUB_IMM:
                value->type = MONO_VARIABLE_SUMMARIZED_VALUE;
                value->value.variable.variable = ins->sreg1;
-               value->value.variable.delta = ins->inst_imm;
+               value->value.variable.delta = -ins->inst_imm;
                /* FIXME: */
                //check_delta_safety (area, result);
                break;
@@ -334,10 +322,73 @@ get_relation_from_ins (MonoVariableRelationsEvaluationArea *area, MonoInst *ins,
                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 */
        default:
+               /* These opcodes are not currently handled while running SciMark, first
+                * column is the number of times the warning was shown:
+                *
+                *       1 add_imm
+                *       1 float_conv_to_i8
+                *       1 int_mul_ovf_un
+                *       1 int_neg
+                *       1 int_or
+                *       1 int_shr_un
+                *       1 localloc
+                *       1 long_ceq
+                *       1 long_rem
+                *       1 long_sub
+                *       2 int_ceq
+                *       2 int_conv_to_i2
+                *       2 int_min
+                *       2 lcall
+                *       2 long_div
+                *       3 int_conv_to_u2
+                *       3 long_shr_imm
+                *       4 int_rem
+                *       4 int_rem_imm
+                *       4 loadi1_membase
+                *       4 loadu4_membase
+                *       5 int_div
+                *       5 shl_imm
+                *       6 int_div_imm
+                *       6 int_mul
+                *       9 int_mul_imm
+                *       9 zext_i4
+                *      10 int_shr_imm
+                *      12 int_shr_un_imm
+                *      12 long_add_imm
+                *      12 outarg_vtretaddr
+                *      12 strlen
+                *      13 int_or_imm
+                *      23 call_membase
+                *      23 int_conv_to_u1
+                *      23 long_add
+                *      24 int_and_imm
+                *      24 int_shl_imm
+                *      24 loadu2_membase
+                *      29 loadi8_membase
+                *      31 llvm_outarg_vt
+                *      34 int_sub
+                *      34 loadu1_membase
+                *      42 int_add
+                *      85 ldaddr
+                *     116 loadi4_membase
+                *     159 x86_lea
+                *     179 sext_i4
+                *     291 load_membase
+                *     462 i8const
+                *     472 call
+                */
+               
                break;
        }
        return value_kind;
@@ -486,12 +537,9 @@ remove_change_from_evaluation_area (MonoAdditionalVariableRelation *change)
 
 
 static void
-clean_contexts (MonoRelationsEvaluationContext *contexts, int number)
+clean_contexts (MonoVariableRelationsEvaluationArea *area, int number)
 {
-       int i;
-       for (i = 0; i < number; i++) {
-               contexts [i].status = MONO_RELATIONS_EVALUATION_NOT_STARTED;
-       }
+       memset(area->statuses, MONO_RELATIONS_EVALUATION_NOT_STARTED, number * sizeof(MonoRelationsEvaluationStatus));
 }
 
 
@@ -604,13 +652,14 @@ intersect_ranges( MonoRelationsEvaluationRanges *ranges, MonoRelationsEvaluation
  *                 (or NULL for the first invocation)
  */
 static void
-evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *area, int variable, int target_variable, MonoRelationsEvaluationContext *father_context)
+evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *area, const int variable, const int target_variable, MonoRelationsEvaluationContext *father_context)
 {
-       MonoRelationsEvaluationContext *context = &(area->contexts [variable]);
+       MonoRelationsEvaluationContext * const context = &(area->contexts [variable]);
+       MonoRelationsEvaluationStatus * const status = &(area->statuses [variable]);
        
        // First of all, we check the evaluation status
        // (what must be done is *very* different in each case)
-       switch (context->status) {
+       switch (*status) {
        case MONO_RELATIONS_EVALUATION_NOT_STARTED: {
                MonoSummarizedValueRelation *relation = &(area->relations [variable]);
                
@@ -621,7 +670,7 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are
                }
                
                // We properly inizialize the context
-               context->status = MONO_RELATIONS_EVALUATION_IN_PROGRESS;
+               *status = MONO_RELATIONS_EVALUATION_IN_PROGRESS;
                context->father = father_context;
                MONO_MAKE_RELATIONS_EVALUATION_RANGES_WEAK (context->ranges);
                
@@ -663,24 +712,25 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are
                                if (relation->relation != MONO_ANY_RELATION) {
                                        int related_variable = relation->related_value.value.variable.variable;
                                        MonoRelationsEvaluationContext *related_context = &(area->contexts [related_variable]);
+                                       MonoRelationsEvaluationStatus related_status = area->statuses [related_variable];
                                        
                                        // The second condition in the "or" avoids messing with "back edges" in the graph traversal
                                        // (they are simply ignored instead of triggering the handling of recursion)
-                                       if ( (related_context->status == MONO_RELATIONS_EVALUATION_NOT_STARTED) || !
+                                       if ( (related_status == MONO_RELATIONS_EVALUATION_NOT_STARTED) || !
                                                        ((related_context->current_relation->related_value.type == MONO_VARIABLE_SUMMARIZED_VALUE) &&
                                                        (related_context->current_relation->related_value.value.variable.variable == variable))) {
                                                // Evaluate the related variable
                                                evaluate_relation_with_target_variable (area, related_variable, target_variable, context);
                                                
                                                // Check if we are part of a recursive loop
-                                               if (context->status & MONO_RELATIONS_EVALUATION_IS_RECURSIVE) {
+                                               if (*status & MONO_RELATIONS_EVALUATION_IS_RECURSIVE) {
                                                        if (TRACE_ABC_REMOVAL) {
                                                                printf ("Recursivity detected for variable %d (target variable %d), status ", variable, target_variable);
-                                                               print_evaluation_context_status (context->status);
+                                                               print_evaluation_context_status (*status);
                                                        }
                                                        
                                                        // If we are, check if the evaluation of the related variable is complete
-                                                       if (related_context->status == MONO_RELATIONS_EVALUATION_COMPLETED) {
+                                                       if (related_status == MONO_RELATIONS_EVALUATION_COMPLETED) {
                                                                // If it is complete, we are part of a recursive definition.
                                                                // Since it is a *definition* (and definitions are evaluated *before*
                                                                // conditions because they are first in the list), intersection is not
@@ -688,7 +738,7 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are
                                                                context->ranges = related_context->ranges;
                                                                /* Delta has already been checked for over/under-flow when evaluating values */
                                                                MONO_ADD_DELTA_SAFELY_TO_RANGES (context->ranges, relation->related_value.value.variable.delta);
-                                                               context->status = MONO_RELATIONS_EVALUATION_COMPLETED;
+                                                               *status = MONO_RELATIONS_EVALUATION_COMPLETED;
                                                                if (TRACE_ABC_REMOVAL) {
                                                                        printf (", ranges already computed, result: \n");
                                                                        print_evaluation_context_ranges (&(context->ranges));
@@ -726,25 +776,25 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are
                                        evaluate_relation_with_target_variable (area, phi_alternative, target_variable, context);
                                        
                                        // This means we are part of a recursive loop
-                                       if (context->status & MONO_RELATIONS_EVALUATION_IS_RECURSIVE) {
+                                       if (*status & MONO_RELATIONS_EVALUATION_IS_RECURSIVE) {
                                                if (TRACE_ABC_REMOVAL) {
                                                        printf ("Recursivity detected for variable %d (target variable %d), status ", variable, target_variable);
-                                                       print_evaluation_context_status (context->status);
+                                                       print_evaluation_context_status (*status);
                                                        printf ("\n");
                                                }
-                                               if (context->status & MONO_RELATIONS_EVALUATION_IS_RECURSIVELY_ASCENDING) {
+                                               if (*status & MONO_RELATIONS_EVALUATION_IS_RECURSIVELY_ASCENDING) {
                                                        is_ascending = TRUE;
                                                }
-                                               if (context->status & MONO_RELATIONS_EVALUATION_IS_RECURSIVELY_DESCENDING) {
+                                               if (*status & MONO_RELATIONS_EVALUATION_IS_RECURSIVELY_DESCENDING) {
                                                        is_descending = TRUE;
                                                }
-                                               if (context->status & MONO_RELATIONS_EVALUATION_IS_RECURSIVELY_INDEFINITE) {
+                                               if (*status & MONO_RELATIONS_EVALUATION_IS_RECURSIVELY_INDEFINITE) {
                                                        is_ascending = TRUE;
                                                        is_descending = TRUE;
                                                }
                                                
                                                // Clear "recursivity" bits in the status (recursion has been handled)
-                                               context->status = MONO_RELATIONS_EVALUATION_IN_PROGRESS;
+                                               *status = MONO_RELATIONS_EVALUATION_IN_PROGRESS;
                                        } else {
                                                MONO_RELATIONS_EVALUATION_RANGES_UNION (phi_ranges, area->contexts [phi_alternative].ranges);
                                        }
@@ -773,16 +823,16 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are
                }
                
                // Check if any recursivity bits are still in the status, and in any case clear them
-               if (context->status & MONO_RELATIONS_EVALUATION_IS_RECURSIVE) {
+               if (*status & MONO_RELATIONS_EVALUATION_IS_RECURSIVE) {
                        if (TRACE_ABC_REMOVAL) {
                                printf ("Recursivity for variable %d (target variable %d) discards computation, status ", variable, target_variable);
-                               print_evaluation_context_status (context->status);
+                               print_evaluation_context_status (*status);
                                printf ("\n");
                        }
                        // If yes, we did not have enough information (most likely we were evaluated inside a PHI, but we also
                        // depended on the same PHI, which was still in evaluation...), so clear the status to "NOT_STARTED"
                        // (if we will be evaluated again, the PHI will be already done, so our evaluation will succeed)
-                       context->status = MONO_RELATIONS_EVALUATION_NOT_STARTED;
+                       *status = MONO_RELATIONS_EVALUATION_NOT_STARTED;
                } else {
                        if (TRACE_ABC_REMOVAL) {
                                printf ("Ranges for variable %d (target variable %d) computed: ", variable, target_variable);
@@ -790,7 +840,7 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are
                                printf ("\n");
                        }
                        // If not (the common case) the evaluation is complete, and the result is in the context
-                       context->status = MONO_RELATIONS_EVALUATION_COMPLETED;
+                       *status = MONO_RELATIONS_EVALUATION_COMPLETED;
                }
                break;
        }
@@ -804,7 +854,7 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are
                
                if (TRACE_ABC_REMOVAL) {
                        printf ("Evaluation of variable %d (target variable %d) already in progress\n", variable, target_variable);
-                       print_evaluation_context (context);
+                       print_evaluation_context (context, *status);
                        print_summarized_value_relation (context->current_relation);
                        printf ("\n");
                }
@@ -854,7 +904,9 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are
                        
                        current_context = father_context;
                        while (current_context != last_context) {
-                               current_context->status |= recursive_status;
+                               int index = father_context - area->contexts;
+                               MonoRelationsEvaluationStatus *current_status = &(area->statuses [index]);
+                               *current_status = (MonoRelationsEvaluationStatus)(*current_status | recursive_status);
                                current_context = current_context->father;
                        }
                } else {
@@ -870,7 +922,7 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are
        default:
                if (TRACE_ABC_REMOVAL) {
                        printf ("Variable %d (target variable %d) already in a recursive ring, skipping\n", variable, target_variable);
-                       print_evaluation_context (context);
+                       print_evaluation_context (context, *status);
                        print_summarized_value_relation (context->current_relation);
                        printf ("\n");
                }
@@ -935,7 +987,7 @@ remove_abc_from_inst (MonoInst *ins, MonoVariableRelationsEvaluationArea *area)
        MonoRelationsEvaluationContext *array_context = &(area->contexts [array_variable]);
        MonoRelationsEvaluationContext *index_context = &(area->contexts [index_variable]);
                                
-       clean_contexts (area->contexts, area->cfg->next_vreg);
+       clean_contexts (area, area->cfg->next_vreg);
                                
        evaluate_relation_with_target_variable (area, index_variable, array_variable, NULL);
        evaluate_relation_with_target_variable (area, array_variable, array_variable, NULL);
@@ -944,8 +996,8 @@ remove_abc_from_inst (MonoInst *ins, MonoVariableRelationsEvaluationArea *area)
                if (REPORT_ABC_REMOVAL) {
                        printf ("ARRAY-ACCESS: removed bounds check on array %d with index %d\n",
                                        array_variable, index_variable);
-                       NULLIFY_INS (ins);
                }
+               NULLIFY_INS (ins);
        } else {
                if (TRACE_ABC_REMOVAL) {
                        if (index_context->ranges.zero.lower >= 0) {
@@ -961,6 +1013,34 @@ remove_abc_from_inst (MonoInst *ins, MonoVariableRelationsEvaluationArea *area)
        }
 }
 
+static gboolean
+eval_non_null (MonoVariableRelationsEvaluationArea *area, int reg)
+{
+       MonoRelationsEvaluationContext *context = &(area->contexts [reg]);
+
+       clean_contexts (area, area->cfg->next_vreg);
+       evaluate_relation_with_target_variable (area, reg, reg, NULL);
+                               
+       return context->ranges.zero.lower > 0;
+}
+
+static void
+add_non_null (MonoVariableRelationsEvaluationArea *area, MonoCompile *cfg, int reg,
+                         GSList **check_relations)
+{
+       MonoAdditionalVariableRelation *rel;
+
+       rel = (MonoAdditionalVariableRelation *)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoAdditionalVariableRelation));
+       rel->variable = reg;
+       rel->relation.relation = MONO_GT_RELATION;
+       rel->relation.related_value.type = MONO_CONSTANT_SUMMARIZED_VALUE;
+       rel->relation.related_value.value.constant.value = 0;
+
+       apply_change_to_evaluation_area (area, rel);
+
+       *check_relations = g_slist_append_mempool (cfg->mempool, *check_relations, rel);
+}
+
 /*
  * Process a BB removing bounds checks from array accesses.
  * It does the following (in sequence):
@@ -986,6 +1066,9 @@ process_block (MonoCompile *cfg, MonoBasicBlock *bb, MonoVariableRelationsEvalua
                printf ("\nProcessing block %d [dfn %d]...\n", bb->block_num, bb->dfn);
        }
 
+       if (bb->region != -1)
+               return;
+
        get_relations_from_previous_bb (area, bb, &additional_relations);
        if (TRACE_ABC_REMOVAL) {
                if (additional_relations.relation1.relation.relation != MONO_ANY_RELATION) {
@@ -1024,7 +1107,7 @@ process_block (MonoCompile *cfg, MonoBasicBlock *bb, MonoVariableRelationsEvalua
 
                        /* We can derive additional relations from the bounds check */
                        if (ins->opcode != OP_NOP) {
-                               rel = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoAdditionalVariableRelation));
+                               rel = (MonoAdditionalVariableRelation *)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoAdditionalVariableRelation));
                                rel->variable = index_var;
                                rel->relation.relation = MONO_LT_RELATION;
                                rel->relation.related_value.type = MONO_VARIABLE_SUMMARIZED_VALUE;
@@ -1035,7 +1118,7 @@ process_block (MonoCompile *cfg, MonoBasicBlock *bb, MonoVariableRelationsEvalua
 
                                check_relations = g_slist_append_mempool (cfg->mempool, check_relations, rel);
 
-                               rel = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoAdditionalVariableRelation));
+                               rel = (MonoAdditionalVariableRelation *)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoAdditionalVariableRelation));
                                rel->variable = index_var;
                                rel->relation.relation = MONO_GE_RELATION;
                                rel->relation.related_value.type = MONO_CONSTANT_SUMMARIZED_VALUE;
@@ -1048,28 +1131,57 @@ process_block (MonoCompile *cfg, MonoBasicBlock *bb, MonoVariableRelationsEvalua
                }
 
                if (ins->opcode == OP_CHECK_THIS) {
-                       MonoRelationsEvaluationContext *context = &(area->contexts [ins->sreg1]);
-
-                       clean_contexts (area->contexts, area->cfg->next_vreg);
-                       evaluate_relation_with_target_variable (area, ins->sreg1, ins->sreg1, NULL);
-                               
-                       if (context->ranges.zero.lower > 0) {
+                       if (eval_non_null (area, ins->sreg1)) {
                                if (REPORT_ABC_REMOVAL)
                                        printf ("ARRAY-ACCESS: removed check_this instruction.\n");
                                NULLIFY_INS (ins);
                        }
                }
 
-               if (ins->opcode == OP_NOT_NULL) {
-                       rel = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoAdditionalVariableRelation));
-                       rel->variable = ins->sreg1;
-                       rel->relation.relation = MONO_GT_RELATION;
-                       rel->relation.related_value.type = MONO_CONSTANT_SUMMARIZED_VALUE;
-                       rel->relation.related_value.value.constant.value = 0;
-
-                       apply_change_to_evaluation_area (area, rel);
+               if (ins->opcode == OP_NOT_NULL)
+                       add_non_null (area, cfg, ins->sreg1, &check_relations);
 
-                       check_relations = g_slist_append_mempool (cfg->mempool, check_relations, rel);
+               /* 
+                * 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.
+                */
+               if (COMPILE_LLVM (cfg) && (ins->opcode == OP_LDLEN ||
+                                                                  ins->opcode == OP_BOUNDS_CHECK ||
+                                                                  ins->opcode == OP_STRLEN ||
+                                                                  (MONO_IS_LOAD_MEMBASE (ins) && (ins->flags & MONO_INST_FAULT)) ||
+                                                                  (MONO_IS_STORE_MEMBASE (ins) && (ins->flags & MONO_INST_FAULT)))) {
+                       int reg;
+
+                       if (MONO_IS_STORE_MEMBASE (ins))
+                               reg = ins->inst_destbasereg;
+                       else if (MONO_IS_LOAD_MEMBASE (ins))
+                               reg = ins->inst_basereg;
+                       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");
+                               ins->flags &= ~MONO_INST_FAULT;
+                       } else {
+                               add_non_null (area, cfg, reg, &check_relations);
+                       }
+                       */
                }
        }       
        
@@ -1082,7 +1194,7 @@ process_block (MonoCompile *cfg, MonoBasicBlock *bb, MonoVariableRelationsEvalua
        }
 
        for (l = check_relations; l; l = l->next)
-               remove_change_from_evaluation_area (l->data);
+               remove_change_from_evaluation_area ((MonoAdditionalVariableRelation *)l->data);
        
        remove_change_from_evaluation_area (&(additional_relations.relation1));
        remove_change_from_evaluation_area (&(additional_relations.relation2));
@@ -1113,10 +1225,10 @@ type_to_value_kind (MonoType *type)
                return MONO_UNSIGNED_INTEGER_VALUE_SIZE_4;
                break;
        case MONO_TYPE_I:
-               return SIZEOF_VOID_P;
+               return (MonoIntegerValueKind)SIZEOF_VOID_P;
                break;
        case MONO_TYPE_U:
-               return (MONO_UNSIGNED_VALUE_FLAG|SIZEOF_VOID_P);
+               return (MonoIntegerValueKind)(MONO_UNSIGNED_VALUE_FLAG | SIZEOF_VOID_P);
                break;
        case MONO_TYPE_I8:
                return MONO_INTEGER_VALUE_SIZE_8;
@@ -1160,16 +1272,23 @@ mono_perform_abc_removal (MonoCompile *cfg)
        area.cfg = cfg;
        area.relations = (MonoSummarizedValueRelation *)
                mono_mempool_alloc (cfg->mempool, sizeof (MonoSummarizedValueRelation) * (cfg->next_vreg) * 2);
+
        area.contexts = (MonoRelationsEvaluationContext *)
-               mono_mempool_alloc (cfg->mempool, sizeof (MonoRelationsEvaluationContext) * (cfg->next_vreg));
+               mono_mempool_alloc0 (cfg->mempool, sizeof (MonoRelationsEvaluationContext) * (cfg->next_vreg));
+
+       area.statuses = (MonoRelationsEvaluationStatus *)
+               mono_mempool_alloc0 (cfg->mempool, sizeof (MonoRelationsEvaluationStatus) * (cfg->next_vreg));
+
        area.variable_value_kind = (MonoIntegerValueKind *)
                mono_mempool_alloc (cfg->mempool, sizeof (MonoIntegerValueKind) * (cfg->next_vreg));
+       area.defs = (MonoInst **)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) {
@@ -1262,4 +1381,8 @@ mono_perform_abc_removal (MonoCompile *cfg)
        process_block (cfg, cfg->bblocks [0], &area);
 }
 
-#endif /* DISABLE_JIT */
+#else /* !DISABLE_JIT */
+
+MONO_EMPTY_SOURCE_FILE (abcremoval);
+
+#endif /* !DISABLE_JIT */