From ded51d86b9ccf7f38695954aef5899769b8a4801 Mon Sep 17 00:00:00 2001 From: Jan Vrany Date: Fri, 2 Feb 2024 14:37:56 +0000 Subject: [PATCH 1/5] Remove duplicated load of LibUnix on Pharo --- pharo/GNUmakefile | 1 - 1 file changed, 1 deletion(-) diff --git a/pharo/GNUmakefile b/pharo/GNUmakefile index b685cea..c46634c 100644 --- a/pharo/GNUmakefile +++ b/pharo/GNUmakefile @@ -76,7 +76,6 @@ $(PROJECT).image: ../src/*/*.st $(call pharo-load-local, $@, SmallRSP, $(SMALLRSP_DIR)/src) $(call pharo-load-local, $@, LibUnix, $(PHARO_HACKS_DIR)/src) $(call pharo-load-local, $@, LibCompat, $(PHARO_HACKS_DIR)/src) - $(call pharo-load-local, $@, LibUnix, $(PHARO_HACKS_DIR)/src) $(call pharo-load-local, $@, PTerm, $(PTERM_DIR)) $(call pharo-load-local, $@, LibGDBs, $(LIBGDBS_DIR)/ports/pharo/src-generated) $(call pharo-load-local, $@, Tinyrossa, ../src) From 819227bfe9975833a46d5d8cc2b9e83706828f7a Mon Sep 17 00:00:00 2001 From: Jan Vrany Date: Fri, 1 Mar 2024 20:55:53 +0000 Subject: [PATCH 2/5] Implement new optimization pass to turn `?mul` to `?shl` This commit introduces new optimization pass - `TRILXmul2Xshl` - which replaces ?mul ?const with ?shl ?const > While this may not have real impact on modern CPUs, it serves as an example of how to do simple TRIL-to-TRIL optimizations. It is *not* included in default optimization pipeline as of now (and may never be). --- .../TRILXmul2XshlTests.class.st | 51 +++++++++++++++++++ src/Tinyrossa/TRILOpcode.class.st | 15 ++++++ src/Tinyrossa/TRILOpcodeTables.class.st | 12 +++++ src/Tinyrossa/TRILXmul2Xshl.class.st | 23 +++++++++ 4 files changed, 101 insertions(+) create mode 100644 src/Tinyrossa-Tests/TRILXmul2XshlTests.class.st create mode 100644 src/Tinyrossa/TRILXmul2Xshl.class.st diff --git a/src/Tinyrossa-Tests/TRILXmul2XshlTests.class.st b/src/Tinyrossa-Tests/TRILXmul2XshlTests.class.st new file mode 100644 index 0000000..6e85ddd --- /dev/null +++ b/src/Tinyrossa-Tests/TRILXmul2XshlTests.class.st @@ -0,0 +1,51 @@ +Class { + #name : #TRILXmul2XshlTests, + #superclass : #TRILTestCase, + #pools : [ + 'TRDataTypes', + 'TRILOpcodes' + ], + #category : #'Tinyrossa-Tests' +} + +{ #category : #running } +TRILXmul2XshlTests >> setUp [ + super setUp. + compilation config optimizationPasses: { TRILXmul2Xshl }. +] + +{ #category : #tests } +TRILXmul2XshlTests >> test_imul2ishl_01 [ + | b | + + b := TRILFunctionBuilder forCompilation: compilation. + b defineName: testSelector type: Int32. + b defineParameter: 'x' type: Int32. + b ireturn: { + b imul: { + b iload: 'x' . + b iconst: 2 } }. + + compilation optimize. + + self assert: compilation cfg treetops second child1 opcode = ishl. + self assert: compilation cfg treetops second child1 child2 constant = 1. +] + +{ #category : #tests } +TRILXmul2XshlTests >> test_imul2ishl_02 [ + | b | + + b := TRILFunctionBuilder forCompilation: compilation. + b defineName: testSelector type: Int32. + b defineParameter: 'x' type: Int32. + b ireturn: { + b imul: { + b iload: 'x' . + b iconst: 3 } }. + + compilation optimize. + + self assert: compilation cfg treetops second child1 opcode = imul. + self assert: compilation cfg treetops second child1 child2 constant = 3. +] diff --git a/src/Tinyrossa/TRILOpcode.class.st b/src/Tinyrossa/TRILOpcode.class.st index 7dfa978..5652bfa 100644 --- a/src/Tinyrossa/TRILOpcode.class.st +++ b/src/Tinyrossa/TRILOpcode.class.st @@ -234,6 +234,21 @@ TRILOpcode >> isReturn [ ^ props1 anyMask: Return ] +{ #category : #testing } +TRILOpcode >> isShift [ + ^ props1 anyMask: LeftShift | RightShift +] + +{ #category : #testing } +TRILOpcode >> isShiftLeft [ + ^ props1 anyMask: LeftShift +] + +{ #category : #testing } +TRILOpcode >> isShiftRight [ + ^ props1 anyMask: RightShift +] + { #category : #testing } TRILOpcode >> isStore [ ^ props1 anyMask: Store diff --git a/src/Tinyrossa/TRILOpcodeTables.class.st b/src/Tinyrossa/TRILOpcodeTables.class.st index 7072086..277b947 100644 --- a/src/Tinyrossa/TRILOpcodeTables.class.st +++ b/src/Tinyrossa/TRILOpcodeTables.class.st @@ -6,6 +6,7 @@ Class { 'CompareOpcodes', 'ConstOpcodes', 'LoadOpcodes', + 'ShiftLeftOpcodes', 'StoreOpcodes' ], #pools : [ @@ -189,4 +190,15 @@ TRILOpcodeTables class >> initialize [ Rem . invalid . }. }. + + ShiftLeftOpcodes := SmallDictionary newFromPairs: { + Int8 . bshl . + Int16 . sshl . + Int32 . ishl . + Int64 . lshl . + Address . invalid . + Float . invalid . + Double . invalid . + Void . invalid . + }. ] diff --git a/src/Tinyrossa/TRILXmul2Xshl.class.st b/src/Tinyrossa/TRILXmul2Xshl.class.st new file mode 100644 index 0000000..c617854 --- /dev/null +++ b/src/Tinyrossa/TRILXmul2Xshl.class.st @@ -0,0 +1,23 @@ +Class { + #name : #TRILXmul2Xshl, + #superclass : #TRILRewritingPass, + #pools : [ + 'TRILOpcodes' + ], + #category : #'Tinyrossa-Optimizer' +} + +{ #category : #rewriting } +TRILXmul2Xshl >> rewrite: node [ + node opcode isMul ifFalse:[ ^ node ]. + node opcode type isIntegerType ifFalse:[ ^ node ]. + node child2 opcode isLoadConst ifFalse: [ ^ node ]. + node child2 constant isPowerOfTwo ifFalse: [ ^ node ]. + + ^TRILNode opcode: ishl children: + { node child1 . + TRILNode opcode: iconst constant: (node child2 constant log:2) asInteger } + + + +] From c44390f50e42492a346d9203214c50f373de67fd Mon Sep 17 00:00:00 2001 From: Jan Vrany Date: Fri, 23 Feb 2024 22:12:33 +0000 Subject: [PATCH 3/5] Introduce `TRCodeGeneratorBase`: a base superclass for code generators --- src/Tinyrossa/TRCodeGenerator.class.st | 36 +---------------- src/Tinyrossa/TRCodeGeneratorBase.class.st | 47 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 34 deletions(-) create mode 100644 src/Tinyrossa/TRCodeGeneratorBase.class.st diff --git a/src/Tinyrossa/TRCodeGenerator.class.st b/src/Tinyrossa/TRCodeGenerator.class.st index 133666e..e4850d1 100644 --- a/src/Tinyrossa/TRCodeGenerator.class.st +++ b/src/Tinyrossa/TRCodeGenerator.class.st @@ -1,11 +1,9 @@ Class { #name : #TRCodeGenerator, - #superclass : #Object, + #superclass : #TRCodeGeneratorBase, #instVars : [ - 'compilation', 'virtualRegisters', 'linkage', - 'evaluator', 'generate', 'linkRegisterKilled' ], @@ -15,16 +13,6 @@ Class { #category : #'Tinyrossa-Codegen' } -{ #category : #'instance creation' } -TRCodeGenerator class >> forCompilation: aTRCompilation [ - ^ self basicNew initializeWithCompilation: aTRCompilation -] - -{ #category : #'instance creation' } -TRCodeGenerator class >> new [ - self shouldNotImplement. "Use #forCompilation:" -] - { #category : #registers } TRCodeGenerator >> allocateRegister [ ^ self allocateRegister: GPR @@ -62,21 +50,11 @@ TRCodeGenerator >> codeBuffer [ ^ generate memory ] -{ #category : #accessing } -TRCodeGenerator >> compilation [ - ^ compilation -] - { #category : #'instance creation' } TRCodeGenerator >> createAssembler [ ^ self assemblerClass new ] -{ #category : #'instance creation' } -TRCodeGenerator >> createEvaluator [ - ^ self evaluatorClass forCodeGenerator: self -] - { #category : #'instance creation' } TRCodeGenerator >> createLinkage: linkageClass [ ^ linkageClass forCodeGenerator: self @@ -92,16 +70,6 @@ TRCodeGenerator >> cursor: anInteger [ generate cursor: anInteger ] -{ #category : #accessing } -TRCodeGenerator >> evaluator [ - ^ evaluator -] - -{ #category : #'accessing - config' } -TRCodeGenerator >> evaluatorClass [ - ^ self subclassResponsibility -] - { #category : #'code gen-phases' } TRCodeGenerator >> fixupBranches [ compilation isAOT ifTrue: [ @@ -237,7 +205,7 @@ TRCodeGenerator >> generatePrologue [ { #category : #initialization } TRCodeGenerator >> initializeWithCompilation: aTRCompilation [ - compilation := aTRCompilation. + super initializeWithCompilation: aTRCompilation. virtualRegisters := Dictionary new. generate := self createAssembler. evaluator := self createEvaluator. diff --git a/src/Tinyrossa/TRCodeGeneratorBase.class.st b/src/Tinyrossa/TRCodeGeneratorBase.class.st new file mode 100644 index 0000000..48ffb84 --- /dev/null +++ b/src/Tinyrossa/TRCodeGeneratorBase.class.st @@ -0,0 +1,47 @@ +Class { + #name : #TRCodeGeneratorBase, + #superclass : #Object, + #instVars : [ + 'compilation', + 'evaluator' + ], + #pools : [ + 'TRRegisterKinds' + ], + #category : #'Tinyrossa-Codegen' +} + +{ #category : #'instance creation' } +TRCodeGeneratorBase class >> forCompilation: aTRCompilation [ + ^ self basicNew initializeWithCompilation: aTRCompilation +] + +{ #category : #'instance creation' } +TRCodeGeneratorBase class >> new [ + self shouldNotImplement. "Use #forCompilation:" +] + +{ #category : #accessing } +TRCodeGeneratorBase >> compilation [ + ^ compilation +] + +{ #category : #'instance creation' } +TRCodeGeneratorBase >> createEvaluator [ + ^ self evaluatorClass forCodeGenerator: self +] + +{ #category : #accessing } +TRCodeGeneratorBase >> evaluator [ + ^ evaluator +] + +{ #category : #'accessing - config' } +TRCodeGeneratorBase >> evaluatorClass [ + ^ self subclassResponsibility +] + +{ #category : #initialization } +TRCodeGeneratorBase >> initializeWithCompilation: aTRCompilation [ + compilation := aTRCompilation. +] From 2ccbdf9643d75b3bc9072a921bfcc3c617b8b16a Mon Sep 17 00:00:00 2001 From: Jan Vrany Date: Thu, 21 Mar 2024 16:14:18 +0000 Subject: [PATCH 4/5] Fix `TRCompilationTestShellRemoteUsingSSH >> #setUp` --- ...RCompilationTestShellRemoteUsingSSH.class.st | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Tinyrossa-Tests/TRCompilationTestShellRemoteUsingSSH.class.st b/src/Tinyrossa-Tests/TRCompilationTestShellRemoteUsingSSH.class.st index 12dec08..e90ac5b 100644 --- a/src/Tinyrossa-Tests/TRCompilationTestShellRemoteUsingSSH.class.st +++ b/src/Tinyrossa-Tests/TRCompilationTestShellRemoteUsingSSH.class.st @@ -22,13 +22,20 @@ TRCompilationTestShellRemoteUsingSSH >> setUp [ | scpCmd | super setUp. - scpCmd := 'scp ' , debugger pathName , ' ' , self class host , ':/tmp'. + scpCmd := 'scp ' , binary pathName , ' ' , self class host , ':/tmp'. - self assert: (OperatingSystem executeCommand: scpCmd) + self assert: (OSProcess new command: scpCmd) execute description: 'Cannot upload shell'. - target := GDBDebugger new. - target executable: debugger. - target send: 'target extended-remote | ssh -C ', self class host , ' gdbserver - /tmp/' , debugger baseName. + (Smalltalk includesKey: #GDBDebugger) ifTrue:[ + "Use LibGDBs if available..." + + debugger := (Smalltalk at: #GDBDebugger) new. + debugger executable: binary. + target send: 'target extended-remote | ssh -C ', self class host , ' gdbserver - /tmp/' , binary baseName. + ^self + ] ifFalse:[ + self error: 'This shell require libgdbs' + ]. ] From d78196bf2f0dbebb0b82caae3c47cda13e91df4f Mon Sep 17 00:00:00 2001 From: Jan Vrany Date: Fri, 22 Mar 2024 13:30:45 +0000 Subject: [PATCH 5/5] Silence errors (in fact, warnings) when shadowing a variable in tests This commit silence errors produced by Pharo compiler about variables being shadowed. The way Pharo browser is handling it makes it impossible to ignore the warning (one cannot accept). Sigh. --- src/Tinyrossa-Tests/TRCompilationTestCase.class.st | 8 ++++++++ src/Tinyrossa/TRCompilationExamples.class.st | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/Tinyrossa-Tests/TRCompilationTestCase.class.st b/src/Tinyrossa-Tests/TRCompilationTestCase.class.st index 52360d3..422ec90 100644 --- a/src/Tinyrossa-Tests/TRCompilationTestCase.class.st +++ b/src/Tinyrossa-Tests/TRCompilationTestCase.class.st @@ -11,6 +11,14 @@ Class { #category : #'Tinyrossa-Tests' } +{ #category : #accessing } +TRCompilationTestCase class >> compiler [ + Smalltalk isPharo ifTrue:[ + ^super compiler options: #(+ optionSkipSemanticWarnings) + ]. + ^super compiler +] + { #category : #testing } TRCompilationTestCase class >> isAbstract [ ^ self == TRCompilationTestCase diff --git a/src/Tinyrossa/TRCompilationExamples.class.st b/src/Tinyrossa/TRCompilationExamples.class.st index 41b20c8..5cdffef 100644 --- a/src/Tinyrossa/TRCompilationExamples.class.st +++ b/src/Tinyrossa/TRCompilationExamples.class.st @@ -13,6 +13,14 @@ Class { #category : #'Tinyrossa-Compile-Examples' } +{ #category : #accessing } +TRCompilationExamples class >> compiler [ + Smalltalk isPharo ifTrue:[ + ^super compiler options: #(+ optionSkipSemanticWarnings) + ]. + ^super compiler +] + { #category : #accessing } TRCompilationExamples class >> testSelectors [ ^ self selectors select: [ :each | each beginsWith:'example' ]