Skip to content

Commit a38460a

Browse files
committed
change the structure of regMaskTP for performance
1 parent 4fe1caa commit a38460a

File tree

3 files changed

+79
-13
lines changed

3 files changed

+79
-13
lines changed

src/coreclr/jit/lsrabuild.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2847,7 +2847,7 @@ void LinearScan::buildIntervals()
28472847
#endif
28482848
else
28492849
{
2850-
actualRegistersMask = regMaskTP(~RBM_NONE, ~RBM_NONE);
2850+
actualRegistersMask = regMaskTP(~RBM_NONE, ~0);
28512851
}
28522852

28532853
#ifdef DEBUG

src/coreclr/jit/regMaskTPOps.cpp

+45-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,36 @@
55

66
struct regMaskTP;
77

8+
9+
//------------------------------------------------------------------------
10+
// encodeForRegisterIndex: Shifts the high-32 bits of float to low-32 bits
11+
// and return. For gpr and predicate registers, it returns the same value.
12+
//
13+
// Parameters:
14+
// index - Register type index
15+
// value - value to encode
16+
//
17+
/* static */ RegSet32 regMaskTP::encodeForRegisterIndex(int index, regMaskSmall value)
18+
{
19+
int shiftAmount = 32 * (index == 1);
20+
return (RegSet32)(value >> shiftAmount);
21+
}
22+
23+
//------------------------------------------------------------------------
24+
// decodeForRegisterIndex: Shifts the low-32 bits of float to high-32 bits
25+
// and return. For gpr and predicate registers, it returns the same value.
26+
//
27+
// Parameters:
28+
// index - Register type index
29+
// value - value to encode
30+
//
31+
/* static */ regMaskSmall regMaskTP::decodeForRegisterIndex(int index, RegSet32 value)
32+
{
33+
int shiftAmount = 32 * (index == 1);
34+
return ((regMaskSmall)value << shiftAmount);
35+
}
36+
37+
838
//------------------------------------------------------------------------
939
// RemoveRegNumFromMask: Removes `reg` from the mask
1040
//
@@ -13,7 +43,13 @@ struct regMaskTP;
1343
//
1444
void regMaskTP::RemoveRegNumFromMask(regNumber reg)
1545
{
16-
low &= ~genSingleTypeRegMask(reg);
46+
SingleTypeRegSet value = genSingleTypeRegMask(reg);
47+
#ifdef HAS_MORE_THAN_64_REGISTERS
48+
int index = getRegisterTypeIndex(reg);
49+
_registers[index] &= ~encodeForRegisterIndex(index, value);
50+
#else
51+
low &= ~value;
52+
#endif
1753
}
1854

1955
//------------------------------------------------------------------------
@@ -24,10 +60,16 @@ void regMaskTP::RemoveRegNumFromMask(regNumber reg)
2460
//
2561
bool regMaskTP::IsRegNumInMask(regNumber reg)
2662
{
27-
return (low & genRegMask(reg)) != 0;
63+
SingleTypeRegSet value = genSingleTypeRegMask(reg);
64+
#ifdef HAS_MORE_THAN_64_REGISTERS
65+
int index = getRegisterTypeIndex(reg);
66+
return (_registers[index] & encodeForRegisterIndex(index, value)) != RBM_NONE;
67+
#else
68+
return (low & value) != RBM_NONE;
69+
#endif
2870
}
2971

30-
/* static */ const int regMaskTP::getRegisterTypeIndex(regNumber reg)
72+
/* static */ int regMaskTP::getRegisterTypeIndex(regNumber reg)
3173
{
3274
static const BYTE _registerTypeIndex[] = {
3375
#ifdef TARGET_ARM64

src/coreclr/jit/target.h

+33-9
Original file line numberDiff line numberDiff line change
@@ -236,21 +236,46 @@ typedef uint64_t regMaskSmall;
236236
#define MORE_THAN_64_REGISTERS_ARG(x)
237237
#endif // TARGET_ARM64
238238

239+
//TODO: Rename regMaskSmall as RegSet64 (at least for 64-bit)
239240
typedef regMaskSmall SingleTypeRegSet;
241+
typedef unsigned RegSet32;
240242
inline SingleTypeRegSet genSingleTypeRegMask(regNumber reg);
241243

242244
struct regMaskTP
243245
{
244246
private:
245-
regMaskSmall low;
246247
#ifdef HAS_MORE_THAN_64_REGISTERS
247-
regMaskSmall high;
248+
union
249+
{
250+
RegSet32 _registers[3];
251+
struct
252+
{
253+
union
254+
{
255+
// Represents combined registers bitset including gpr/float
256+
regMaskSmall low;
257+
struct
258+
{
259+
RegSet32 gprRegs;
260+
RegSet32 floatRegs;
261+
};
262+
};
263+
RegSet32 high;
264+
};
265+
};
266+
#else
267+
// Represents combined registers bitset including gpr/float and on some platforms
268+
// mask or predicate registers
269+
regMaskSmall low;
248270
#endif
249-
inline static const int getRegisterTypeIndex(regNumber reg);
271+
272+
FORCEINLINE static int getRegisterTypeIndex(regNumber reg);
273+
FORCEINLINE static RegSet32 encodeForRegisterIndex(int index, regMaskSmall value);
274+
FORCEINLINE static regMaskSmall decodeForRegisterIndex(int index, RegSet32 value);
250275

251276
public:
252277

253-
regMaskTP(regMaskSmall lowMask, regMaskSmall highMask)
278+
regMaskTP(regMaskSmall lowMask, RegSet32 highMask)
254279
: low(lowMask)
255280
#ifdef HAS_MORE_THAN_64_REGISTERS
256281
, high(highMask)
@@ -308,12 +333,15 @@ struct regMaskTP
308333
}
309334

310335
#ifdef HAS_MORE_THAN_64_REGISTERS
311-
regMaskSmall getHigh() const
336+
RegSet32 getHigh() const
312337
{
313338
return high;
314339
}
315340
#endif
316341

342+
void RemoveRegNumFromMask(regNumber reg);
343+
bool IsRegNumInMask(regNumber reg);
344+
317345
bool IsEmpty() const
318346
{
319347
return low == RBM_NONE;
@@ -344,10 +372,6 @@ struct regMaskTP
344372
return getLow();
345373
}
346374

347-
void RemoveRegNumFromMask(regNumber reg);
348-
349-
bool IsRegNumInMask(regNumber reg);
350-
351375
void operator|=(const regMaskTP& second)
352376
{
353377
low |= second.getLow();

0 commit comments

Comments
 (0)