-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Arm64: Implement VectorTableLookup/VectorTableLookupExtension intrinsinsic + Consecutive registers support #80297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 46 commits
c92fbdf
bee0f8c
426f68a
83eb54c
d06c4a2
99adc17
7b10969
87f66f7
98e7bd2
786e350
e0a82b3
47848b0
25a738d
e492829
385abf1
2f4a4e3
8d3744b
8d66d45
85d90f5
0a0faed
036a273
791563a
db6036b
fdc94ed
cf84fda
06a78d4
2afe249
a086ab7
450a08d
5bb9302
8027c5a
6b1ba8a
723477b
c6e77e4
5696a6e
a9e1a7a
2617b77
2d4fd5c
6a21205
c6d338f
db4f846
bce8c5a
3d15fcb
75f142b
e4cbad9
96de024
11b345a
4526b41
46f0abd
6ef7c68
b0b6a5e
0197b73
2734023
1cb22d0
6e30b3a
721823b
5b9fac5
cb29aee
53b07b5
302d3ba
5e828f1
fc93cc2
78e87cd
60d383e
05f9fc6
b52059e
0721ad4
8a5c696
e64527b
22270c5
f3884fd
f2a1f19
985fe25
ab043fd
13601eb
7bf9105
40aa7c7
1f95637
e7bb069
6ebb12a
2d75291
68cd4d7
7b83053
903c3de
a8ec819
961e9c2
b9d0f15
cbe999f
6665536
2b9f49e
5fec6e1
5371c30
4875925
597e6de
4a1171d
1f124a4
9686773
55071f6
757c682
79e0bd5
a44cf60
5fefae6
2a5e52c
a17b44f
3c390d8
a9995e6
ae2e633
02f8ad2
984c6ee
8fe130a
7f8e77f
090bf26
c91bc77
1591deb
0c4d71f
0c56514
35a7550
ff587ac
dab2121
e94cfcf
ab007d0
5d6cc2d
24e6158
4026aa6
53c91f0
7d168b2
7cffe7a
dd10bbe
b4ea77e
0dc4ea6
6d9e136
f247b3c
e8d3ee5
524d983
289110d
d778833
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1243,6 +1243,10 @@ PhaseStatus LinearScan::doLinearScan() | |
|
|
||
| splitBBNumToTargetBBNumMap = nullptr; | ||
|
|
||
| #ifdef TARGET_ARM64 | ||
| nextConsecutiveRefPositionMap = nullptr; | ||
| #endif | ||
|
|
||
| // This is complicated by the fact that physical registers have refs associated | ||
| // with locations where they are killed (e.g. calls), but we don't want to | ||
| // count these as being touched. | ||
|
|
@@ -2218,6 +2222,8 @@ void LinearScan::checkLastUses(BasicBlock* block) | |
| loc); | ||
| foundDiff = true; | ||
| } | ||
|
|
||
| JITDUMP("++ V%02u in computedLive\n", compiler->lvaTrackedIndexToLclNum(varIndex)); | ||
kunalspathak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| VarSetOps::AddElemD(compiler, computedLive, varIndex); | ||
| } | ||
| else if (currentRefPosition->lastUse) | ||
|
|
@@ -2233,6 +2239,7 @@ void LinearScan::checkLastUses(BasicBlock* block) | |
|
|
||
| if (currentRefPosition->refType == RefTypeDef || currentRefPosition->refType == RefTypeDummyDef) | ||
| { | ||
| JITDUMP("-- V%02u from computedLive\n", compiler->lvaTrackedIndexToLclNum(varIndex)); | ||
kunalspathak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| VarSetOps::RemoveElemD(compiler, computedLive, varIndex); | ||
| } | ||
| } | ||
|
|
@@ -2837,8 +2844,17 @@ regNumber LinearScan::allocateReg(Interval* currentInterval, | |
| } | ||
| } | ||
| } | ||
|
|
||
| assignPhysReg(availablePhysRegRecord, currentInterval); | ||
| refPosition->registerAssignment = foundRegBit; | ||
|
|
||
| #ifdef TARGET_ARM64 | ||
|
||
| if (refPosition->isFirstRefPositionOfConsecutiveRegisters()) | ||
| { | ||
| setNextConsecutiveRegisterAssignment(refPosition, foundRegBit); | ||
| } | ||
| #endif // TARGET_ARM64 | ||
|
|
||
| return foundReg; | ||
| } | ||
|
|
||
|
|
@@ -5297,6 +5313,19 @@ void LinearScan::allocateRegisters() | |
| lastAllocatedRefPosition = ¤tRefPosition; | ||
| regMaskTP copyRegMask = getRegMask(copyReg, currentInterval->registerType); | ||
| regMaskTP assignedRegMask = getRegMask(assignedRegister, currentInterval->registerType); | ||
|
|
||
| #ifdef TARGET_ARM64 | ||
| if (currentRefPosition.needsConsecutive) | ||
| { | ||
| // For consecutive register, it doesn't matter what the assigned register was. | ||
| // We have just assigned it `copyRegMask` and that's the one in-use, and not the | ||
| // one that was assigned previously. | ||
| assignedRegMask = REG_NA; | ||
|
|
||
| // This should never be the first refposition of the series. | ||
| assert(currentRefPosition.regCount == 0); | ||
| } | ||
| #endif | ||
| regsInUseThisLocation |= copyRegMask | assignedRegMask; | ||
| if (currentRefPosition.lastUse) | ||
| { | ||
|
|
@@ -5351,6 +5380,43 @@ void LinearScan::allocateRegisters() | |
| } | ||
| } | ||
|
|
||
| #ifdef TARGET_ARM64 | ||
| if (currentRefPosition.needsConsecutive) | ||
| { | ||
| // For consecutive register, we would like to assign a register (if not already assigned) | ||
| // to the 1st refPosition and the subsequent refPositions will just get the consecutive register. | ||
| if (currentRefPosition.regCount > 0) | ||
| { | ||
| // 1st refPosition of the series... | ||
| if (assignedRegister != REG_NA) | ||
| { | ||
| // For the 1st refPosition, if it already has a register assigned, then just assign | ||
| // subsequent registers to the remaining position and skip the allocation for the | ||
| // 1st refPosition altogether. | ||
|
|
||
| setNextConsecutiveRegisterAssignment(¤tRefPosition, assignedRegBit); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| // remaining refPosition of the series... | ||
| if (assignedRegBit == currentRefPosition.registerAssignment) | ||
| { | ||
| // For the subsequent position, if they already have the subsequent register assigned, then | ||
| // no need to find register to assign. | ||
| allocate = false; | ||
| } | ||
| else | ||
| { | ||
| // If the subsequent refPosition is not assigned to the consecutive register, then reassign the | ||
| // right | ||
| // consecutive register. | ||
| assignedRegister = REG_NA; | ||
| } | ||
| } | ||
| } | ||
| #endif // TARGET_ARM64 | ||
|
|
||
| if (assignedRegister == REG_NA) | ||
| { | ||
| if (currentRefPosition.RegOptional()) | ||
|
|
@@ -11942,7 +12008,7 @@ regMaskTP LinearScan::RegisterSelection::select(Interval* currentInterval, | |
| reverseSelect = linearScan->doReverseSelect(); | ||
| #endif // DEBUG | ||
|
|
||
| freeCandidates = linearScan->getFreeCandidates(candidates, regType); | ||
| freeCandidates = linearScan->getFreeCandidates(candidates ARM_ARG(regType)); | ||
|
|
||
| // If no free candidates, then double check if refPosition is an actual ref. | ||
| if (freeCandidates == RBM_NONE) | ||
|
|
||
| Original file line number | Diff line number | Diff line change | |||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1179,10 +1179,15 @@ class LinearScan : public LinearScanInterface | ||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| void spillGCRefs(RefPosition* killRefPosition); | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| /***************************************************************************** | |||||||||||||||||||||||||||||
| * Register selection | |||||||||||||||||||||||||||||
| ****************************************************************************/ | |||||||||||||||||||||||||||||
| regMaskTP getFreeCandidates(regMaskTP candidates, var_types regType) | |||||||||||||||||||||||||||||
| /***************************************************************************** | |||||||||||||||||||||||||||||
| * Register selection | |||||||||||||||||||||||||||||
| ****************************************************************************/ | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| #if defined(TARGET_ARM64) | |||||||||||||||||||||||||||||
| void setNextConsecutiveRegisterAssignment(RefPosition* firstRefPosition, regMaskTP firstRegAssigned); | |||||||||||||||||||||||||||||
| #endif // TARGET_ARM64 | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| regMaskTP getFreeCandidates(regMaskTP candidates ARM_ARG(var_types regType)) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| regMaskTP result = candidates & m_AvailableRegs; | |||||||||||||||||||||||||||||
| #ifdef TARGET_ARM | |||||||||||||||||||||||||||||
|
|
@@ -1354,6 +1359,21 @@ class LinearScan : public LinearScanInterface | ||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| regNumber getTempRegForResolution(BasicBlock* fromBlock, BasicBlock* toBlock, var_types type); | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| #ifdef TARGET_ARM64 | |||||||||||||||||||||||||||||
| typedef JitHashTable<RefPosition*, JitPtrKeyFuncs<RefPosition>, RefPosition*> NextConsecutiveRefPositionsMap; | |||||||||||||||||||||||||||||
| NextConsecutiveRefPositionsMap* nextConsecutiveRefPositionMap; | |||||||||||||||||||||||||||||
| NextConsecutiveRefPositionsMap* getNextConsecutiveRefPositionsMap() | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| if (nextConsecutiveRefPositionMap == nullptr) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| nextConsecutiveRefPositionMap = | |||||||||||||||||||||||||||||
| new (getAllocator(compiler)) NextConsecutiveRefPositionsMap(getAllocator(compiler)); | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| return nextConsecutiveRefPositionMap; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| RefPosition* getNextConsecutiveRefPosition(RefPosition* refPosition); | |||||||||||||||||||||||||||||
| #endif | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| #ifdef DEBUG | |||||||||||||||||||||||||||||
| void dumpVarToRegMap(VarToRegMap map); | |||||||||||||||||||||||||||||
| void dumpInVarToRegMap(BasicBlock* block); | |||||||||||||||||||||||||||||
|
|
@@ -2259,6 +2279,14 @@ class RefPosition | ||||||||||||||||||||||||||||
| // would be 0..MAX_RET_REG_COUNT-1. | |||||||||||||||||||||||||||||
| unsigned char multiRegIdx : 2; | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| #ifdef TARGET_ARM64 | |||||||||||||||||||||||||||||
| // If this refposition needs consecutive register assignment | |||||||||||||||||||||||||||||
| bool needsConsecutive; | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| // How many consecutive registers does this and subsequent refPositions need | |||||||||||||||||||||||||||||
| unsigned char regCount : 3; | |||||||||||||||||||||||||||||
| #endif // TARGET_ARM64 | |||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the impact on the size of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. None. Before and after they remain 48 bytes.
|
|||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| // Last Use - this may be true for multiple RefPositions in the same Interval | |||||||||||||||||||||||||||||
| unsigned char lastUse : 1; | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
|
|
@@ -2344,6 +2372,10 @@ class RefPosition | ||||||||||||||||||||||||||||
| , registerAssignment(RBM_NONE) | |||||||||||||||||||||||||||||
| , refType(refType) | |||||||||||||||||||||||||||||
| , multiRegIdx(0) | |||||||||||||||||||||||||||||
| #ifdef TARGET_ARM64 | |||||||||||||||||||||||||||||
| , needsConsecutive(false) | |||||||||||||||||||||||||||||
| , regCount(0) | |||||||||||||||||||||||||||||
| #endif | |||||||||||||||||||||||||||||
| , lastUse(false) | |||||||||||||||||||||||||||||
| , reload(false) | |||||||||||||||||||||||||||||
| , spillAfter(false) | |||||||||||||||||||||||||||||
|
|
@@ -2497,6 +2529,19 @@ class RefPosition | ||||||||||||||||||||||||||||
| return (isFixedRefOfRegMask(genRegMask(regNum))); | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| #ifdef TARGET_ARM64 | |||||||||||||||||||||||||||||
| /// For consecutive registers, returns true if this RefPosition is | |||||||||||||||||||||||||||||
| /// the first of the series. | |||||||||||||||||||||||||||||
| FORCEINLINE bool isFirstRefPositionOfConsecutiveRegisters() | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| if (needsConsecutive) | |||||||||||||||||||||||||||||
| { | |||||||||||||||||||||||||||||
| return regCount != 0; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| return false; | |||||||||||||||||||||||||||||
| } | |||||||||||||||||||||||||||||
| #endif // TARGET_ARM64 | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
| #ifdef DEBUG | |||||||||||||||||||||||||||||
| // operator= copies everything except 'rpNum', which must remain unique | |||||||||||||||||||||||||||||
| RefPosition& operator=(const RefPosition& rp) | |||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.