Skip to content

Commit

Permalink
Expanding peephole opt even more. Trying to improve tp.
Browse files Browse the repository at this point in the history
  • Loading branch information
TIHan committed Dec 8, 2022
1 parent 53ecd41 commit 0f42667
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6893,7 +6893,7 @@ void CodeGen::genIntToIntCast(GenTreeCast* cast)
case GenIntCastDesc::LOAD_ZERO_EXTEND_INT:
ins = INS_mov;
insSize = 4;
canSkip = emit->AreUpper32BitsZero(srcReg);
canSkip = compiler->opts.OptimizationEnabled() && emit->AreUpper32BitsZero(srcReg);
break;
case GenIntCastDesc::SIGN_EXTEND_INT:
case GenIntCastDesc::LOAD_SIGN_EXTEND_INT:
Expand Down
26 changes: 1 addition & 25 deletions src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1423,33 +1423,9 @@ size_t emitter::emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp)
void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz)
{
#ifdef TARGET_XARCH
// Record the last instruction's peephole info on whether or not
// the instruction's destination register has its upper 32-bits set to zero.
if (emitComp->opts.OptimizationEnabled())
{
regNumber dstReg;
bool isDstRegUpper32BitsZero;
if (TryGetUpper32BitsInfoFromLastInstruction(&dstReg, &isDstRegUpper32BitsZero))
{
if (dstReg != REG_NA)
{
if (isDstRegUpper32BitsZero)
{
upper32BitsZeroRegLookup |= (1 << dstReg);
}
else
{
upper32BitsZeroRegLookup &= ~(1 << dstReg);
}
}
}
else
{
// If we were not able to get peephole info, we assume
// that looking at information from previous instructions is not safe.
// Therefore, we must reset the lookup.
upper32BitsZeroRegLookup = 0;
}
UpdateUpper32BitsZeroRegLookup();
}
#endif // TARGET_XARCH

Expand Down
191 changes: 184 additions & 7 deletions src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,135 @@ bool emitter::IsFlagsAlwaysModified(instrDesc* id)
return true;
}

//------------------------------------------------------------------------
// UpdateUpper32BitsZeroRegLookup: TODO
//
void emitter::UpdateUpper32BitsZeroRegLookup()
{
if (emitLastIns == nullptr)
return;

instrDesc* id = emitLastIns;

// This is conservative. Just look for what seems to be common.
switch (id->idInsFmt())
{
case IF_LABEL:
case IF_RWR_LABEL:
case IF_SWR_LABEL:
case IF_METHOD:
case IF_METHPTR:
{
// If we were not able to get peephole info, we assume
// that looking at information from previous instructions is not safe.
// Therefore, we must reset the lookup.
upper32BitsZeroRegLookup = 0;
return;
}

case IF_RRD:
case IF_RWR:
case IF_RRW:

case IF_RRD_CNS:
case IF_RWR_CNS:
case IF_RRW_CNS:
case IF_RRW_SHF:

case IF_RRD_RRD:
case IF_RWR_RRD:
case IF_RRW_RRD:
case IF_RRW_RRW:
case IF_RRW_RRW_CNS:

case IF_RWR_RRD_RRD:
case IF_RWR_RRD_RRD_CNS:

case IF_RWR_RRD_RRD_RRD:

case IF_RRD_MRD:
case IF_RWR_MRD:
case IF_RRW_MRD:
case IF_RRW_MRD_CNS:

case IF_RWR_RRD_MRD:
case IF_RWR_MRD_CNS:
case IF_RWR_RRD_MRD_CNS:
case IF_RWR_RRD_MRD_RRD:
case IF_MRD_OFF:

case IF_RRD_SRD:
case IF_RWR_SRD:
case IF_RRW_SRD:
case IF_RRW_SRD_CNS:

case IF_RWR_RRD_SRD:
case IF_RWR_SRD_CNS:
case IF_RWR_RRD_SRD_CNS:
case IF_RWR_RRD_SRD_RRD:

case IF_RRD_ARD:
case IF_RWR_ARD:
case IF_RRW_ARD:
case IF_RRW_ARD_CNS:

case IF_RWR_RRD_ARD:
case IF_RWR_ARD_CNS:
case IF_RWR_ARD_RRD:
case IF_RWR_RRD_ARD_CNS:
case IF_RWR_RRD_ARD_RRD:
{
regNumber dstReg = id->idReg1();

#ifdef TARGET_AMD64
if ((dstReg < REG_RAX) || (dstReg > REG_R15))
#else
if ((dstReg < REG_EAX) || (dstReg > REG_EDI))
#endif // !TARGET_AMD64
{
return;
}

// movsx always sign extends to 8 bytes.
if (id->idIns() == INS_movsx)
{
upper32BitsZeroRegLookup &= ~(1 << dstReg);
return;
}

#ifdef TARGET_AMD64
if (id->idIns() == INS_movsxd)
{
upper32BitsZeroRegLookup &= ~(1 << dstReg);
return;
}
#endif

// movzx always zeroes the upper 32 bits.
if (id->idIns() == INS_movzx)
{
upper32BitsZeroRegLookup |= (1 << dstReg);
return;
}

// otherwise rely on operation size.
if (id->idOpSize() == EA_4BYTE)
{
upper32BitsZeroRegLookup |= (1 << dstReg);
}
else
{
upper32BitsZeroRegLookup &= ~(1 << dstReg);
}
}

default:
{
return;
}
}
}

//------------------------------------------------------------------------
// TryGetUpper32BitsInfoFromLastInstruction: Using the previously emitted instruction,
// get instruction information such as the destination register and if the destiniation register is guaranteed
Expand Down Expand Up @@ -497,17 +626,68 @@ bool emitter::TryGetUpper32BitsInfoFromLastInstruction(regNumber* outDstReg, boo

instrDesc* id = emitLastIns;

// This is conservative. Just look for what seems to be common.
switch (id->idInsFmt())
{
case IF_LABEL:
case IF_RWR_LABEL:
case IF_SWR_LABEL:
case IF_METHOD:
case IF_METHPTR:
{
return false;
}

case IF_RRD:
case IF_RWR:
case IF_RRW:

case IF_RRD_CNS:
case IF_RWR_CNS:
case IF_RRW_CNS:
case IF_RRW_SHF:

case IF_RRD_RRD:
case IF_RWR_RRD:
case IF_RRW_RRD:
case IF_RRW_RRW:
case IF_RRW_RRW_CNS:

case IF_RWR_RRD_RRD:
case IF_RWR_RRD_RRD_CNS:

case IF_RWR_RRD_RRD_RRD:

case IF_RRD_MRD:
case IF_RWR_MRD:
case IF_RRW_MRD:
case IF_RRW_MRD_CNS:

case IF_RWR_RRD_MRD:
case IF_RWR_MRD_CNS:
case IF_RWR_RRD_MRD_CNS:
case IF_RWR_RRD_MRD_RRD:
case IF_MRD_OFF:

case IF_RRD_SRD:
case IF_RWR_SRD:
case IF_RRW_SRD:
case IF_RRW_SRD_CNS:

case IF_RWR_RRD_SRD:
case IF_RWR_SRD_CNS:
case IF_RWR_RRD_SRD_CNS:
case IF_RWR_RRD_SRD_RRD:

case IF_RRD_ARD:
case IF_RWR_ARD:
case IF_RRW_ARD:
case IF_RRW_ARD_CNS:

case IF_RWR_RRD_ARD:
case IF_RWR_ARD_CNS:
case IF_RWR_ARD_RRD:
case IF_RWR_RRD_ARD_CNS:
case IF_RWR_RRD_ARD_RRD:
{
regNumber reg = id->idReg1();

Expand Down Expand Up @@ -553,7 +733,9 @@ bool emitter::TryGetUpper32BitsInfoFromLastInstruction(regNumber* outDstReg, boo

default:
{
return false;
*outDstReg = REG_NA;
*outIsDstRegUpper32BitsZero = false;
return true;
}
}
}
Expand All @@ -571,11 +753,6 @@ bool emitter::TryGetUpper32BitsInfoFromLastInstruction(regNumber* outDstReg, boo
//
bool emitter::AreUpper32BitsZero(regNumber reg)
{
if (emitComp->opts.OptimizationDisabled())
{
return false;
}

regNumber dstReg;
bool isUpper32BitsZero;
bool isSafe = TryGetUpper32BitsInfoFromLastInstruction(&dstReg, &isUpper32BitsZero);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/emitxarch.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ bool IsRedundantStackMov(instruction ins, insFormat fmt, emitAttr size, regNumbe
static bool IsJccInstruction(instruction ins);
static bool IsJmpInstruction(instruction ins);

void UpdateUpper32BitsZeroRegLookup();
bool TryGetUpper32BitsInfoFromLastInstruction(regNumber* outDstReg, bool* outIsDstRegUpper32BitsZero);
bool AreUpper32BitsZero(regNumber reg);

Expand Down

0 comments on commit 0f42667

Please sign in to comment.