Skip to content
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

Improve register allocation (part 2) #48

Merged
merged 12 commits into from
May 31, 2024
Merged
2 changes: 1 addition & 1 deletion src/Tinyrossa-POWER/TRPPC64PSABILinkage.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ TRPPC64PSABILinkage class >> initialize [

{ #category : #accessing }
TRPPC64PSABILinkage >> allocatableRegisters [
^ self preservedRegisters reversed
^ self preservedRegisters reversed , self parameterRegisters reversed
]

{ #category : #'code generation' }
Expand Down
43 changes: 34 additions & 9 deletions src/Tinyrossa-RISCV/TRRV64GCodeEvaluator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,45 @@ TRRV64GCodeEvaluator >> commonMul: node [
] ifFalse:[
child2 constant == -1 ifTrue:[
dstReg := self codegen allocateRegister.
generate sub: dstReg, zero, src1Reg
]]].
generate sub: dstReg, zero, src1Reg
]]].
] ifFalse:[
src2Reg := self evaluate: child2.
src2Reg := self evaluate: child2.
dstReg := self codegen allocateRegister.
node type == Int64 ifTrue:[
generate mul: dstReg, src1Reg , src2Reg
] ifFalse:[
generate mulw: dstReg, src1Reg , src2Reg
].

codegen compilation config stressRA ifTrue: [
"User requested to put more stress on RA (presumably for
RA debugging purposes).

So here we force argument and return value to be in
certain real register."

| real insn deps |

real := t0.
deps := TRRegisterDependencies new.
deps pre addDependency: src1Reg on: real.
deps post addDependency: dstReg on: real.

node type == Int64 ifTrue:[
insn := generate mul: real, real , src2Reg
] ifFalse:[
insn := generate mulw: real, real , src2Reg
].
insn dependencies: deps.
] ifFalse: [
node type == Int64 ifTrue:[
generate mul: dstReg, src1Reg , src2Reg
] ifFalse:[
generate mulw: dstReg, src1Reg , src2Reg
].
].



].

^dstReg

]

{ #category : #'evaluation-helpers' }
Expand Down
2 changes: 2 additions & 0 deletions src/Tinyrossa-RISCV/TRRV64GCodeGenerator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ TRRV64GCodeGenerator >> registerLoad: reg from: sym [

self assert: reg isTRRegister.
self assert: sym isTRAutomaticSymbol.
self assert: sym useCount > 0.
self assert: sym type == Address.

offset := AcDSLSymbol value: sym name.
Expand All @@ -140,6 +141,7 @@ TRRV64GCodeGenerator >> registerStore: reg to: sym [

self assert: reg isTRRegister.
self assert: sym isTRAutomaticSymbol.
self assert: sym useCount > 0.
self assert: sym type == Address.

offset := AcDSLSymbol value: sym name.
Expand Down
4 changes: 2 additions & 2 deletions src/Tinyrossa-RISCV/TRRV64GPSABILinkage.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ TRRV64GPSABILinkage >> allocatableRegisters [
over preserved registers. This might save us a need to spill / reload (preserved)
registers in prologue / epilogue for small methods."

^ self volatileRegisters , self preservedRegisters
^ self volatileRegisters , (self parameterRegisters reversed) , self preservedRegisters
] ifFalse:[
"For non-leaf methods we prefer preserved registers over volatile registers.
This might save us a need to spill / reload (volatile) registers at call
instructions for small functions."

^ self preservedRegisters , self volatileRegisters
^ self preservedRegisters , self volatileRegisters , (self parameterRegisters reversed)
]
]

Expand Down
4 changes: 3 additions & 1 deletion src/Tinyrossa-Tests/TRCompilationTestCase.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ TRCompilationTestCase >> int64Values [
{ #category : #accessing }
TRCompilationTestCase >> parametersIterator [
^ super parametersIterator ,
(self parameter: #target values: { self target })
(self parameter: #target values: { self target }),
(self parameter: #stressRA values: { true . false })
]

{ #category : #running }
Expand All @@ -67,6 +68,7 @@ TRCompilationTestCase >> setUp [
target := testParameters at:#target.

compilation := TRCompilation forTarget: target.
compilation config stressRA: (testParameters at: #stressRA).
shell := TRCompilationTestShell forCompilation: compilation.
]

Expand Down
5 changes: 5 additions & 0 deletions src/Tinyrossa/TRMemoryReference.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Class {
#name : #TRMemoryReference,
#superclass : #AcDSLMemRef,
#category : #'Tinyrossa-Codegen'
}
10 changes: 10 additions & 0 deletions src/Tinyrossa/TRRealRegister.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ TRRealRegister class >> value: value kind: kind [
^ self basicNew initializeWithValue: value kind: kind
]

{ #category : #arithmetic }
TRRealRegister >> + offset [
^ TRMemoryReference base: self offset: offset asAcDSLOperand
]

{ #category : #arithmetic }
TRRealRegister >> - offset [
^ TRMemoryReference base: self offset: offset negated asAcDSLOperand
]

{ #category : #accessing }
TRRealRegister >> allocation [
^ self
Expand Down
17 changes: 13 additions & 4 deletions src/Tinyrossa/TRRegisterDependency.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,22 @@ TRRegisterDependency >> initializeWithVirtual: aTRVirtualRegister real: aTRRealR
]

{ #category : #testing }
TRRegisterDependency >> isDependency [
^ vreg notNil
TRRegisterDependency >> isTrash [
^ vreg isNil
]

{ #category : #testing }
TRRegisterDependency >> isTrash [
^ vreg isNil
TRRegisterDependency >> isUnsatisfiedDependency [
"Return true, if
(1) this dependency express dependency on
real register (a value of virtual register has to be
in specified real register)
AND
(ii) this dependecy is not satisfied, that is
the virtual register is allocated a different register
than required real register"

^ vreg notNil and: [ vreg allocation ~~ rreg ]
]

{ #category : #'printing & storing' }
Expand Down
Loading
Loading