Skip to content

Commit

Permalink
Merge pull request #49 from janvrany/pr/fix-bug-in-RLSRA-live-interva…
Browse files Browse the repository at this point in the history
…l-splitting

RLSRA: correctly update register dependencies when splitting intervals
  • Loading branch information
janvrany authored Jun 18, 2024
2 parents 1ac545a + e3543cb commit 8caa63f
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 8 deletions.
20 changes: 20 additions & 0 deletions src/Tinyrossa/AcInstruction.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,23 @@ AcInstruction >> node [
AcInstruction >> node: aTRILNode [
^ self annotationAddOrReplace: aTRILNode
]

{ #category : #'*Tinyrossa' }
AcInstruction >> replaceVirtualRegistersUsing: replacementMap [
"Replace all references according to `replacementMap` and return
new instruction.
`replacementMap` should be a dictionary mapping old v-register NAME
to new v-register ITSELF. That is, keys are strings, values are v-regs.
This is similar to `#inEnvironment:` except it also updates register
dependencies (and other Tinyrossa-specific metadata that may come
in future).
Implementation note: using strings as keys instead of original vreg
this looks silly, but here we're limited by `Z3Node >> #inEnvironment:`
which works with either Z3Nodes or Strings a keys.
"

"Nothing to do here, overriden in ProcessorInstruction"
]
19 changes: 19 additions & 0 deletions src/Tinyrossa/ProcessorInstruction.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Extension { #name : #ProcessorInstruction }

{ #category : #'*Tinyrossa' }
ProcessorInstruction >> replaceVirtualRegistersUsing: replacementMap [
| updated |

replacementMap keysAndValuesDo: [ :name :vreg |
self assert: name isString.
self assert: vreg isTRVirtualRegister
].

replacementMap isEmpty ifTrue: [ ^ self ].

updated := self inEnvironment: replacementMap.
self dependencies notNil ifTrue: [
updated dependencies: (self dependencies replaceVirtualRegistersUsing: replacementMap)
].
^ updated
]
30 changes: 25 additions & 5 deletions src/Tinyrossa/TRRegisterDependencies.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,22 @@ Class {

{ #category : #'instance creation' }
TRRegisterDependencies class >> new [
"return an initialized instance"
^ self pre: TRRegisterDependencyGroup new post: TRRegisterDependencyGroup new
]

{ #category : #'instance creation' }
TRRegisterDependencies class >> post: postDependencyGroup [
^ self pre: TRRegisterDependencyGroup new post: postDependencyGroup
]

{ #category : #'instance creation' }
TRRegisterDependencies class >> pre: preDependencyGroup [
^ self pre: preDependencyGroup post: TRRegisterDependencyGroup new
]

^ self basicNew initialize.
{ #category : #'instance creation' }
TRRegisterDependencies class >> pre: pre post: post [
^ self basicNew initializeWithPre: pre post: post.
]

{ #category : #'adding & removing' }
Expand All @@ -77,9 +90,9 @@ TRRegisterDependencies >> addPreDependencyOf: vreg on: rreg [
]

{ #category : #initialization }
TRRegisterDependencies >> initialize [
pre := TRRegisterDependencyGroup new.
post := TRRegisterDependencyGroup new.
TRRegisterDependencies >> initializeWithPre: preDependencyGroup post: postDependencyGroup [
pre := preDependencyGroup.
post := postDependencyGroup
]

{ #category : #testing }
Expand All @@ -101,3 +114,10 @@ TRRegisterDependencies >> post [
TRRegisterDependencies >> pre [
^ pre
]

{ #category : #utilities }
TRRegisterDependencies >> replaceVirtualRegistersUsing: replacementMap [
^ self class
pre: (pre replaceVirtualRegistersUsing: replacementMap)
post: (post replaceVirtualRegistersUsing: replacementMap)
]
15 changes: 15 additions & 0 deletions src/Tinyrossa/TRRegisterDependencyGroup.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,18 @@ TRRegisterDependencyGroup >> addTrashed: rReg [

self add: (TRRegisterDependency virtual: nil real: rReg).
]

{ #category : #utilities }
TRRegisterDependencyGroup >> replaceVirtualRegistersUsing: replacementMap [
(self anySatisfy: [:dep | dep vreg notNil and:[replacementMap includesKey: dep vreg name] ]) ifTrue: [
^ self collect: [ :dep |
(dep vreg notNil and:[replacementMap includesKey: dep vreg name]) ifTrue: [
TRRegisterDependency virtual: (replacementMap at: dep vreg name) real: dep rreg
] ifFalse: [
dep
].
].
] ifFalse: [
^ self
].
]
6 changes: 3 additions & 3 deletions src/Tinyrossa/TRReverseLinearScanRegisterAllocator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -469,14 +469,14 @@ TRReverseLinearScanRegisterAllocator >> splitRegister: interval at: insnIndex [
"Create new interval representing the first part of original interval
up to current position. While walking definitions and uses,
update instructions to use new virtual registers"
regmap := Dictionary new at: interval register name put: before register name; yourself.
regmap := Dictionary new at: interval register name put: before register; yourself.
interval defdDo: [ :i |
before defdAt:i.
instructions at: i put: ((instructions at: i) inEnvironment: regmap).
instructions at: i put: ((instructions at: i) replaceVirtualRegistersUsing: regmap).
].
interval usedDo: [:i | i <= insnIndex ifTrue: [
before usedAt:i.
instructions at: i put: ((instructions at: i) inEnvironment: regmap).
instructions at: i put: ((instructions at: i) replaceVirtualRegistersUsing: regmap).
]].

"Allocate spill slot for being-splitted `interval`. Insert reload
Expand Down

0 comments on commit 8caa63f

Please sign in to comment.