Skip to content

Commit

Permalink
Add high field
Browse files Browse the repository at this point in the history
  • Loading branch information
kunalspathak committed May 24, 2024
1 parent eb4515d commit 95abd7c
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 30 deletions.
42 changes: 34 additions & 8 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
// Assumptions:
// The mask contains one and only one register.

inline regNumber genRegNumFromMask(regMaskTP mask)
inline regNumber genRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

Expand All @@ -947,6 +947,27 @@ inline regNumber genRegNumFromMask(regMaskTP mask)
return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
//

inline regNumber genFirstRegNumFromMask(const regMaskTP& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
Expand All @@ -964,34 +985,39 @@ inline regNumber genFirstRegNumFromMaskAndToggle(regMaskTP& mask)

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);
regNumber regNum = (regNumber)genFirstRegNumFromMask(mask);

mask ^= genRegMask(regNum);
mask ^= regNum;

return regNum;
}

//------------------------------------------------------------------------------
// genFirstRegNumFromMask : Maps first bit set in the register mask to a register number.
//
// genFirstRegNumFromMaskAndToggle : Maps first bit set in the register mask to a
// register number and also toggle the bit in the `mask`.
// Arguments:
// mask - the register mask
//
// Return Value:
// The number of the first register contained in the mask.
// The number of the first register contained in the mask and updates the `mask` to toggle
// the bit.
//

inline regNumber genFirstRegNumFromMask(regMaskTP mask)
inline regNumber genFirstRegNumFromMaskAndToggle(SingleTypeRegSet& mask)
{
assert(mask.IsNonEmpty()); // Must have one bit set, so can't have a mask of zero
assert(mask != RBM_NONE); // Must have one bit set, so can't have a mask of zero

/* Convert the mask to a register number */

regNumber regNum = (regNumber)BitScanForward(mask);

mask ^= genRegMask(regNum);

return regNum;
}



/*****************************************************************************
*
* Return the size in bytes of the given type.
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4022,7 +4022,7 @@ void LinearScan::processKills(RefPosition* killRefPosition)
{
RefPosition* nextKill = killRefPosition->nextRefPosition;

regMaskTP killedRegs = killRefPosition->registerAssignment;
SingleTypeRegSet killedRegs = killRefPosition->registerAssignment;
while (killedRegs != RBM_NONE)
{
regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
Expand Down Expand Up @@ -4064,7 +4064,7 @@ void LinearScan::spillGCRefs(RefPosition* killRefPosition)
{
// For each physical register that can hold a GC type,
// if it is occupied by an interval of a GC type, spill that interval.
regMaskTP candidateRegs = killRefPosition->registerAssignment;
SingleTypeRegSet candidateRegs = killRefPosition->registerAssignment;
INDEBUG(bool killedRegs = false);
while (candidateRegs != RBM_NONE)
{
Expand Down Expand Up @@ -4157,7 +4157,7 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar
{
// If we're rotating the register locations at block boundaries, try to use
// the next higher register number of the appropriate register type.
regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
SingleTypeRegSet candidateRegs = allRegs(interval->registerType) & availableRegs.GetRegSetForType(interval->registerType);
regNumber firstReg = REG_NA;
regNumber newReg = REG_NA;
while (candidateRegs != RBM_NONE)
Expand Down Expand Up @@ -12182,7 +12182,7 @@ void LinearScan::verifyFinalAllocation()
// However, we will assert that, at resolution time, no registers contain GC refs.
{
DBEXEC(VERBOSE, printf(" "));
regMaskTP candidateRegs = currentRefPosition.registerAssignment;
SingleTypeRegSet candidateRegs = currentRefPosition.registerAssignment;
while (candidateRegs != RBM_NONE)
{
regNumber nextReg = genFirstRegNumFromMaskAndToggle(candidateRegs);
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/lsrabuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2825,6 +2825,9 @@ void LinearScan::buildIntervals()
availableRegCount = REG_INT_COUNT;
}

#ifdef HAS_MORE_THAN_64_REGISTERS
actualRegistersMask = regMaskTP(~RBM_NONE);
#else
if (availableRegCount < (sizeof(regMaskTP) * 8))
{
// Mask out the bits that are between 64 ~ availableRegCount
Expand All @@ -2834,6 +2837,7 @@ void LinearScan::buildIntervals()
{
actualRegistersMask = ~RBM_NONE;
}
#endif

#ifdef DEBUG
// Make sure we don't have any blocks that were not visited
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/regset.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class RegSet
bool rsRegsModified(regMaskTP mask) const
{
assert(rsModifiedRegsMaskInitialized);
return (rsModifiedRegsMask & mask) != 0;
return (rsModifiedRegsMask & mask).IsNonEmpty();
}

void verifyRegUsed(regNumber reg);
Expand Down
49 changes: 32 additions & 17 deletions src/coreclr/jit/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,16 +229,28 @@ typedef uint64_t regMaskSmall;
#define REG_MASK_ALL_FMT "%016llX"
#endif

#ifdef TARGET_ARM64
#define HAS_MORE_THAN_64_REGISTERS 1
#define MORE_THAN_64_REGISTERS(x) x
#else
#define MORE_THAN_64_REGISTERS(x)
#endif // TARGET_ARM64

typedef regMaskSmall SingleTypeRegSet;
inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

struct regMaskTP
{
private:
regMaskSmall low;
MORE_THAN_64_REGISTERS(regMaskSmall high);

public:
constexpr regMaskTP(regMaskSmall regMask)
regMaskTP(regMaskSmall regMask)
: low(regMask)
{

}

regMaskTP()
Expand Down Expand Up @@ -278,12 +290,12 @@ struct regMaskTP
return low;
}

bool IsEmpty()
bool IsEmpty() const
{
return low == RBM_NONE;
}

bool IsNonEmpty()
bool IsNonEmpty() const
{
return !IsEmpty();
}
Expand All @@ -298,48 +310,54 @@ struct regMaskTP
bool IsRegNumInMask(regNumber reg);
};

static regMaskTP operator^(regMaskTP first, regMaskTP second)
static regMaskTP operator^(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() ^ second.getLow());
return result;
}

static regMaskTP operator&(regMaskTP first, regMaskTP second)
static regMaskTP operator&(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() & second.getLow());
return result;
}

static regMaskTP operator|(regMaskTP first, regMaskTP second)
static regMaskTP operator|(const regMaskTP& first, const regMaskTP& second)
{
regMaskTP result(first.getLow() | second.getLow());
return result;
}

static regMaskTP& operator|=(regMaskTP& first, regMaskTP second)
static regMaskTP& operator|=(regMaskTP& first, const regMaskTP& second)
{
first = first | second;
return first;
}

static regMaskTP& operator^=(regMaskTP& first, regMaskTP second)
static regMaskTP& operator^=(regMaskTP& first, const regMaskTP& second)
{
first = first ^ second;
return first;
}

static regMaskTP& operator&=(regMaskTP& first, regMaskTP second)
static regMaskTP& operator^=(regMaskTP& first, const regNumber reg)
{
first = first ^ genRegMask(reg);
return first;
}

static regMaskTP& operator&=(regMaskTP& first, const regMaskTP& second)
{
first = first & second;
return first;
}

static bool operator==(regMaskTP first, regMaskTP second)
static bool operator==(const regMaskTP& first, const regMaskTP& second)
{
return (first.getLow() == second.getLow());
}

static bool operator!=(regMaskTP first, regMaskTP second)
static bool operator!=(const regMaskTP& first, const regMaskTP& second)
{
return !(first == second);
}
Expand Down Expand Up @@ -375,18 +393,18 @@ static regMaskTP& operator<<=(regMaskTP& first, const int b)
}
#endif

static regMaskTP operator~(regMaskTP first)
static regMaskTP operator~(const regMaskTP& first)
{
regMaskTP result(~first.getLow());
return result;
}

static uint32_t PopCount(regMaskTP value)
static uint32_t PopCount(const regMaskTP& value)
{
return BitOperations::PopCount(value.getLow());
}

static uint32_t BitScanForward(regMaskTP mask)
static uint32_t BitScanForward(const regMaskTP& mask)
{
return BitOperations::BitScanForward(mask.getLow());
}
Expand Down Expand Up @@ -508,9 +526,6 @@ inline bool isByteReg(regNumber reg)
}
#endif

inline SingleTypeRegSet genRegMask(regNumber reg);
inline SingleTypeRegSet genRegMaskFloat(regNumber reg ARM_ARG(var_types type = TYP_DOUBLE));

/*****************************************************************************
* Return true if the register number is valid
*/
Expand Down

0 comments on commit 95abd7c

Please sign in to comment.