X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fabcremoval.c;h=c5d5f4dfb34f92459d610fb9ee02032010067340;hb=77fb4aee8189d85d295c6f0735ee8097e9d2946c;hp=45d5394a6679a188dd8435e8311e12ae11523d4e;hpb=3a86569d2768d0fb43d7eac5be868c0005501e4a;p=mono.git diff --git a/mono/mini/abcremoval.c b/mono/mini/abcremoval.c index 45d5394a667..c5d5f4dfb34 100644 --- a/mono/mini/abcremoval.c +++ b/mono/mini/abcremoval.c @@ -1,5 +1,6 @@ -/* - * abcremoval.c: Array bounds check removal +/** + * \file + * Array bounds check removal * * Author: * Massimiliano Mantione (massi@ximian.com) @@ -13,6 +14,7 @@ #include #include #include +#include #include @@ -62,8 +64,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))) @@ -183,10 +185,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"); @@ -537,12 +538,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)); } @@ -655,13 +653,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]); @@ -672,7 +671,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); @@ -714,24 +713,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 @@ -739,7 +739,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)); @@ -777,25 +777,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); } @@ -824,16 +824,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); @@ -841,7 +841,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; } @@ -855,7 +855,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"); } @@ -905,7 +905,9 @@ evaluate_relation_with_target_variable (MonoVariableRelationsEvaluationArea *are current_context = father_context; while (current_context != last_context) { - current_context->status |= recursive_status; + int index = current_context - area->contexts; + MonoRelationsEvaluationStatus *current_status = &(area->statuses [index]); + *current_status = (MonoRelationsEvaluationStatus)(*current_status | recursive_status); current_context = current_context->father; } } else { @@ -921,7 +923,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"); } @@ -986,7 +988,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); @@ -1017,7 +1019,7 @@ eval_non_null (MonoVariableRelationsEvaluationArea *area, int reg) { MonoRelationsEvaluationContext *context = &(area->contexts [reg]); - clean_contexts (area->contexts, area->cfg->next_vreg); + clean_contexts (area, area->cfg->next_vreg); evaluate_relation_with_target_variable (area, reg, reg, NULL); return context->ranges.zero.lower > 0; @@ -1029,7 +1031,7 @@ add_non_null (MonoVariableRelationsEvaluationArea *area, MonoCompile *cfg, int r { MonoAdditionalVariableRelation *rel; - rel = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoAdditionalVariableRelation)); + 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; @@ -1106,7 +1108,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; @@ -1117,7 +1119,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; @@ -1193,7 +1195,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)); @@ -1224,10 +1226,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; @@ -1241,7 +1243,7 @@ type_to_value_kind (MonoType *type) /** * mono_perform_abc_removal: - * @cfg: Control Flow Graph + * \param cfg Control Flow Graph * * Performs the ABC removal from a cfg in SSA form. * It does the following: @@ -1271,11 +1273,16 @@ 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 = mono_mempool_alloc (cfg->mempool, sizeof (MonoInst*) * 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; @@ -1293,10 +1300,22 @@ mono_perform_abc_removal (MonoCompile *cfg) for (ins = bb->code; ins; ins = ins->next) { const char *spec = INS_INFO (ins->opcode); + gint32 idx, *reg; if (spec [MONO_INST_DEST] == ' ' || MONO_IS_STORE_MEMBASE (ins)) continue; + MONO_INS_FOR_EACH_REG (ins, idx, reg) { + MonoInst *var = get_vreg_to_inst (cfg, *reg); + if (var && (!MONO_VARINFO (cfg, var->inst_c0)->def)) + break; + } + if (idx < MONO_INST_LEN) { + if (TRACE_ABC_REMOVAL) + printf ("Global register %d is not in the SSA form, skipping.\n", *reg); + continue; + } + if (spec [MONO_INST_DEST] == 'i') { MonoIntegerValueKind effective_value_kind; MonoRelationsEvaluationRange range; @@ -1375,4 +1394,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 */