2008-08-23 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / aliasing.c
index 30ae15ea32c4ba4e1d96a69a33ddb9976b234b61..f0ef836024967522f0cc56659ae2691f836ff822 100644 (file)
@@ -48,7 +48,7 @@ static const char *mono_stack_type_names[] = {
 
 
 #define OP_IS_OUTARG(op) (((op)==OP_OUTARG)||((op)==OP_OUTARG_REG)||((op)==OP_OUTARG_IMM)||((op)==OP_OUTARG_R4)||((op)==OP_OUTARG_R8)||((op)==OP_OUTARG_VT))
-#define OP_IS_CALL(op) (((op)==CEE_CALLI)||((op)==CEE_CALL)||((op)==CEE_CALLVIRT)||(((op)>=OP_VOIDCALL)&&((op)<=OP_CALL_MEMBASE)))
+#define OP_IS_CALL(op) (((op)==CEE_CALLI)||((op)==OP_CALL)||((op)==OP_CALLVIRT)||(((op)>=OP_VOIDCALL)&&((op)<=OP_CALL_MEMBASE)))
 #define OP_IS_STORE(op) (((op)==CEE_STIND_REF)||((op)==CEE_STIND_I1)||((op)==CEE_STIND_I2)||((op)==CEE_STIND_I4)||((op)==CEE_STIND_I8)||((op)==CEE_STIND_R4)||((op)==CEE_STIND_R8)||((op)==CEE_STIND_I))
 #define OP_IS_LOAD(op) (((op)==CEE_LDIND_REF)||((op)==CEE_LDIND_I1)||((op)==CEE_LDIND_I2)||((op)==CEE_LDIND_I4)||((op)==CEE_LDIND_U1)||((op)==CEE_LDIND_U2)||((op)==CEE_LDIND_U4)||((op)==CEE_LDIND_I8)||((op)==CEE_LDIND_R4)||((op)==CEE_LDIND_R8)||((op)==CEE_LDIND_I))
 #define OP_IS_CONST(op) (((op)==OP_ICONST)||((op)==OP_I8CONST)||((op)==OP_R4CONST)||((op)==OP_R8CONST)||((op)==OP_AOTCONST))
@@ -158,8 +158,8 @@ print_tree_node (MonoInst *tree) {
        case CEE_NEWARR:
                printf ("[%s]",  tree->inst_newa_class->name);
                break;
-       case CEE_CALL:
-       case CEE_CALLVIRT:
+       case OP_CALL:
+       case OP_CALLVIRT:
        case OP_FCALL:
        case OP_FCALLVIRT:
        case OP_LCALL:
@@ -167,7 +167,23 @@ print_tree_node (MonoInst *tree) {
        case OP_VCALL:
        case OP_VCALLVIRT:
        case OP_VOIDCALL:
-       case OP_VOIDCALLVIRT: {
+       case OP_VOIDCALLVIRT:
+       case OP_TRAMPCALL_VTABLE:
+       case OP_CALL_RGCTX:
+       case OP_FCALL_RGCTX:
+       case OP_VOIDCALL_RGCTX:
+       case OP_LCALL_RGCTX:
+       case OP_VCALL_RGCTX:
+       case OP_CALL_REG_RGCTX:
+       case OP_FCALL_REG_RGCTX:
+       case OP_VOIDCALL_REG_RGCTX:
+       case OP_LCALL_REG_RGCTX:
+       case OP_VCALL_REG_RGCTX:
+       case OP_CALLVIRT_IMT:
+       case OP_VOIDCALLVIRT_IMT:
+       case OP_FCALLVIRT_IMT:
+       case OP_LCALLVIRT_IMT:
+       case OP_VCALLVIRT_IMT: {
                MonoCallInst *call = (MonoCallInst*)tree;
                if (call->method)
                        printf ("[%s]", call->method->name);
@@ -199,7 +215,7 @@ print_tree_node (MonoInst *tree) {
        case OP_LOADI2_MEMBASE:
                printf ("[%s] <- [%s + 0x%x]", mono_arch_regname (tree->dreg), mono_arch_regname (tree->inst_basereg), (int)tree->inst_offset);
                break;
-       case CEE_BR:
+       case OP_BR:
        case OP_CALL_HANDLER:
                printf ("[B%d]", tree->inst_target_bb->block_num);
                break;
@@ -314,7 +330,7 @@ print_code_with_aliasing_information (MonoAliasingInformation *info) {
                
                printf ("CODE FOR BB %d\n", bb_info->bb->block_num);
                mono_aliasing_initialize_code_traversal (info, bb_info->bb);
-               for (inst = bb_info->bb->code; inst != NULL; inst = inst->next) {
+               MONO_BB_FOR_EACH_INS (bb_info->bb, inst) {
                        print_tree_with_aliasing_information (info, inst);
                        printf ("\n");
                }
@@ -642,30 +658,39 @@ update_aliasing_information_on_inst (MonoAliasingInformation *info, MonoAliasing
        } else if ((inst->opcode == OP_UNBOXCAST) || OP_IS_PCONV (inst->opcode) || OP_IS_ICONV (inst->opcode)) {
                father_alias->type = context.subtree_aliases [0].type;
                father_alias->variable_index = context.subtree_aliases [0].variable_index;
-       } else if ((inst->opcode == CEE_LDELEMA) || (inst->opcode == OP_COMPARE) || (inst->opcode == CEE_SWITCH)) {
+       } else if ((inst->opcode == CEE_LDELEMA) || (inst->opcode == OP_COMPARE) || (inst->opcode == OP_SWITCH)) {
                if (father_alias != NULL) {
                        father_alias->type = MONO_ALIASING_TYPE_NO_ALIAS;
                }
        } else {
                MonoAliasType father_type = MONO_ALIASING_TYPE_NO_ALIAS;
+               MonoLocalVariableList *affected_variables = NULL;
+               
                if ((context.subtree_aliases [0].type == MONO_ALIASING_TYPE_LOCAL) || (context.subtree_aliases [0].type == MONO_ALIASING_TYPE_LOCAL_FIELD)) {
-                       MonoAliasUsageInformation *use = mono_mempool_alloc (info->mempool, sizeof (MonoAliasUsageInformation));
-                       
-                       inst->ssa_op = MONO_SSA_INDIRECT_LOAD_STORE;
-                       use->inst = inst;
-                       use->affected_variables = &(info->variables [context.subtree_aliases [0].variable_index]);
-                       APPEND_USE (info, bb_info, use);
+                       affected_variables = &(info->variables [context.subtree_aliases [0].variable_index]);
                        ADD_BAD_ALIAS (info, context.subtree_aliases [0].variable_index);
                }
                if ((context.subtree_aliases [1].type == MONO_ALIASING_TYPE_LOCAL) || (context.subtree_aliases [1].type == MONO_ALIASING_TYPE_LOCAL_FIELD)) {
+                       if (affected_variables == NULL) {
+                               affected_variables = &(info->variables [context.subtree_aliases [1].variable_index]);
+                       } else if (affected_variables->variable_index != context.subtree_aliases [1].variable_index) {
+                               int previous_index = affected_variables->variable_index;
+                               affected_variables = NULL;
+                               ADD_UNIQUE_VARIABLE (info, affected_variables, previous_index);
+                               ADD_UNIQUE_VARIABLE (info, affected_variables, context.subtree_aliases [1].variable_index);
+                       }
+                       ADD_BAD_ALIAS (info, context.subtree_aliases [1].variable_index);
+               }
+               
+               if (affected_variables != NULL) {
                        MonoAliasUsageInformation *use = mono_mempool_alloc (info->mempool, sizeof (MonoAliasUsageInformation));
                        
                        inst->ssa_op = MONO_SSA_INDIRECT_LOAD_STORE;
                        use->inst = inst;
-                       use->affected_variables = &(info->variables [context.subtree_aliases [1].variable_index]);
+                       use->affected_variables = affected_variables;
                        APPEND_USE (info, bb_info, use);
-                       ADD_BAD_ALIAS (info, context.subtree_aliases [1].variable_index);
                }
+               
                if (father_alias != NULL) { 
                        if ((context.subtree_aliases [0].type == MONO_ALIASING_TYPE_ANY) || (context.subtree_aliases [1].type == MONO_ALIASING_TYPE_ANY)) {
                                father_type = MONO_ALIASING_TYPE_ANY;
@@ -733,7 +758,7 @@ mono_build_aliasing_information (MonoCompile *cfg) {
                bb_info->potential_alias_uses = NULL;
                info->next_interesting_inst = NULL;
                
-               for (inst = bb->code; inst != NULL; inst = inst->next) {
+               MONO_BB_FOR_EACH_INS (bb, inst) {
                        if (FOLLOW_ALIAS_ANALYSIS) {
                                printf ("TRAVERSING INST: ");
                                mono_print_tree_nl (inst);
@@ -944,7 +969,7 @@ mono_aliasing_deadce_on_inst (MonoAliasingInformation *info, MonoInst **possibly
                                                printf ("KILLING slot %d at inst ", affected_variable->variable_index);
                                                mono_print_tree_nl (inst);
                                        }
-                                       possibly_dead_assignments [affected_variable->variable_index]->opcode = CEE_NOP;
+                                       possibly_dead_assignments [affected_variable->variable_index]->opcode = OP_NOP;
                                        possibly_dead_assignments [affected_variable->variable_index]->ssa_op = MONO_SSA_NOP;
                                        possibly_dead_assignments [affected_variable->variable_index] = NULL;
                                }
@@ -978,9 +1003,7 @@ mono_aliasing_deadce (MonoAliasingInformation *info) {
        possibly_dead_assignments = alloca (cfg->num_varinfo * sizeof (MonoInst*));
        
        if (LOG_DEADCE) {
-               printf ("BEFORE DEADCE START\n");
-               mono_print_code (cfg);
-               printf ("BEFORE DEADCE END\n");
+               mono_print_code (cfg, "BEFORE DEADCE START");
        }
        
 #if (MONO_APPLY_DEADCE_TO_SINGLE_METHOD)
@@ -1005,9 +1028,9 @@ mono_aliasing_deadce (MonoAliasingInformation *info) {
                        printf ("Working on BB %d\n", bb->block_num);
                }
                
-               for (inst = bb->code; inst != NULL; inst = inst->next) {
+               MONO_BB_FOR_EACH_INS (bb, inst) {
                        mono_aliasing_deadce_on_inst (info, possibly_dead_assignments, inst);
-                       if (inst->opcode == CEE_JMP) {
+                       if (inst->opcode == OP_JMP) {
                                /* Keep arguments live! */
                                for (variable_index = 0; variable_index < cfg->num_varinfo; variable_index++) {
                                        if (cfg->varinfo [variable_index]->opcode == OP_ARG) {
@@ -1030,15 +1053,13 @@ mono_aliasing_deadce (MonoAliasingInformation *info) {
                                
                                //printf ("FAST DEADCE DEAD LOCAL\n");
                                
-                               possibly_dead_assignments [variable_index]->opcode = CEE_NOP;
+                               possibly_dead_assignments [variable_index]->opcode = OP_NOP;
                                possibly_dead_assignments [variable_index]->ssa_op = MONO_SSA_NOP;
                        }
                }
        }
        
        if (LOG_DEADCE) {
-               printf ("AFTER DEADCE START\n");
-               mono_print_code (cfg);
-               printf ("AFTER DEADCE END\n");
+               mono_print_code (cfg, "AFTER DEADCE");
        }
 }