fix r2r relative indirection for arm. (#16171)
authorSergey Andreenko <seandree@microsoft.com>
Sat, 10 Mar 2018 18:48:57 +0000 (10:48 -0800)
committerGitHub <noreply@github.com>
Sat, 10 Mar 2018 18:48:57 +0000 (10:48 -0800)
src/jit/lower.cpp
src/jit/morph.cpp
src/jit/rationalize.cpp
src/jit/valuenum.cpp

index 10fa081..38bfeb7 100644 (file)
@@ -3175,19 +3175,7 @@ GenTree* Lowering::LowerDirectCall(GenTreeCall* call)
             // a single indirection.
             GenTree* cellAddr = AddrGen(addr);
             GenTree* indir    = Ind(cellAddr);
-
-#ifdef FEATURE_READYTORUN_COMPILER
-#if defined(_TARGET_ARMARCH_)
-            // For arm64, we dispatch code same as VSD using X11 for indirection cell address,
-            // which ZapIndirectHelperThunk expects.
-            if (call->IsR2RRelativeIndir())
-            {
-                cellAddr->gtRegNum = REG_R2R_INDIRECT_PARAM;
-                indir->gtRegNum    = REG_JUMP_THUNK_PARAM;
-            }
-#endif
-#endif
-            result = indir;
+            result            = indir;
             break;
         }
 
index 372b00b..aeca2fe 100644 (file)
@@ -3134,7 +3134,26 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call)
             call->gtCallType    = CT_HELPER;
             call->gtCallMethHnd = eeFindHelper(CORINFO_HELP_PINVOKE_CALLI);
         }
-#endif // !defined(LEGACY_BACKEND)
+#if defined(FEATURE_READYTORUN_COMPILER) && defined(_TARGET_ARMARCH_)
+        // For arm, we dispatch code same as VSD using virtualStubParamInfo->GetReg()
+        // for indirection cell address, which ZapIndirectHelperThunk expects.
+        if (call->IsR2RRelativeIndir())
+        {
+            assert(call->gtEntryPoint.addr != nullptr);
+
+            size_t   addrValue            = (size_t)call->gtEntryPoint.addr;
+            GenTree* indirectCellAddress  = gtNewIconHandleNode(addrValue, GTF_ICON_FTN_ADDR);
+            indirectCellAddress->gtRegNum = REG_R2R_INDIRECT_PARAM;
+
+            // Push the stub address onto the list of arguments.
+            call->gtCallArgs = gtNewListNode(indirectCellAddress, call->gtCallArgs);
+
+            numArgs++;
+            nonStandardArgs.Add(indirectCellAddress, indirectCellAddress->gtRegNum);
+        }
+
+#endif // FEATURE_READYTORUN_COMPILER && _TARGET_ARMARCH_
+#endif // !LEGACY_BACKEND
 
         // Allocate the fgArgInfo for the call node;
         //
index 84a0415..a2ab62f 100644 (file)
@@ -160,14 +160,14 @@ void Rationalizer::RewriteNodeAsCall(GenTree**             use,
     assert(JITtype2varType(sig.retType) == tree->gtType);
 #endif // DEBUG
 
-    call = comp->fgMorphArgs(call);
-    // Determine if this call has changed any codegen requirements.
-    comp->fgCheckArgCnt();
-
 #ifdef FEATURE_READYTORUN_COMPILER
     call->gtCall.setEntryPoint(entryPoint);
 #endif
 
+    call = comp->fgMorphArgs(call);
+    // Determine if this call has changed any codegen requirements.
+    comp->fgCheckArgCnt();
+
     // Replace "tree" with "call"
     if (parents.Height() > 1)
     {
index 4fd4e84..fcb38d3 100644 (file)
@@ -7426,6 +7426,22 @@ void Compiler::fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueN
         vnpUniq.SetBoth(vnStore->VNForExpr(compCurBB, call->TypeGet()));
     }
 
+#if defined(FEATURE_READYTORUN_COMPILER) && defined(_TARGET_ARMARCH_)
+    if (call->IsR2RRelativeIndir())
+    {
+#ifdef DEBUG
+        assert(args->Current()->OperGet() == GT_ARGPLACE);
+
+        // Find the corresponding late arg.
+        GenTree* indirectCellAddress = call->fgArgInfo->GetLateArg(0);
+        assert(indirectCellAddress->IsCnsIntOrI() && indirectCellAddress->gtRegNum == REG_R2R_INDIRECT_PARAM);
+#endif // DEBUG
+        // For ARM indirectCellAddress is consumed by the call itself, so it should have added as an implicit argument
+        // in morph. So we do not need to use EntryPointAddrAsArg0, because arg0 is already an entry point addr.
+        useEntryPointAddrAsArg0 = false;
+    }
+#endif // FEATURE_READYTORUN_COMPILER && _TARGET_ARMARCH_
+
     if (nArgs == 0)
     {
         if (generateUniqueVN)
@@ -7467,7 +7483,7 @@ void Compiler::fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueN
             vnp0                = ValueNumPair(callAddrVN, callAddrVN);
         }
         else
-#endif
+#endif // FEATURE_READYTORUN_COMPILER
         {
             assert(!useEntryPointAddrAsArg0);
             ValueNumPair vnp0wx = getCurrentArg(0)->gtVNPair;