Skip to content

Commit

Permalink
Handle more than 64 registers - Part 2 (#102297)
Browse files Browse the repository at this point in the history
* Make regMaskTP struct for non-arm64 platforms

* some refactoring

* jit format

* fix missing paranethesis in arm

* fix riscv64 and loongarch build

* minor change

* review feedback
  • Loading branch information
kunalspathak authored May 22, 2024
1 parent 0709995 commit 761c9a5
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 101 deletions.
19 changes: 10 additions & 9 deletions src/coreclr/jit/codegenarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1927,14 +1927,15 @@ void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pIni

void CodeGen::genPushFltRegs(regMaskTP regMask)
{
assert(regMask != 0); // Don't call uness we have some registers to push
assert((regMask & RBM_ALLFLOAT) == regMask); // Only floasting point registers should be in regMask
assert(regMask != 0); // Don't call unless we have some registers to push
assert((regMask & RBM_ALLFLOAT) == regMask); // Only floating point registers should be in regMask

regNumber lowReg = genRegNumFromMask(genFindLowestBit(regMask));
int slots = genCountBits(regMask);

// regMask should be contiguously set
regMaskTP tmpMask = ((regMask >> lowReg) + 1); // tmpMask should have a single bit set
assert((tmpMask & (tmpMask - 1)) == 0);
regMaskSmall tmpMask = ((regMask.getLow() >> lowReg) + 1); // tmpMask should have a single bit set
assert(genMaxOneBit(tmpMask));
assert(lowReg == REG_F16); // Currently we expect to start at F16 in the unwind codes

// Our calling convention requires that we only use vpush for TYP_DOUBLE registers
Expand All @@ -1952,8 +1953,8 @@ void CodeGen::genPopFltRegs(regMaskTP regMask)
regNumber lowReg = genRegNumFromMask(genFindLowestBit(regMask));
int slots = genCountBits(regMask);
// regMask should be contiguously set
regMaskTP tmpMask = ((regMask >> lowReg) + 1); // tmpMask should have a single bit set
assert((tmpMask & (tmpMask - 1)) == 0);
regMaskSmall tmpMask = ((regMask.getLow() >> lowReg) + 1); // tmpMask should have a single bit set
assert(genMaxOneBit(tmpMask));

// Our calling convention requires that we only use vpop for TYP_DOUBLE registers
noway_assert(floatRegCanHoldType(lowReg, TYP_DOUBLE));
Expand Down Expand Up @@ -2192,7 +2193,7 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog)
genUsedPopToReturn = false;
}

assert(FitsIn<int>(maskPopRegsInt));
assert(FitsIn<int>(maskPopRegsInt.getLow()));
inst_IV(INS_pop, (int)maskPopRegsInt);
compiler->unwindPopMaskInt(maskPopRegsInt);
}
Expand Down Expand Up @@ -2320,7 +2321,7 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
regMaskTP maskStackAlloc = genStackAllocRegisterMask(genFuncletInfo.fiSpDelta, maskPushRegsFloat);
maskPushRegsInt |= maskStackAlloc;

assert(FitsIn<int>(maskPushRegsInt));
assert(FitsIn<int>(maskPushRegsInt.getLow()));
inst_IV(INS_push, (int)maskPushRegsInt);
compiler->unwindPushMaskInt(maskPushRegsInt);

Expand Down Expand Up @@ -2437,7 +2438,7 @@ void CodeGen::genFuncletEpilog()
compiler->unwindPopMaskFloat(maskPopRegsFloat);
}

assert(FitsIn<int>(maskPopRegsInt));
assert(FitsIn<int>(maskPopRegsInt.getLow()));
inst_IV(INS_pop, (int)maskPopRegsInt);
compiler->unwindPopMaskInt(maskPopRegsInt);

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe
assert((spDelta % 16) == 0);

// We also can save FP and LR, even though they are not in RBM_CALLEE_SAVED.
assert(regsToSaveCount <= genCountBits(RBM_CALLEE_SAVED | RBM_FP | RBM_LR));
assert(regsToSaveCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED | RBM_FP | RBM_LR)));

// Save integer registers at higher addresses than floating-point registers.

Expand Down Expand Up @@ -1035,7 +1035,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
assert((spDelta % 16) == 0);

// We also can restore FP and LR, even though they are not in RBM_CALLEE_SAVED.
assert(regsToRestoreCount <= genCountBits(RBM_CALLEE_SAVED | RBM_FP | RBM_LR));
assert(regsToRestoreCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED | RBM_FP | RBM_LR)));

// Point past the end, to start. We predecrement to find the offset to load from.
static_assert_no_msg(REGSIZE_BYTES == FPSAVE_REGSIZE_BYTES);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4687,7 +4687,7 @@ void CodeGen::genPushCalleeSavedRegisters()

maskPushRegsInt |= genStackAllocRegisterMask(compiler->compLclFrameSize, maskPushRegsFloat);

assert(FitsIn<int>(maskPushRegsInt));
assert(FitsIn<int>(maskPushRegsInt.getLow()));
inst_IV(INS_push, (int)maskPushRegsInt);
compiler->unwindPushMaskInt(maskPushRegsInt);

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/codegenloongarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe
return;
}

assert(genCountBits(regsToSaveMask) <= genCountBits(RBM_CALLEE_SAVED));
assert(genCountBits(regsToSaveMask) <= genCountBits(regMaskTP(RBM_CALLEE_SAVED)));

// Save integer registers at higher addresses than floating-point registers.

Expand Down Expand Up @@ -626,7 +626,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in

unsigned regsToRestoreCount = genCountBits(regsToRestoreMask);
// The FP and RA are not in RBM_CALLEE_SAVED.
assert(regsToRestoreCount <= genCountBits(RBM_CALLEE_SAVED));
assert(regsToRestoreCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED)));

// Point past the end, to start. We predecrement to find the offset to load from.
static_assert_no_msg(REGSIZE_BYTES == FPSAVE_REGSIZE_BYTES);
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe

assert((spDelta % STACK_ALIGN) == 0);

assert(regsToSaveCount <= genCountBits(RBM_CALLEE_SAVED));
assert(regsToSaveCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED)));

// Save integer registers at higher addresses than floating-point registers.
regMaskTP maskSaveRegsFloat = regsToSaveMask & RBM_ALLFLOAT;
Expand Down Expand Up @@ -718,7 +718,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
assert((spDelta % STACK_ALIGN) == 0);

// We also can restore FP and RA, even though they are not in RBM_CALLEE_SAVED.
assert(regsToRestoreCount <= genCountBits(RBM_CALLEE_SAVED | RBM_FP | RBM_RA));
assert(regsToRestoreCount <= genCountBits(regMaskTP(RBM_CALLEE_SAVED | RBM_FP | RBM_RA)));

// Point past the end, to start. We predecrement to find the offset to load from.
static_assert_no_msg(REGSIZE_BYTES == FPSAVE_REGSIZE_BYTES);
Expand Down
33 changes: 0 additions & 33 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ inline bool genExactlyOneBit(T value)
return ((value != 0) && genMaxOneBit(value));
}

#ifdef TARGET_ARM64
inline regMaskTP genFindLowestBit(regMaskTP value)
{
return regMaskTP(genFindLowestBit(value.getLow()));
Expand All @@ -124,7 +123,6 @@ inline bool genExactlyOneBit(regMaskTP value)
{
return genExactlyOneBit(value.getLow());
}
#endif

/*****************************************************************************
*
Expand Down Expand Up @@ -169,17 +167,10 @@ inline unsigned uhi32(uint64_t value)
* A rather simple routine that counts the number of bits in a given number.
*/

inline unsigned genCountBits(uint64_t bits)
{
return BitOperations::PopCount(bits);
}

#ifdef TARGET_ARM64
inline unsigned genCountBits(regMaskTP mask)
{
return BitOperations::PopCount(mask.getLow());
}
#endif

/*****************************************************************************
*
Expand Down Expand Up @@ -948,19 +939,11 @@ inline regNumber genRegNumFromMask(regMaskTP mask)

/* Convert the mask to a register number */

#ifdef TARGET_ARM64
regNumber regNum = (regNumber)genLog2(mask.getLow());

/* Make sure we got it right */
assert(genRegMask(regNum) == mask.getLow());

#else
regNumber regNum = (regNumber)genLog2(mask);

/* Make sure we got it right */
assert(genRegMask(regNum) == mask);
#endif

return regNum;
}

Expand Down Expand Up @@ -4505,46 +4488,30 @@ inline void* operator new[](size_t sz, Compiler* compiler, CompMemKind cmk)

inline void printRegMask(regMaskTP mask)
{
#ifdef TARGET_ARM64
printf(REG_MASK_ALL_FMT, mask.getLow());
#else
printf(REG_MASK_ALL_FMT, mask);
#endif
}

inline char* regMaskToString(regMaskTP mask, Compiler* context)
{
const size_t cchRegMask = 24;
char* regmask = new (context, CMK_Unknown) char[cchRegMask];

#ifdef TARGET_ARM64
sprintf_s(regmask, cchRegMask, REG_MASK_ALL_FMT, mask.getLow());
#else
sprintf_s(regmask, cchRegMask, REG_MASK_ALL_FMT, mask);
#endif

return regmask;
}

inline void printRegMaskInt(regMaskTP mask)
{
#ifdef TARGET_ARM64
printf(REG_MASK_INT_FMT, (mask & RBM_ALLINT).getLow());
#else
printf(REG_MASK_INT_FMT, (mask & RBM_ALLINT));
#endif
}

inline char* regMaskIntToString(regMaskTP mask, Compiler* context)
{
const size_t cchRegMask = 24;
char* regmask = new (context, CMK_Unknown) char[cchRegMask];

#ifdef TARGET_ARM64
sprintf_s(regmask, cchRegMask, REG_MASK_INT_FMT, (mask & RBM_ALLINT).getLow());
#else
sprintf_s(regmask, cchRegMask, REG_MASK_INT_FMT, (mask & RBM_ALLINT));
#endif

return regmask;
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8787,7 +8787,7 @@ void emitter::emitRecordGCcall(BYTE* codePos, unsigned char callInstrSize)
callDsc* call;

#ifdef JIT32_GCENCODER
unsigned regs = (emitThisGCrefRegs | emitThisByrefRegs) & ~RBM_INTRET;
unsigned regs = (unsigned)(emitThisGCrefRegs | emitThisByrefRegs) & ~RBM_INTRET;

// The JIT32 GCInfo encoder allows us to (as the comment previously here said):
// "Bail if this is a totally boring call", but the GCInfoEncoder/Decoder interface
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/emitarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5771,15 +5771,15 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
assert(REG_NA == (int)REG_NA);

VARSET_TP GCvars(VarSetOps::UninitVal());
regMaskTP gcrefRegs;
regMaskTP byrefRegs;

/* What instruction format have we got? */

switch (fmt)
{
int imm;
BYTE* addr;
regMaskTP gcrefRegs;
regMaskTP byrefRegs;
int imm;
BYTE* addr;

case IF_T1_A: // T1_A ................
sz = SMALL_IDSC_SIZE;
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15795,6 +15795,7 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id)
break;

case IF_RRW_CNS:
{
assert(id->idGCref() == GCT_BYREF);

#ifdef DEBUG
Expand All @@ -15816,7 +15817,7 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id)
// Mark it as holding a GCT_BYREF
emitGCregLiveUpd(GCT_BYREF, id->idReg1(), dst);
break;

}
default:
#ifdef DEBUG
emitDispIns(id, false, false, false);
Expand Down Expand Up @@ -16609,6 +16610,8 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
assert(instrIs3opImul(id->idIns()) == 0 || size >= EA_4BYTE); // Has no 'w' bit

VARSET_TP GCvars(VarSetOps::UninitVal());
regMaskTP gcrefRegs;
regMaskTP byrefRegs;

// What instruction format have we got?
switch (insFmt)
Expand All @@ -16621,9 +16624,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
BYTE* addr;
bool recCall;

regMaskTP gcrefRegs;
regMaskTP byrefRegs;

/********************************************************************/
/* No operands */
/********************************************************************/
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/gcencode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2874,7 +2874,7 @@ size_t GCInfo::gcMakeRegPtrTable(BYTE* dest, int mask, const InfoHdr& header, un

if (compiler->lvaKeepAliveAndReportThis() && compiler->lvaTable[compiler->info.compThisArg].lvRegister)
{
unsigned thisRegMask = genRegMask(compiler->lvaTable[compiler->info.compThisArg].GetRegNum());
unsigned thisRegMask = (unsigned)genRegMask(compiler->lvaTable[compiler->info.compThisArg].GetRegNum());
unsigned thisPtrRegEnc = gceEncodeCalleeSavedRegs(thisRegMask) << 4;

if (thisPtrRegEnc)
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/lsraxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ int LinearScan::BuildNode(GenTree* tree)
// Comparand is preferenced to RAX.
// The remaining two operands can be in any reg other than RAX.

const unsigned nonRaxCandidates = availableIntRegs & ~RBM_RAX;
const regMaskTP nonRaxCandidates = availableIntRegs & ~RBM_RAX;
BuildUse(addr, nonRaxCandidates);
BuildUse(data, varTypeIsByte(tree) ? (nonRaxCandidates & RBM_BYTE_REGS) : nonRaxCandidates);
BuildUse(comparand, RBM_RAX);
Expand Down
Loading

0 comments on commit 761c9a5

Please sign in to comment.