summaryrefslogtreecommitdiff
path: root/src/jit/codegenlinear.cpp
diff options
context:
space:
mode:
authorCarol Eidt <carol.eidt@microsoft.com>2019-03-26 16:13:40 -0700
committerGitHub <noreply@github.com>2019-03-26 16:13:40 -0700
commitda6ed1197abcb1be420351af1bb3758de6048c8f (patch)
treeec26f10d197a21d7f3c80478da6fb728abd8aa31 /src/jit/codegenlinear.cpp
parentaa072b639fc2eb0e60a8083e4c74426db91341e0 (diff)
downloadcoreclr-da6ed1197abcb1be420351af1bb3758de6048c8f.tar.gz
coreclr-da6ed1197abcb1be420351af1bb3758de6048c8f.tar.bz2
coreclr-da6ed1197abcb1be420351af1bb3758de6048c8f.zip
Handle addressing modes for HW intrinsics (#22944)
* Handle addressing modes for HW intrinsics Also, eliminate some places where the code size estimates were over-estimating. Contribute to #19550 Fix #19521
Diffstat (limited to 'src/jit/codegenlinear.cpp')
-rw-r--r--src/jit/codegenlinear.cpp77
1 files changed, 68 insertions, 9 deletions
diff --git a/src/jit/codegenlinear.cpp b/src/jit/codegenlinear.cpp
index 7c5c01895e..72f9fa68db 100644
--- a/src/jit/codegenlinear.cpp
+++ b/src/jit/codegenlinear.cpp
@@ -1339,12 +1339,27 @@ void CodeGen::genConsumeRegs(GenTree* tree)
// Update the life of the lcl var.
genUpdateLife(tree);
}
-#endif // _TARGET_XARCH_
- else if (tree->OperIsInitVal())
+#ifdef FEATURE_HW_INTRINSICS
+ else if (tree->OperIs(GT_HWIntrinsic))
{
- genConsumeReg(tree->gtGetOp1());
+ // Only load/store HW intrinsics can be contained (and the address may also be contained).
+ HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(tree->AsHWIntrinsic()->gtHWIntrinsicId);
+ assert((category == HW_Category_MemoryLoad) || (category == HW_Category_MemoryStore));
+ int numArgs = HWIntrinsicInfo::lookupNumArgs(tree->AsHWIntrinsic());
+ genConsumeAddress(tree->gtGetOp1());
+ if (category == HW_Category_MemoryStore)
+ {
+ assert((numArgs == 2) && !tree->gtGetOp2()->isContained());
+ genConsumeReg(tree->gtGetOp2());
+ }
+ else
+ {
+ assert(numArgs == 1);
+ }
}
- else if (tree->OperIsHWIntrinsic())
+#endif // FEATURE_HW_INTRINSICS
+#endif // _TARGET_XARCH_
+ else if (tree->OperIsInitVal())
{
genConsumeReg(tree->gtGetOp1());
}
@@ -1374,11 +1389,6 @@ void CodeGen::genConsumeRegs(GenTree* tree)
// Return Value:
// None.
//
-// Notes:
-// Note that this logic is localized here because we must do the liveness update in
-// the correct execution order. This is important because we may have two operands
-// that involve the same lclVar, and if one is marked "lastUse" we must handle it
-// after the first.
void CodeGen::genConsumeOperands(GenTreeOp* tree)
{
@@ -1395,6 +1405,55 @@ void CodeGen::genConsumeOperands(GenTreeOp* tree)
}
}
+#ifdef FEATURE_HW_INTRINSICS
+//------------------------------------------------------------------------
+// genConsumeHWIntrinsicOperands: Do liveness update for the operands of a GT_HWIntrinsic node
+//
+// Arguments:
+// node - the GenTreeHWIntrinsic node whose operands will have their liveness updated.
+//
+// Return Value:
+// None.
+//
+
+void CodeGen::genConsumeHWIntrinsicOperands(GenTreeHWIntrinsic* node)
+{
+ int numArgs = HWIntrinsicInfo::lookupNumArgs(node);
+ GenTree* op1 = node->gtGetOp1();
+ if (op1 == nullptr)
+ {
+ assert((numArgs == 0) && (node->gtGetOp2() == nullptr));
+ return;
+ }
+ if (op1->OperIs(GT_LIST))
+ {
+ int foundArgs = 0;
+ assert(node->gtGetOp2() == nullptr);
+ for (GenTreeArgList* list = op1->AsArgList(); list != nullptr; list = list->Rest())
+ {
+ GenTree* operand = list->Current();
+ genConsumeRegs(operand);
+ foundArgs++;
+ }
+ assert(foundArgs == numArgs);
+ }
+ else
+ {
+ genConsumeRegs(op1);
+ GenTree* op2 = node->gtGetOp2();
+ if (op2 != nullptr)
+ {
+ genConsumeRegs(op2);
+ assert(numArgs == 2);
+ }
+ else
+ {
+ assert(numArgs == 1);
+ }
+ }
+}
+#endif // FEATURE_HW_INTRINSICS
+
#if FEATURE_PUT_STRUCT_ARG_STK
//------------------------------------------------------------------------
// genConsumePutStructArgStk: Do liveness update for the operands of a PutArgStk node.