[ARM32/RyuJIT] Set the source candidates for PutArgSplit nodes
authorJiyoung Yun <jy910.yun@samsung.com>
Tue, 8 Aug 2017 09:44:43 +0000 (18:44 +0900)
committerJiyoung Yun <jy910.yun@samsung.com>
Tue, 8 Aug 2017 10:23:09 +0000 (19:23 +0900)
The Use RefPosition of PutArgSplit should use the same register with the Def RefPosition.

src/jit/codegenarmarch.cpp
src/jit/lsra.cpp
src/jit/lsraarmarch.cpp

index c6e881f..11d2258 100644 (file)
@@ -1797,9 +1797,12 @@ void CodeGen::genCallInstruction(GenTreeCall* call)
 
         GenTreePtr argNode = list->Current();
 
-        fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode->gtSkipReloadOrCopy());
+        fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode);
         assert(curArgTabEntry);
 
+        // GT_RELOAD/GT_COPY use the child node
+        argNode = argNode->gtSkipReloadOrCopy();
+
         if (curArgTabEntry->regNum == REG_STK)
             continue;
 
index 252dea5..49a4854 100644 (file)
@@ -3935,6 +3935,10 @@ void LinearScan::buildRefPositionsForNode(GenTree*                  tree,
         assert(removed);
         assert(!operandDefs.IsEmpty());
 
+#ifdef _TARGET_ARM_
+        regMaskTP currCandidates = RBM_NONE;
+#endif // _TARGET_ARM_
+
         LocationInfoListNode* const operandDefsEnd = operandDefs.End();
         for (LocationInfoListNode* operandDefsIterator = operandDefs.Begin(); operandDefsIterator != operandDefsEnd;
              operandDefsIterator                       = operandDefsIterator->Next())
@@ -3985,6 +3989,14 @@ void LinearScan::buildRefPositionsForNode(GenTree*                  tree,
 #endif // DEBUG
 
             regMaskTP candidates = getUseCandidates(useNode);
+#ifdef _TARGET_ARM_
+            // If oper is GT_PUTARG_SPLIT, set bits in useCandidates must be in sequential order.
+            if (useNode->OperIsPutArgSplit())
+            {
+                // get i-th candidate
+                candidates = genFindLowestReg(candidates & ~currCandidates);
+                currCandidates |= candidates;
+            }
 #ifdef ARM_SOFTFP
             // If oper is GT_PUTARG_REG, set bits in useCandidates must be in sequential order.
             if (useNode->OperIsMultiRegOp())
@@ -3994,6 +4006,8 @@ void LinearScan::buildRefPositionsForNode(GenTree*                  tree,
                 candidates = candidate;
             }
 #endif // ARM_SOFTFP
+#endif // _TARGET_ARM_
+
             assert((candidates & allRegs(i->registerType)) != 0);
 
             // For non-localVar uses we record nothing, as nothing needs to be written back to the tree.
index d6c372f..2aca40f 100644 (file)
@@ -684,6 +684,7 @@ void Lowering::TreeNodeInfoInitPutArgSplit(GenTreePutArgSplit* argNode, TreeNode
         argMask |= genRegMask((regNumber)((unsigned)argReg + i));
     }
     argNode->gtLsraInfo.setDstCandidates(m_lsra, argMask);
+    argNode->gtLsraInfo.setSrcCandidates(m_lsra, argMask);
 
     if (putArgChild->OperGet() == GT_FIELD_LIST)
     {