From: Mike Danes Date: Thu, 23 Jun 2016 19:02:50 +0000 (+0300) Subject: Implement GT_NEG decomposition X-Git-Tag: accepted/tizen/base/20180629.140029~4068^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cdb8a214a807ef0207b7e3cd9313cfaf163bf392;p=platform%2Fupstream%2Fcoreclr.git Implement GT_NEG decomposition --- diff --git a/src/jit/decomposelongs.cpp b/src/jit/decomposelongs.cpp index f505ed0..988d071 100644 --- a/src/jit/decomposelongs.cpp +++ b/src/jit/decomposelongs.cpp @@ -219,7 +219,7 @@ void DecomposeLongs::DecomposeNode(GenTree** ppTree, Compiler::fgWalkData* data) break; case GT_NEG: - NYI("GT_NEG of TYP_LONG"); + DecomposeNeg(ppTree, data); break; // Binary operators. Those that require different computation for upper and lower half are @@ -905,6 +905,56 @@ void DecomposeLongs::DecomposeNot(GenTree** ppTree, Compiler::fgWalkData* data) FinalizeDecomposition(ppTree, data, loResult, hiResult); } +//------------------------------------------------------------------------ +// DecomposeNeg: Decompose GT_NEG. +// +// Arguments: +// ppTree - the tree to decompose +// data - tree walk context +// +// Return Value: +// None. +// +void DecomposeLongs::DecomposeNeg(GenTree** ppTree, Compiler::fgWalkData* data) +{ + assert(ppTree != nullptr); + assert(*ppTree != nullptr); + assert(data != nullptr); + assert((*ppTree)->OperGet() == GT_NEG); + assert(m_compiler->compCurStmt != nullptr); + + GenTreeStmt* curStmt = m_compiler->compCurStmt->AsStmt(); + GenTree* tree = *ppTree; + GenTree* op1 = tree->gtGetOp1(); + noway_assert(op1->OperGet() == GT_LONG); + + CreateTemporary(&(op1->gtOp.gtOp1)); + CreateTemporary(&(op1->gtOp.gtOp2)); + // Neither GT_NEG nor the introduced temporaries have side effects. + tree->gtFlags &= ~GTF_ALL_EFFECT; + GenTree* loOp1 = op1->gtGetOp1(); + GenTree* hiOp1 = op1->gtGetOp2(); + Compiler::fgSnipNode(curStmt, op1); + + GenTree* loResult = tree; + loResult->gtType = TYP_INT; + loResult->gtOp.gtOp1 = loOp1; + + GenTree* zero = m_compiler->gtNewZeroConNode(TYP_INT); + GenTree* hiAdjust = m_compiler->gtNewOperNode(GT_ADD_HI, TYP_INT, hiOp1, zero); + GenTree* hiResult = m_compiler->gtNewOperNode(GT_NEG, TYP_INT, hiAdjust); + hiResult->gtFlags = tree->gtFlags; + + Compiler::fgSnipNode(curStmt, hiOp1); + // fgSnipNode doesn't clear gtNext/gtPrev... + hiOp1->gtNext = nullptr; + hiOp1->gtPrev = nullptr; + SimpleLinkNodeAfter(hiOp1, zero); + SimpleLinkNodeAfter(zero, hiAdjust); + SimpleLinkNodeAfter(hiAdjust, hiResult); + + FinalizeDecomposition(ppTree, data, loResult, hiResult); +} //------------------------------------------------------------------------ // DecomposeArith: Decompose GT_ADD, GT_SUB, GT_OR, GT_XOR, GT_AND. diff --git a/src/jit/decomposelongs.h b/src/jit/decomposelongs.h index 376f655..b4a48a0 100644 --- a/src/jit/decomposelongs.h +++ b/src/jit/decomposelongs.h @@ -44,6 +44,7 @@ private: void DecomposeCall(GenTree** ppTree, Compiler::fgWalkData* data); void DecomposeStoreInd(GenTree** ppTree, Compiler::fgWalkData* data); void DecomposeNot(GenTree** ppTree, Compiler::fgWalkData* data); + void DecomposeNeg(GenTree** ppTree, Compiler::fgWalkData* data); void DecomposeArith(GenTree** ppTree, Compiler::fgWalkData* data); // Helper functions diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp old mode 100755 new mode 100644 index 7a133f7..80b5f4c --- a/src/jit/lower.cpp +++ b/src/jit/lower.cpp @@ -1147,7 +1147,10 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg) GenTreePtr argLo = arg->gtGetOp1(); GenTreePtr argHi = arg->gtGetOp2(); - NYI_IF(argHi->OperGet() == GT_ADD_HI || argHi->OperGet() == GT_SUB_HI, "Hi and Lo cannot be reordered"); + NYI_IF((argHi->OperGet() == GT_ADD_HI) || + (argHi->OperGet() == GT_SUB_HI) || + (argHi->OperGet() == GT_NEG), + "Hi and Lo cannot be reordered"); GenTreePtr putArgLo = NewPutArg(call, argLo, info, type); GenTreePtr putArgHi = NewPutArg(call, argHi, info, type);