Refactor GT_STOREIND
authorBruce Forstall <brucefo@microsoft.com>
Tue, 2 May 2017 00:49:21 +0000 (17:49 -0700)
committerBruce Forstall <brucefo@microsoft.com>
Tue, 2 May 2017 00:49:21 +0000 (17:49 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/ab0582bd7c6666e7889f062a9584d7ecf788a883

src/coreclr/src/jit/codegenarm.cpp
src/coreclr/src/jit/codegenarm64.cpp
src/coreclr/src/jit/codegenlinear.h

index a96e5de..019641e 100644 (file)
@@ -549,10 +549,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
         break;
 
         case GT_INTRINSIC:
-        {
             genIntrinsic(treeNode);
-        }
-        break;
+            break;
 
         case GT_EQ:
         case GT_NE:
@@ -670,72 +668,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
         break;
 
         case GT_STOREIND:
-        {
-            GenTreeStoreInd* storeInd   = treeNode->AsStoreInd();
-            GenTree*         data       = storeInd->Data();
-            GenTree*         addr       = storeInd->Addr();
-            var_types        targetType = storeInd->TypeGet();
-
-            assert(!varTypeIsFloating(targetType) || (targetType == data->TypeGet()));
-
-            GCInfo::WriteBarrierForm writeBarrierForm = gcInfo.gcIsWriteBarrierCandidate(treeNode, data);
-            if (writeBarrierForm != GCInfo::WBF_NoBarrier)
-            {
-                // data and addr must be in registers.
-                // Consume both registers so that any copies of interfering
-                // registers are taken care of.
-                genConsumeOperands(storeInd->AsOp());
-
-#if NOGC_WRITE_BARRIERS
-                NYI_ARM("NOGC_WRITE_BARRIERS");
-#else
-                // At this point, we should not have any interference.
-                // That is, 'data' must not be in REG_ARG_0,
-                //  as that is where 'addr' must go.
-                noway_assert(data->gtRegNum != REG_ARG_0);
-
-                // addr goes in REG_ARG_0
-                if (addr->gtRegNum != REG_ARG_0)
-                {
-                    inst_RV_RV(INS_mov, REG_ARG_0, addr->gtRegNum, addr->TypeGet());
-                }
-
-                // data goes in REG_ARG_1
-                if (data->gtRegNum != REG_ARG_1)
-                {
-                    inst_RV_RV(INS_mov, REG_ARG_1, data->gtRegNum, data->TypeGet());
-                }
-#endif // NOGC_WRITE_BARRIERS
-
-                genGCWriteBarrier(storeInd, writeBarrierForm);
-            }
-            else // A normal store, not a WriteBarrier store
-            {
-                bool reverseOps  = ((storeInd->gtFlags & GTF_REVERSE_OPS) != 0);
-                bool dataIsUnary = false;
-
-                // We must consume the operands in the proper execution order,
-                // so that liveness is updated appropriately.
-                if (!reverseOps)
-                {
-                    genConsumeAddress(addr);
-                }
-
-                if (!data->isContained())
-                {
-                    genConsumeRegs(data);
-                }
-
-                if (reverseOps)
-                {
-                    genConsumeAddress(addr);
-                }
-
-                emit->emitInsLoadStoreOp(ins_Store(targetType), emitTypeSize(storeInd), data->gtRegNum,
-                                         treeNode->AsIndir());
-            }
-        }
-        break;
+            genCodeForStoreInd(treeNode->AsStoreInd());
+            break;
 
         case GT_COPY:
             // This is handled at the time we call genConsumeReg() on the GT_COPY
@@ -1643,6 +1577,78 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea)
 }
 
 //------------------------------------------------------------------------
+// genCodeForStoreInd: Produce code for a GT_STOREIND node.
+//
+// Arguments:
+//    tree - the GT_STOREIND node
+//
+void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
+{
+    GenTree*  data       = tree->Data();
+    GenTree*  addr       = tree->Addr();
+    var_types targetType = tree->TypeGet();
+    emitter*  emit       = getEmitter();
+
+    assert(!varTypeIsFloating(targetType) || (targetType == data->TypeGet()));
+
+    GCInfo::WriteBarrierForm writeBarrierForm = gcInfo.gcIsWriteBarrierCandidate(tree, data);
+    if (writeBarrierForm != GCInfo::WBF_NoBarrier)
+    {
+        // data and addr must be in registers.
+        // Consume both registers so that any copies of interfering
+        // registers are taken care of.
+        genConsumeOperands(tree);
+
+#if NOGC_WRITE_BARRIERS
+        NYI_ARM("NOGC_WRITE_BARRIERS");
+#else
+        // At this point, we should not have any interference.
+        // That is, 'data' must not be in REG_ARG_0,
+        //  as that is where 'addr' must go.
+        noway_assert(data->gtRegNum != REG_ARG_0);
+
+        // addr goes in REG_ARG_0
+        if (addr->gtRegNum != REG_ARG_0)
+        {
+            inst_RV_RV(INS_mov, REG_ARG_0, addr->gtRegNum, addr->TypeGet());
+        }
+
+        // data goes in REG_ARG_1
+        if (data->gtRegNum != REG_ARG_1)
+        {
+            inst_RV_RV(INS_mov, REG_ARG_1, data->gtRegNum, data->TypeGet());
+        }
+#endif // NOGC_WRITE_BARRIERS
+
+        genGCWriteBarrier(tree, writeBarrierForm);
+    }
+    else // A normal store, not a WriteBarrier store
+    {
+        bool reverseOps  = ((tree->gtFlags & GTF_REVERSE_OPS) != 0);
+        bool dataIsUnary = false;
+
+        // We must consume the operands in the proper execution order,
+        // so that liveness is updated appropriately.
+        if (!reverseOps)
+        {
+            genConsumeAddress(addr);
+        }
+
+        if (!data->isContained())
+        {
+            genConsumeRegs(data);
+        }
+
+        if (reverseOps)
+        {
+            genConsumeAddress(addr);
+        }
+
+        emit->emitInsLoadStoreOp(ins_Store(targetType), emitTypeSize(tree), data->gtRegNum, tree);
+    }
+}
+
+//------------------------------------------------------------------------
 // genCompareLong: Generate code for comparing two longs when the result of the compare
 // is manifested in a register.
 //
index 96598bb..8deeff3 100644 (file)
@@ -2460,93 +2460,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
         break;
 
         case GT_STOREIND:
-        {
-            GenTree*                 data             = treeNode->gtOp.gtOp2;
-            GenTree*                 addr             = treeNode->gtOp.gtOp1;
-            GCInfo::WriteBarrierForm writeBarrierForm = gcInfo.gcIsWriteBarrierCandidate(treeNode, data);
-            if (writeBarrierForm != GCInfo::WBF_NoBarrier)
-            {
-                // data and addr must be in registers.
-                // Consume both registers so that any copies of interfering
-                // registers are taken care of.
-                genConsumeOperands(treeNode->AsOp());
-
-#if NOGC_WRITE_BARRIERS
-                // At this point, we should not have any interference.
-                // That is, 'data' must not be in REG_WRITE_BARRIER_DST_BYREF,
-                //  as that is where 'addr' must go.
-                noway_assert(data->gtRegNum != REG_WRITE_BARRIER_DST_BYREF);
-
-                // 'addr' goes into x14 (REG_WRITE_BARRIER_DST_BYREF)
-                if (addr->gtRegNum != REG_WRITE_BARRIER_DST_BYREF)
-                {
-                    inst_RV_RV(INS_mov, REG_WRITE_BARRIER_DST_BYREF, addr->gtRegNum, addr->TypeGet());
-                }
-
-                // 'data'  goes into x15 (REG_WRITE_BARRIER)
-                if (data->gtRegNum != REG_WRITE_BARRIER)
-                {
-                    inst_RV_RV(INS_mov, REG_WRITE_BARRIER, data->gtRegNum, data->TypeGet());
-                }
-#else
-                // At this point, we should not have any interference.
-                // That is, 'data' must not be in REG_ARG_0,
-                //  as that is where 'addr' must go.
-                noway_assert(data->gtRegNum != REG_ARG_0);
-
-                // addr goes in REG_ARG_0
-                if (addr->gtRegNum != REG_ARG_0)
-                {
-                    inst_RV_RV(INS_mov, REG_ARG_0, addr->gtRegNum, addr->TypeGet());
-                }
-
-                // data goes in REG_ARG_1
-                if (data->gtRegNum != REG_ARG_1)
-                {
-                    inst_RV_RV(INS_mov, REG_ARG_1, data->gtRegNum, data->TypeGet());
-                }
-#endif // NOGC_WRITE_BARRIERS
-
-                genGCWriteBarrier(treeNode, writeBarrierForm);
-            }
-            else // A normal store, not a WriteBarrier store
-            {
-                bool     reverseOps  = ((treeNode->gtFlags & GTF_REVERSE_OPS) != 0);
-                bool     dataIsUnary = false;
-                GenTree* nonRMWsrc   = nullptr;
-                // We must consume the operands in the proper execution order,
-                // so that liveness is updated appropriately.
-                if (!reverseOps)
-                {
-                    genConsumeAddress(addr);
-                }
-
-                if (!data->isContained())
-                {
-                    genConsumeRegs(data);
-                }
-
-                if (reverseOps)
-                {
-                    genConsumeAddress(addr);
-                }
-
-                regNumber dataReg = REG_NA;
-                if (data->isContainedIntOrIImmed())
-                {
-                    assert(data->IsIntegralConst(0));
-                    dataReg = REG_ZR;
-                }
-                else // data is not contained, so evaluate it into a register
-                {
-                    assert(!data->isContained());
-                    dataReg = data->gtRegNum;
-                }
-
-                emit->emitInsLoadStoreOp(ins_Store(targetType), emitTypeSize(treeNode), dataReg, treeNode->AsIndir());
-            }
-        }
-        break;
+            genCodeForStoreInd(treeNode->AsStoreInd());
+            break;
 
         case GT_COPY:
             // This is handled at the time we call genConsumeReg() on the GT_COPY
@@ -4103,6 +4018,104 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea)
     genProduceReg(lea);
 }
 
+//------------------------------------------------------------------------
+// genCodeForStoreInd: Produce code for a GT_STOREIND node.
+//
+// Arguments:
+//    tree - the GT_STOREIND node
+//
+void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
+{
+    GenTree*  data       = tree->Data();
+    GenTree*  addr       = tree->Addr();
+    var_types targetType = tree->TypeGet();
+    emitter*  emit       = getEmitter();
+
+    GCInfo::WriteBarrierForm writeBarrierForm = gcInfo.gcIsWriteBarrierCandidate(tree, data);
+    if (writeBarrierForm != GCInfo::WBF_NoBarrier)
+    {
+        // data and addr must be in registers.
+        // Consume both registers so that any copies of interfering
+        // registers are taken care of.
+        genConsumeOperands(tree);
+
+#if NOGC_WRITE_BARRIERS
+        // At this point, we should not have any interference.
+        // That is, 'data' must not be in REG_WRITE_BARRIER_DST_BYREF,
+        //  as that is where 'addr' must go.
+        noway_assert(data->gtRegNum != REG_WRITE_BARRIER_DST_BYREF);
+
+        // 'addr' goes into x14 (REG_WRITE_BARRIER_DST_BYREF)
+        if (addr->gtRegNum != REG_WRITE_BARRIER_DST_BYREF)
+        {
+            inst_RV_RV(INS_mov, REG_WRITE_BARRIER_DST_BYREF, addr->gtRegNum, addr->TypeGet());
+        }
+
+        // 'data'  goes into x15 (REG_WRITE_BARRIER)
+        if (data->gtRegNum != REG_WRITE_BARRIER)
+        {
+            inst_RV_RV(INS_mov, REG_WRITE_BARRIER, data->gtRegNum, data->TypeGet());
+        }
+#else
+        // At this point, we should not have any interference.
+        // That is, 'data' must not be in REG_ARG_0,
+        //  as that is where 'addr' must go.
+        noway_assert(data->gtRegNum != REG_ARG_0);
+
+        // addr goes in REG_ARG_0
+        if (addr->gtRegNum != REG_ARG_0)
+        {
+            inst_RV_RV(INS_mov, REG_ARG_0, addr->gtRegNum, addr->TypeGet());
+        }
+
+        // data goes in REG_ARG_1
+        if (data->gtRegNum != REG_ARG_1)
+        {
+            inst_RV_RV(INS_mov, REG_ARG_1, data->gtRegNum, data->TypeGet());
+        }
+#endif // NOGC_WRITE_BARRIERS
+
+        genGCWriteBarrier(tree, writeBarrierForm);
+    }
+    else // A normal store, not a WriteBarrier store
+    {
+        bool     reverseOps  = ((tree->gtFlags & GTF_REVERSE_OPS) != 0);
+        bool     dataIsUnary = false;
+        GenTree* nonRMWsrc   = nullptr;
+        // We must consume the operands in the proper execution order,
+        // so that liveness is updated appropriately.
+        if (!reverseOps)
+        {
+            genConsumeAddress(addr);
+        }
+
+        if (!data->isContained())
+        {
+            genConsumeRegs(data);
+        }
+
+        if (reverseOps)
+        {
+            genConsumeAddress(addr);
+        }
+
+        regNumber dataReg = REG_NA;
+        if (data->isContainedIntOrIImmed())
+        {
+            assert(data->IsIntegralConst(0));
+            dataReg = REG_ZR;
+        }
+        else // data is not contained, so evaluate it into a register
+        {
+            assert(!data->isContained());
+            dataReg = data->gtRegNum;
+        }
+
+        emit->emitInsLoadStoreOp(ins_Store(targetType), emitTypeSize(tree), dataReg, tree);
+    }
+}
+
+
 //-------------------------------------------------------------------------------------------
 // genSetRegToCond:  Set a register 'dstReg' to the appropriate one or zero value
 //                   corresponding to a binary Relational operator result.
index 8e4c8e7..89322a9 100644 (file)
@@ -174,6 +174,8 @@ void genCodeForStoreLclFld(GenTreeLclFld* tree);
 
 void genCodeForStoreLclVar(GenTreeLclVar* tree);
 
+void genCodeForStoreInd(GenTreeStoreInd* tree);
+
 void genCodeForCpObj(GenTreeObj* cpObjNode);
 
 void genCodeForCpBlk(GenTreeBlk* cpBlkNode);