Skip to content

Commit

Permalink
RLSRA: correctly update register dependencies when splitting intervals
Browse files Browse the repository at this point in the history
This commit fixes horrible bug in RSLRA causing arguments not being
moved to argument registers when the original interval was split.

This was because when updating instructions to use newly create v-reg
for just-split interval, register dependencies were not updated,
referring to original v-reg.

To fix this problem, this commit introduces mew method -
`#replaceVirtualRegistersUsing:` - to perform v-reg replacements which
updates not only register used by the instruction, but also those
referred-to in dependencies (and possibly other Tinyrossa-specific
metadata attached to an instruction).
  • Loading branch information
janvrany committed Jun 18, 2024
1 parent 1ac545a commit 794071f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
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 794071f

Please sign in to comment.