From db20f3f1bb8595633a7e16c8900fd401a453a6b5 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Tue, 27 Dec 2016 16:46:08 +0900 Subject: Imported Upstream version 1.0.0.9127 --- src/jit/assertionprop.cpp | 119 +++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 65 deletions(-) (limited to 'src/jit/assertionprop.cpp') diff --git a/src/jit/assertionprop.cpp b/src/jit/assertionprop.cpp index fe35c3b780..cb0832fe47 100644 --- a/src/jit/assertionprop.cpp +++ b/src/jit/assertionprop.cpp @@ -1100,11 +1100,6 @@ Compiler::AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1, CNS_COMMON: { - // TODO-1stClassStructs: handle constant propagation to struct types. - if (varTypeIsStruct(lclVar)) - { - goto DONE_ASSERTION; - } // // Must either be an OAK_EQUAL or an OAK_NOT_EQUAL assertion // @@ -2034,12 +2029,7 @@ void Compiler::optAssertionGen(GenTreePtr tree) { case GT_ASG: // VN takes care of non local assertions for assignments and data flow. - // TODO-1stClassStructs: Enable assertion prop for struct types. - if (varTypeIsStruct(tree)) - { - // Do nothing. - } - else if (optLocalAssertionProp) + if (optLocalAssertionProp) { assertionIndex = optCreateAssertion(tree->gtOp.gtOp1, tree->gtOp.gtOp2, OAK_EQUAL); } @@ -2052,26 +2042,15 @@ void Compiler::optAssertionGen(GenTreePtr tree) case GT_OBJ: case GT_BLK: case GT_DYN_BLK: - // TODO-1stClassStructs: These should always be considered to create a non-null - // assertion, but previously, when these indirections were implicit due to a block - // copy or init, they were not being considered to do so. - break; case GT_IND: - // TODO-1stClassStructs: All indirections should be considered to create a non-null - // assertion, but previously, when these indirections were implicit due to a block - // copy or init, they were not being considered to do so. - if (tree->gtType == TYP_STRUCT) - { - GenTree* parent = tree->gtGetParent(nullptr); - if ((parent != nullptr) && (parent->gtOper == GT_ASG)) - { - break; - } - } case GT_NULLCHECK: + // All indirections create non-null assertions + assertionIndex = optCreateAssertion(tree->AsIndir()->Addr(), nullptr, OAK_NOT_EQUAL); + break; + case GT_ARR_LENGTH: - // An array length can create a non-null assertion - assertionIndex = optCreateAssertion(tree->gtOp.gtOp1, nullptr, OAK_NOT_EQUAL); + // An array length is an indirection (but doesn't derive from GenTreeIndir). + assertionIndex = optCreateAssertion(tree->AsArrLen()->ArrRef(), nullptr, OAK_NOT_EQUAL); break; case GT_ARR_BOUNDS_CHECK: @@ -2629,9 +2608,29 @@ GenTreePtr Compiler::optConstantAssertionProp(AssertionDsc* curAssertion, else { bool isArrIndex = ((tree->gtFlags & GTF_VAR_ARR_INDEX) != 0); - newTree->ChangeOperConst(GT_CNS_INT); - newTree->gtIntCon.gtIconVal = curAssertion->op2.u1.iconVal; - newTree->ClearIconHandleMask(); + // If we have done constant propagation of a struct type, it is only valid for zero-init, + // and we have to ensure that we have the right zero for the type. + if (varTypeIsStruct(tree)) + { + assert(curAssertion->op2.u1.iconVal == 0); + } +#ifdef FEATURE_SIMD + if (varTypeIsSIMD(tree)) + { + var_types simdType = tree->TypeGet(); + tree->ChangeOperConst(GT_CNS_DBL); + GenTree* initVal = tree; + initVal->gtType = TYP_FLOAT; + newTree = + gtNewSIMDNode(simdType, initVal, nullptr, SIMDIntrinsicInit, TYP_FLOAT, genTypeSize(simdType)); + } + else +#endif // FEATURE_SIMD + { + newTree->ChangeOperConst(GT_CNS_INT); + newTree->gtIntCon.gtIconVal = curAssertion->op2.u1.iconVal; + newTree->ClearIconHandleMask(); + } // If we're doing an array index address, assume any constant propagated contributes to the index. if (isArrIndex) { @@ -3421,32 +3420,13 @@ GenTreePtr Compiler::optAssertionProp_Ind(ASSERT_VALARG_TP assertions, const Gen { assert(tree->OperIsIndir()); - // TODO-1stClassStructs: All indirections should be handled here, but - // previously, when these indirections were GT_OBJ, or implicit due to a block - // copy or init, they were not being handled. - if (tree->TypeGet() == TYP_STRUCT) - { - if (tree->OperIsBlk()) - { - return nullptr; - } - else - { - GenTree* parent = tree->gtGetParent(nullptr); - if ((parent != nullptr) && parent->OperIsBlkOp()) - { - return nullptr; - } - } - } - if (!(tree->gtFlags & GTF_EXCEPT)) { return nullptr; } // Check for add of a constant. - GenTreePtr op1 = tree->gtOp.gtOp1; + GenTreePtr op1 = tree->AsIndir()->Addr(); if ((op1->gtOper == GT_ADD) && (op1->gtOp.gtOp2->gtOper == GT_CNS_INT)) { op1 = op1->gtOp.gtOp1; @@ -3700,6 +3680,21 @@ GenTreePtr Compiler::optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, const assert(tree->gtOper == GT_ARR_BOUNDS_CHECK); +#ifdef FEATURE_ENABLE_NO_RANGE_CHECKS + if (JitConfig.JitNoRangeChks()) + { +#ifdef DEBUG + if (verbose) + { + printf("\nFlagging check redundant due to JitNoRangeChks in BB%02u:\n", compCurBB->bbNum); + gtDispTree(tree, nullptr, nullptr, true); + } +#endif // DEBUG + tree->gtFlags |= GTF_ARR_BOUND_INBND; + return nullptr; + } +#endif // FEATURE_ENABLE_NO_RANGE_CHECKS + BitVecOps::Iter iter(apTraits, assertions); unsigned index = 0; while (iter.NextElem(apTraits, &index)) @@ -4688,9 +4683,8 @@ GenTreePtr Compiler::optVNConstantPropOnJTrue(BasicBlock* block, GenTreePtr stmt newStmt = fgInsertStmtNearEnd(block, sideEffList); sideEffList = nullptr; } - fgMorphBlockStmt(block, newStmt DEBUGARG(__FUNCTION__)); - gtSetStmtInfo(newStmt); - fgSetStmtSeq(newStmt); + + fgMorphBlockStmt(block, newStmt->AsStmt() DEBUGARG(__FUNCTION__)); } // Transform the relop's operands to be both zeroes. @@ -4748,7 +4742,6 @@ Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, Gen case GT_MOD: case GT_UDIV: case GT_UMOD: - case GT_MULHI: case GT_EQ: case GT_NE: case GT_LT: @@ -4767,6 +4760,10 @@ Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, Gen case GT_INTRINSIC: break; + case GT_MULHI: + assert(false && "Unexpected GT_MULHI node encountered before lowering"); + break; + case GT_JTRUE: break; @@ -4911,9 +4908,7 @@ GenTreePtr Compiler::optVNAssertionPropCurStmt(BasicBlock* block, GenTreePtr stm if (optAssertionPropagatedCurrentStmt) { - fgMorphBlockStmt(block, stmt DEBUGARG("optVNAssertionPropCurStmt")); - gtSetStmtInfo(stmt); - fgSetStmtSeq(stmt); + fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("optVNAssertionPropCurStmt")); } // Check if propagation removed statements starting from current stmt. @@ -5110,13 +5105,7 @@ void Compiler::optAssertionPropMain() } #endif // Re-morph the statement. - fgMorphBlockStmt(block, stmt DEBUGARG("optAssertionPropMain")); - - // Recalculate the gtCostSz, etc... - gtSetStmtInfo(stmt); - - // Re-thread the nodes - fgSetStmtSeq(stmt); + fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("optAssertionPropMain")); } // Check if propagation removed statements starting from current stmt. -- cgit v1.2.3