Skip to content

Commit

Permalink
[Arm64] Replace pairs of str with stp (#85032)
Browse files Browse the repository at this point in the history
* Add emitIns_SS_R_R_R_I()

* Introduce instrDescStrPair and use it

* rename some variables and fix a bug in outputInstr

* Rename to instrDescLclVarPair

* Add the missing SetIsLclVar()

* review feedback

* Use same code for GC/non-GC lclVar for stp'

* Use same code path for ldp/stp

* Just have asending/descending

* refactor code around emitOutputInstr()

* jit format

* Remove the comment

* Separate instrDescLclVarPair and instrDescLclVarPairCns

* useRsvdReg for assert

* add back the assert around `adr + ofs`

* Move OptimizeLdrStr() in emitarm64.cpp

* Update the assert for offset distance

* Rename emitIns_SS_R_R_R_I() to emitIns_R_R_R_I_LdStPair()

* jit format

* review feedback
  • Loading branch information
kunalspathak authored Apr 27, 2023
1 parent e029183 commit 318186b
Show file tree
Hide file tree
Showing 3 changed files with 484 additions and 138 deletions.
116 changes: 103 additions & 13 deletions src/coreclr/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -782,17 +782,18 @@ class emitter
unsigned _idNoGC : 1; // Some helpers don't get recorded in GC tables

#ifdef TARGET_ARM64
opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16
insOpts _idInsOpt : 6; // options for instructions
unsigned _idLclVar : 1; // access a local on stack
opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16
insOpts _idInsOpt : 6; // options for instructions
unsigned _idLclVar : 1; // access a local on stack
unsigned _idLclVarPair : 1 // carries information for 2 GC lcl vars.
#endif

#ifdef TARGET_LOONGARCH64
// TODO-LoongArch64: maybe delete on future.
opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16
insOpts _idInsOpt : 6; // loongarch options for special: placeholders. e.g emitIns_R_C, also identifying the
// accessing a local on stack.
unsigned _idLclVar : 1; // access a local on stack.
// TODO-LoongArch64: maybe delete on future.
opSize _idOpSize : 3; // operand size: 0=1 , 1=2 , 2=4 , 3=8, 4=16
insOpts _idInsOpt : 6; // loongarch options for special: placeholders. e.g emitIns_R_C, also identifying the
// accessing a local on stack.
unsigned _idLclVar : 1; // access a local on stack.
#endif

#ifdef TARGET_RISCV64
Expand All @@ -815,7 +816,7 @@ class emitter
// x86: 46 bits
// amd64: 46 bits
// arm: 48 bits
// arm64: 49 bits
// arm64: 50 bits
// loongarch64: 46 bits

//
Expand All @@ -827,7 +828,7 @@ class emitter
#if defined(TARGET_ARM)
#define ID_EXTRA_BITFIELD_BITS (16)
#elif defined(TARGET_ARM64)
#define ID_EXTRA_BITFIELD_BITS (17)
#define ID_EXTRA_BITFIELD_BITS (18)
#elif defined(TARGET_XARCH) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
#define ID_EXTRA_BITFIELD_BITS (14)
#else
Expand Down Expand Up @@ -867,7 +868,7 @@ class emitter
// x86: 52/48 bits
// amd64: 53/48 bits
// arm: 54/50 bits
// arm64: 56/51 bits
// arm64: 57/52 bits
// loongarch64: 53/48 bits
CLANG_FORMAT_COMMENT_ANCHOR;

Expand All @@ -885,7 +886,7 @@ class emitter
// x86: 12/16 bits
// amd64: 11/16 bits
// arm: 10/14 bits
// arm64: 8/13 bits
// arm64: 7/12 bits
// loongarch64: 11/16 bits

unsigned _idSmallCns : ID_BIT_SMALL_CNS;
Expand Down Expand Up @@ -1432,6 +1433,16 @@ class emitter
{
_idLclVar = 1;
}
#ifdef TARGET_ARM64
bool idIsLclVarPair() const
{
return _idLclVarPair != 0;
}
void idSetIsLclVarPair()
{
_idLclVarPair = 1;
}
#endif // TARGET_ARM64
#endif // TARGET_ARMARCH

#if defined(TARGET_ARM)
Expand Down Expand Up @@ -1819,6 +1830,22 @@ class emitter

#endif // TARGET_XARCH

#ifdef TARGET_ARM64
struct instrDescLclVarPair : instrDesc // contains 2 gc vars to be tracked
{
instrDescLclVarPair() = delete;

emitLclVarAddr iiaLclVar2;
};

struct instrDescLclVarPairCns : instrDescCns // contains 2 gc vars to be tracked, with large cons
{
instrDescLclVarPairCns() = delete;

emitLclVarAddr iiaLclVar2;
};
#endif

struct instrDescCGCA : instrDesc // call with ...
{
instrDescCGCA() = delete;
Expand Down Expand Up @@ -2600,7 +2627,26 @@ class emitter
#endif // EMITTER_STATS
return (instrDescLbl*)emitAllocAnyInstr(sizeof(instrDescLbl), EA_4BYTE);
}
#endif // !TARGET_ARM64
#endif // TARGET_ARM64

#if defined(TARGET_ARM64)
instrDescLclVarPair* emitAllocInstrLclVarPair(emitAttr attr)
{
instrDescLclVarPair* result = (instrDescLclVarPair*)emitAllocAnyInstr(sizeof(instrDescLclVarPair), attr);
result->idSetIsLclVarPair();
return result;
}

instrDescLclVarPairCns* emitAllocInstrLclVarPairCns(emitAttr attr, cnsval_size_t cns)
{
instrDescLclVarPairCns* result =
(instrDescLclVarPairCns*)emitAllocAnyInstr(sizeof(instrDescLclVarPairCns), attr);
result->idSetIsLargeCns();
result->idSetIsLclVarPair();
result->idcCnsVal = cns;
return result;
}
#endif // TARGET_ARM64

instrDescCns* emitAllocInstrCns(emitAttr attr)
{
Expand Down Expand Up @@ -2686,6 +2732,8 @@ class emitter

#if !defined(TARGET_ARM64)
instrDescLbl* emitNewInstrLbl();
#else
instrDesc* emitNewInstrLclVarPair(emitAttr attr, cnsval_ssize_t cns);
#endif // !TARGET_ARM64

static const BYTE emitFmtToOps[];
Expand Down Expand Up @@ -3249,6 +3297,36 @@ inline emitter::instrDescLbl* emitter::emitNewInstrLbl()
{
return emitAllocInstrLbl();
}
#else
inline emitter::instrDesc* emitter::emitNewInstrLclVarPair(emitAttr attr, cnsval_ssize_t cns)
{
#if EMITTER_STATS
emitTotalIDescCnt++;
emitTotalIDescCnsCnt++;
#endif // EMITTER_STATS

if (instrDesc::fitsInSmallCns(cns))
{
instrDescLclVarPair* id = emitAllocInstrLclVarPair(attr);
id->idSmallCns(cns);
#if EMITTER_STATS
emitSmallCnsCnt++;
if ((cns - ID_MIN_SMALL_CNS) >= (SMALL_CNS_TSZ - 1))
emitSmallCns[SMALL_CNS_TSZ - 1]++;
else
emitSmallCns[cns - ID_MIN_SMALL_CNS]++;
#endif
return id;
}
else
{
instrDescLclVarPairCns* id = emitAllocInstrLclVarPairCns(attr, cns);
#if EMITTER_STATS
emitLargeCnsCnt++;
#endif
return id;
}
}
#endif // !TARGET_ARM64

inline emitter::instrDesc* emitter::emitNewInstrDsp(emitAttr attr, target_ssize_t dsp)
Expand Down Expand Up @@ -3329,10 +3407,22 @@ inline size_t emitter::emitGetInstrDescSize(const instrDesc* id)
}
else if (id->idIsLargeCns())
{
#ifdef TARGET_ARM64
if (id->idIsLclVarPair())
{
return sizeof(instrDescLclVarPairCns);
}
#endif
return sizeof(instrDescCns);
}
else
{
#ifdef TARGET_ARM64
if (id->idIsLclVarPair())
{
return sizeof(instrDescLclVarPair);
}
#endif
return sizeof(instrDesc);
}
}
Expand Down
Loading

0 comments on commit 318186b

Please sign in to comment.