Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Move JCMP transform to LowerJTrue
Unlike many other relop transforms we do this one is only triggerred by the presence of a conditional branch (JTRUE) so it makes more sense to do it when lowering JTRUE nodes, avoids unnecessary calls to TryGetUse.
  • Loading branch information
mikedn committed Oct 2, 2017
commit 5402ec55b132188d9a04f30af9e814695409f913
64 changes: 61 additions & 3 deletions src/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,10 @@ GenTree* Lowering::LowerNode(GenTree* node)
case GT_TEST_EQ:
case GT_TEST_NE:
case GT_CMP:
case GT_JCMP:
return LowerCompare(node);

case GT_JTRUE:
ContainCheckJTrue(node->AsOp());
break;
return LowerJTrue(node->AsOp());

case GT_JMP:
LowerJmpMethod(node);
Expand Down Expand Up @@ -2696,6 +2694,66 @@ GenTree* Lowering::LowerCompare(GenTree* cmp)
return cmp->gtNext;
}

//------------------------------------------------------------------------
// Lowering::LowerJTrue: Lowers a JTRUE node.
//
// Arguments:
// jtrue - the JTRUE node
//
// Return Value:
// The next node to lower (usually nullptr).
//
// Notes:
// On ARM64 this may remove the JTRUE node and transform its associated
// relop into a JCMP node.
//
GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue)
{
#ifdef _TARGET_ARM64_
GenTree* relop = jtrue->gtGetOp1();
GenTree* relopOp2 = relop->gtOp.gtGetOp2();

if ((relop->gtNext == jtrue) && relopOp2->IsCnsIntOrI())
{
bool useJCMP = false;
unsigned flags = 0;

if (relop->OperIs(GT_EQ, GT_NE) && relopOp2->IsIntegralConst(0))
{
// Codegen will use cbz or cbnz in codegen which do not affect the flag register
flags = relop->OperIs(GT_EQ) ? GTF_JCMP_EQ : 0;
useJCMP = true;
}
else if (relop->OperIs(GT_TEST_EQ, GT_TEST_NE) && isPow2(relopOp2->AsIntCon()->IconValue()))
{
// Codegen will use tbz or tbnz in codegen which do not affect the flag register
flags = GTF_JCMP_TST | (relop->OperIs(GT_TEST_EQ) ? GTF_JCMP_EQ : 0);
useJCMP = true;
}

if (useJCMP)
{
relop->SetOper(GT_JCMP);
relop->gtFlags &= ~(GTF_JCMP_TST | GTF_JCMP_EQ);
relop->gtFlags |= flags;
relop->gtLsraInfo.isNoRegCompare = true;

relopOp2->SetContained();

BlockRange().Remove(jtrue);

assert(relop->gtNext == nullptr);
return nullptr;
}
}
#endif // _TARGET_ARM64_

ContainCheckJTrue(jtrue);

assert(jtrue->gtNext == nullptr);
return nullptr;
}

// Lower "jmp <method>" tail call to insert PInvoke method epilog if required.
void Lowering::LowerJmpMethod(GenTree* jmp)
{
Expand Down
1 change: 1 addition & 0 deletions src/jit/lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ class Lowering : public Phase
// ------------------------------
void LowerCall(GenTree* call);
GenTree* LowerCompare(GenTree* tree);
GenTree* LowerJTrue(GenTreeOp* jtrue);
void LowerJmpMethod(GenTree* jmp);
void LowerRet(GenTree* ret);
GenTree* LowerDelegateInvoke(GenTreeCall* call);
Expand Down
41 changes: 1 addition & 40 deletions src/jit/lowerarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -694,46 +694,7 @@ void Lowering::ContainCheckCast(GenTreeCast* node)
//
void Lowering::ContainCheckCompare(GenTreeOp* cmp)
{
if (CheckImmedAndMakeContained(cmp, cmp->gtOp2))
{
#ifdef _TARGET_ARM64_
GenTreePtr op1 = cmp->gtOp.gtOp1;
GenTreePtr op2 = cmp->gtOp.gtOp2;

if (!varTypeIsFloating(cmp) && op2->IsCnsIntOrI())
{
LIR::Use cmpUse;
bool useJCMP = false;
uint64_t flags = 0;

if (cmp->OperIs(GT_EQ, GT_NE) && op2->IsIntegralConst(0) && BlockRange().TryGetUse(cmp, &cmpUse) &&
cmpUse.User()->OperIs(GT_JTRUE))
{
// Codegen will use cbz or cbnz in codegen which do not affect the flag register
flags = cmp->OperIs(GT_EQ) ? GTF_JCMP_EQ : 0;
useJCMP = true;
}
else if (cmp->OperIs(GT_TEST_EQ, GT_TEST_NE) && isPow2(op2->gtIntCon.IconValue()) &&
BlockRange().TryGetUse(cmp, &cmpUse) && cmpUse.User()->OperIs(GT_JTRUE))
{
// Codegen will use tbz or tbnz in codegen which do not affect the flag register
flags = GTF_JCMP_TST | (cmp->OperIs(GT_TEST_EQ) ? GTF_JCMP_EQ : 0);
useJCMP = true;
}

if (useJCMP)
{
cmp->gtLsraInfo.isNoRegCompare = true;
cmp->SetOper(GT_JCMP);

cmp->gtFlags &= ~(GTF_JCMP_TST | GTF_JCMP_EQ);
cmp->gtFlags |= flags;

BlockRange().Remove(cmpUse.User());
}
}
#endif // _TARGET_ARM64_
}
CheckImmedAndMakeContained(cmp, cmp->gtOp2);
}

//------------------------------------------------------------------------
Expand Down