2009-11-13 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Fri, 13 Nov 2009 02:37:20 +0000 (02:37 -0000)
committerZoltan Varga <vargaz@gmail.com>
Fri, 13 Nov 2009 02:37:20 +0000 (02:37 -0000)
* mini-llvm.c: Add support for OP_VPHI.

* objects.cs: Add a test.

svn path=/trunk/mono/; revision=146096

mono/mini/ChangeLog
mono/mini/mini-llvm.c
mono/mini/objects.cs

index dea18624f5a3e46c58a73b848a8ad2b80ce3e07a..42ce1f72ba8e7f2cdb12fb4131d2293abc6ef900 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-13  Zoltan Varga  <vargaz@gmail.com>
+
+       * mini-llvm.c: Add support for OP_VPHI.
+
+       * objects.cs: Add a test.
+
 2009-11-13  Zoltan Varga  <vargaz@gmail.com>
 
        * debugger-agent.c (mono_debugger_agent_single_step_event): Avoid a crash if
index ccf826348f2861aec06f021a526f3d8f38fc5688..0ac9fc1bcfbbc7dcd4dad0b081a877d2be469f09 100644 (file)
@@ -985,7 +985,9 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder, int *pindexes)
                if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
                        vtype = type_to_llvm_type (ctx, var->inst_vtype);
                        CHECK_FAILURE (ctx);
-                       ctx->addresses [var->dreg] = LLVMBuildAlloca (builder, vtype, "");
+                       /* Could be already created by an OP_VPHI */
+                       if (!ctx->addresses [var->dreg])
+                               ctx->addresses [var->dreg] = LLVMBuildAlloca (builder, vtype, "");
                        ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
                }
        }
@@ -1197,11 +1199,18 @@ mono_llvm_emit_method (MonoCompile *cfg)
                for (ins = bb->code; ins; ins = ins->next) {
                        switch (ins->opcode) {
                        case OP_PHI:
-                       case OP_FPHI: {
+                       case OP_FPHI:
+                       case OP_VPHI: {
                                LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
 
                                CHECK_FAILURE (ctx);
 
+                               if (ins->opcode == OP_VPHI) {
+                                       /* Treat valuetype PHI nodes as operating on the address itself */
+                                       g_assert (ins->klass);
+                                       phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
+                               }
+
                                /* 
                                 * Have to precreate these, as they can be referenced by
                                 * earlier instructions.
@@ -1210,6 +1219,9 @@ mono_llvm_emit_method (MonoCompile *cfg)
                                dname = dname_buf;
                                values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
 
+                               if (ins->opcode == OP_VPHI)
+                                       addresses [ins->dreg] = values [ins->dreg];
+
                                g_ptr_array_add (phi_values, values [ins->dreg]);
 
                                /* 
@@ -1531,7 +1543,8 @@ mono_llvm_emit_method (MonoCompile *cfg)
                                break;
                        }
                        case OP_PHI:
-                       case OP_FPHI: {
+                       case OP_FPHI:
+                       case OP_VPHI: {
                                int i;
                                gboolean empty = TRUE;
 
@@ -2598,8 +2611,13 @@ mono_llvm_emit_method (MonoCompile *cfg)
                        }
 
                        /* Convert the value to the type required by phi nodes */
-                       if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg])
-                               values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
+                       if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg]) {
+                               if (!values [ins->dreg])
+                                       /* vtypes */
+                                       values [ins->dreg] = addresses [ins->dreg];
+                               else
+                                       values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
+                       }
 
                        /* Add stores for volatile variables */
                        if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
index 424f5502653b7a51aac09c256c585ebc2b9a49b6..2b02c0c0aeaa9202fe20f4707a0197e19603ce29 100644 (file)
@@ -1433,5 +1433,28 @@ ncells ) {
                        return 1;
                return 0;
        }
+
+       struct VTypePhi {
+               public int i;
+       }
+
+       static int vtype_phi (VTypePhi v1, VTypePhi v2, bool first) {
+               VTypePhi v = first ? v1 : v2;
+
+               return v.i;
+       }
+
+       static int test_0_vtype_phi ()
+       {
+               VTypePhi v1 = new VTypePhi () { i = 1 };
+               VTypePhi v2 = new VTypePhi () { i = 2 };
+
+               if (vtype_phi (v1, v2, true) != 1)
+                       return 1;
+               if (vtype_phi (v1, v2, false) != 2)
+                       return 2;
+
+               return 0;
+       }
 }