Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 48bb261

Browse files
committed
Also for brtrue
1 parent da8589f commit 48bb261

File tree

1 file changed

+134
-71
lines changed

1 file changed

+134
-71
lines changed

src/coreclr/jit/importer.cpp

Lines changed: 134 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -5328,89 +5328,152 @@ GenTree* Compiler::impOptimizeCastClassOrIsInst(GenTree* op1, CORINFO_RESOLVED_T
53285328
int Compiler::impIsInstPatternMatch(
53295329
GenTree* op1, GenTree* op2, const BYTE* codeAddr, const BYTE* codeEndp)
53305330
{
5331-
if ((impGetNonPrefixOpcode(codeAddr, codeEndp) == CEE_LDNULL))
5331+
switch (impGetNonPrefixOpcode(codeAddr, codeEndp))
53325332
{
5333-
switch (impGetNonPrefixOpcode(codeAddr + 1, codeEndp))
5334-
{
5335-
case CEE_CGT_UN:
5336-
// isinst + ldnull + cgt.un
5337-
// convert to op1 == null ? false : *op1 == op2
5338-
{
5339-
GenTree* condNull;
5340-
//
5341-
// expand the null check:
5342-
//
5343-
// condNull ==> GT_NE
5344-
// / \.
5345-
// op1Copy CNS_INT
5346-
// null
5347-
//
5348-
condNull = gtNewOperNode(GT_NE, TYP_INT, gtClone(op1), gtNewNull());
5333+
case CEE_LDNULL:
5334+
switch (impGetNonPrefixOpcode(codeAddr + 1, codeEndp))
5335+
{
5336+
case CEE_CGT_UN:
5337+
// isinst + ldnull + cgt.un
5338+
// convert to op1 == null ? false : *op1 == op2
5339+
{
5340+
GenTree* condNull;
5341+
//
5342+
// expand the null check:
5343+
//
5344+
// condNull ==> GT_NE
5345+
// / \.
5346+
// op1Copy CNS_INT
5347+
// null
5348+
//
5349+
condNull = gtNewOperNode(GT_NE, TYP_INT, gtClone(op1), gtNewNull());
53495350

5350-
GenTree* temp;
5351-
GenTree* condMT;
5352-
//
5353-
// expand the methodtable match:
5354-
//
5355-
// condMT ==> GT_EQ
5356-
// / \.
5357-
// GT_IND op2 (typically CNS_INT)
5358-
// |
5359-
// op1Copy
5360-
//
5351+
GenTree* temp;
5352+
GenTree* condMT;
5353+
//
5354+
// expand the methodtable match:
5355+
//
5356+
// condMT ==> GT_EQ
5357+
// / \.
5358+
// GT_IND op2 (typically CNS_INT)
5359+
// |
5360+
// op1Copy
5361+
//
53615362

5362-
// This can replace op1 with a GT_COMMA that evaluates op1 into a local
5363-
//
5364-
op1 = impCloneExpr(op1, &temp, CHECK_SPILL_ALL, nullptr DEBUGARG("CASTCLASS eval op1"));
5365-
//
5366-
// op1 is now known to be a non-complex tree
5367-
// thus we can use gtClone(op1) from now on
5368-
//
5363+
// This can replace op1 with a GT_COMMA that evaluates op1 into a local
5364+
//
5365+
op1 = impCloneExpr(op1, &temp, CHECK_SPILL_ALL, nullptr DEBUGARG("CASTCLASS eval op1"));
5366+
//
5367+
// op1 is now known to be a non-complex tree
5368+
// thus we can use gtClone(op1) from now on
5369+
//
53695370

5370-
GenTree* op2Var = op2;
5371-
temp = gtNewMethodTableLookup(temp);
5372-
condMT = gtNewOperNode(GT_EQ, TYP_INT, temp, op2);
5371+
GenTree* op2Var = op2;
5372+
temp = gtNewMethodTableLookup(temp);
5373+
condMT = gtNewOperNode(GT_EQ, TYP_INT, temp, op2);
53735374

5374-
GenTree* qmarkNull;
5375-
//
5376-
// Generate QMARK - COLON tree
5377-
//
5378-
// qmarkNull ==> GT_QMARK
5379-
// / \.
5380-
// condNull GT_COLON
5381-
// / \.
5382-
// condMT CNS_INT
5383-
// false
5384-
//
5385-
temp = new (this, GT_COLON) GenTreeColon(TYP_INT, condMT, gtNewFalse());
5386-
qmarkNull = gtNewQmarkNode(TYP_INT, condNull, temp->AsColon());
5375+
GenTree* qmarkNull;
5376+
//
5377+
// Generate QMARK - COLON tree
5378+
//
5379+
// qmarkNull ==> GT_QMARK
5380+
// / \.
5381+
// condNull GT_COLON
5382+
// / \.
5383+
// condMT CNS_INT
5384+
// false
5385+
//
5386+
temp = new (this, GT_COLON) GenTreeColon(TYP_INT, condMT, gtNewFalse());
5387+
qmarkNull = gtNewQmarkNode(TYP_INT, condNull, temp->AsColon());
53875388

5388-
// Make QMark node a top level node by spilling it.
5389-
unsigned tmp = lvaGrabTemp(true DEBUGARG("spilling QMark"));
5390-
impStoreTemp(tmp, qmarkNull, CHECK_SPILL_NONE);
5389+
// Make QMark node a top level node by spilling it.
5390+
unsigned tmp = lvaGrabTemp(true DEBUGARG("spilling QMark"));
5391+
impStoreTemp(tmp, qmarkNull, CHECK_SPILL_NONE);
53915392

5392-
GenTree* lclVar = gtNewLclvNode(tmp, TYP_INT);
5393-
impPushOnStack(lclVar, TYP_INT);
5394-
return 3;
5395-
}
5393+
GenTree* lclVar = gtNewLclvNode(tmp, TYP_INT);
5394+
impPushOnStack(lclVar, TYP_INT);
5395+
return 3;
5396+
}
53965397

5397-
case CEE_CEQ:
5398-
// isinst + ldnull + ceq
5399-
// convert to op1 == null ? true : *op1 != op2
5398+
case CEE_CEQ:
5399+
// isinst + ldnull + ceq
5400+
// convert to op1 == null ? true : *op1 != op2
54005401

5401-
break;
5402+
break;
5403+
default:
5404+
return -1;
5405+
}
5406+
break;
54025407

5403-
case CEE_BRTRUE:
5404-
case CEE_BRTRUE_S:
5405-
break;
5408+
case CEE_BRTRUE:
5409+
case CEE_BRTRUE_S:
5410+
// isinst + brtrue
5411+
// convert isinst to op1 == null ? false : *op1 == op2, leave the branch IL
5412+
{
5413+
GenTree* condNull;
5414+
//
5415+
// expand the null check:
5416+
//
5417+
// condNull ==> GT_NE
5418+
// / \.
5419+
// op1Copy CNS_INT
5420+
// null
5421+
//
5422+
condNull = gtNewOperNode(GT_NE, TYP_INT, gtClone(op1), gtNewNull());
54065423

5407-
case CEE_BRFALSE:
5408-
case CEE_BRFALSE_S:
5424+
GenTree* temp;
5425+
GenTree* condMT;
5426+
//
5427+
// expand the methodtable match:
5428+
//
5429+
// condMT ==> GT_EQ
5430+
// / \.
5431+
// GT_IND op2 (typically CNS_INT)
5432+
// |
5433+
// op1Copy
5434+
//
54095435

5410-
break;
5411-
default:
5412-
return -1;
5413-
}
5436+
// This can replace op1 with a GT_COMMA that evaluates op1 into a local
5437+
//
5438+
op1 = impCloneExpr(op1, &temp, CHECK_SPILL_ALL, nullptr DEBUGARG("CASTCLASS eval op1"));
5439+
//
5440+
// op1 is now known to be a non-complex tree
5441+
// thus we can use gtClone(op1) from now on
5442+
//
5443+
5444+
GenTree* op2Var = op2;
5445+
temp = gtNewMethodTableLookup(temp);
5446+
condMT = gtNewOperNode(GT_EQ, TYP_INT, temp, op2);
5447+
5448+
GenTree* qmarkNull;
5449+
//
5450+
// Generate QMARK - COLON tree
5451+
//
5452+
// qmarkNull ==> GT_QMARK
5453+
// / \.
5454+
// condNull GT_COLON
5455+
// / \.
5456+
// condMT CNS_INT
5457+
// false
5458+
//
5459+
temp = new (this, GT_COLON) GenTreeColon(TYP_INT, condMT, gtNewFalse());
5460+
qmarkNull = gtNewQmarkNode(TYP_INT, condNull, temp->AsColon());
5461+
5462+
// Make QMark node a top level node by spilling it.
5463+
unsigned tmp = lvaGrabTemp(true DEBUGARG("spilling QMark"));
5464+
impStoreTemp(tmp, qmarkNull, CHECK_SPILL_NONE);
5465+
5466+
GenTree* lclVar = gtNewLclvNode(tmp, TYP_INT);
5467+
impPushOnStack(lclVar, TYP_INT);
5468+
return 0;
5469+
}
5470+
5471+
case CEE_BRFALSE:
5472+
case CEE_BRFALSE_S:
5473+
5474+
break;
5475+
default:
5476+
return -1;
54145477
}
54155478

54165479
return -1;

0 commit comments

Comments
 (0)