From 65e7ca8aaa9b49fc48d06a575152e1c7af55e3b1 Mon Sep 17 00:00:00 2001 From: Mike Danes Date: Sat, 17 Dec 2016 22:28:07 +0200 Subject: [PATCH] Remove unused code Commit migrated from https://github.com/dotnet/coreclr/commit/a379e21469ea9f7d9a5c10cd7004e691eb75afd8 --- src/coreclr/src/jit/codegenlinear.cpp | 6 --- src/coreclr/src/jit/codegenxarch.cpp | 49 +++++---------------- src/coreclr/src/jit/lowerxarch.cpp | 83 +++++++++++++++-------------------- 3 files changed, 46 insertions(+), 92 deletions(-) diff --git a/src/coreclr/src/jit/codegenlinear.cpp b/src/coreclr/src/jit/codegenlinear.cpp index 415d6cf..6829d96 100644 --- a/src/coreclr/src/jit/codegenlinear.cpp +++ b/src/coreclr/src/jit/codegenlinear.cpp @@ -1220,12 +1220,6 @@ void CodeGen::genConsumeRegs(GenTree* tree) { genConsumeAddress(tree->AsIndir()->Addr()); } - else if (tree->OperGet() == GT_AND) - { - // This is the special contained GT_AND that we created in Lowering::TreeNodeInfoInitCmp() - // Now we need to consume the operands of the GT_AND node. - genConsumeOperands(tree->AsOp()); - } #ifdef _TARGET_XARCH_ else if (tree->OperGet() == GT_LCL_VAR) { diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 9974bef..1959650 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -6072,7 +6072,7 @@ void CodeGen::genCompareInt(GenTreePtr treeNode) GenTreePtr op2 = tree->gtOp2; var_types op1Type = op1->TypeGet(); var_types op2Type = op2->TypeGet(); - regNumber targetReg = treeNode->gtRegNum; + regNumber targetReg = tree->gtRegNum; // Case of op1 == 0 or op1 != 0: // Optimize generation of 'test' instruction if op1 sets flags. @@ -6132,9 +6132,6 @@ void CodeGen::genCompareInt(GenTreePtr treeNode) genConsumeOperands(tree); - instruction ins; - emitAttr cmpAttr; - // TODO-CQ: We should be able to support swapping op1 and op2 to generate cmp reg, imm. // https://github.com/dotnet/coreclr/issues/7270 assert(!op1->isContainedIntOrIImmed()); // We no longer support @@ -6144,10 +6141,10 @@ void CodeGen::genCompareInt(GenTreePtr treeNode) assert(!varTypeIsLong(op1Type) && !varTypeIsLong(op2Type)); #endif // _TARGET_X86_ - // By default we use an int32 sized cmp instruction + // By default we use an int32 sized cmp/test instruction // - ins = ((treeNode->OperGet() == GT_TEST_EQ) || (treeNode->OperGet() == GT_TEST_NE)) ? INS_test : INS_cmp; - var_types cmpType = TYP_INT; + instruction ins = ((tree->OperGet() == GT_TEST_EQ) || (tree->OperGet() == GT_TEST_NE)) ? INS_test : INS_cmp; + var_types cmpType = TYP_INT; // In the if/then/else statement below we may change the // 'cmpType' and/or 'ins' to generate a smaller instruction @@ -6166,8 +6163,6 @@ void CodeGen::genCompareInt(GenTreePtr treeNode) // If we have two different int64 types we need to use a long compare cmpType = TYP_LONG; } - - cmpAttr = emitTypeSize(cmpType); } else // Here we know that (op1Type != op2Type) { @@ -6204,45 +6199,21 @@ void CodeGen::genCompareInt(GenTreePtr treeNode) } } #endif // _TARGET_AMD64_ - - cmpAttr = emitTypeSize(cmpType); } // See if we can generate a "test" instruction instead of a "cmp". // For this to generate the correct conditional branch we must have // a compare against zero. // - if (op2->IsIntegralConst(0)) + if ((ins == INS_cmp) && !op1->isContained() && op2->IsIntegralConst(0)) { - if (!op1->isUsedFromReg()) - { - // op1 can be a contained memory op - // or the special contained GT_AND that we created in Lowering::TreeNodeInfoInitCmp() - // - if ((op1->OperGet() == GT_AND) && op1->gtGetOp2()->isContainedIntOrIImmed() && - ((tree->OperGet() == GT_EQ) || (tree->OperGet() == GT_NE))) - { - ins = INS_test; // we will generate "test andOp1, andOp2CnsVal" - op2 = op1->gtOp.gtOp2; // must assign op2 before we overwrite op1 - op1 = op1->gtOp.gtOp1; // overwrite op1 - - if (op1->isUsedFromMemory()) - { - // use the size andOp1 if it is a contained memoryop. - cmpAttr = emitTypeSize(op1->TypeGet()); - } - // fallthrough to emit->emitInsBinary(ins, cmpAttr, op1, op2); - } - } - else // op1 is not contained thus it must be in a register - { - ins = INS_test; - op2 = op1; // we will generate "test reg1,reg1" - // fallthrough to emit->emitInsBinary(ins, cmpAttr, op1, op2); - } + // op1 is not contained thus it must be in a register + ins = INS_test; + op2 = op1; // we will generate "test reg1,reg1" + // fallthrough to emit->emitInsBinary(ins, cmpAttr, op1, op2); } - getEmitter()->emitInsBinary(ins, cmpAttr, op1, op2); + getEmitter()->emitInsBinary(ins, emitTypeSize(cmpType), op1, op2); // Are we evaluating this into a register? if (targetReg != REG_NA) diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index 2408b76..9ab2116 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -3443,64 +3443,53 @@ void Lowering::TreeNodeInfoInitCmp(GenTreePtr tree) // TODO-XArch-CQ: factor out cmp optimization in 'genCondSetFlags' to be used here // or in other backend. - bool hasShortCast = false; if (CheckImmedAndMakeContained(tree, op2)) { // If the types are the same, or if the constant is of the correct size, // we can treat the isMemoryOp as contained. - bool op1CanBeContained = (genTypeSize(op1Type) == genTypeSize(op2Type)); - - if (op1CanBeContained) + if (genTypeSize(op1Type) == genTypeSize(op2Type)) { if (op1->isMemoryOp()) { MakeSrcContained(tree, op1); } + // If op1 codegen sets ZF and SF flags and ==/!= against + // zero, we don't need to generate test instruction, + // provided we don't have another GenTree node between op1 + // and tree that could potentially modify flags. + // + // TODO-CQ: right now the below peep is inexpensive and + // gets the benefit in most of cases because in majority + // of cases op1, op2 and tree would be in that order in + // execution. In general we should be able to check that all + // the nodes that come after op1 in execution order do not + // modify the flags so that it is safe to avoid generating a + // test instruction. Such a check requires that on each + // GenTree node we need to set the info whether its codegen + // will modify flags. + // + // TODO-CQ: We can optimize compare against zero in the + // following cases by generating the branch as indicated + // against each case. + // 1) unsigned compare + // < 0 - always FALSE + // <= 0 - ZF=1 and jne + // > 0 - ZF=0 and je + // >= 0 - always TRUE + // + // 2) signed compare + // < 0 - SF=1 and js + // >= 0 - SF=0 and jns + else if (((tree->gtOper == GT_EQ) || (tree->gtOper == GT_NE)) && op1->gtSetZSFlags() && + op2->IsIntegralConst(0) && (op1->gtNext == op2) && (op2->gtNext == tree)) + { + // Require codegen of op1 to set the flags. + assert(!op1->gtSetFlags()); + op1->gtFlags |= GTF_SET_FLAGS; + } else { - bool op1IsMadeContained = false; - bool isEqualityCompare = (tree->gtOper == GT_EQ || tree->gtOper == GT_NE); - - // If not made contained, op1 can be marked as reg-optional. - if (!op1IsMadeContained) - { - SetRegOptional(op1); - - // If op1 codegen sets ZF and SF flags and ==/!= against - // zero, we don't need to generate test instruction, - // provided we don't have another GenTree node between op1 - // and tree that could potentially modify flags. - // - // TODO-CQ: right now the below peep is inexpensive and - // gets the benefit in most of cases because in majority - // of cases op1, op2 and tree would be in that order in - // execution. In general we should be able to check that all - // the nodes that come after op1 in execution order do not - // modify the flags so that it is safe to avoid generating a - // test instruction. Such a check requires that on each - // GenTree node we need to set the info whether its codegen - // will modify flags. - // - // TODO-CQ: We can optimize compare against zero in the - // following cases by generating the branch as indicated - // against each case. - // 1) unsigned compare - // < 0 - always FALSE - // <= 0 - ZF=1 and jne - // > 0 - ZF=0 and je - // >= 0 - always TRUE - // - // 2) signed compare - // < 0 - SF=1 and js - // >= 0 - SF=0 and jns - if (isEqualityCompare && op1->gtSetZSFlags() && op2->IsIntegralConst(0) && (op1->gtNext == op2) && - (op2->gtNext == tree)) - { - // Require codegen of op1 to set the flags. - assert(!op1->gtSetFlags()); - op1->gtFlags |= GTF_SET_FLAGS; - } - } + SetRegOptional(op1); } } } -- 2.7.4