Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit f5c1ced

Browse files
committed
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.
1 parent ac66a0a commit f5c1ced

File tree

3 files changed

+63
-43
lines changed

3 files changed

+63
-43
lines changed

src/jit/lower.cpp

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,10 @@ GenTree* Lowering::LowerNode(GenTree* node)
178178
case GT_TEST_EQ:
179179
case GT_TEST_NE:
180180
case GT_CMP:
181-
case GT_JCMP:
182181
return LowerCompare(node);
183182

184183
case GT_JTRUE:
185-
ContainCheckJTrue(node->AsOp());
186-
break;
184+
return LowerJTrue(node->AsOp());
187185

188186
case GT_JMP:
189187
LowerJmpMethod(node);
@@ -2696,6 +2694,66 @@ GenTree* Lowering::LowerCompare(GenTree* cmp)
26962694
return cmp->gtNext;
26972695
}
26982696

2697+
//------------------------------------------------------------------------
2698+
// Lowering::LowerJTrue: Lowers a JTRUE node.
2699+
//
2700+
// Arguments:
2701+
// jtrue - the JTRUE node
2702+
//
2703+
// Return Value:
2704+
// The next node to lower (usually nullptr).
2705+
//
2706+
// Notes:
2707+
// On ARM64 this may remove the JTRUE node and transform its associated
2708+
// relop into a JCMP node.
2709+
//
2710+
GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue)
2711+
{
2712+
#ifdef _TARGET_ARM64_
2713+
GenTree* relop = jtrue->gtGetOp1();
2714+
GenTree* relopOp2 = relop->gtOp.gtGetOp2();
2715+
2716+
if ((relop->gtNext == jtrue) && relopOp2->IsCnsIntOrI())
2717+
{
2718+
bool useJCMP = false;
2719+
unsigned flags = 0;
2720+
2721+
if (relop->OperIs(GT_EQ, GT_NE) && relopOp2->IsIntegralConst(0))
2722+
{
2723+
// Codegen will use cbz or cbnz in codegen which do not affect the flag register
2724+
flags = relop->OperIs(GT_EQ) ? GTF_JCMP_EQ : 0;
2725+
useJCMP = true;
2726+
}
2727+
else if (relop->OperIs(GT_TEST_EQ, GT_TEST_NE) && isPow2(relopOp2->AsIntCon()->IconValue()))
2728+
{
2729+
// Codegen will use tbz or tbnz in codegen which do not affect the flag register
2730+
flags = GTF_JCMP_TST | (relop->OperIs(GT_TEST_EQ) ? GTF_JCMP_EQ : 0);
2731+
useJCMP = true;
2732+
}
2733+
2734+
if (useJCMP)
2735+
{
2736+
relop->SetOper(GT_JCMP);
2737+
relop->gtFlags &= ~(GTF_JCMP_TST | GTF_JCMP_EQ);
2738+
relop->gtFlags |= flags;
2739+
relop->gtLsraInfo.isNoRegCompare = true;
2740+
2741+
relopOp2->SetContained();
2742+
2743+
BlockRange().Remove(jtrue);
2744+
2745+
assert(relop->gtNext == nullptr);
2746+
return nullptr;
2747+
}
2748+
}
2749+
#endif // _TARGET_ARM64_
2750+
2751+
ContainCheckJTrue(jtrue);
2752+
2753+
assert(jtrue->gtNext == nullptr);
2754+
return nullptr;
2755+
}
2756+
26992757
// Lower "jmp <method>" tail call to insert PInvoke method epilog if required.
27002758
void Lowering::LowerJmpMethod(GenTree* jmp)
27012759
{

src/jit/lower.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class Lowering : public Phase
138138
// ------------------------------
139139
void LowerCall(GenTree* call);
140140
GenTree* LowerCompare(GenTree* tree);
141+
GenTree* LowerJTrue(GenTreeOp* jtrue);
141142
void LowerJmpMethod(GenTree* jmp);
142143
void LowerRet(GenTree* ret);
143144
GenTree* LowerDelegateInvoke(GenTreeCall* call);

src/jit/lowerarmarch.cpp

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -694,46 +694,7 @@ void Lowering::ContainCheckCast(GenTreeCast* node)
694694
//
695695
void Lowering::ContainCheckCompare(GenTreeOp* cmp)
696696
{
697-
if (CheckImmedAndMakeContained(cmp, cmp->gtOp2))
698-
{
699-
#ifdef _TARGET_ARM64_
700-
GenTreePtr op1 = cmp->gtOp.gtOp1;
701-
GenTreePtr op2 = cmp->gtOp.gtOp2;
702-
703-
if (!varTypeIsFloating(cmp) && op2->IsCnsIntOrI())
704-
{
705-
LIR::Use cmpUse;
706-
bool useJCMP = false;
707-
uint64_t flags = 0;
708-
709-
if (cmp->OperIs(GT_EQ, GT_NE) && op2->IsIntegralConst(0) && BlockRange().TryGetUse(cmp, &cmpUse) &&
710-
cmpUse.User()->OperIs(GT_JTRUE))
711-
{
712-
// Codegen will use cbz or cbnz in codegen which do not affect the flag register
713-
flags = cmp->OperIs(GT_EQ) ? GTF_JCMP_EQ : 0;
714-
useJCMP = true;
715-
}
716-
else if (cmp->OperIs(GT_TEST_EQ, GT_TEST_NE) && isPow2(op2->gtIntCon.IconValue()) &&
717-
BlockRange().TryGetUse(cmp, &cmpUse) && cmpUse.User()->OperIs(GT_JTRUE))
718-
{
719-
// Codegen will use tbz or tbnz in codegen which do not affect the flag register
720-
flags = GTF_JCMP_TST | (cmp->OperIs(GT_TEST_EQ) ? GTF_JCMP_EQ : 0);
721-
useJCMP = true;
722-
}
723-
724-
if (useJCMP)
725-
{
726-
cmp->gtLsraInfo.isNoRegCompare = true;
727-
cmp->SetOper(GT_JCMP);
728-
729-
cmp->gtFlags &= ~(GTF_JCMP_TST | GTF_JCMP_EQ);
730-
cmp->gtFlags |= flags;
731-
732-
BlockRange().Remove(cmpUse.User());
733-
}
734-
}
735-
#endif // _TARGET_ARM64_
736-
}
697+
CheckImmedAndMakeContained(cmp, cmp->gtOp2);
737698
}
738699

739700
//------------------------------------------------------------------------

0 commit comments

Comments
 (0)