From 1c995722193b47e246482b6bd06ba722b0e1e445 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Thu, 18 Apr 2024 09:01:41 +0200 Subject: [PATCH 01/33] Draft of stack effect coallescing --- ...DRBytecodeScenarioCompilationTest.class.st | 68 ++++++++++++++ Druid-Tests/DRProductionBytecodeTest.class.st | 1 - Druid-Tests/DruidTestInterpreter.class.st | 35 +++++++ Druid-Tests/DruidTestRTLCompiler.class.st | 92 +++++++++++++++++++ Druid/DRAbstractCompilerCompiler.class.st | 1 - Druid/DRAbstractInstruction.class.st | 7 +- Druid/DRBasicBlock.class.st | 2 +- Druid/DRBytecodeCompilerCompiler.class.st | 13 --- Druid/DRBytecodeIRGenerator.class.st | 6 +- Druid/DRCogitStackCanonicaliser.class.st | 2 +- Druid/DRCogitStackCoallescing.class.st | 73 +++++++++++++++ Druid/DRControlFlowGraph.class.st | 13 ++- Druid/DRIRGenerator.class.st | 13 ++- Druid/DRInstructionFactory.class.st | 8 +- Druid/DRLoadStackValue.class.st | 18 +++- Druid/DRMethodIRGenerator.class.st | 1 + Druid/DRPop.class.st | 26 ++++-- Druid/DRPopMany.class.st | 8 +- Druid/DRPush.class.st | 25 +++-- Druid/DRStackEffect.class.st | 28 ++++++ Druid/DRStackInstruction.class.st | 51 +++++++++- Druid/DRVMState.class.st | 22 ++++- .../StackToRegisterMappingCogit.extension.st | 1 + 23 files changed, 459 insertions(+), 55 deletions(-) create mode 100644 Druid/DRCogitStackCoallescing.class.st create mode 100644 Druid/DRStackEffect.class.st diff --git a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st index 0f5a7f3f..4d9005d2 100644 --- a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st +++ b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st @@ -73,6 +73,74 @@ DRBytecodeScenarioCompilationTest >> testPopAfterFlushStack [ self assert: cogit ssTop constant equals: 237 ] +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testPopsAreCoallesced [ + + self + compileBytecode: 0 + selector: #bytecodePopOnTwoBranches + thenDo: [ :generator | "Push the receiver" + cogit ssPushRegister: ReceiverResultReg. + "Then execute the druid's compiled code" + generator value ]. + + self executePrimitiveWithReceiver: 17. + + self assert: machineSimulator receiverRegisterValue equals: 17 +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testPushAreCoallescedBranchOne [ + + self + compileBytecode: 0 + selector: #bytecodePushOnTwoBranches + thenDo: [ :generator | "Push the receiver" + cogit ssPushRegister: ReceiverResultReg. + "Then execute the druid's compiled code" + generator value. + cogit genReturnTopFromMethod ]. + + self executePrimitiveWithReceiver: 17. + + self assert: machineSimulator receiverRegisterValue equals: 1 +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testPushAreCoallescedBranchTwo [ + + self + compileBytecode: 0 + selector: #bytecodePushOnTwoBranches + thenDo: [ :generator | "Push the receiver" + cogit ssPushRegister: ReceiverResultReg. + "Then execute the druid's compiled code" + generator value. + cogit genReturnTopFromMethod ]. + + self executePrimitiveWithReceiver: -17. + + self assert: machineSimulator receiverRegisterValue equals: 2 +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testTwoPopsAreCoallesced [ + + self + compileBytecode: 0 + selector: #bytecodeTwoPopOnTwoBranches + thenDo: [ :generator | "Push the receiver" + cogit ssPushRegister: ReceiverResultReg. + cogit ssPushRegister: Arg0Reg. + "Then execute the druid's compiled code" + generator value. + cogit genReturnTopFromMethod ]. + + self executePrimitiveWithReceiver: 17 withArguments: { 42 }. + + self assert: machineSimulator receiverRegisterValue equals: 59 +] + { #category : #tests } DRBytecodeScenarioCompilationTest >> testUnknownBytecode [ diff --git a/Druid-Tests/DRProductionBytecodeTest.class.st b/Druid-Tests/DRProductionBytecodeTest.class.st index f0497ef5..076ee277 100644 --- a/Druid-Tests/DRProductionBytecodeTest.class.st +++ b/Druid-Tests/DRProductionBytecodeTest.class.st @@ -8,7 +8,6 @@ Class { DRProductionBytecodeTest >> testBytecodeAdd [ "We do not support the static type prediction yet" - self skip. sendTrampolineAddress := self compile: [ cogit RetN: 0 ]. cogit ordinarySendTrampolineAt: 1 put: sendTrampolineAddress. diff --git a/Druid-Tests/DruidTestInterpreter.class.st b/Druid-Tests/DruidTestInterpreter.class.st index f769261c..204706cb 100644 --- a/Druid-Tests/DruidTestInterpreter.class.st +++ b/Druid-Tests/DruidTestInterpreter.class.st @@ -23,6 +23,41 @@ DruidTestInterpreter >> basicInlineMethod [ ^ self lazyDouble: 42 ] +{ #category : #bytecode } +DruidTestInterpreter >> bytecodePopOnTwoBranches [ + + + | r1 | + self stackTop > 0 + ifTrue: [ r1 := self popStack ] + ifFalse: [ r1 := self popStack ]. + self push: r1 +] + +{ #category : #bytecode } +DruidTestInterpreter >> bytecodePushOnTwoBranches [ + + + self stackTop > 0 + ifTrue: [ self push: 1 ] + ifFalse: [ self push: 2 ] +] + +{ #category : #bytecode } +DruidTestInterpreter >> bytecodeTwoPopOnTwoBranches [ + + + | r1 r2 | + self stackTop > 0 + ifTrue: [ + r1 := self popStack. + r2 := self popStack ] + ifFalse: [ + r1 := self popStack. + r2 := self popStack ]. + self push: r1 + r2 +] + { #category : #bytecode } DruidTestInterpreter >> bytecodeWithDeoptimisation [ diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index 96baede3..3e603956 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -861,6 +861,32 @@ DruidTestRTLCompiler >> gen_branchingWithAssigments [ ^ CompletePrimitive ] +{ #category : #generated } +DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ + "AutoGenerated by Druid" + + | t0 jump1 s2 currentBlock jump2 live | + live := 0. + self annotateBytecode: self Label. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + (self ssValue: 0) copyToReg: t0. + self CmpCq: 0 R: t0. + jump1 := self JumpLessOrEqual: 0. + (self ssValue: 0) copyToReg: t0. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + (self ssValue: 0) copyToReg: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + self ssPop: 1. + self ssPushRegister: t0. + ^ 0 +] + { #category : #generated } DruidTestRTLCompiler >> gen_bytecodePrimAdd [ "AutoGenerated by Druid" @@ -1079,6 +1105,72 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ ^ 0 ] +{ #category : #generated } +DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ + "AutoGenerated by Druid" + + | t0 s8 jump1 s2 currentBlock jump2 live s5 | + live := 0. + self annotateBytecode: self Label. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + (self ssValue: 0) copyToReg: t0. + self CmpCq: 0 R: t0. + jump1 := self JumpLessOrEqual: 0. + s5 := 1. + self MoveCq: s5 R: t0. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + s8 := 2. + self MoveCq: s8 R: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + self ssPushRegister: t0. + ^ 0 +] + +{ #category : #generated } +DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ + "AutoGenerated by Druid" + + | t0 jump1 s2 currentBlock t1 jump2 live t2 | + live := 0. + self annotateBytecode: self Label. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + (self ssValue: 0) copyToReg: t0. + self CmpCq: 0 R: t0. + jump1 := self JumpLessOrEqual: 0. + (self ssValue: 0) copyToReg: t0. + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + (self ssValue: 1) copyToReg: t1. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + (self ssValue: 0) copyToReg: t1. + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + (self ssValue: 1) copyToReg: t2. + self MoveR: t1 R: t0. + self MoveR: t2 R: t1. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + self ssPop: 2. + self AddR: t1 R: t0. + self ssPushRegister: t0. + ^ 0 +] + { #category : #generated } DruidTestRTLCompiler >> gen_bytecodeWithDeoptimisation [ "AutoGenerated by Druid" diff --git a/Druid/DRAbstractCompilerCompiler.class.st b/Druid/DRAbstractCompilerCompiler.class.st index 497733ac..9c975ac4 100644 --- a/Druid/DRAbstractCompilerCompiler.class.st +++ b/Druid/DRAbstractCompilerCompiler.class.st @@ -119,7 +119,6 @@ DRAbstractCompilerCompiler >> generateDruidIRFor: method [ cfg := irGenerator ir. - "Clean garbage to generate a valid CFG" DRDeadBlockElimination new applyTo: cfg. DRDeadCodeElimination new applyTo: cfg. diff --git a/Druid/DRAbstractInstruction.class.st b/Druid/DRAbstractInstruction.class.st index b1912fef..789d13af 100644 --- a/Druid/DRAbstractInstruction.class.st +++ b/Druid/DRAbstractInstruction.class.st @@ -150,6 +150,12 @@ DRAbstractInstruction >> isNegate [ ^ false ] +{ #category : #testing } +DRAbstractInstruction >> isStackEffect [ + + ^ false +] + { #category : #accessing } DRAbstractInstruction >> nextInstruction [ @@ -161,7 +167,6 @@ DRAbstractInstruction >> replaceBy: anotherInstruction [ self = anotherInstruction ifTrue: [ ^ self ]. - self haltIf: [self asString = 'a DRPhiFunction(R250 := Ø R218 R177)']. basicBlock replace: self by: anotherInstruction. self replaceUsesBy: anotherInstruction. diff --git a/Druid/DRBasicBlock.class.st b/Druid/DRBasicBlock.class.st index 33ad10fe..10c967c2 100644 --- a/Druid/DRBasicBlock.class.st +++ b/Druid/DRBasicBlock.class.st @@ -232,7 +232,7 @@ DRBasicBlock >> canBeLinearizedBefore: aDRBasicBlock [ "Pops and Pushes are constraints for linearization" controlFlowGraph stackInstructions do: [ :stackInstruction | "There is a stack instruction in my path ..." (stackInstruction basicBlock isDominatedBy: self) ifTrue: [ - stackInstruction stackDependency ifNotNil: [ :dependency | "... with a dependecy in the other path ..." + stackInstruction stackDependency do: [ :dependency | "... with a dependecy in the other path ..." (dependency basicBlock isDominatedBy: aDRBasicBlock) ifTrue: [ "... then the other path must be linearized before" ^ false ] ] ] ]. diff --git a/Druid/DRBytecodeCompilerCompiler.class.st b/Druid/DRBytecodeCompilerCompiler.class.st index c1d5f670..5485a336 100644 --- a/Druid/DRBytecodeCompilerCompiler.class.st +++ b/Druid/DRBytecodeCompilerCompiler.class.st @@ -38,19 +38,6 @@ DRBytecodeCompilerCompiler >> configureForCompilerClass: aCompilerClass [ optimisations := compilerClass druidNewOptimizationList ] -{ #category : #'generation-IR' } -DRBytecodeCompilerCompiler >> createInitialBasicBlock [ - | initial initialBasicBlock | - - "Probably to be removed? the bytecode does not have a failure code. - Although some bytecode use primitive code and use the failure code!!" - - initialBasicBlock := super createInitialBasicBlock. - irGenerator currentPrimitiveFailureCode: (initial := irGenerator instructionFactory copy: 0). - initialBasicBlock addInstruction: initial. - ^ initialBasicBlock -] - { #category : #accessing } DRBytecodeCompilerCompiler >> newIRGenerator [ diff --git a/Druid/DRBytecodeIRGenerator.class.st b/Druid/DRBytecodeIRGenerator.class.st index 2becb407..ec4cbb90 100644 --- a/Druid/DRBytecodeIRGenerator.class.st +++ b/Druid/DRBytecodeIRGenerator.class.st @@ -20,7 +20,7 @@ DRBytecodeIRGenerator >> addAnnotateBytecode: aRBMethodNode [ { #category : #visiting } DRBytecodeIRGenerator >> finishCodeInterpretation: lastFrame [ - "Nothing" + currentBasicBlock jumpTo: controlFlowGraph exitBasicBlock ] { #category : #accessing } @@ -390,7 +390,7 @@ DRBytecodeIRGenerator >> interpretStackPointerWith: aRBVariableNode [ { #category : #'special cases - stack' } DRBytecodeIRGenerator >> interpretStackTopWith: aRBMessageNode [ - + ^ self addInstructionFrom: aRBMessageNode instructionKind: DRLoadStackValue @@ -405,7 +405,7 @@ DRBytecodeIRGenerator >> interpretStackValueWith: aRBMessageNode [ | value | aRBMessageNode arguments first acceptVisitor: self. - +1halt. ^ self addInstructionFrom: aRBMessageNode instructionKind: DRLoadStackValue diff --git a/Druid/DRCogitStackCanonicaliser.class.st b/Druid/DRCogitStackCanonicaliser.class.st index 10a5aa0f..225b2038 100644 --- a/Druid/DRCogitStackCanonicaliser.class.st +++ b/Druid/DRCogitStackCanonicaliser.class.st @@ -8,7 +8,7 @@ Class { DRCogitStackCanonicaliser >> visitPush: aDRPush [ | pushedValue | - pushedValue := aDRPush operand1 simpleConstantFold. + pushedValue := aDRPush operand1 simpleConstantFold asDRValue. pushedValue isLoad ifFalse: [ ^ self ]. pushedValue address isAbsolute ifTrue: [ self flag: #FIXME. "?" diff --git a/Druid/DRCogitStackCoallescing.class.st b/Druid/DRCogitStackCoallescing.class.st new file mode 100644 index 00000000..1dad9986 --- /dev/null +++ b/Druid/DRCogitStackCoallescing.class.st @@ -0,0 +1,73 @@ +Class { + #name : #DRCogitStackCoallescing, + #superclass : #DROptimisation, + #category : #'Druid-Cogit' +} + +{ #category : #accessing } +DRCogitStackCoallescing >> applyTo: cfg [ + "Get all stack effect instructions (push and pops). + We should move them down to their common post dominator. + Effects that apply the same operation on different branches get coallesced into a single effect (one push on each branch turns into a single push down in the CFG)" + + | commonPostDominator basicBlock instructionsByStackDepth stackEffects | + stackEffects := cfg instructions select: [ :e | e isStackEffect ]. + 1 haltIf: [ stackEffects anySatisfy: [ :p | p hasUsers ] ]. + instructionsByStackDepth := stackEffects groupedBy: [ :effect | + {effect stackDepth . effect class} ]. + instructionsByStackDepth keysAndValuesDo: [ :depth :instructionsAtDepth | + instructionsAtDepth size > 1 ifTrue: [ + commonPostDominator := cfg postDominatorTree dominatorOfAll: + instructionsAtDepth. + basicBlock := commonPostDominator block. + + instructionsAtDepth anyOne isPush + ifTrue: [ + self coallescePushes: instructionsAtDepth in: basicBlock ] + ifFalse: [ self coallescePops: instructionsAtDepth in: basicBlock ] ] ] +] + +{ #category : #accessing } +DRCogitStackCoallescing >> coallescePops: pops in: postDominator [ + + postDominator addInstructionFirst: + postDominator instructionFactory pop. + + pops do: [ :p | p removeFromCFG ] +] + +{ #category : #accessing } +DRCogitStackCoallescing >> coallescePushes: pushes in: postDominator [ + "We have two pushes in two different branches + + | | + Push R1 Push R2 + \__________/ + | + ... + + We should make a phi function between the two pushed values (R1, R2) and push that phi in the postdominator + + | | + ... ... + \__________/ + | + R3 = ø(R1,R2) + Push R3 + ... + " + + "Replace the push by a copy instruction. + This simplifyies Phi creation because phis cannot contain constants + " + + | copy copies phi | + copies := pushes collect: [ :e | + copy := e instructionFactory copy: e operand1. + e replaceBy: copy. + copy ]. + + phi := postDominator phiWithVariables: copies. + postDominator addInstructionFirst: + (postDominator instructionFactory push: phi) +] diff --git a/Druid/DRControlFlowGraph.class.st b/Druid/DRControlFlowGraph.class.st index 58b18a53..62d7547c 100644 --- a/Druid/DRControlFlowGraph.class.st +++ b/Druid/DRControlFlowGraph.class.st @@ -209,7 +209,9 @@ DRControlFlowGraph >> blockById: anInteger [ { #category : #iterating } DRControlFlowGraph >> blocks [ - ^ basicBlocks + ^ basicBlocks copyWithAll: { + initialBasicBlock. + exitBasicBlock } ] { #category : #accessing } @@ -223,7 +225,7 @@ DRControlFlowGraph >> blocksBetween: sourceBlock and: destinationBlock [ { #category : #iterating } DRControlFlowGraph >> blocksDo: aFullBlockClosure [ - basicBlocks do: aFullBlockClosure + self blocks do: aFullBlockClosure ] { #category : #iterating } @@ -279,7 +281,7 @@ DRControlFlowGraph >> clearEdges [ DRControlFlowGraph >> configureVisualization: view [ | blockViews controller | - blockViews := self blocks collect: [ :b | self createBlockView: b. ]. + blockViews := self blocks collect: [ :b | self createBlockView: b ]. view addAll: blockViews. self showLines: blockViews in: view. @@ -292,8 +294,8 @@ DRControlFlowGraph >> configureVisualization: view [ self showInfoIn: view. controller := RSCanvasController new - noLegend; - yourself. + noLegend; + yourself. view @ controller ] @@ -518,6 +520,7 @@ DRControlFlowGraph >> initialize [ nextBasicBlockId := -1. exitBasicBlock := self privateNewBasicBlock. + exitBasicBlock beExitBlock. initialBasicBlock := self privateNewBasicBlock ] diff --git a/Druid/DRIRGenerator.class.st b/Druid/DRIRGenerator.class.st index cc82b7c1..6c7e1432 100644 --- a/Druid/DRIRGenerator.class.st +++ b/Druid/DRIRGenerator.class.st @@ -31,6 +31,16 @@ DRIRGenerator >> addDeferredReturnState: anExecutionState [ addDeferredReturnState: anExecutionState ] +{ #category : #visiting } +DRIRGenerator >> addEndInstructionFrom: aNode instructionKind: instructionClass operands: operands [ + + | instruction | + instruction := self + instantiate: instructionClass + operands: operands. + ^ self addEndInstruction: instruction from: aNode +] + { #category : #'execution state' } DRIRGenerator >> addFrameReturn: aDRStackFrame [ @@ -2070,10 +2080,11 @@ DRIRGenerator >> visitReturnNode: aRBReturnNode [ homeFrame := fork topFrame homeFrameWithState: fork. homeFrame push: value. homeFrame returnValue: value. - self addDeferredReturnState: { fork. self addFrameReturn: homeFrame }. + + executionState vmState lastStackInstructions: #(). "The return is a statement with no value" self pushOperand: DRNullValue new diff --git a/Druid/DRInstructionFactory.class.st b/Druid/DRInstructionFactory.class.st index 336404ab..84a7f4a1 100644 --- a/Druid/DRInstructionFactory.class.st +++ b/Druid/DRInstructionFactory.class.st @@ -104,7 +104,7 @@ DRInstructionFactory >> flushStack [ { #category : #factory } DRInstructionFactory >> frameReturn: aValue [ - +1halt. ^ DRFrameReturn operands: { aValue asDRValue } result: self allocateTemporaryRegister ] @@ -268,6 +268,12 @@ DRInstructionFactory >> phiWithVariables: variables [ yourself ] +{ #category : #factory } +DRInstructionFactory >> pop [ + + ^ DRPop operands: #( ) result: self allocateTemporaryRegister +] + { #category : #factory } DRInstructionFactory >> push: operand [ diff --git a/Druid/DRLoadStackValue.class.st b/Druid/DRLoadStackValue.class.st index 07d3bff1..87d6907a 100644 --- a/Druid/DRLoadStackValue.class.st +++ b/Druid/DRLoadStackValue.class.st @@ -1,6 +1,6 @@ Class { #name : #DRLoadStackValue, - #superclass : #DRInstruction, + #superclass : #DRStackInstruction, #category : #'Druid-IR' } @@ -28,3 +28,19 @@ DRLoadStackValue >> sccpLatticeValueFor: sccp [ "We know that we know nothing about the frame pointer" ^ sccp bottom ] + +{ #category : #'as yet unclassified' } +DRLoadStackValue >> shiftStackAccessBy: anInteger [ + + self assert: operands first isConstant. + operands := OrderedCollection with: (operands first value + anInteger) asDRValue. + super shiftStackAccessBy: anInteger +] + +{ #category : #testing } +DRLoadStackValue >> stackDepth [ + + "I don't change the stack depth, so just return the stack depth of my stack dependant" + stackDependency ifEmpty: [ ^ 0 ]. + ^ stackDependency anyOne stackDepth +] diff --git a/Druid/DRMethodIRGenerator.class.st b/Druid/DRMethodIRGenerator.class.st index b7dfc944..d33a2c3c 100644 --- a/Druid/DRMethodIRGenerator.class.st +++ b/Druid/DRMethodIRGenerator.class.st @@ -98,6 +98,7 @@ DRMethodIRGenerator >> resolveDeferredMethodReturns: aDRFrame [ | mirrorFrame newFrameReturn deferredReturnsBlock pieces deferredFrameReturn newReturn | aDRFrame deferredMethodReturns ifEmpty: [ ^ self ]. + 1halt. mirrorFrame := aDRFrame mirrorFrame. "If there were returns attached to popped frame, merge all of them in a single state. If there was only one return this is important also to override implicit returns" diff --git a/Druid/DRPop.class.st b/Druid/DRPop.class.st index 64c507ab..0e245a62 100644 --- a/Druid/DRPop.class.st +++ b/Druid/DRPop.class.st @@ -1,6 +1,6 @@ Class { #name : #DRPop, - #superclass : #DRStackInstruction, + #superclass : #DRStackEffect, #category : #'Druid-BytecodeToJITCompilation' } @@ -10,12 +10,6 @@ DRPop >> acceptVisitor: aVisitor [ ^ aVisitor visitPop: self ] -{ #category : #testing } -DRPop >> isMandatoryInstruction [ - - ^ true -] - { #category : #testing } DRPop >> isPop [ @@ -47,3 +41,21 @@ DRPop >> size [ ^ 8 "bytes" ] + +{ #category : #accessing } +DRPop >> stackDelta [ + + "If I don't pop, my dependants should add one to their stack indexes" + ^ 1 +] + +{ #category : #testing } +DRPop >> stackDepth [ + + "Return the stack depth left on the stack after applying this operation. + Pop will remove one element from the stack depth of the previous stack instruction" + + stackDependency ifEmpty: [ ^ 0 ]. + ^ stackDependency anyOne stackDepth - 1 + +] diff --git a/Druid/DRPopMany.class.st b/Druid/DRPopMany.class.st index 2387081f..25cdc4de 100644 --- a/Druid/DRPopMany.class.st +++ b/Druid/DRPopMany.class.st @@ -1,6 +1,6 @@ Class { #name : #DRPopMany, - #superclass : #DRStackInstruction, + #superclass : #DRStackEffect, #category : #'Druid-BytecodeToJITCompilation' } @@ -10,12 +10,6 @@ DRPopMany >> acceptVisitor: aVisitor [ aVisitor visitPopMany: self ] -{ #category : #testing } -DRPopMany >> isMandatoryInstruction [ - - ^ true -] - { #category : #testing } DRPopMany >> isPop [ diff --git a/Druid/DRPush.class.st b/Druid/DRPush.class.st index 6dc2a6c5..483df15b 100644 --- a/Druid/DRPush.class.st +++ b/Druid/DRPush.class.st @@ -1,6 +1,6 @@ Class { #name : #DRPush, - #superclass : #DRStackInstruction, + #superclass : #DRStackEffect, #category : #'Druid-BytecodeToJITCompilation' } @@ -10,12 +10,6 @@ DRPush >> acceptVisitor: aVisitor [ ^ aVisitor visitPush: self ] -{ #category : #testing } -DRPush >> isMandatoryInstruction [ - - ^ true -] - { #category : #testing } DRPush >> isPush [ @@ -28,6 +22,13 @@ DRPush >> opcode [ ^ 'Push' ] +{ #category : #removing } +DRPush >> removeFromCFG [ + + self halt. + super removeFromCFG +] + { #category : #'users-definitions' } DRPush >> replaceDependency: anOperand by: anotherOperand [ @@ -53,3 +54,13 @@ DRPush >> size [ ^ 8 "bytes" ] + +{ #category : #testing } +DRPush >> stackDepth [ + + "Return the stack depth left on the stack after applying this operation. + Push will add one element to the stack depth of the previous stack instruction" + + stackDependency ifEmpty: [ ^ 1 ]. + ^ stackDependency anyOne stackDepth + 1 +] diff --git a/Druid/DRStackEffect.class.st b/Druid/DRStackEffect.class.st new file mode 100644 index 00000000..207fe5a6 --- /dev/null +++ b/Druid/DRStackEffect.class.st @@ -0,0 +1,28 @@ +Class { + #name : #DRStackEffect, + #superclass : #DRStackInstruction, + #category : #'Druid-BytecodeToJITCompilation' +} + +{ #category : #testing } +DRStackEffect >> isMandatoryInstruction [ + + ^ true +] + +{ #category : #testing } +DRStackEffect >> isStackEffect [ + + ^ true +] + +{ #category : #removing } +DRStackEffect >> removeFromCFG [ + "I'm a pop. If I'm removed, all my dependents should shift up by one their stack accesses" + + stackDependents do: [ :e | + e shiftStackAccessBy: self stackDelta. + e removeStackDependency: self ]. + + super removeFromCFG +] diff --git a/Druid/DRStackInstruction.class.st b/Druid/DRStackInstruction.class.st index 66ea57d5..6fbae51b 100644 --- a/Druid/DRStackInstruction.class.st +++ b/Druid/DRStackInstruction.class.st @@ -2,17 +2,50 @@ Class { #name : #DRStackInstruction, #superclass : #DRInstruction, #instVars : [ - 'stackDependency' + 'stackDependency', + 'stackDependents' ], - #category : #'Druid-BytecodeToJITCompilation' + #category : #'Druid-IR' } +{ #category : #adding } +DRStackInstruction >> addStackDependent: aStackInstruction [ + + stackDependents add: aStackInstruction +] + +{ #category : #testing } +DRStackInstruction >> initialize [ + + super initialize. + stackDependents := OrderedCollection new +] + { #category : #testing } DRStackInstruction >> isStackInstruction [ ^ true ] +{ #category : #removing } +DRStackInstruction >> removeStackDependency: aStackDependency [ + + stackDependency := stackDependency copyWithout: aStackDependency +] + +{ #category : #removing } +DRStackInstruction >> removeStackDependent: aStackDependent [ + + stackDependents := stackDependents copyWithout: aStackDependent +] + +{ #category : #'as yet unclassified' } +DRStackInstruction >> shiftStackAccessBy: anInteger [ + + "Delegate to my stack dependents" + stackDependents do: [ :e | e shiftStackAccessBy: anInteger ]. +] + { #category : #accessing } DRStackInstruction >> stackDependency [ @@ -22,5 +55,17 @@ DRStackInstruction >> stackDependency [ { #category : #accessing } DRStackInstruction >> stackDependency: anObject [ - stackDependency := anObject + stackDependency := anObject. + stackDependency do: [ :e | e addStackDependent: self ] +] + +{ #category : #accessing } +DRStackInstruction >> stackDependents [ + ^ stackDependents +] + +{ #category : #validation } +DRStackInstruction >> validate [ + + super validate ] diff --git a/Druid/DRVMState.class.st b/Druid/DRVMState.class.st index e2cd7578..dfac4b47 100644 --- a/Druid/DRVMState.class.st +++ b/Druid/DRVMState.class.st @@ -74,6 +74,8 @@ DRVMState >> addTo: aDRVMState depth: maxVMStackDepth [ primitiveFailureCode ifNotNil: [ "Only valid for primitives" aDRVMState addPrimitiveFailureCode: primitiveFailureCode ]. + + aDRVMState lastStackInstructions: (aDRVMState lastStackInstructions copyWithAll: self lastStackInstructions). ] { #category : #merging } @@ -98,7 +100,8 @@ DRVMState >> completeOperandStackUpTo: anInteger do: aBlockValue [ DRVMState >> initialize [ super initialize. - operandStack := Stack new + operandStack := Stack new. + lastStackInstruction := #() ] { #category : #initialization } @@ -127,7 +130,22 @@ DRVMState >> lastStackInstruction [ { #category : #accessing } DRVMState >> lastStackInstruction: aDRStackInstruction [ - lastStackInstruction := aDRStackInstruction + self haltIf: [ aDRStackInstruction isStackInstruction not ]. + + lastStackInstruction := {aDRStackInstruction} +] + +{ #category : #accessing } +DRVMState >> lastStackInstructions [ + + ^ lastStackInstruction +] + +{ #category : #accessing } +DRVMState >> lastStackInstructions: aCollectionOfStackInstructions [ + + self haltIf: [ aCollectionOfStackInstructions anySatisfy: [ :e | e isStackInstruction not ] ]. + lastStackInstruction := aCollectionOfStackInstructions ] { #category : #accessing } diff --git a/Druid/StackToRegisterMappingCogit.extension.st b/Druid/StackToRegisterMappingCogit.extension.st index 3e84d9aa..c934554f 100644 --- a/Druid/StackToRegisterMappingCogit.extension.st +++ b/Druid/StackToRegisterMappingCogit.extension.st @@ -13,6 +13,7 @@ StackToRegisterMappingCogit class >> druidNewOptimizationList [ optimisations := OrderedCollection new. optimisations add: (DRCleanControlFlow then: DRCopyPropagation). + optimisations add: DRCogitStackCoallescing new. 4 timesRepeat: [ optimisations add: DRBranchCollapse new. optimisations add: DRFailureCodeBasedTailDuplication new. From 9d22dcb2c236f80a9f1280222dbc496aa3881dd8 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Tue, 23 Apr 2024 11:45:04 +0200 Subject: [PATCH 02/33] Fix primitive tests --- Druid/DRPrimitiveControlFlowGraph.class.st | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Druid/DRPrimitiveControlFlowGraph.class.st b/Druid/DRPrimitiveControlFlowGraph.class.st index 356c6209..596c8e2e 100644 --- a/Druid/DRPrimitiveControlFlowGraph.class.st +++ b/Druid/DRPrimitiveControlFlowGraph.class.st @@ -14,6 +14,12 @@ Class { #category : #'Druid-IR' } +{ #category : #iterating } +DRPrimitiveControlFlowGraph >> blocks [ + + ^ basicBlocks +] + { #category : #accessing } DRPrimitiveControlFlowGraph >> failureExitBlock [ From f812b73ee654540d1f008a1cc432792787ec6379 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Tue, 23 Apr 2024 11:54:36 +0200 Subject: [PATCH 03/33] Rename and add tests --- ...DRBytecodeScenarioCompilationTest.class.st | 34 +++++++++++++++++++ Druid-Tests/DruidTestInterpreter.class.st | 14 ++++++++ Druid-Tests/DruidTestRTLCompiler.class.st | 29 ++++++++++++++++ ...ass.st => DRCogitStackCoalescing.class.st} | 12 +++---- .../StackToRegisterMappingCogit.extension.st | 2 +- 5 files changed, 84 insertions(+), 7 deletions(-) rename Druid/{DRCogitStackCoallescing.class.st => DRCogitStackCoalescing.class.st} (84%) diff --git a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st index 4d9005d2..f1384d5e 100644 --- a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st +++ b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st @@ -141,6 +141,40 @@ DRBytecodeScenarioCompilationTest >> testTwoPopsAreCoallesced [ self assert: machineSimulator receiverRegisterValue equals: 59 ] +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testTwoPushesAreCoallescedBranchOne [ + + self + compileBytecode: 0 + selector: #bytecodeTwoPushOnTwoBranches + thenDo: [ :generator | "Push the receiver" + cogit ssPushRegister: ReceiverResultReg. + "Then execute the druid's compiled code" + generator value. + cogit genReturnTopFromMethod ]. + + self executePrimitiveWithReceiver: 17. + + self assert: machineSimulator receiverRegisterValue equals: 3 +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testTwoPushesAreCoallescedBranchTwo [ + + self + compileBytecode: 0 + selector: #bytecodeTwoPushOnTwoBranches + thenDo: [ :generator | "Push the receiver" + cogit ssPushRegister: ReceiverResultReg. + "Then execute the druid's compiled code" + generator value. + cogit genReturnTopFromMethod ]. + + self executePrimitiveWithReceiver: -17. + + self assert: machineSimulator receiverRegisterValue equals: 7 +] + { #category : #tests } DRBytecodeScenarioCompilationTest >> testUnknownBytecode [ diff --git a/Druid-Tests/DruidTestInterpreter.class.st b/Druid-Tests/DruidTestInterpreter.class.st index b0779be3..f603387a 100644 --- a/Druid-Tests/DruidTestInterpreter.class.st +++ b/Druid-Tests/DruidTestInterpreter.class.st @@ -58,6 +58,20 @@ DruidTestInterpreter >> bytecodeTwoPopOnTwoBranches [ self push: r1 + r2 ] +{ #category : #bytecode } +DruidTestInterpreter >> bytecodeTwoPushOnTwoBranches [ + + + self popStack > 0 + ifTrue: [ + self push: 1. + self push: 2 ] + ifFalse: [ + self push: 3. + self push: 4 ]. + self push: self popStack + self popStack +] + { #category : #bytecode } DruidTestInterpreter >> bytecodeWithDeoptimisation [ diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index 3e603956..1ea35629 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -1171,6 +1171,35 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ ^ 0 ] +{ #category : #generated } +DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ + "AutoGenerated by Druid" + + | t0 s8 jump1 s2 currentBlock jump2 live s5 | + live := 0. + self annotateBytecode: self Label. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + (self ssValue: 0) copyToReg: t0. + self CmpCq: 0 R: t0. + jump1 := self JumpLessOrEqual: 0. + s5 := 2. + self MoveCq: s5 R: t0. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + s8 := 4. + self MoveCq: s8 R: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + self ssPushRegister: t0. + self ssPop: 2. + self ssPushRegister: t0. + ^ 0 +] + { #category : #generated } DruidTestRTLCompiler >> gen_bytecodeWithDeoptimisation [ "AutoGenerated by Druid" diff --git a/Druid/DRCogitStackCoallescing.class.st b/Druid/DRCogitStackCoalescing.class.st similarity index 84% rename from Druid/DRCogitStackCoallescing.class.st rename to Druid/DRCogitStackCoalescing.class.st index 1dad9986..04449bef 100644 --- a/Druid/DRCogitStackCoallescing.class.st +++ b/Druid/DRCogitStackCoalescing.class.st @@ -1,11 +1,11 @@ Class { - #name : #DRCogitStackCoallescing, + #name : #DRCogitStackCoalescing, #superclass : #DROptimisation, #category : #'Druid-Cogit' } { #category : #accessing } -DRCogitStackCoallescing >> applyTo: cfg [ +DRCogitStackCoalescing >> applyTo: cfg [ "Get all stack effect instructions (push and pops). We should move them down to their common post dominator. Effects that apply the same operation on different branches get coallesced into a single effect (one push on each branch turns into a single push down in the CFG)" @@ -23,12 +23,12 @@ DRCogitStackCoallescing >> applyTo: cfg [ instructionsAtDepth anyOne isPush ifTrue: [ - self coallescePushes: instructionsAtDepth in: basicBlock ] - ifFalse: [ self coallescePops: instructionsAtDepth in: basicBlock ] ] ] + self coalescePushes: instructionsAtDepth in: basicBlock ] + ifFalse: [ self coalescePops: instructionsAtDepth in: basicBlock ] ] ] ] { #category : #accessing } -DRCogitStackCoallescing >> coallescePops: pops in: postDominator [ +DRCogitStackCoalescing >> coalescePops: pops in: postDominator [ postDominator addInstructionFirst: postDominator instructionFactory pop. @@ -37,7 +37,7 @@ DRCogitStackCoallescing >> coallescePops: pops in: postDominator [ ] { #category : #accessing } -DRCogitStackCoallescing >> coallescePushes: pushes in: postDominator [ +DRCogitStackCoalescing >> coalescePushes: pushes in: postDominator [ "We have two pushes in two different branches | | diff --git a/Druid/StackToRegisterMappingCogit.extension.st b/Druid/StackToRegisterMappingCogit.extension.st index c934554f..c9b5320e 100644 --- a/Druid/StackToRegisterMappingCogit.extension.st +++ b/Druid/StackToRegisterMappingCogit.extension.st @@ -13,7 +13,7 @@ StackToRegisterMappingCogit class >> druidNewOptimizationList [ optimisations := OrderedCollection new. optimisations add: (DRCleanControlFlow then: DRCopyPropagation). - optimisations add: DRCogitStackCoallescing new. + optimisations add: DRCogitStackCoalescing new. 4 timesRepeat: [ optimisations add: DRBranchCollapse new. optimisations add: DRFailureCodeBasedTailDuplication new. From 41e096171b783f9c0aa29ee9589f09d9fd0a9e2c Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Tue, 23 Apr 2024 15:09:14 +0200 Subject: [PATCH 04/33] Add tests on stack dependencies --- Druid-Tests/DRStackEffectTest.class.st | 108 +++++++++++++++++++++++ Druid/DRControlFlowGraph.class.st | 20 +++++ Druid/DRIRGenerator.class.st | 117 ++++++++++++++----------- Druid/DRInstruction.class.st | 2 +- Druid/DRStackInstruction.class.st | 12 ++- 5 files changed, 203 insertions(+), 56 deletions(-) create mode 100644 Druid-Tests/DRStackEffectTest.class.st diff --git a/Druid-Tests/DRStackEffectTest.class.st b/Druid-Tests/DRStackEffectTest.class.st new file mode 100644 index 00000000..3e06c779 --- /dev/null +++ b/Druid-Tests/DRStackEffectTest.class.st @@ -0,0 +1,108 @@ +Class { + #name : #DRStackEffectTest, + #superclass : #DRIRTest, + #category : #'Druid-Tests' +} + +{ #category : #tests } +DRStackEffectTest >> testInitialStackInstructionHasNoStackDependencies [ + + | irBuilder push pop | + irBuilder := DRMetaCompilerIRGenerator new. + irBuilder pushFrame: DRStackFrame new. + + push := irBuilder addInstructionFrom: nil instructionKind: DRPush operands: { 17 }. + pop := irBuilder addInstructionFrom: nil instructionKind: DRPop. + + self assert: push stackDependency isEmpty +] + +{ #category : #tests } +DRStackEffectTest >> testLastStackInstructionHasNoStackDependents [ + + | irBuilder push pop | + irBuilder := DRMetaCompilerIRGenerator new. + irBuilder pushFrame: DRStackFrame new. + + push := irBuilder addInstructionFrom: nil instructionKind: DRPush operands: { 17 }. + pop := irBuilder addInstructionFrom: nil instructionKind: DRPop. + + self assert: pop stackDependents isEmpty +] + +{ #category : #tests } +DRStackEffectTest >> testPopDependsOnPush [ + + | irBuilder push pop | + irBuilder := DRMetaCompilerIRGenerator new. + irBuilder pushFrame: DRStackFrame new. + + push := irBuilder addInstructionFrom: nil instructionKind: DRPush operands: { 17 }. + pop := irBuilder addInstructionFrom: nil instructionKind: DRPop. + + self assert: pop stackDependency asArray equals: { push }. + self assert: push stackDependents asArray equals: { pop } +] + +{ #category : #tests } +DRStackEffectTest >> testPopInMergePointDependsOnBothBranches [ + + | irBuilder pop1 pop2 finalStackInstruction | + irBuilder := DRMetaCompilerIRGenerator new. + irBuilder pushFrame: (DRStackFrame new + returnValue: DRPhiFunction new; + yourself). + + + pop1 := irBuilder addInstructionFrom: nil instructionKind: DRPop. + irBuilder buildIfTrue: nil then: [ + pop2 := irBuilder addInstructionFrom: nil instructionKind: DRPop ]. "Condition" + + finalStackInstruction := irBuilder + addInstructionFrom: nil + instructionKind: DRPush + operands: { 17 }. + + self assert: finalStackInstruction stackDependency asArray equals: { + pop1. + pop2 } +] + +{ #category : #tests } +DRStackEffectTest >> testPushDependsOnPop [ + + | irBuilder push pop | + irBuilder := DRMetaCompilerIRGenerator new. + irBuilder pushFrame: DRStackFrame new. + + pop := irBuilder addInstructionFrom: nil instructionKind: DRPop. + push := irBuilder addInstructionFrom: nil instructionKind: DRPush operands: { 17 }. + + self assert: push stackDependency asArray equals: { pop }. + self assert: pop stackDependents asArray equals: { push } +] + +{ #category : #tests } +DRStackEffectTest >> testRebuildStackDependenciesReconstructsOriginalGraph [ + + | irBuilder pop1 pop2 finalStackInstruction | + irBuilder := DRMetaCompilerIRGenerator new. + irBuilder pushFrame: (DRStackFrame new + returnValue: DRPhiFunction new; + yourself). + + + pop1 := irBuilder addInstructionFrom: nil instructionKind: DRPop. + irBuilder buildIfTrue: nil then: [ + pop2 := irBuilder addInstructionFrom: nil instructionKind: DRPop ]. "Condition" + + finalStackInstruction := irBuilder + addInstructionFrom: nil + instructionKind: DRPush + operands: { 17 }. + + irBuilder ir rebuildStackDependencies. + self assert: finalStackInstruction stackDependency asArray equals: { + pop1. + pop2 } +] diff --git a/Druid/DRControlFlowGraph.class.st b/Druid/DRControlFlowGraph.class.st index 62d7547c..8a6803dc 100644 --- a/Druid/DRControlFlowGraph.class.st +++ b/Druid/DRControlFlowGraph.class.st @@ -721,6 +721,26 @@ DRControlFlowGraph >> privateNewBasicBlock [ ^ newBlock ] +{ #category : #building } +DRControlFlowGraph >> rebuildStackDependencies [ + + | lastStackInstructionPerBlock incomingStackInstructions | + lastStackInstructionPerBlock := Dictionary new. + + self reversePostOrderBlocks do: [ :e | + incomingStackInstructions := e predecessors flatCollect: [ :p | + lastStackInstructionPerBlock + at: p + ifAbsent: [ #( ) ] ]. + e instructions do: [ :i | + i isStackInstruction ifTrue: [ + i clearStackDependencies. + i stackDependency: incomingStackInstructions. + incomingStackInstructions do: [ :s | s addStackDependent: i ]. + incomingStackInstructions := { i } ] ]. + lastStackInstructionPerBlock at: e put: incomingStackInstructions ] +] + { #category : #removing } DRControlFlowGraph >> removeBasicBlock: aDRBasicBlock [ diff --git a/Druid/DRIRGenerator.class.st b/Druid/DRIRGenerator.class.st index 5b4ad0d5..2e4a311e 100644 --- a/Druid/DRIRGenerator.class.st +++ b/Druid/DRIRGenerator.class.st @@ -11,7 +11,8 @@ Class { 'executionState', 'variableSpecialCases', 'typeSystem', - 'staging' + 'staging', + 'currentASTNode' ], #category : #'Druid-CompilerCompiler' } @@ -33,13 +34,10 @@ DRIRGenerator >> addDeferredReturnState: anExecutionState [ ] { #category : #visiting } -DRIRGenerator >> addEndInstructionFrom: aNode instructionKind: instructionClass operands: operands [ - - | instruction | - instruction := self - instantiate: instructionClass - operands: operands. - ^ self addEndInstruction: instruction from: aNode +DRIRGenerator >> addEndInstruction: instruction [ + + self currentBasicBlock endInstruction: instruction. + instruction originAST: currentASTNode ] { #category : #'execution state' } @@ -73,6 +71,15 @@ DRIRGenerator >> addInstructionCall: operands from: aRBMessageNode [ operands: operands ] +{ #category : #visiting } +DRIRGenerator >> addInstructionFrom: aNode instructionKind: instructionClass [ + + ^ self + addInstructionFrom: aNode + instructionKind: instructionClass + operands: #( ) +] + { #category : #visiting } DRIRGenerator >> addInstructionFrom: aNode instructionKind: instructionClass operands: operands [ @@ -168,6 +175,51 @@ DRIRGenerator >> branchFrom: startingBasicBlock onEdge: anEdgeBlock doing: aBloc ^ branchExitBlock ] +{ #category : #building } +DRIRGenerator >> buildIfTrue: aCondition then: aBuildingBlock [ + + | conditionalJump executionStateBeforeBranch trueBranchBasicBlockOut startingBasicBlock | + conditionalJump := self + instantiateNoResultInstruction: + DRBranchIfCondition + operands: { + DREqualsThanComparison new. + aCondition. + true asDRValue }. + self addEndInstruction: conditionalJump. + + self pushOperand: DRNullValue new. + executionStateBeforeBranch := executionState copy. + self popOperand. + + trueBranchBasicBlockOut := self + branchFrom: self currentBasicBlock + onEdge: [ :branchEntryBlock | + conditionalJump trueBranch: + branchEntryBlock ] + doing: aBuildingBlock. + + "Merge point" + startingBasicBlock := self currentBasicBlock. + self newBasicBlock. + self currentBasicBlock addPredecessor: startingBasicBlock. + conditionalJump falseBranch: self currentBasicBlock. + + "Could happen that the evaluated block had a non local return. + In that case, this block should not arrive to this merge point + => do not add the jump" + trueBranchBasicBlockOut hasFinalInstruction + ifTrue: [ executionState := executionStateBeforeBranch ] + ifFalse: [ + executionState := DRStackMerger new + builder: self; + mergeBlock: currentBasicBlock; + mergeAll: { + executionStateBeforeBranch. + executionState copy }. + trueBranchBasicBlockOut jumpTo: self currentBasicBlock ] +] + { #category : #accessing } DRIRGenerator >> compiler [ @@ -955,52 +1007,11 @@ DRIRGenerator >> interpretHiddenRootsObjectWith: aRBVariableNode [ { #category : #'special cases' } DRIRGenerator >> interpretIfTrueWith: aRBMessageNode [ - | trueBranchBasicBlockOut conditionalJump startingBasicBlock executionStateBeforeBranch | aRBMessageNode receiver acceptVisitor: self. - conditionalJump := self - instantiateNoResultInstruction: - DRBranchIfCondition - operands: { - DREqualsThanComparison new. - self popOperand. - true asDRValue }. - conditionalJump originAST: aRBMessageNode. - - self currentBasicBlock endInstruction: conditionalJump. - - self pushOperand: DRNullValue new. - executionStateBeforeBranch := executionState copy. - - self popOperand. - - trueBranchBasicBlockOut := self - branchFrom: self currentBasicBlock - onEdge: [ :branchEntryBlock | - conditionalJump trueBranch: - branchEntryBlock ] - doing: [ - self interpretBlockBody: - aRBMessageNode arguments first ]. - - "Merge point" - startingBasicBlock := self currentBasicBlock. - self newBasicBlock. - self currentBasicBlock addPredecessor: startingBasicBlock. - conditionalJump falseBranch: self currentBasicBlock. - - "Could happen that the evaluated block had a non local return. - In that case, this block should not arrive to this merge point - => do not add the jump" - trueBranchBasicBlockOut hasFinalInstruction - ifTrue: [ executionState := executionStateBeforeBranch ] - ifFalse: [ - executionState := DRStackMerger new - builder: self; - mergeBlock: currentBasicBlock; - mergeAll: { - executionStateBeforeBranch. - executionState copy }. - trueBranchBasicBlockOut jumpTo: self currentBasicBlock ] + currentASTNode := aRBMessageNode. + self + buildIfTrue: self popOperand + then: [ self interpretBlockBody: aRBMessageNode arguments first ] ] { #category : #'special cases' } diff --git a/Druid/DRInstruction.class.st b/Druid/DRInstruction.class.st index 64cc0cf3..6ae241e1 100644 --- a/Druid/DRInstruction.class.st +++ b/Druid/DRInstruction.class.st @@ -441,7 +441,7 @@ DRInstruction >> operands [ DRInstruction >> operands: aCollection [ operands asSet do: [ :each | each removeUser: self ]. - operands := aCollection asOrderedCollection. + operands := aCollection collect: [:e | e asDRValue ]. self dependencies asSet do: [ :each | each addUser: self ] ] diff --git a/Druid/DRStackInstruction.class.st b/Druid/DRStackInstruction.class.st index 6fbae51b..16cd10cd 100644 --- a/Druid/DRStackInstruction.class.st +++ b/Druid/DRStackInstruction.class.st @@ -14,11 +14,19 @@ DRStackInstruction >> addStackDependent: aStackInstruction [ stackDependents add: aStackInstruction ] +{ #category : #dependencies } +DRStackInstruction >> clearStackDependencies [ + + stackDependency := OrderedCollection new. + stackDependents := OrderedCollection new +] + { #category : #testing } DRStackInstruction >> initialize [ super initialize. - stackDependents := OrderedCollection new + + self clearStackDependencies ] { #category : #testing } @@ -39,7 +47,7 @@ DRStackInstruction >> removeStackDependent: aStackDependent [ stackDependents := stackDependents copyWithout: aStackDependent ] -{ #category : #'as yet unclassified' } +{ #category : #dependencies } DRStackInstruction >> shiftStackAccessBy: anInteger [ "Delegate to my stack dependents" From 932b1b902c7868bceea191466618b8c63af06851 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Tue, 23 Apr 2024 15:12:40 +0200 Subject: [PATCH 05/33] Merge DRPop and DRPopMany --- Druid/DRBytecodeCompilerCompiler.class.st | 2 +- Druid/DRBytecodeIRGenerator.class.st | 2 +- Druid/DRCPSEdge.class.st | 6 ---- Druid/DRCogitCanonicaliser.class.st | 13 ++----- Druid/DRCogitOperandSorter.class.st | 6 ---- ...itStackToRegisterMappingGenerator.class.st | 6 ---- Druid/DRInstructionFactory.class.st | 2 +- Druid/DRPop.class.st | 2 +- Druid/DRPopMany.class.st | 36 ------------------- 9 files changed, 7 insertions(+), 68 deletions(-) delete mode 100644 Druid/DRPopMany.class.st diff --git a/Druid/DRBytecodeCompilerCompiler.class.st b/Druid/DRBytecodeCompilerCompiler.class.st index 5485a336..7e6d8d0b 100644 --- a/Druid/DRBytecodeCompilerCompiler.class.st +++ b/Druid/DRBytecodeCompilerCompiler.class.st @@ -41,7 +41,7 @@ DRBytecodeCompilerCompiler >> configureForCompilerClass: aCompilerClass [ { #category : #accessing } DRBytecodeCompilerCompiler >> newIRGenerator [ - ^ DRBytecodeIRGenerator new + ^ DRBytecodeIRGenerator new compiler: self ] { #category : #'generation-IR' } diff --git a/Druid/DRBytecodeIRGenerator.class.st b/Druid/DRBytecodeIRGenerator.class.st index ec4cbb90..ec8aa631 100644 --- a/Druid/DRBytecodeIRGenerator.class.st +++ b/Druid/DRBytecodeIRGenerator.class.st @@ -457,7 +457,7 @@ DRBytecodeIRGenerator >> pop [ self addInstructionFrom: nil instructionKind: DRPop - operands: #(). + operands: #( 1 ). ^ self popOperand ] diff --git a/Druid/DRCPSEdge.class.st b/Druid/DRCPSEdge.class.st index fd26dbf7..ad49083f 100644 --- a/Druid/DRCPSEdge.class.st +++ b/Druid/DRCPSEdge.class.st @@ -625,12 +625,6 @@ DRCPSEdge >> visitPop: aDRPop [ ^ nil ] -{ #category : #visiting } -DRCPSEdge >> visitPopMany: aDRPopMany [ - - ^ nil -] - { #category : #visiting } DRCPSEdge >> visitPush: aDRPush [ diff --git a/Druid/DRCogitCanonicaliser.class.st b/Druid/DRCogitCanonicaliser.class.st index 0a69db3c..d1f4845c 100644 --- a/Druid/DRCogitCanonicaliser.class.st +++ b/Druid/DRCogitCanonicaliser.class.st @@ -358,28 +358,21 @@ DRCogitCanonicaliser >> visitPhiFunction: aDRPhiFunction [ { #category : #visiting } DRCogitCanonicaliser >> visitPop: aDRPop [ - "If I have no users, and my previous instruction is also a pop without users, merge us in a single PopMany instruction" | canBeMerged previous | previous := aDRPop previousInstruction ifNil: [ ^ self ]. - canBeMerged := aDRPop hasUsers not and: [ + canBeMerged := aDRPop hasUsers not and: [ previous isPop and: [ previous hasUsers not ] ]. - canBeMerged ifTrue: [ + canBeMerged ifTrue: [ aDRPop previousInstruction removeFromCFG. - aDRPop replaceBy: (DRPopMany + aDRPop replaceBy: (DRPop operands: { (previous numberOfPoppedElements + aDRPop numberOfPoppedElements) asDRValue } result: DRNoRegister new) ] ] -{ #category : #visiting } -DRCogitCanonicaliser >> visitPopMany: aDRPopMany [ - - ^ self visitPop: aDRPopMany -] - { #category : #visiting } DRCogitCanonicaliser >> visitPush: aDRPush [ diff --git a/Druid/DRCogitOperandSorter.class.st b/Druid/DRCogitOperandSorter.class.st index a4299525..dd4210ef 100644 --- a/Druid/DRCogitOperandSorter.class.st +++ b/Druid/DRCogitOperandSorter.class.st @@ -327,12 +327,6 @@ DRCogitOperandSorter >> visitPop: aDRPop [ "Nothing" ] -{ #category : #visiting } -DRCogitOperandSorter >> visitPopMany: aDRPopMany [ - - "Nothing" -] - { #category : #visiting } DRCogitOperandSorter >> visitPush: aDRPush [ diff --git a/Druid/DRCogitStackToRegisterMappingGenerator.class.st b/Druid/DRCogitStackToRegisterMappingGenerator.class.st index 110efc54..b928cd3c 100644 --- a/Druid/DRCogitStackToRegisterMappingGenerator.class.st +++ b/Druid/DRCogitStackToRegisterMappingGenerator.class.st @@ -196,12 +196,6 @@ DRCogitStackToRegisterMappingGenerator >> visitPop: aDRPop [ arguments: { (RBLiteralValueNode value: aDRPop numberOfPoppedElements) }) ] -{ #category : #visiting } -DRCogitStackToRegisterMappingGenerator >> visitPopMany: aDRPopMany [ - - ^ self visitPop: aDRPopMany -] - { #category : #visiting } DRCogitStackToRegisterMappingGenerator >> visitPush: aDRPush [ diff --git a/Druid/DRInstructionFactory.class.st b/Druid/DRInstructionFactory.class.st index 84a7f4a1..710ea6ca 100644 --- a/Druid/DRInstructionFactory.class.st +++ b/Druid/DRInstructionFactory.class.st @@ -271,7 +271,7 @@ DRInstructionFactory >> phiWithVariables: variables [ { #category : #factory } DRInstructionFactory >> pop [ - ^ DRPop operands: #( ) result: self allocateTemporaryRegister + ^ DRPop operands: #( 1 ) result: self allocateTemporaryRegister ] { #category : #factory } diff --git a/Druid/DRPop.class.st b/Druid/DRPop.class.st index 0e245a62..02c5a9c4 100644 --- a/Druid/DRPop.class.st +++ b/Druid/DRPop.class.st @@ -19,7 +19,7 @@ DRPop >> isPop [ { #category : #accessing } DRPop >> numberOfPoppedElements [ - ^ 1 + ^ self operand1 value ] { #category : #printing } diff --git a/Druid/DRPopMany.class.st b/Druid/DRPopMany.class.st deleted file mode 100644 index 25cdc4de..00000000 --- a/Druid/DRPopMany.class.st +++ /dev/null @@ -1,36 +0,0 @@ -Class { - #name : #DRPopMany, - #superclass : #DRStackEffect, - #category : #'Druid-BytecodeToJITCompilation' -} - -{ #category : #visiting } -DRPopMany >> acceptVisitor: aVisitor [ - - aVisitor visitPopMany: self -] - -{ #category : #testing } -DRPopMany >> isPop [ - - ^ true -] - -{ #category : #accessing } -DRPopMany >> numberOfPoppedElements [ - - ^ self operand1 value -] - -{ #category : #printing } -DRPopMany >> opcode [ - - ^ 'PopN' -] - -{ #category : #SCCP } -DRPopMany >> sccpLatticeValueFor: sccp [ - - "We know that we know nothing about what is in the stack" - ^ sccp bottom -] From 647cdbcbbdcf8a826529cb63eb7d6c91a572313e Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Tue, 23 Apr 2024 17:18:20 +0200 Subject: [PATCH 06/33] Fix bytecode tests - bytecode compilation should use the default CFG and not the primitive one - refactor IRGenerators to move bytecodeIRGenerator as a sibbling of primitiveIRGenerator --- Druid-Tests/DruidTestRTLCompiler.class.st | 80 ++++++++++--------- Druid/DRBytecodeIRGenerator.class.st | 17 ++-- Druid/DRCogitCodeGenerator.class.st | 22 ++--- Druid/DRCogitPrimitiveCodeGenerator.class.st | 15 ++++ ...itStackToRegisterMappingGenerator.class.st | 11 +-- Druid/DRMetaCompilerIRGenerator.class.st | 64 ++++++++++++++- Druid/DRPrimitiveIRGenerator.class.st | 64 +-------------- Druid/SimpleStackBasedCogit.extension.st | 1 - .../StackToRegisterMappingCogit.extension.st | 1 - 9 files changed, 147 insertions(+), 128 deletions(-) diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index 1ea35629..a18ce185 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -905,7 +905,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimAdd [ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ "AutoGenerated by Druid" - | jump1 b504 s57 s54 t1 jump6 jump3 currentBlock b500 t0 jump5 jump2 live t2 jump4 | + | jump1 s57 s54 t1 jump6 jump3 b496 b500 currentBlock t0 jump5 jump2 live t2 jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -930,7 +930,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t2. - b504 := self Label. + b500 := self Label. self MoveR: t2 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -941,7 +941,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ jump4 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t0. self MoveR: t0 R: t2. - jump5 := self Jump: b504. + jump5 := self Jump: b500. currentBlock := self Label. jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. @@ -961,7 +961,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t2. - b500 := self Label. + b496 := self Label. self MoveR: t2 R: t1. self AndCq: 7 R: t1. self CmpCq: 0 R: t1. @@ -972,7 +972,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t1. self MoveR: t1 R: t2. - jump6 := self Jump: b500. + jump6 := self Jump: b496. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -1007,7 +1007,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ "AutoGenerated by Druid" - | jump1 b504 s57 s54 t1 jump6 jump3 currentBlock b500 t0 jump5 jump2 live t2 jump4 | + | jump1 s57 s54 t1 jump6 jump3 b496 b500 currentBlock t0 jump5 jump2 live t2 jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -1032,7 +1032,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t2. - b504 := self Label. + b500 := self Label. self MoveR: t2 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -1043,7 +1043,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ jump4 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t0. self MoveR: t0 R: t2. - jump5 := self Jump: b504. + jump5 := self Jump: b500. currentBlock := self Label. jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. @@ -1063,7 +1063,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t2. - b500 := self Label. + b496 := self Label. self MoveR: t2 R: t1. self AndCq: 7 R: t1. self CmpCq: 0 R: t1. @@ -1074,7 +1074,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t1. self MoveR: t1 R: t2. - jump6 := self Jump: b500. + jump6 := self Jump: b496. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -1486,7 +1486,7 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ "AutoGenerated by Druid" - | s6 s11 s88 jump5 s55 s4 jump3 jump8 s2 s36 currentBlock s84 s58 s12 s60 t1 jump1 s82 s47 jump6 s10 s5 live b617 jump4 jumpTrue jumpNext jump9 s3 t2 jump2 jump7 t0 s50 | + | s6 s11 s88 jump5 s55 s4 jump3 jump8 s2 s36 currentBlock s84 s58 s12 s60 t1 jump1 s82 s47 jump6 s10 s5 live jump4 jumpTrue jumpNext jump9 s3 t2 jump2 b613 jump7 t0 s50 | live := 0. self annotateBytecode: self Label. s3 := byte1. @@ -1518,7 +1518,7 @@ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ self CmpCq: 0 R: t2. jump1 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t2. - b617 := self Label. + b613 := self Label. self MoveR: t2 R: t1. self AndCq: 7 R: t1. self CmpCq: 0 R: t1. @@ -1529,7 +1529,7 @@ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t1. self MoveR: t1 R: t2. - jump4 := self Jump: b617. + jump4 := self Jump: b613. currentBlock := self Label. jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -1861,7 +1861,7 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ DruidTestRTLCompiler >> gen_extUnconditionalJump [ "AutoGenerated by Druid" - | s6 s3 jump1 s28 s10 t1 s8 s5 s2 s18 currentBlock s12 s27 t0 s4 s26 live s9 | + | s6 s3 s28 s10 t1 s8 s5 s2 s18 currentBlock s12 s27 t0 jump2 s4 s26 live s9 | live := 0. self annotateBytecode: self Label. s3 := byte1. @@ -1904,6 +1904,7 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ s28 := s27 + 2. self Jump: (self ensureFixupAt: s28). deadCode := true. + jump1 := self Jump: 0. ^ 0 ]. s12 := 0. s10 := s12. @@ -1921,15 +1922,16 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ self MoveR: SPReg R: t0. self MoveAw: coInterpreter stackLimitAddress R: t1. self CmpR: t1 R: t0. - jump1 := self JumpAboveOrEqual: 0. + jump2 := self JumpAboveOrEqual: 0. self CallRT: ceCheckForInterruptTrampoline. currentBlock := self Label. - jump1 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. s26 := bytecodePC. s27 := s26 + s6. s28 := s27 + 2. self Jump: (self ensureFixupAt: s28). deadCode := true. + jump2 := self Jump: 0. ^ 0 ] @@ -1937,7 +1939,7 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ DruidTestRTLCompiler >> gen_extendedPushBytecode [ "AutoGenerated by Druid" - | s6 s3 s19 s28 t1 s8 s5 s2 s18 currentBlock s27 s53 t0 s4 s26 live s20 s52 | + | s6 s3 s19 s28 s54 t1 s8 s5 s2 s30 currentBlock s21 t0 s4 s29 s55 live s20 | live := 0. s2 := byte1. s3 := s2 >> 6. @@ -1952,7 +1954,8 @@ DruidTestRTLCompiler >> gen_extendedPushBytecode [ self MoveR: ReceiverResultReg R: t0. s8 := s5 << 3. self AddCq: s8 R: t0. - self ssPushBase: t0 offset: 8. + self MoveM64: 8 r: t0 R: t0. + self ssPushRegister: t0. ^ 0 ]. s4 = 1 ifTrue: [ (self simStackTempAt: s5) copyToReg: t0. @@ -1960,30 +1963,31 @@ DruidTestRTLCompiler >> gen_extendedPushBytecode [ ^ 0 ]. s4 = 2 ifTrue: [ self genMoveConstant: methodObj R: t0. - s18 := LiteralStart. - s19 := s5 + s18. - s20 := s19 << 3. - self AddCq: s20 R: t0. - self ssPushBase: t0 offset: 8. + s19 := LiteralStart. + s20 := s5 + s19. + s21 := s20 << 3. + self AddCq: s21 R: t0. + self MoveM64: 8 r: t0 R: t0. + self ssPushRegister: t0. ^ 0 ]. t1 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). s4 = 3 ifTrue: [ - | jump3 jump1 b327 jump4 jump2 | + | jump3 jump1 b320 jump4 jump2 | self genMoveConstant: methodObj R: t0. - s26 := LiteralStart. - s27 := s5 + s26. - s28 := s27 << 3. - self AddCq: s28 R: t0. + s28 := LiteralStart. + s29 := s5 + s28. + s30 := s29 << 3. + self AddCq: s30 R: t0. self MoveM64: 8 r: t0 R: t0. self MoveM64: 0 r: t0 R: t1. self AndCq: 16r3FFFF7 R: t1. self CmpCq: 0 R: t1. jump1 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t1. - b327 := self Label. + b320 := self Label. self MoveR: t1 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -1994,7 +1998,7 @@ DruidTestRTLCompiler >> gen_extendedPushBytecode [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t0. self MoveR: t0 R: t1. - jump4 := self Jump: b327. + jump4 := self Jump: b320. currentBlock := self Label. jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -2004,11 +2008,13 @@ DruidTestRTLCompiler >> gen_extendedPushBytecode [ jump1 jmpTarget: currentBlock. currentBlock := self Label. jump3 jmpTarget: currentBlock. - s52 := ValueIndex. - s53 := s52 << 3. - self AddCq: s53 R: t0. - self ssPushBase: t0 offset: 8. + s54 := ValueIndex. + s55 := s54 << 3. + self AddCq: s55 R: t0. + self MoveM64: 8 r: t0 R: t0. + self ssPushRegister: t0. ^ 0 ]. + self ssPushRegister: t0. ^ 0 ] @@ -8016,7 +8022,7 @@ DruidTestRTLCompiler >> gen_pushLiteralConstantBytecode [ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ "AutoGenerated by Druid" - | jump1 s3 s28 t1 jump3 b237 currentBlock t0 jump2 s4 s29 live jump4 | + | jump1 s3 s28 b232 t1 jump3 currentBlock t0 jump2 s4 s29 live jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -8036,7 +8042,7 @@ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ self CmpCq: 0 R: t1. jump1 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t1. - b237 := self Label. + b232 := self Label. self MoveR: t1 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -8047,7 +8053,7 @@ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t0. self MoveR: t0 R: t1. - jump4 := self Jump: b237. + jump4 := self Jump: b232. currentBlock := self Label. jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. diff --git a/Druid/DRBytecodeIRGenerator.class.st b/Druid/DRBytecodeIRGenerator.class.st index ec8aa631..c0aea7bb 100644 --- a/Druid/DRBytecodeIRGenerator.class.st +++ b/Druid/DRBytecodeIRGenerator.class.st @@ -1,6 +1,6 @@ Class { #name : #DRBytecodeIRGenerator, - #superclass : #DRPrimitiveIRGenerator, + #superclass : #DRMetaCompilerIRGenerator, #instVars : [ 'jumpOffset' ], @@ -23,16 +23,11 @@ DRBytecodeIRGenerator >> finishCodeInterpretation: lastFrame [ currentBasicBlock jumpTo: controlFlowGraph exitBasicBlock ] -{ #category : #accessing } +{ #category : #initialization } DRBytecodeIRGenerator >> initialize [ super initialize. - jumpOffset := 0. - - controlFlowGraph successExitBlock:controlFlowGraph newBasicBlock. - controlFlowGraph successExitBlock beExitBlock. - controlFlowGraph failureExitBlock: controlFlowGraph newBasicBlock. - controlFlowGraph failureExitBlock beExitBlock. + jumpOffset := 0 ] { #category : #accessing } @@ -405,7 +400,7 @@ DRBytecodeIRGenerator >> interpretStackValueWith: aRBMessageNode [ | value | aRBMessageNode arguments first acceptVisitor: self. -1halt. + ^ self addInstructionFrom: aRBMessageNode instructionKind: DRLoadStackValue @@ -436,10 +431,10 @@ DRBytecodeIRGenerator >> newBasicBlockWithState: executionState [ ^ newBasicBlock ] -{ #category : #accessing } +{ #category : #initialization } DRBytecodeIRGenerator >> newCFG [ - ^ DRPrimitiveControlFlowGraph new + ^ DRControlFlowGraph new ] { #category : #accessing } diff --git a/Druid/DRCogitCodeGenerator.class.st b/Druid/DRCogitCodeGenerator.class.st index 02c6c571..6834d53c 100644 --- a/Druid/DRCogitCodeGenerator.class.st +++ b/Druid/DRCogitCodeGenerator.class.st @@ -254,15 +254,7 @@ DRCogitCodeGenerator >> generateCodeForCFG: aDRControlFlowGraph [ aDRControlFlowGraph stagedRegisters do: [ :e | generatorMethodBuilder addVariableNamed: e prettyPrint ]. - "Sort the blocks" - blocks := aDRControlFlowGraph reversePostOrderBlocks. - - "Make sure the failure exit block is at the end, so it works as a fallthrough with the following bytecode" - (blocks includes: aDRControlFlowGraph failureExitBlock) ifTrue: [ - blocks remove: aDRControlFlowGraph failureExitBlock. - blocks addLast: aDRControlFlowGraph failureExitBlock ]. - - "Generate CFG code" + blocks := self linearizeBlocksInCFG: aDRControlFlowGraph. self generateCodeFromBlocks. "Generate the postamble in the fallthrough case" @@ -452,6 +444,12 @@ DRCogitCodeGenerator >> generatorMethodBuilder: aDRGeneratorMethodBuilder [ generatorMethodBuilder := aDRGeneratorMethodBuilder ] +{ #category : #'jump-management' } +DRCogitCodeGenerator >> hasDeferredBranchesTo: aDRBasicBlock [ + + ^ deferredBranches includesKey: aDRBasicBlock +] + { #category : #testing } DRCogitCodeGenerator >> hasIncomingBackjumps: aDRBasicBlock [ @@ -563,6 +561,12 @@ DRCogitCodeGenerator >> labelForJump: jumpIndex [ ^ 'jump', jumpIndex asString ] +{ #category : #'ir-to-ast' } +DRCogitCodeGenerator >> linearizeBlocksInCFG: aDRControlFlowGraph [ + + ^ aDRControlFlowGraph reversePostOrderBlocks +] + { #category : #visiting } DRCogitCodeGenerator >> oneOperandCogitRTL: aMnemonic operands: operands instruction: anInstruction [ diff --git a/Druid/DRCogitPrimitiveCodeGenerator.class.st b/Druid/DRCogitPrimitiveCodeGenerator.class.st index 24d5fcfb..e6d240d3 100644 --- a/Druid/DRCogitPrimitiveCodeGenerator.class.st +++ b/Druid/DRCogitPrimitiveCodeGenerator.class.st @@ -15,6 +15,21 @@ DRCogitPrimitiveCodeGenerator >> copyRegister: sourceRegister to: destinationReg (RBVariableNode named: destinationRegister) }) ] +{ #category : #'ir-to-ast' } +DRCogitPrimitiveCodeGenerator >> linearizeBlocksInCFG: aControlFlowGraph [ + + | linearizedBlocks | + linearizedBlocks := super linearizeBlocksInCFG: aControlFlowGraph. + + "Make sure the failure exit block is at the end, so it works as a fallthrough with the following bytecode" + (linearizedBlocks includes: aControlFlowGraph failureExitBlock) + ifTrue: [ + linearizedBlocks remove: aControlFlowGraph failureExitBlock. + linearizedBlocks addLast: aControlFlowGraph failureExitBlock ]. + + ^ linearizedBlocks +] + { #category : #'ir-to-ast' } DRCogitPrimitiveCodeGenerator >> returnNodeForCompiledMethod: aDRControlFlowGraph [ diff --git a/Druid/DRCogitStackToRegisterMappingGenerator.class.st b/Druid/DRCogitStackToRegisterMappingGenerator.class.st index b928cd3c..fb1cb738 100644 --- a/Druid/DRCogitStackToRegisterMappingGenerator.class.st +++ b/Druid/DRCogitStackToRegisterMappingGenerator.class.st @@ -62,11 +62,12 @@ DRCogitStackToRegisterMappingGenerator >> moveToReg: aRBMessageNode from: aDRIns { #category : #'ir-to-ast' } DRCogitStackToRegisterMappingGenerator >> preProcessBlock: aBasicBlock [ - markDeadCode ifTrue: [ "If a previous instruction marked dead code, we need to unmark it because we keep generating code" - markDeadCode := false. - generatorMethodBuilder addStatement: (RBAssignmentNode - variable: (RBVariableNode named: 'deadCode') - value: (RBLiteralNode value: false)) ]. + (markDeadCode and: [ self hasDeferredBranchesTo: aBasicBlock ]) + ifTrue: [ "If a previous instruction marked dead code, we need to unmark it because we keep generating code" + markDeadCode := false. + generatorMethodBuilder addStatement: (RBAssignmentNode + variable: (RBVariableNode named: 'deadCode') + value: (RBLiteralNode value: false)) ]. super preProcessBlock: aBasicBlock ] diff --git a/Druid/DRMetaCompilerIRGenerator.class.st b/Druid/DRMetaCompilerIRGenerator.class.st index efb4bb9f..bf3defd0 100644 --- a/Druid/DRMetaCompilerIRGenerator.class.st +++ b/Druid/DRMetaCompilerIRGenerator.class.st @@ -18,7 +18,7 @@ DRMetaCompilerIRGenerator >> currentPrimitiveFailureCode: anInstruction [ self executionState primitiveFailureCode: anInstruction ] -{ #category : #initialization } +{ #category : #'special cases' } DRMetaCompilerIRGenerator >> initializeSpecialCases [ super initializeSpecialCases. @@ -32,6 +32,30 @@ DRMetaCompilerIRGenerator >> initializeSpecialCases [ specialCases at: #pop: put: #interpretPopThenPushWith:. specialCases at: #push: put: #interpretPushWith:. + specialCases at: #remember: put: #interpretRememberWith:. +] + +{ #category : #interpreting } +DRMetaCompilerIRGenerator >> interpretAssignmentNode: aRBAssignmentNode [ + + | value | + aRBAssignmentNode value acceptVisitor: self. + "Keep instruction in CFG for inlinings" + value := currentBasicBlock strongCopyForInlining: self operandStackTop. + + aRBAssignmentNode variable binding isInstanceVariable ifTrue: [ + ^ self receiver value + instVarNamed: aRBAssignmentNode variable name + put: value ]. + + aRBAssignmentNode variable binding originalVar isTempVariable + ifTrue: [ + ^ self topFrame + temporaryAt: aRBAssignmentNode variable name + put: value + withState: executionState ]. + + self halt ] { #category : #interpretation } @@ -61,6 +85,18 @@ DRMetaCompilerIRGenerator >> interpretPushWith: aRBMessageNode [ ^ self addInstructionWithNoResultFrom: aRBMessageNode instructionKind: DRPush operands: { receiver } ] +{ #category : #'special-cases' } +DRMetaCompilerIRGenerator >> interpretRememberWith: aRBMessageNode [ + + | obj | + obj := self visitOperand: aRBMessageNode arguments first. + ^ (self + addInstructionCall: { + 'ceStoreCheckTrampoline'. + obj } + from: aRBMessageNode) beMapped saveLinkReg +] + { #category : #visiting } DRMetaCompilerIRGenerator >> methodFor: aRBMessageNode withReceiver: receiver [ @@ -81,6 +117,32 @@ DRMetaCompilerIRGenerator >> numberOfArguments: aValue [ self push: (self argRegisterNumber: i) ] ] +{ #category : #'frame-access' } +DRMetaCompilerIRGenerator >> popFrameMergingDeferredReturns [ + + | exitBasicBlock topReturns | + exitBasicBlock := self topFrame exitBasicBlock. + topReturns := self topFrame deferredMethodReturns. + topReturns size > 0 + ifTrue: [ + | mergedState | + self assert: exitBasicBlock predecessors isEmpty. "If not, check if new predecessors will be added" + topReturns keysDo: [ :frameReturn | + frameReturn breakBasicBlock. "Breaking the block in case of be shared by many returns" + frameReturn basicBlock jumpTo: exitBasicBlock ]. + mergedState := DRStackMerger new + builder: self; + mergeBlock: exitBasicBlock; + mergeAll: topReturns values upTo: self topFrame. + executionState := mergedState. + currentBasicBlock := exitBasicBlock ]. + + "Returns installed in the CFG -> stop tracking" + self topFrame clearDeferredMethodReturns. + + ^ executionState popFrame +] + { #category : #configure } DRMetaCompilerIRGenerator >> receiver: aDRValue [ diff --git a/Druid/DRPrimitiveIRGenerator.class.st b/Druid/DRPrimitiveIRGenerator.class.st index 36446204..d4ba7a5d 100644 --- a/Druid/DRPrimitiveIRGenerator.class.st +++ b/Druid/DRPrimitiveIRGenerator.class.st @@ -85,7 +85,7 @@ DRPrimitiveIRGenerator >> initialize [ controlFlowGraph failureExitBlock beExitBlock. ] -{ #category : #accessing } +{ #category : #'special cases' } DRPrimitiveIRGenerator >> initializeSpecialCases [ super initializeSpecialCases. @@ -93,7 +93,6 @@ DRPrimitiveIRGenerator >> initializeSpecialCases [ specialCases at: #executeFullCogBlock:closure:mayContextSwitch: put: #executeFullCogBlockClosureMayContextSwitchWith:. - specialCases at: #remember: put: #interpretRememberWith:. specialCases at: #newHashBitsOf: put: #interpretNewHashBitsOfWith: ] @@ -108,29 +107,6 @@ DRPrimitiveIRGenerator >> inlineGenerator [ yourself ] -{ #category : #interpreting } -DRPrimitiveIRGenerator >> interpretAssignmentNode: aRBAssignmentNode [ - - | value | - aRBAssignmentNode value acceptVisitor: self. - "Keep instruction in CFG for inlinings" - value := currentBasicBlock strongCopyForInlining: self operandStackTop. - - aRBAssignmentNode variable binding isInstanceVariable ifTrue: [ - ^ self receiver value - instVarNamed: aRBAssignmentNode variable name - put: value ]. - - aRBAssignmentNode variable binding originalVar isTempVariable - ifTrue: [ - ^ self topFrame - temporaryAt: aRBAssignmentNode variable name - put: value - withState: executionState ]. - - self halt -] - { #category : #interpretation } DRPrimitiveIRGenerator >> interpretDruidExitPointWith: aRBMethodNode [ @@ -188,18 +164,6 @@ DRPrimitiveIRGenerator >> interpretPrimFailCodeWith: aRBNode [ self pushOperand: executionState primitiveFailureCode ] -{ #category : #'special-cases' } -DRPrimitiveIRGenerator >> interpretRememberWith: aRBMessageNode [ - - | obj | - obj := self visitOperand: aRBMessageNode arguments first. - ^ (self - addInstructionCall: { - 'ceStoreCheckTrampoline'. - obj } - from: aRBMessageNode) beMapped saveLinkReg -] - { #category : #accessing } DRPrimitiveIRGenerator >> newBasicBlock [ @@ -221,32 +185,6 @@ DRPrimitiveIRGenerator >> newCFG [ ^ DRPrimitiveControlFlowGraph new ] -{ #category : #'frame-access' } -DRPrimitiveIRGenerator >> popFrameMergingDeferredReturns [ - - | exitBasicBlock topReturns | - exitBasicBlock := self topFrame exitBasicBlock. - topReturns := self topFrame deferredMethodReturns. - topReturns size > 0 - ifTrue: [ - | mergedState | - self assert: exitBasicBlock predecessors isEmpty. "If not, check if new predecessors will be added" - topReturns keysDo: [ :frameReturn | - frameReturn breakBasicBlock. "Breaking the block in case of be shared by many returns" - frameReturn basicBlock jumpTo: exitBasicBlock ]. - mergedState := DRStackMerger new - builder: self; - mergeBlock: exitBasicBlock; - mergeAll: topReturns values upTo: self topFrame. - executionState := mergedState. - currentBasicBlock := exitBasicBlock ]. - - "Returns installed in the CFG -> stop tracking" - self topFrame clearDeferredMethodReturns. - - ^ executionState popFrame -] - { #category : #frames } DRPrimitiveIRGenerator >> pushFrame: aDruidStackFrame [ diff --git a/Druid/SimpleStackBasedCogit.extension.st b/Druid/SimpleStackBasedCogit.extension.st index ff93950c..b0ffc46e 100644 --- a/Druid/SimpleStackBasedCogit.extension.st +++ b/Druid/SimpleStackBasedCogit.extension.st @@ -16,7 +16,6 @@ SimpleStackBasedCogit class >> druidNewOptimizationList [ "Basic set of optimizations twice for primitives" 3 timesRepeat: [ optimisations add: DRBranchCollapse new. - optimisations add: DRFailureCodeBasedTailDuplication new. optimisations add: (DRSCCP then: DRDeadBlockElimination). optimisations add: DRCopyPropagation new. diff --git a/Druid/StackToRegisterMappingCogit.extension.st b/Druid/StackToRegisterMappingCogit.extension.st index c9b5320e..3c95ba71 100644 --- a/Druid/StackToRegisterMappingCogit.extension.st +++ b/Druid/StackToRegisterMappingCogit.extension.st @@ -16,7 +16,6 @@ StackToRegisterMappingCogit class >> druidNewOptimizationList [ optimisations add: DRCogitStackCoalescing new. 4 timesRepeat: [ optimisations add: DRBranchCollapse new. - optimisations add: DRFailureCodeBasedTailDuplication new. optimisations add: (DRSCCP then: DRDeadBlockElimination). optimisations add: (DRPhiSimplication then: DRCopyPropagation). optimisations add: DRCogitStackCanonicaliser new. From 9e2d78b0754dd7ddf96f2741171e7581f30fd6bf Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Wed, 24 Apr 2024 11:14:49 +0200 Subject: [PATCH 07/33] Division operands should be mutable --- Druid-Tests/DruidTestRTLCompiler.class.st | 17 +++++++++-------- Druid/DRDivision.class.st | 6 ++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index a18ce185..5b696043 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -3604,16 +3604,17 @@ DruidTestRTLCompiler >> gen_primitiveBitShift [ self CmpCq: 0 R: SendNumArgsReg. jump1 := self JumpLessOrEqual: 0. self LogicalShiftLeftR: SendNumArgsReg R: ClassReg. - self MoveR: ClassReg R: ReceiverResultReg. + self MoveR: ClassReg R: SendNumArgsReg. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: SendNumArgsReg. self NegateR: SendNumArgsReg. self LogicalShiftRightR: SendNumArgsReg R: ClassReg. - self MoveR: ClassReg R: ReceiverResultReg. + self MoveR: ClassReg R: SendNumArgsReg. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -4131,9 +4132,9 @@ DruidTestRTLCompiler >> gen_primitiveDivide [ self DivR: SendNumArgsReg R: ClassReg - Quo: SendNumArgsReg - Rem: ClassReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. + Quo: ClassReg + Rem: SendNumArgsReg. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -5972,9 +5973,9 @@ DruidTestRTLCompiler >> gen_primitiveIntegerDivide [ self DivR: SendNumArgsReg R: ClassReg - Quo: ClassReg - Rem: SendNumArgsReg. - self MoveR: ClassReg R: ReceiverResultReg. + Quo: SendNumArgsReg + Rem: ClassReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] diff --git a/Druid/DRDivision.class.st b/Druid/DRDivision.class.st index f2c5ae89..13425c72 100644 --- a/Druid/DRDivision.class.st +++ b/Druid/DRDivision.class.st @@ -22,6 +22,12 @@ DRDivision >> opcode [ ^ 'DIV' ] +{ #category : #accessing } +DRDivision >> operands: aCollection [ + + super operands: aCollection asOrderedCollection +] + { #category : #SCCP } DRDivision >> sccpOperateOnLattice: operand and: operand2 [ From 76e40c836307a70b176f36f2f460854321476393 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Wed, 24 Apr 2024 11:19:52 +0200 Subject: [PATCH 08/33] Fix dead block elimination tests --- Druid-Tests/DRDeadBlockEliminationTest.class.st | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Druid-Tests/DRDeadBlockEliminationTest.class.st b/Druid-Tests/DRDeadBlockEliminationTest.class.st index 6f131e2c..ac7ef4e2 100644 --- a/Druid-Tests/DRDeadBlockEliminationTest.class.st +++ b/Druid-Tests/DRDeadBlockEliminationTest.class.st @@ -16,7 +16,7 @@ Class { #category : #'Druid-Tests-Optimizations' } -{ #category : #initialization } +{ #category : #running } DRDeadBlockEliminationTest >> setUp [ super setUp. @@ -25,7 +25,7 @@ DRDeadBlockEliminationTest >> setUp [ cfg := DRControlFlowGraph new. entryBlock := cfg newBasicBlock. - exitBlock := cfg newBasicBlock. + exitBlock := cfg exitBasicBlock. deadBlock := cfg newBasicBlock. deadBlock2 := cfg newBasicBlock. From 8895f872e1d53a4fce58cff235e6e2a3afcfb1d7 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Wed, 24 Apr 2024 11:50:30 +0200 Subject: [PATCH 09/33] Fix linearization tests merge state tests --- Druid-Tests/DRLinearizationTest.class.st | 4 ++-- Druid/DRPhiFunction.class.st | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Druid-Tests/DRLinearizationTest.class.st b/Druid-Tests/DRLinearizationTest.class.st index 25118325..1868526d 100644 --- a/Druid-Tests/DRLinearizationTest.class.st +++ b/Druid-Tests/DRLinearizationTest.class.st @@ -79,7 +79,7 @@ DRLinearizationTest >> testBranchingControlFlowWithStackDependency [ firstPush := b2 push: 1. secondPush := b3 push: 2. - secondPush stackDependency: firstPush. + secondPush stackDependency: {firstPush}. self assert: cfg reversePostOrderBlocks asArray equals: { b1. @@ -113,7 +113,7 @@ DRLinearizationTest >> testBranchingControlFlowWithStackDependencyReversed [ firstPush := b3 push: 1. secondPush := b2 push: 2. - secondPush stackDependency: firstPush. + secondPush stackDependency: {firstPush}. self assert: cfg reversePostOrderBlocks asArray equals: { b1. diff --git a/Druid/DRPhiFunction.class.st b/Druid/DRPhiFunction.class.st index b61e189f..ddd648eb 100644 --- a/Druid/DRPhiFunction.class.st +++ b/Druid/DRPhiFunction.class.st @@ -152,6 +152,12 @@ DRPhiFunction >> opcode [ ] +{ #category : #accessing } +DRPhiFunction >> operands: aCollection [ + + super operands: aCollection asOrderedCollection +] + { #category : #accessing } DRPhiFunction >> predecessorAtOperand: anOperand [ From 53d65afbe329381af5caf92944ae619fbe2e02fe Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Wed, 24 Apr 2024 13:58:21 +0200 Subject: [PATCH 10/33] Removal of exitBasicBlock step 1 --- ...RComposedConditionalSplittingTest.class.st | 12 +++--- .../DRDeadBlockEliminationTest.class.st | 2 +- .../DRDeadCodeEliminationTest.class.st | 37 ++++++++++--------- .../DRDeadPathEliminationTest.class.st | 6 +-- Druid-Tests/DRDominatorTreeTest.class.st | 20 +++++----- Druid-Tests/DRIRTest.class.st | 8 ++-- Druid-Tests/DRPostdominatorTreeTest.class.st | 20 +++++----- ...CCPConditionalConstantFoldingTest.class.st | 2 +- .../DRSCCPConstantFoldingTest.class.st | 30 +++++++-------- ...CCPConstantFoldingWithStagingTest.class.st | 14 +++---- .../DRSCCPConstantPropagationTest.class.st | 22 +++++------ Druid-Tests/DRTailDuplicationTest.class.st | 14 +++---- Druid/DRBasicBlock.class.st | 8 +++- Druid/DRBytecodeIRGenerator.class.st | 4 +- Druid/DRCode.class.st | 3 +- Druid/DRControlFlowGraph.class.st | 22 +++++------ Druid/DRDominatorTree.class.st | 21 ++++------- Druid/DRIRGenerator.class.st | 1 + Druid/DRMetaCompilerIRGenerator.class.st | 2 +- Druid/DRMethodIRGenerator.class.st | 16 ++++---- Druid/DRPrimitiveControlFlowGraph.class.st | 6 --- Druid/DRStackFrame.class.st | 12 ------ 22 files changed, 131 insertions(+), 151 deletions(-) diff --git a/Druid-Tests/DRComposedConditionalSplittingTest.class.st b/Druid-Tests/DRComposedConditionalSplittingTest.class.st index 5f822e13..7b334299 100644 --- a/Druid-Tests/DRComposedConditionalSplittingTest.class.st +++ b/Druid-Tests/DRComposedConditionalSplittingTest.class.st @@ -34,7 +34,7 @@ DRComposedConditionalSplittingTest >> testSplitAnd [ cfg applyOptimisation: optimisation. - newBlock := cfg blocks last. + newBlock := jump trueBranch. newJump := newBlock endInstruction. self assert: jump operand1 equals: composedCondition operand1. @@ -60,9 +60,9 @@ DRComposedConditionalSplittingTest >> testSplitMultipleComposedCondition [ cfg applyOptimisation: optimisation. - newBlock1 := cfg blocks allButLast last. + newBlock1 := jump trueBranch endInstruction trueBranch. newJump1 := newBlock1 endInstruction. - newBlock2 := cfg blocks last. + newBlock2 := jump trueBranch. newJump2 := newBlock2 endInstruction. self assert: jump operand1 equals: composedCondition operand1 operand1. @@ -91,9 +91,9 @@ DRComposedConditionalSplittingTest >> testSplitMultipleComposedConditionLeftAsso cfg applyOptimisation: optimisation. - newBlock1 := cfg blocks last. + newBlock1 := jump trueBranch. newJump1 := newBlock1 endInstruction. - newBlock2 := cfg blocks allButLast last. + newBlock2 := jump trueBranch endInstruction trueBranch. newJump2 := newBlock2 endInstruction. self assert: jump operand1 equals: composedCondition operand1 operand1. @@ -122,7 +122,7 @@ DRComposedConditionalSplittingTest >> testSplitOr [ cfg applyOptimisation: optimisation. - newBlock := cfg blocks last. + newBlock := jump falseBranch. newJump := newBlock endInstruction. self assert: jump operand1 equals: composedCondition operand1. diff --git a/Druid-Tests/DRDeadBlockEliminationTest.class.st b/Druid-Tests/DRDeadBlockEliminationTest.class.st index ac7ef4e2..abf8828e 100644 --- a/Druid-Tests/DRDeadBlockEliminationTest.class.st +++ b/Druid-Tests/DRDeadBlockEliminationTest.class.st @@ -25,7 +25,7 @@ DRDeadBlockEliminationTest >> setUp [ cfg := DRControlFlowGraph new. entryBlock := cfg newBasicBlock. - exitBlock := cfg exitBasicBlock. + exitBlock := cfg newBasicBlock. deadBlock := cfg newBasicBlock. deadBlock2 := cfg newBasicBlock. diff --git a/Druid-Tests/DRDeadCodeEliminationTest.class.st b/Druid-Tests/DRDeadCodeEliminationTest.class.st index 54cbe48a..5d9e96d3 100644 --- a/Druid-Tests/DRDeadCodeEliminationTest.class.st +++ b/Druid-Tests/DRDeadCodeEliminationTest.class.st @@ -14,7 +14,7 @@ DRDeadCodeEliminationTest >> setUp [ { #category : #tests } DRDeadCodeEliminationTest >> testDCEOnConditionalJump [ - | cfg copy1 copy2 copy3 copy4 copy5 copy6 jump add1 add2 phi| + | cfg copy1 copy2 copy3 copy4 copy5 copy6 jump add1 add2 phi instructionsBefore | copy1 := DRCopy operands: { (DRConstantValue value: 1) } result: (DRSSARegister name: 1). @@ -52,17 +52,18 @@ DRDeadCodeEliminationTest >> testDCEOnConditionalJump [ "value" phi. "address" 17 asDRValue }). + instructionsBefore := cfg instructions size. optimisation applyTo: cfg. "Should eliminate R1:= and R2:=" - self assert: cfg instructions size equals: 12. + self assert: cfg instructions size equals: instructionsBefore - 2. ] { #category : #tests } DRDeadCodeEliminationTest >> testDCEOnDeadEndInstruction [ - | cfg copy1 copy2 phi1| + | cfg copy1 copy2 phi1 instructionsBefore | cfg := self setUpCFG: 2. cfg b1 addInstruction: (DRCopy operands: { DRConstantValue value: 1 } result: (DRSSARegister name: 1)). @@ -78,31 +79,30 @@ DRDeadCodeEliminationTest >> testDCEOnDeadEndInstruction [ "value" phi1. "address" 17 asDRValue }). + instructionsBefore := cfg instructions size. optimisation applyTo: cfg. - self assert: cfg instructions size equals: 6. "4 + Jump + Noop" + self assert: cfg instructions size equals: instructionsBefore - 1. self assert: cfg instructions first equals: copy1. ] { #category : #tests } DRDeadCodeEliminationTest >> testDCEOnSeveralBlocs [ - | b1 b2 cfg copy1 | - cfg := self setUpCFG: 2. - + | b1 b2 cfg copy1 instructionsBefore | + cfg := self setUpCFG: 2. + b1 := cfg b1. b2 := cfg b2. - b1 addInstruction: (copy1 := DRCopy operands: { DRConstantValue value: 1 } result: (DRSSARegister name: 1)). - - b2 addInstruction: (DRStore new operands: { - "size" 8 asDRValue. - "value" copy1. - "address" 17 asDRValue }). + b1 copy: 1. + + b2 storeSInt64: copy1 at: 17 asDRValue. + instructionsBefore := cfg instructions size. optimisation applyTo: cfg. - - self assert: cfg instructions size equals: 4. + + self assert: cfg instructions size equals: instructionsBefore - 1 ] { #category : #test } @@ -123,13 +123,14 @@ DRDeadCodeEliminationTest >> testNotRemoveUnusedMandatoryInstruction [ { #category : #tests } DRDeadCodeEliminationTest >> testRemoveUnusedNoop [ - | cfg | + | cfg instructionsBefore | cfg := self setUpCFG: 2. cfg b2 addInstruction: (DRNoop new result: DRNoRegister new). - + + instructionsBefore := cfg instructions size. optimisation applyTo: cfg. - self assert: cfg instructions size equals: 2. + self assert: cfg instructions size equals: instructionsBefore - 1. self assert: cfg instructions first isJump. "1 -> 2" ] diff --git a/Druid-Tests/DRDeadPathEliminationTest.class.st b/Druid-Tests/DRDeadPathEliminationTest.class.st index ed246e3f..f5e82175 100644 --- a/Druid-Tests/DRDeadPathEliminationTest.class.st +++ b/Druid-Tests/DRDeadPathEliminationTest.class.st @@ -90,8 +90,8 @@ DRDeadPathEliminationTest >> testEliminateDoubleDeadPaths [ cfg generatePaths. - lastPaths := cfg incomingEdgesFor: cfg lastBasicBlock. - lastBlocks := cfg lastBasicBlock predecessors. + lastPaths := cfg exitBasicBlocks collect: [ :e | cfg incomingEdgesFor: e ]. + lastBlocks := cfg exitBasicBlocks. lastPathsLeft := cfg incomingEdgesFor: lastBlocks first. lastPathsRight := cfg incomingEdgesFor: lastBlocks last. @@ -132,7 +132,7 @@ DRDeadPathEliminationTest >> testEliminateInnerDeadPaths [ self optimize: cfg. cfg generatePaths. - lastBlocks := cfg lastBasicBlock predecessors. + lastBlocks := cfg exitBasicBlocks. self assert: cfg deadPaths isEmpty. self assert: lastBlocks first firstInstruction isCopy. diff --git a/Druid-Tests/DRDominatorTreeTest.class.st b/Druid-Tests/DRDominatorTreeTest.class.st index 20e7157b..e441f15e 100644 --- a/Druid-Tests/DRDominatorTreeTest.class.st +++ b/Druid-Tests/DRDominatorTreeTest.class.st @@ -12,7 +12,7 @@ DRDominatorTreeTest >> testConditionalCFGDomination [ b0 := cfg initialBasicBlock. b1 := cfg newBasicBlock. - b2 := cfg exitBasicBlock. + b2 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b2. @@ -57,7 +57,7 @@ DRDominatorTreeTest >> testDegenerateLoopCFGDomination [ b2 := cfg newBasicBlock. b3 := cfg newBasicBlock. b4 := cfg newBasicBlock. - b5 := cfg exitBasicBlock. + b5 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b3. @@ -89,7 +89,7 @@ DRDominatorTreeTest >> testDegenerateLoopCFGImmediateDomination [ b2 := cfg newBasicBlock. b3 := cfg newBasicBlock. b4 := cfg newBasicBlock. - b5 := cfg exitBasicBlock. + b5 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b3. @@ -118,7 +118,7 @@ DRDominatorTreeTest >> testDiamondConditionalCFGDomination [ b0 := cfg initialBasicBlock. b1 := cfg newBasicBlock. b2 := cfg newBasicBlock. - b3 := cfg exitBasicBlock. + b3 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b3. @@ -150,7 +150,7 @@ DRDominatorTreeTest >> testDoubleDiamondConditionalCFGDomination [ b4 := cfg newBasicBlock. b5 := cfg newBasicBlock. - b6 := cfg exitBasicBlock. + b6 := cfg newBasicBlock. b3 jumpIf: true to: b4 ifFalseTo: b5. b4 jumpTo: b6. @@ -191,7 +191,7 @@ DRDominatorTreeTest >> testDoubleDiamondConditionalCFGImmediateDomination [ b4 := cfg newBasicBlock. b5 := cfg newBasicBlock. - b6 := cfg exitBasicBlock. + b6 := cfg newBasicBlock. b3 jumpIf: true to: b4 ifFalseTo: b5. b4 jumpTo: b6. @@ -212,7 +212,7 @@ DRDominatorTreeTest >> testExactDominationFailsWithIncompleteNumberOfBlocks [ b0 := cfg initialBasicBlock. b1 := cfg newBasicBlock. b2 := cfg newBasicBlock. - b3 := cfg exitBasicBlock. + b3 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b3. b2 jumpTo: b3. @@ -233,7 +233,7 @@ DRDominatorTreeTest >> testLinearCFGDomination [ cfg := DRControlFlowGraphForTesting new. b0 := cfg initialBasicBlock. - b1 := cfg exitBasicBlock. + b1 := cfg newBasicBlock. b0 jumpTo: b1. self assert: (b0 isDominatorOfExactly: { b1 }). @@ -251,7 +251,7 @@ DRDominatorTreeTest >> testNestedDiamondConditionalCFGDomination [ b2 := cfg newBasicBlock. b3 := cfg newBasicBlock. b4 := cfg newBasicBlock. - b5 := cfg exitBasicBlock. + b5 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b5. @@ -285,7 +285,7 @@ DRDominatorTreeTest >> testNestedDiamondConditionalCFGImmediateDomination [ b2 := cfg newBasicBlock. b3 := cfg newBasicBlock. b4 := cfg newBasicBlock. - b5 := cfg exitBasicBlock. + b5 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b5. diff --git a/Druid-Tests/DRIRTest.class.st b/Druid-Tests/DRIRTest.class.st index f3fee084..d840240b 100644 --- a/Druid-Tests/DRIRTest.class.st +++ b/Druid-Tests/DRIRTest.class.st @@ -102,28 +102,28 @@ DRIRTest >> setUpCFG: n [ b0 := cfg initialBasicBlock. cfg b0: b0. n = 0 ifTrue: [ - b0 jumpTo: cfg exitBasicBlock. + b0 jumpTo: cfg newBasicBlock. ^ cfg ]. b1 := cfg newBasicBlock. cfg b1: b1. b0 jumpTo: b1. n = 1 ifTrue: [ - b1 jumpTo: cfg exitBasicBlock. + b1 jumpTo: cfg newBasicBlock. ^ cfg ]. b2 := cfg newBasicBlock. cfg b2: b2. b1 jumpTo: b2. n = 2 ifTrue: [ - b2 jumpTo: cfg exitBasicBlock. + b2 jumpTo: cfg newBasicBlock. ^ cfg ]. b3 := cfg newBasicBlock. cfg b3: b3. b2 jumpTo: b3. n = 3 ifTrue: [ - b3 jumpTo: cfg exitBasicBlock. + b3 jumpTo: cfg newBasicBlock. ^ cfg ]. self error: 'Unsupported graph size: ', n asString diff --git a/Druid-Tests/DRPostdominatorTreeTest.class.st b/Druid-Tests/DRPostdominatorTreeTest.class.st index dab7bf2c..2be2b4af 100644 --- a/Druid-Tests/DRPostdominatorTreeTest.class.st +++ b/Druid-Tests/DRPostdominatorTreeTest.class.st @@ -12,7 +12,7 @@ DRPostdominatorTreeTest >> testConditionalCFGDomination [ b0 := cfg initialBasicBlock. b1 := cfg newBasicBlock. - b2 := cfg exitBasicBlock. + b2 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b2. @@ -57,7 +57,7 @@ DRPostdominatorTreeTest >> testDegenerateLoopCFGDomination [ b2 := cfg newBasicBlock. b3 := cfg newBasicBlock. b4 := cfg newBasicBlock. - b5 := cfg exitBasicBlock. + b5 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b3. @@ -89,7 +89,7 @@ DRPostdominatorTreeTest >> testDegenerateLoopCFGImmediateDomination [ b2 := cfg newBasicBlock. b3 := cfg newBasicBlock. b4 := cfg newBasicBlock. - b5 := cfg exitBasicBlock. + b5 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b3. @@ -118,7 +118,7 @@ DRPostdominatorTreeTest >> testDiamondConditionalCFGDomination [ b0 := cfg initialBasicBlock. b1 := cfg newBasicBlock. b2 := cfg newBasicBlock. - b3 := cfg exitBasicBlock. + b3 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b3. @@ -150,7 +150,7 @@ DRPostdominatorTreeTest >> testDoubleDiamondConditionalCFGDomination [ b4 := cfg newBasicBlock. b5 := cfg newBasicBlock. - b6 := cfg exitBasicBlock. + b6 := cfg newBasicBlock. b3 jumpIf: true to: b4 ifFalseTo: b5. b4 jumpTo: b6. @@ -191,7 +191,7 @@ DRPostdominatorTreeTest >> testDoubleDiamondConditionalCFGImmediateDomination [ b4 := cfg newBasicBlock. b5 := cfg newBasicBlock. - b6 := cfg exitBasicBlock. + b6 := cfg newBasicBlock. b3 jumpIf: true to: b4 ifFalseTo: b5. b4 jumpTo: b6. @@ -212,7 +212,7 @@ DRPostdominatorTreeTest >> testExactDominationFailsWithIncompleteNumberOfBlocks b0 := cfg initialBasicBlock. b1 := cfg newBasicBlock. b2 := cfg newBasicBlock. - b3 := cfg exitBasicBlock. + b3 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b3. b2 jumpTo: b3. @@ -233,7 +233,7 @@ DRPostdominatorTreeTest >> testLinearCFGDomination [ cfg := DRControlFlowGraphForTesting new. b0 := cfg initialBasicBlock. - b1 := cfg exitBasicBlock. + b1 := cfg newBasicBlock. b0 jumpTo: b1. @@ -253,7 +253,7 @@ DRPostdominatorTreeTest >> testNestedDiamondConditionalCFGDomination [ b3 := cfg newBasicBlock. b4 := cfg newBasicBlock. b5 := cfg newBasicBlock. - b6 := cfg exitBasicBlock. + b6 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b6. @@ -291,7 +291,7 @@ DRPostdominatorTreeTest >> testNestedDiamondConditionalCFGImmediateDomination [ b3 := cfg newBasicBlock. b4 := cfg newBasicBlock. b5 := cfg newBasicBlock. - b6 := cfg exitBasicBlock. + b6 := cfg newBasicBlock. b0 jumpIf: true to: b1 ifFalseTo: b2. b1 jumpTo: b6. diff --git a/Druid-Tests/DRSCCPConditionalConstantFoldingTest.class.st b/Druid-Tests/DRSCCPConditionalConstantFoldingTest.class.st index 70cd0b54..98c37c57 100644 --- a/Druid-Tests/DRSCCPConditionalConstantFoldingTest.class.st +++ b/Druid-Tests/DRSCCPConditionalConstantFoldingTest.class.st @@ -253,5 +253,5 @@ DRSCCPConditionalConstantFoldingTest >> testSCCPPropagationWithFarAwayPhiFunctio cfg applyOptimisation: optimisation. - self assertCollection: cfg blocks hasSameElements: { b0 . b4 } + self assertCollection: cfg blocks hasSameElements: { b0 . b4 . cfg initialBasicBlock } ] diff --git a/Druid-Tests/DRSCCPConstantFoldingTest.class.st b/Druid-Tests/DRSCCPConstantFoldingTest.class.st index cc8915aa..f46d5066 100644 --- a/Druid-Tests/DRSCCPConstantFoldingTest.class.st +++ b/Druid-Tests/DRSCCPConstantFoldingTest.class.st @@ -7,8 +7,8 @@ Class { { #category : #assertions } DRSCCPConstantFoldingTest >> assertLastInstructionOf: cfg isCopyOf: instruction [ - self assert: cfg instructions allButLast last isCopy. - self assert: cfg instructions allButLast last operand1 equals: instruction. + self assert: cfg instructions fourth isCopy. + self assert: cfg instructions fourth operand1 equals: instruction. ] { #category : #assertions } @@ -40,9 +40,9 @@ DRSCCPConstantFoldingTest >> testConstantFoldingAddInSingleBasicBlock [ | cfg | cfg := self testConstantFoldingOf: DRAdd between: 3 and: 4. - self assert: cfg instructions allButLast last isCopy. + self assert: cfg instructions third isCopy. self - assert: cfg instructions allButLast last operand1 + assert: cfg instructions third operand1 equals: 7 asDRValue ] @@ -87,9 +87,9 @@ DRSCCPConstantFoldingTest >> testConstantFoldingBitAndInSingleBasicBlock [ between: 2r0101010110 and: 2r0101011111. - self assert: cfg instructions allButLast last isCopy. + self assert: cfg instructions third isCopy. self - assert: cfg instructions allButLast last operand1 + assert: cfg instructions third operand1 equals: 2r0101010110 asDRValue ] @@ -199,7 +199,7 @@ DRSCCPConstantFoldingTest >> testConstantFoldingLoadConstant [ optimisation applyTo: cfg. self assert: cfg instructions first isCopy. - self assert: cfg instructions allButLast last isLoad + self assert: cfg instructions second isLoad ] { #category : #tests } @@ -211,10 +211,10 @@ DRSCCPConstantFoldingTest >> testConstantFoldingLoadJitCompileExpression [ betweenOp: DRPointerType new and: self varJITExpression. - self assert: cfg instructions allButLast last isCopy. - self assert: (cfg instructions allButLast: 2) last isLoad. + self assert: cfg instructions first isCopy. + self assert: cfg instructions second isLoad. self - assert: (cfg instructions allButLast: 2) last address expression + assert: cfg instructions second address expression equals: cfg instructions first ] @@ -475,9 +475,9 @@ DRSCCPConstantFoldingTest >> testFoldBitShiftWithConstants [ | cfg | cfg := self testConstantFoldingOf: DRBitShift between: 2r1000 and: 1. - self assert: cfg instructions allButLast last isCopy. + self assert: cfg instructions third isCopy. self - assert: cfg instructions allButLast last operand1 + assert: cfg instructions third operand1 equals: 2r100 asDRValue ] @@ -507,8 +507,8 @@ DRSCCPConstantFoldingTest >> testFoldingLoadWithConstant [ optimisation applyTo: cfg. - self assert: cfg instructions nextToLast isCopy. - self assert: cfg instructions nextToLast operand1 equals: load + self assert: cfg instructions second isCopy. + self assert: cfg instructions second operand1 equals: load ] { #category : #tests } @@ -527,7 +527,7 @@ DRSCCPConstantFoldingTest >> testFoldingLoadWithOperation [ optimisation applyTo: cfg. "T3 := T2" - self assert: cfg instructions nextToLast operand1 equals: load + self assert: cfg instructions third operand1 equals: load ] { #category : #constant } diff --git a/Druid-Tests/DRSCCPConstantFoldingWithStagingTest.class.st b/Druid-Tests/DRSCCPConstantFoldingWithStagingTest.class.st index 3314cdfa..c46b4332 100644 --- a/Druid-Tests/DRSCCPConstantFoldingWithStagingTest.class.st +++ b/Druid-Tests/DRSCCPConstantFoldingWithStagingTest.class.st @@ -78,27 +78,27 @@ DRSCCPConstantFoldingWithStagingTest >> testConstantFoldingTrueAndRegisterIsRegi { #category : #tests } DRSCCPConstantFoldingWithStagingTest >> testFoldingLoadWithConstant [ - | cfg load | + | cfg load copyOfCopy | cfg := self setUpCFG: 1. "T1 := LOAD 1" load := cfg b1 load: 1. "T2 := T1" - cfg b1 copy: load. + copyOfCopy := cfg b1 copy: load. optimisation applyTo: cfg. "T2 := LOAD_JIT_COMPILE_EXPRESSION 1" - self assert: cfg instructions nextToLast operand1 isInterpreterReference. + self assert: copyOfCopy operand1 isInterpreterReference. self - assert: cfg instructions nextToLast operand1 reference + assert: copyOfCopy operand1 reference equals: '(coInterpreter int64AtPointer: 1)' ] { #category : #tests } DRSCCPConstantFoldingWithStagingTest >> testFoldingLoadWithOperation [ - | cfg load op | + | cfg load op copyOfCopy | cfg := self setUpCFG: 1. "T1 := op" @@ -106,12 +106,12 @@ DRSCCPConstantFoldingWithStagingTest >> testFoldingLoadWithOperation [ "T2 := LOAD T1" load := cfg b1 load: op. "T3 := T2" - cfg b1 copy: load. + copyOfCopy := cfg b1 copy: load. optimisation applyTo: cfg. "T3 := T2" - self assert: cfg instructions nextToLast operand1 equals: load + self assert: copyOfCopy operand1 equals: load ] { #category : #tests } diff --git a/Druid-Tests/DRSCCPConstantPropagationTest.class.st b/Druid-Tests/DRSCCPConstantPropagationTest.class.st index 72370f7f..a621faf2 100644 --- a/Druid-Tests/DRSCCPConstantPropagationTest.class.st +++ b/Druid-Tests/DRSCCPConstantPropagationTest.class.st @@ -55,19 +55,19 @@ DRSCCPConstantPropagationTest >> testDoNotPropagateInReturn [ { #category : #tests } DRSCCPConstantPropagationTest >> testPropagateBetweenBasicBlocks [ - | cfg copy1 | + | cfg copy1 copyOfCopy | cfg := self setUpCFG: 2. "T1 := 1" - cfg b1 addInstruction: (copy1 := instructionFactory copy: 1). + copy1 := cfg b1 copy: 1. "T2 := T1" - cfg b2 addInstruction: (instructionFactory copy: copy1). + copyOfCopy := cfg b2 copy: copy1. optimisation applyTo: cfg. "The T1 access got replaced by the constant 1" - self assert: cfg instructions allButLast last operand1 equals: 1 asDRValue + self assert: copyOfCopy operand1 equals: 1 asDRValue ] { #category : #tests } @@ -107,25 +107,25 @@ DRSCCPConstantPropagationTest >> testPropagateToAddOperand [ optimisation applyTo: cfg. "Assert that we propagated the constant to the ADD operand" - self assert: cfg instructions allButLast last isAdd. - self assert: cfg instructions allButLast last operand2 equals: 1 asDRValue + self assert: cfg instructions second isAdd. + self assert: cfg instructions second operand2 equals: 1 asDRValue ] { #category : #tests } DRSCCPConstantPropagationTest >> testPropagateToCopyOperand [ - | cfg copy1 | + | cfg copy1 copyOfCopy | cfg := self setUpCFG: 1. "T1 := 1" cfg b1 addInstruction: (copy1 := instructionFactory copy: 1). "T2 := T1" - cfg b1 addInstruction: (instructionFactory copy: copy1). + cfg b1 addInstruction: (copyOfCopy := instructionFactory copy: copy1). optimisation applyTo: cfg. "The T1 access got replaced by the constant 1" - self assert: cfg instructions allButLast last operand1 equals: 1 asDRValue + self assert: copyOfCopy operand1 equals: 1 asDRValue ] { #category : #tests } @@ -163,8 +163,8 @@ DRSCCPConstantPropagationTest >> testPropagateToMulOperand [ optimisation applyTo: cfg. "Assert that we propagated the constant to the MUL operand" - self assert: cfg instructions allButLast last isMultiply. - self assert: cfg instructions allButLast last operand2 equals: 1 asDRValue + self assert: cfg instructions second isMultiply. + self assert: cfg instructions second operand2 equals: 1 asDRValue ] { #category : #tests } diff --git a/Druid-Tests/DRTailDuplicationTest.class.st b/Druid-Tests/DRTailDuplicationTest.class.st index a85cd74a..0ab2b8bc 100644 --- a/Druid-Tests/DRTailDuplicationTest.class.st +++ b/Druid-Tests/DRTailDuplicationTest.class.st @@ -105,8 +105,8 @@ DRTailDuplicationTest >> testTailDuplicateBlockWithOusideUsersShouldCreatePhiFun newBlocks := b7 tailDuplicate allButFirst. - phi1 := (cfg blockById: 11) firstInstruction. - phi2 := (cfg blockById: 9) firstInstruction. + phi1 := (cfg blockById: 10) firstInstruction. + phi2 := (cfg blockById: 8) firstInstruction. self assert: phi1 isPhiFunction. self @@ -180,7 +180,7 @@ DRTailDuplicationTest >> testTailDuplicateBlockWithOusideUsersShouldMergePhiFunc b5 tailDuplicate. phi := b7 firstInstruction. - newPhi := (cfg blockById: 8) firstInstruction. + newPhi := (cfg blockById: 7) firstInstruction. self assert: newPhi isPhiFunction. self @@ -279,7 +279,7 @@ DRTailDuplicationTest >> testTailDuplicateBlockWithPhiUsersShouldUpdateOperandTo newBlock := cfg b4 tailDuplicate last. phi := b6 firstInstruction. - newPhi := (cfg blockById: 7) firstInstruction. + newPhi := (cfg blockById: 6) firstInstruction. self assert: newPhi isPhiFunction. self assert: newPhi operands size equals: 2. @@ -359,8 +359,8 @@ DRTailDuplicationTest >> testTailDuplicateInsertingPhiInDegenerateControlFlow [ "This phi has a same value coming from two predecedors" newPhi := b9 phiFunctions unique. - self assert: newPhi operands first equals: (cfg blockById: 5) phiFunctions unique. - self assert: newPhi operands second equals: (cfg blockById: 8) phiFunctions unique. + self assert: newPhi operands first equals: (cfg blockById: 4) phiFunctions unique. + self assert: newPhi operands second equals: (cfg blockById: 7) phiFunctions unique. ] @@ -640,7 +640,7 @@ DRTailDuplicationTest >> testTailDuplicateWithFrontierAsDirectSuccessor [ phiHolders := cfg b4 successors. - frontier := cfg blockById: 6. + frontier := cfg blockById: 5. self assert: cfg blocks size equals: bocksBefore size + 3. "Duplicated + 2 phi holders" diff --git a/Druid/DRBasicBlock.class.st b/Druid/DRBasicBlock.class.st index 10c967c2..498090eb 100644 --- a/Druid/DRBasicBlock.class.st +++ b/Druid/DRBasicBlock.class.st @@ -465,6 +465,12 @@ DRBasicBlock >> hasPredecessors [ ^ predecessors notEmpty ] +{ #category : #accessing } +DRBasicBlock >> hasSuccessors [ + + ^ self successors notEmpty +] + { #category : #accessing } DRBasicBlock >> hyperblock [ @@ -770,7 +776,7 @@ DRBasicBlock >> isEmptyBasicBlock [ { #category : #accessing } DRBasicBlock >> isExitBlock [ - ^ isExitBlock + ^ false ] { #category : #accessing } diff --git a/Druid/DRBytecodeIRGenerator.class.st b/Druid/DRBytecodeIRGenerator.class.st index c0aea7bb..b147b9d1 100644 --- a/Druid/DRBytecodeIRGenerator.class.st +++ b/Druid/DRBytecodeIRGenerator.class.st @@ -19,7 +19,7 @@ DRBytecodeIRGenerator >> addAnnotateBytecode: aRBMethodNode [ { #category : #visiting } DRBytecodeIRGenerator >> finishCodeInterpretation: lastFrame [ - +1halt. currentBasicBlock jumpTo: controlFlowGraph exitBasicBlock ] @@ -471,7 +471,7 @@ DRBytecodeIRGenerator >> pushFrameForCode: aDRCode receiver: aReceiver [ | frame | frame := super pushFrameForCode: aDRCode receiver: aReceiver. - +1halt. "If this is the base frame, it should continue with the next bytecode at the end" executionState baseFrame = frame ifTrue: [ frame exitBasicBlock endInstruction: diff --git a/Druid/DRCode.class.st b/Druid/DRCode.class.st index 74c5f1a2..05f2b654 100644 --- a/Druid/DRCode.class.st +++ b/Druid/DRCode.class.st @@ -49,8 +49,7 @@ DRCode >> pushFrame: frame In: interpreter receiver: aReceiver [ receiver: aReceiver; method: self codeNode; irGenerator: interpreter; - entryBasicBlock: newMethodEntry; - exitBasicBlock: interpreter basicNewBasicBlock. + entryBasicBlock: newMethodEntry. self codeNode temporaryNames , self codeNode argumentNames do: [ :e | frame defineVariableNamed: e ]. frame returnValue: (self defaultReturnValue: aReceiver). diff --git a/Druid/DRControlFlowGraph.class.st b/Druid/DRControlFlowGraph.class.st index 8a6803dc..588ce085 100644 --- a/Druid/DRControlFlowGraph.class.st +++ b/Druid/DRControlFlowGraph.class.st @@ -3,7 +3,6 @@ Class { #superclass : #Object, #instVars : [ 'initialBasicBlock', - 'exitBasicBlock', 'initialConstraint', 'basicBlocks', 'nextBasicBlockId', @@ -209,9 +208,7 @@ DRControlFlowGraph >> blockById: anInteger [ { #category : #iterating } DRControlFlowGraph >> blocks [ - ^ basicBlocks copyWithAll: { - initialBasicBlock. - exitBasicBlock } + ^ basicBlocks copyWithAll: { initialBasicBlock } ] { #category : #accessing } @@ -415,16 +412,19 @@ DRControlFlowGraph >> edgesFrom: sourceBlock to: destinationBlock [ ^ (self outgoingEdgesFor: sourceBlock) select: [ :e | e destination = destinationBlock ] ] -{ #category : #accessing } +{ #category : #testing } DRControlFlowGraph >> exitBasicBlock [ - - ^ exitBasicBlock + + | theExitBlocks | + theExitBlocks := self exitBasicBlocks. + theExitBlocks size > 1 ifTrue: [ self error: 'This CFG has more than one exit basic block' ]. + ^ theExitBlocks anyOne ] -{ #category : #accessing } -DRControlFlowGraph >> exitBasicBlock: anObject [ +{ #category : #testing } +DRControlFlowGraph >> exitBasicBlocks [ - exitBasicBlock := anObject + ^ self blocks select: [ :b | b hasSuccessors not ] ] { #category : #accessing } @@ -519,8 +519,6 @@ DRControlFlowGraph >> initialize [ numberOfSpillSlots := 0. nextBasicBlockId := -1. - exitBasicBlock := self privateNewBasicBlock. - exitBasicBlock beExitBlock. initialBasicBlock := self privateNewBasicBlock ] diff --git a/Druid/DRDominatorTree.class.st b/Druid/DRDominatorTree.class.st index 3d8729f7..be789ea7 100644 --- a/Druid/DRDominatorTree.class.st +++ b/Druid/DRDominatorTree.class.st @@ -40,16 +40,14 @@ DRDominatorTree >> buildDominationTreeOf: cfg startingFrom: initialBasicBlock fo hasChanged := true. [ hasChanged ] whileTrue: [ hasChanged := false. - ({ - cfg initialBasicBlock. - cfg exitBasicBlock } , cfg blocks copyWithout: initialBasicBlock) - do: [ :block | - blockDictionary at: block ifPresent: [ :currentNode | - newImmediateDominator := self findImmediateDominatorOfBlock: - (dominationBlockClosure value: block). - currentNode parent = newImmediateDominator ifFalse: [ - currentNode replaceParent: newImmediateDominator. - hasChanged := true ] ] ] ] + ({ cfg initialBasicBlock } , cfg blocks copyWithout: + initialBasicBlock) do: [ :block | + blockDictionary at: block ifPresent: [ :currentNode | + newImmediateDominator := self findImmediateDominatorOfBlock: + (dominationBlockClosure value: block). + currentNode parent = newImmediateDominator ifFalse: [ + currentNode replaceParent: newImmediateDominator. + hasChanged := true ] ] ] ] ] { #category : #initialization } @@ -65,9 +63,6 @@ DRDominatorTree >> buildDominatorTreeOf: cfg [ { #category : #initialization } DRDominatorTree >> buildPostDominatorTreeOf: cfg [ - cfg exitBasicBlock ifNil: [ - self error: - 'We need an exitBasicBlock to build a post dominator tree' ]. self buildDominationTreeOf: cfg startingFrom: cfg exitBasicBlock diff --git a/Druid/DRIRGenerator.class.st b/Druid/DRIRGenerator.class.st index 2e4a311e..b23d1bfb 100644 --- a/Druid/DRIRGenerator.class.st +++ b/Druid/DRIRGenerator.class.st @@ -1810,6 +1810,7 @@ DRIRGenerator >> popFrame [ | poppedFrame | "Here we are in callee" + poppedFrame := self popFrameMergingDeferredReturns. "Last frame!" diff --git a/Druid/DRMetaCompilerIRGenerator.class.st b/Druid/DRMetaCompilerIRGenerator.class.st index bf3defd0..9c6ee099 100644 --- a/Druid/DRMetaCompilerIRGenerator.class.st +++ b/Druid/DRMetaCompilerIRGenerator.class.st @@ -121,7 +121,7 @@ DRMetaCompilerIRGenerator >> numberOfArguments: aValue [ DRMetaCompilerIRGenerator >> popFrameMergingDeferredReturns [ | exitBasicBlock topReturns | - exitBasicBlock := self topFrame exitBasicBlock. + exitBasicBlock := self newBasicBlock. topReturns := self topFrame deferredMethodReturns. topReturns size > 0 ifTrue: [ diff --git a/Druid/DRMethodIRGenerator.class.st b/Druid/DRMethodIRGenerator.class.st index d33a2c3c..46cf1603 100644 --- a/Druid/DRMethodIRGenerator.class.st +++ b/Druid/DRMethodIRGenerator.class.st @@ -96,16 +96,15 @@ DRMethodIRGenerator >> receiver: aDRValue [ { #category : #'deferred returns' } DRMethodIRGenerator >> resolveDeferredMethodReturns: aDRFrame [ - | mirrorFrame newFrameReturn deferredReturnsBlock pieces deferredFrameReturn newReturn | + | mirrorFrame newFrameReturn deferredReturnsBlock pieces deferredFrameReturn newReturn exitBasicBlock | aDRFrame deferredMethodReturns ifEmpty: [ ^ self ]. - 1halt. + mirrorFrame := aDRFrame mirrorFrame. "If there were returns attached to popped frame, merge all of them in a single state. If there was only one return this is important also to override implicit returns" - + exitBasicBlock := self newBasicBlock. mirrorFrame poppedValue ifNil: [ "There are no provious returns" - self assert: aDRFrame exitBasicBlock isEmptyBasicBlock. - newFrameReturn := self mergeDeferredReturns: aDRFrame deferredMethodReturns in: aDRFrame exitBasicBlock. + newFrameReturn := self mergeDeferredReturns: aDRFrame deferredMethodReturns in: exitBasicBlock. mirrorFrame poppedValue: newFrameReturn. "Save it in a secure and common place" aDRFrame clearDeferredMethodReturns. ^ self ]. @@ -120,11 +119,10 @@ DRMethodIRGenerator >> resolveDeferredMethodReturns: aDRFrame [ pieces := mirrorFrame poppedValue breakBasicBlock. "Update exitBasicBlock and continue from there" - aDRFrame exitBasicBlock: pieces last. - self currentBasicBlock: aDRFrame exitBasicBlock. + self currentBasicBlock: pieces last. - deferredReturnsBlock jumpTo: aDRFrame exitBasicBlock. - newReturn := aDRFrame exitBasicBlock addInstruction: (self instructionFactory phiWithVariables: { }). + deferredReturnsBlock jumpTo: pieces last. + newReturn := pieces last addInstruction: (self instructionFactory phiWithVariables: { }). aDRFrame returnValue: newReturn. newFrameReturn := self addFrameReturn: aDRFrame. mirrorFrame poppedValue replaceUsesBy: newFrameReturn. diff --git a/Druid/DRPrimitiveControlFlowGraph.class.st b/Druid/DRPrimitiveControlFlowGraph.class.st index 596c8e2e..356c6209 100644 --- a/Druid/DRPrimitiveControlFlowGraph.class.st +++ b/Druid/DRPrimitiveControlFlowGraph.class.st @@ -14,12 +14,6 @@ Class { #category : #'Druid-IR' } -{ #category : #iterating } -DRPrimitiveControlFlowGraph >> blocks [ - - ^ basicBlocks -] - { #category : #accessing } DRPrimitiveControlFlowGraph >> failureExitBlock [ diff --git a/Druid/DRStackFrame.class.st b/Druid/DRStackFrame.class.st index 0f3e3e23..b92106c9 100644 --- a/Druid/DRStackFrame.class.st +++ b/Druid/DRStackFrame.class.st @@ -6,7 +6,6 @@ Class { 'method', 'irGenerator', 'entryBasicBlock', - 'exitBasicBlock', 'operandStack', 'temporaries', 'mirrorFrame', @@ -72,17 +71,6 @@ DRStackFrame >> entryBasicBlock: anObject [ entryBasicBlock := anObject ] -{ #category : #accessing } -DRStackFrame >> exitBasicBlock [ - ^ exitBasicBlock -] - -{ #category : #accessing } -DRStackFrame >> exitBasicBlock: aDRBasicBlock [ - - exitBasicBlock := aDRBasicBlock -] - { #category : #temporaries } DRStackFrame >> frameDefining: aName withState: aState [ From a8e94deba0bf9cecc59641bb2fa278ade987fe0a Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Wed, 24 Apr 2024 14:17:34 +0200 Subject: [PATCH 11/33] Fix a dead path test depending on block ids --- Druid-Tests/DRDeadPathEliminationTest.class.st | 8 ++++---- Druid/DRMetaCompilerIRGenerator.class.st | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Druid-Tests/DRDeadPathEliminationTest.class.st b/Druid-Tests/DRDeadPathEliminationTest.class.st index f5e82175..b5b87959 100644 --- a/Druid-Tests/DRDeadPathEliminationTest.class.st +++ b/Druid-Tests/DRDeadPathEliminationTest.class.st @@ -28,25 +28,25 @@ DRDeadPathEliminationTest >> setUp [ { #category : #optimization } DRDeadPathEliminationTest >> testEliminateDeadPathWithOnePredecessor [ - | cfg lastBlocks lastPaths newMergePoint oldMergePoint newBlock | + | cfg lastBlocks lastPaths newMergePoint oldMergePoint newBlock exitBasicBlock | cfg := self generateDruidIRFor: #primitiveSandclock. oldMergePoint := cfg mergeBlocks first. newMergePoint := oldMergePoint newEmptyPredecessor. + exitBasicBlock := cfg exitBasicBlock. + newBlock := cfg newBasicBlockWith: [ :b | b copy: 1 ]. oldMergePoint removePredecessorAt: 1. newMergePoint jumpIf: (DRPhysicalGeneralPurposeRegister name: 'Parameter') to: oldMergePoint ifFalseTo: newBlock. - newBlock jumpTo: (cfg blockById: 1). + newBlock jumpTo: exitBasicBlock. 2 timesRepeat: [ cfg applyOptimisation: optimisation. cfg applyOptimisation: DRCleanControlFlow new ]. cfg generatePaths. - lastBlocks := cfg lastBasicBlock predecessors. - lastPaths := cfg incomingEdgesFor: cfg lastBasicBlock. self assert: cfg deadPaths isEmpty. ] diff --git a/Druid/DRMetaCompilerIRGenerator.class.st b/Druid/DRMetaCompilerIRGenerator.class.st index 9c6ee099..5e059255 100644 --- a/Druid/DRMetaCompilerIRGenerator.class.st +++ b/Druid/DRMetaCompilerIRGenerator.class.st @@ -121,7 +121,7 @@ DRMetaCompilerIRGenerator >> numberOfArguments: aValue [ DRMetaCompilerIRGenerator >> popFrameMergingDeferredReturns [ | exitBasicBlock topReturns | - exitBasicBlock := self newBasicBlock. + exitBasicBlock := self basicNewBasicBlock. topReturns := self topFrame deferredMethodReturns. topReturns size > 0 ifTrue: [ From e97efa7b287890050038398544613a7522817fe2 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Wed, 24 Apr 2024 14:29:12 +0200 Subject: [PATCH 12/33] Fix tail duplication tests --- Druid-Tests/DRDeadPathEliminationTest.class.st | 6 ++---- Druid-Tests/DRTailDuplicationTest.class.st | 8 ++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Druid-Tests/DRDeadPathEliminationTest.class.st b/Druid-Tests/DRDeadPathEliminationTest.class.st index b5b87959..dd08d369 100644 --- a/Druid-Tests/DRDeadPathEliminationTest.class.st +++ b/Druid-Tests/DRDeadPathEliminationTest.class.st @@ -54,12 +54,10 @@ DRDeadPathEliminationTest >> testEliminateDeadPathWithOnePredecessor [ { #category : #optimization } DRDeadPathEliminationTest >> testEliminateDeadPathsOnLoop [ - | cfg lastPaths conditionalConstraint add | + | cfg lastPaths conditionalConstraint | cfg := self generateDruidIRFor: #primitiveLoopIncrementing. cfg generatePaths. - add := cfg instructions detect: [ :i | i isAdd ]. - self assert: cfg deadPaths isNotEmpty. optimisation applyTo: cfg. @@ -71,7 +69,7 @@ DRDeadPathEliminationTest >> testEliminateDeadPathsOnLoop [ self assert: lastPaths size equals: 2. "Should propagate conditional constraint to the result" - conditionalConstraint := lastPaths first constraintFor: DRPhysicalGeneralPurposeRegister receiverResultReg name. + conditionalConstraint := lastPaths first constraintFor: 7"t7". self assertConstraint: (DRGreaterOrEqualsConstraint withValue: 15) includes: conditionalConstraint diff --git a/Druid-Tests/DRTailDuplicationTest.class.st b/Druid-Tests/DRTailDuplicationTest.class.st index 0ab2b8bc..98239a2b 100644 --- a/Druid-Tests/DRTailDuplicationTest.class.st +++ b/Druid-Tests/DRTailDuplicationTest.class.st @@ -371,7 +371,7 @@ DRTailDuplicationTest >> testTailDuplicateOnLoop [ cfg := self generateDruidIRFor: #primitiveLoopIncrementing. "Duplicate loop header" - duplicatedBlocks := (cfg blockById: 6) tailDuplicate. + duplicatedBlocks := (cfg blockById: 4) tailDuplicate. "Build 1 duplication" self assert: duplicatedBlocks size equals: 2. @@ -404,7 +404,7 @@ DRTailDuplicationTest >> testTailDuplicateShouldCopyBlock [ cfg b4 tailDuplicate. cfg validate. - newBlock := cfg blockById: 5. + newBlock := cfg blockById: 4. self assertCollection: cfg b4 predecessors @@ -424,7 +424,7 @@ DRTailDuplicationTest >> testTailDuplicateShouldGenerateNewVariables [ cfg b4 tailDuplicate. cfg validate. - newBlock := cfg blockById: 5. + newBlock := cfg blockById: 4. self assert: newBlock instructions size @@ -447,7 +447,7 @@ DRTailDuplicationTest >> testTailDuplicateShouldKeepInstructionDependenciesInPhi cfg b4 tailDuplicate. cfg validate. - newBlock := cfg blockById: 5. + newBlock := cfg blockById: 4. "On splitting, phis loses one argument" self From 1e842a58f07a451a3583f975775f2d6dd720bd44 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Wed, 24 Apr 2024 15:04:54 +0200 Subject: [PATCH 13/33] Fix dead path elimination tests --- Druid-Tests/DRDeadPathEliminationTest.class.st | 15 +++++++++------ Druid/DRFailureCodeBasedTailDuplication.class.st | 12 +++++++----- Druid/SimpleStackBasedCogit.extension.st | 1 + Druid/StackToRegisterMappingCogit.extension.st | 1 + 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Druid-Tests/DRDeadPathEliminationTest.class.st b/Druid-Tests/DRDeadPathEliminationTest.class.st index dd08d369..9cfbc0d1 100644 --- a/Druid-Tests/DRDeadPathEliminationTest.class.st +++ b/Druid-Tests/DRDeadPathEliminationTest.class.st @@ -79,7 +79,7 @@ DRDeadPathEliminationTest >> testEliminateDeadPathsOnLoop [ DRDeadPathEliminationTest >> testEliminateDoubleDeadPaths [ "TOFIX: it's trying to create phis in wrong 'frontier' blocks" - | cfg lastBlocks lastPaths lastPathsLeft lastPathsRight | + | cfg lastBlocks lastPaths lastPathsOne lastPathsTwo lastPathsThird | cfg := self generateDruidIRFor: #primitiveDNA. 4 timesRepeat: [ @@ -88,15 +88,17 @@ DRDeadPathEliminationTest >> testEliminateDoubleDeadPaths [ cfg generatePaths. - lastPaths := cfg exitBasicBlocks collect: [ :e | cfg incomingEdgesFor: e ]. + lastPaths := cfg exitBasicBlocks flatCollect: [ :e | cfg incomingEdgesFor: e ]. lastBlocks := cfg exitBasicBlocks. - lastPathsLeft := cfg incomingEdgesFor: lastBlocks first. - lastPathsRight := cfg incomingEdgesFor: lastBlocks last. + lastPathsOne := cfg incomingEdgesFor: lastBlocks first. + lastPathsTwo := cfg incomingEdgesFor: lastBlocks second. + lastPathsThird := cfg incomingEdgesFor: lastBlocks third. self assert: cfg deadPaths isEmpty. self assert: lastPaths size equals: 4. "X>10 || 10<=X>7 || 7<=X>0 || 0<=X" - self assert: lastPathsLeft size equals: 2. - self assert: lastPathsRight size equals: 2 + self assert: lastPathsOne size equals: 1. + self assert: lastPathsTwo size equals: 1. + self assert: lastPathsThird size equals: 2. ] { #category : #optimization } @@ -124,6 +126,7 @@ DRDeadPathEliminationTest >> testEliminateDoubleHalfDeadPaths [ DRDeadPathEliminationTest >> testEliminateInnerDeadPaths [ | cfg lastBlocks | + cfg := self generateDruidIRFor: #primitiveInnerBranchingWithDeadBranch. optimisation applyTo: cfg. diff --git a/Druid/DRFailureCodeBasedTailDuplication.class.st b/Druid/DRFailureCodeBasedTailDuplication.class.st index 5b39d7c1..4b491929 100644 --- a/Druid/DRFailureCodeBasedTailDuplication.class.st +++ b/Druid/DRFailureCodeBasedTailDuplication.class.st @@ -4,15 +4,17 @@ Class { #category : #'Druid-Optimizations' } -{ #category : #operations } -DRFailureCodeBasedTailDuplication >> applyTo: aCFG [ +{ #category : #accessing } +DRFailureCodeBasedTailDuplication >> applyTo: aDRControlFlowGraph [ - aCFG successExitBlock predecessors size = 1 ifTrue: [ - aCFG successExitBlock predecessors anyOne tailDuplicate ] + aDRControlFlowGraph exitBasicBlocks do: [ :bb | + bb predecessors size > 1 ifTrue: [ + bb tailDuplicate ] ] ] { #category : #testing } DRFailureCodeBasedTailDuplication >> canBeAppliedIn: aDRControlFlowGraph [ - ^ aDRControlFlowGraph successExitBlock predecessors size = 1 + ^ aDRControlFlowGraph exitBasicBlocks anySatisfy: [ :bb | + bb predecessors size > 1 ] ] diff --git a/Druid/SimpleStackBasedCogit.extension.st b/Druid/SimpleStackBasedCogit.extension.st index b0ffc46e..ff93950c 100644 --- a/Druid/SimpleStackBasedCogit.extension.st +++ b/Druid/SimpleStackBasedCogit.extension.st @@ -16,6 +16,7 @@ SimpleStackBasedCogit class >> druidNewOptimizationList [ "Basic set of optimizations twice for primitives" 3 timesRepeat: [ optimisations add: DRBranchCollapse new. + optimisations add: DRFailureCodeBasedTailDuplication new. optimisations add: (DRSCCP then: DRDeadBlockElimination). optimisations add: DRCopyPropagation new. diff --git a/Druid/StackToRegisterMappingCogit.extension.st b/Druid/StackToRegisterMappingCogit.extension.st index 3c95ba71..c9b5320e 100644 --- a/Druid/StackToRegisterMappingCogit.extension.st +++ b/Druid/StackToRegisterMappingCogit.extension.st @@ -16,6 +16,7 @@ StackToRegisterMappingCogit class >> druidNewOptimizationList [ optimisations add: DRCogitStackCoalescing new. 4 timesRepeat: [ optimisations add: DRBranchCollapse new. + optimisations add: DRFailureCodeBasedTailDuplication new. optimisations add: (DRSCCP then: DRDeadBlockElimination). optimisations add: (DRPhiSimplication then: DRCopyPropagation). optimisations add: DRCogitStackCanonicaliser new. From 817ce42ccb0a50b9106f2003d935434108eda079 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Wed, 24 Apr 2024 15:08:45 +0200 Subject: [PATCH 14/33] fix loop unrolling tests --- Druid/DRLoop.class.st | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Druid/DRLoop.class.st b/Druid/DRLoop.class.st index b14f92b1..3f9087f3 100644 --- a/Druid/DRLoop.class.st +++ b/Druid/DRLoop.class.st @@ -36,9 +36,11 @@ DRLoop >> backJump: aBackJump [ DRLoop >> blocks [ | loopGraphBlocks | - loopGraphBlocks := self loopGraph blocks. + loopGraphBlocks := self controlFlowGraph + blocksBetween: self headerBlock + and: self latchBlock. "The loop graph contains copies of the complete graph's blocks. Return the original blocks" - ^ self controlFlowGraph blocks select: [ :b | + ^ self controlFlowGraph blocks select: [ :b | loopGraphBlocks anySatisfy: [ :loopBlock | b id = loopBlock id ] ] ] From 074a9a6e77765369ec31b19aca62b9e7b55ddf33 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Wed, 24 Apr 2024 15:10:52 +0200 Subject: [PATCH 15/33] Fix loop invariant code motion tests --- Druid-Tests/DRLoopInvariantCodeMotionTest.class.st | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Druid-Tests/DRLoopInvariantCodeMotionTest.class.st b/Druid-Tests/DRLoopInvariantCodeMotionTest.class.st index f532a6f2..cdae4110 100644 --- a/Druid-Tests/DRLoopInvariantCodeMotionTest.class.st +++ b/Druid-Tests/DRLoopInvariantCodeMotionTest.class.st @@ -30,7 +30,7 @@ DRLoopInvariantCodeMotionTest >> testLoopInvariantCodeMotionAdjustsPhiFunctionsO | cfg loopBlock loopInvariantInstruction | cfg := self generateDruidIRFor: #primitiveLoopWithInvariant. - loopBlock := cfg blockById: 7. + loopBlock := cfg blockById: 5. loopInvariantInstruction := loopBlock firstInstruction. cfg applyOptimisation: DRLoopInvariantCodeMotion new. @@ -44,7 +44,7 @@ DRLoopInvariantCodeMotionTest >> testLoopInvariantCodeMotionDoesNotMoveInstructi | cfg ifBlock loopVariantInstruction | cfg := self generateDruidIRFor: #primitiveLoopWithLoopInvariantInstructionInsideIf. - ifBlock := cfg blockById: 8. + ifBlock := cfg blockById: 5. loopVariantInstruction := ifBlock firstInstruction. cfg applyOptimisation: DRLoopInvariantCodeMotion new. @@ -86,7 +86,7 @@ DRLoopInvariantCodeMotionTest >> testLoopInvariantCodeMotionDoesNotMoveLoopVaria | cfg loopBlock loopVariantInstructions | cfg := self generateDruidIRFor: #primitiveLoopWithLoopVariantInstructions. - loopBlock := cfg blockById: 7. + loopBlock := cfg blockById: 5. loopVariantInstructions := loopBlock instructions allButLast. cfg applyOptimisation: DRLoopInvariantCodeMotion new. From f651391ce66f686e8c2fb64719d5e40e8371de66 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Thu, 25 Apr 2024 12:14:52 +0200 Subject: [PATCH 16/33] Remove reliance on single exit block --- .../DRDeadPathEliminationTest.class.st | 30 +- .../DRLoopInvariantCodeMotionTest.class.st | 6 +- Druid-Tests/DRLoopTest.class.st | 37 +- Druid-Tests/DRLoopUnrollingTest.class.st | 4 +- Druid-Tests/DRTailDuplicationTest.class.st | 23 +- Druid-Tests/DruidTestRTLCompiler.class.st | 2188 +++++++++-------- .../DruidTestRTLCompilerForTest.class.st | 225 +- .../SimpleDruidTestRTLCompiler.class.st | 1238 +++++----- Druid/DRAbstractInstruction.class.st | 6 + Druid/DRBasicBlock.class.st | 7 +- Druid/DRBlockDuplicator.class.st | 1 - Druid/DRBytecodeIRGenerator.class.st | 20 +- Druid/DRCogitPrimitiveCodeGenerator.class.st | 16 +- Druid/DRControlFlowGraph.class.st | 2 +- Druid/DRDivision.class.st | 6 - Druid/DRInstruction.class.st | 2 +- Druid/DRInstructionFactory.class.st | 4 +- Druid/DRLoop.class.st | 3 +- Druid/DRPhiFunction.class.st | 6 - Druid/DRPrimitiveCompilerCompiler.class.st | 2 +- Druid/DRPrimitiveControlFlowGraph.class.st | 10 +- Druid/DRPrimitiveFail.class.st | 6 + Druid/DRPrimitiveIRGenerator.class.st | 18 +- Druid/DRPush.class.st | 8 + 24 files changed, 2105 insertions(+), 1763 deletions(-) diff --git a/Druid-Tests/DRDeadPathEliminationTest.class.st b/Druid-Tests/DRDeadPathEliminationTest.class.st index 9cfbc0d1..0794de89 100644 --- a/Druid-Tests/DRDeadPathEliminationTest.class.st +++ b/Druid-Tests/DRDeadPathEliminationTest.class.st @@ -32,7 +32,7 @@ DRDeadPathEliminationTest >> testEliminateDeadPathWithOnePredecessor [ cfg := self generateDruidIRFor: #primitiveSandclock. oldMergePoint := cfg mergeBlocks first. newMergePoint := oldMergePoint newEmptyPredecessor. - exitBasicBlock := cfg exitBasicBlock. + exitBasicBlock := cfg exitBasicBlocks anyOne. newBlock := cfg newBasicBlockWith: [ :b | b copy: 1 ]. oldMergePoint removePredecessorAt: 1. @@ -104,22 +104,22 @@ DRDeadPathEliminationTest >> testEliminateDoubleDeadPaths [ { #category : #optimization } DRDeadPathEliminationTest >> testEliminateDoubleHalfDeadPaths [ - | cfg lastBlocks lastPaths lastPathsLeft lastPathsRight | + | cfg lastBlocks lastPaths | cfg := self generateDruidIRFor: #primitiveDNA2. 3 timesRepeat: [ optimisation applyTo: cfg. 2 timesRepeat: [self optimize: cfg ] ]. cfg generatePaths. - lastPaths := cfg incomingEdgesFor: cfg lastBasicBlock. - lastBlocks := cfg lastBasicBlock predecessors. - lastPathsLeft := cfg incomingEdgesFor: lastBlocks first. - lastPathsRight := cfg incomingEdgesFor: lastBlocks last. + lastPaths := cfg exitBasicBlocks flatCollect: [:e | cfg incomingEdgesFor: e ]. + lastBlocks := cfg exitBasicBlocks. self assert: cfg deadPaths isEmpty. self assert: lastPaths size equals: 4. - self assert: lastPathsLeft size equals: 3. - self assert: lastPathsRight size equals: 1 + self assert: (cfg incomingEdgesFor: lastBlocks first) size equals: 1. + self assert: (cfg incomingEdgesFor: lastBlocks second) size equals: 1. + self assert: (cfg incomingEdgesFor: lastBlocks third) size equals: 1. + self assert: (cfg incomingEdgesFor: lastBlocks fourth) size equals: 1. ] { #category : #optimization } @@ -152,8 +152,8 @@ DRDeadPathEliminationTest >> testEliminateOnlyDeadPaths [ optimisation applyTo: cfg. cfg generatePaths. - lastPaths := cfg incomingEdgesFor: cfg lastBasicBlock. - lastBlocks := cfg lastBasicBlock predecessors. + lastPaths := cfg exitBasicBlocks flatCollect: [ :e | cfg incomingEdgesFor: e ]. + lastBlocks := cfg exitBasicBlocks. lastPathsLeft := cfg incomingEdgesFor: lastBlocks first. lastPathsRight := cfg incomingEdgesFor: lastBlocks last. @@ -173,16 +173,16 @@ DRDeadPathEliminationTest >> testEliminateSimpleDeadPaths [ self optimize: cfg. cfg generatePaths. - lastBlocks := cfg lastBasicBlock predecessors. - lastPaths := cfg incomingEdgesFor: cfg lastBasicBlock. + lastBlocks := cfg exitBasicBlocks. + lastPaths := cfg exitBasicBlocks flatCollect: [ :e | cfg incomingEdgesFor: e ]. self assert: cfg deadPaths isEmpty. self assert: lastPaths size equals: 3. - self assert: lastBlocks first firstInstruction isPhiFunction. "One branch finishes in a phi" - self assert: lastBlocks second firstInstruction isCopy. + self assert: lastBlocks second firstInstruction isPhiFunction. "One branch finishes in a phi" + self assert: lastBlocks first firstInstruction isCopy. self - assert: lastBlocks second firstInstruction operand1 value + assert: lastBlocks first firstInstruction operand1 value equals: 116 "Other branch harcodes the value" ] diff --git a/Druid-Tests/DRLoopInvariantCodeMotionTest.class.st b/Druid-Tests/DRLoopInvariantCodeMotionTest.class.st index cdae4110..fa107b8f 100644 --- a/Druid-Tests/DRLoopInvariantCodeMotionTest.class.st +++ b/Druid-Tests/DRLoopInvariantCodeMotionTest.class.st @@ -30,7 +30,7 @@ DRLoopInvariantCodeMotionTest >> testLoopInvariantCodeMotionAdjustsPhiFunctionsO | cfg loopBlock loopInvariantInstruction | cfg := self generateDruidIRFor: #primitiveLoopWithInvariant. - loopBlock := cfg blockById: 5. + loopBlock := cfg blockById: 6. loopInvariantInstruction := loopBlock firstInstruction. cfg applyOptimisation: DRLoopInvariantCodeMotion new. @@ -44,7 +44,7 @@ DRLoopInvariantCodeMotionTest >> testLoopInvariantCodeMotionDoesNotMoveInstructi | cfg ifBlock loopVariantInstruction | cfg := self generateDruidIRFor: #primitiveLoopWithLoopInvariantInstructionInsideIf. - ifBlock := cfg blockById: 5. + ifBlock := cfg blockById: 6. loopVariantInstruction := ifBlock firstInstruction. cfg applyOptimisation: DRLoopInvariantCodeMotion new. @@ -86,7 +86,7 @@ DRLoopInvariantCodeMotionTest >> testLoopInvariantCodeMotionDoesNotMoveLoopVaria | cfg loopBlock loopVariantInstructions | cfg := self generateDruidIRFor: #primitiveLoopWithLoopVariantInstructions. - loopBlock := cfg blockById: 5. + loopBlock := cfg blockById: 6. loopVariantInstructions := loopBlock instructions allButLast. cfg applyOptimisation: DRLoopInvariantCodeMotion new. diff --git a/Druid-Tests/DRLoopTest.class.st b/Druid-Tests/DRLoopTest.class.st index 685b0ece..efe716ef 100644 --- a/Druid-Tests/DRLoopTest.class.st +++ b/Druid-Tests/DRLoopTest.class.st @@ -25,14 +25,17 @@ DRLoopTest >> setUp [ DRLoopTest >> testCanRetrieveLoopGraphWithIfs [ | cfg loop loopSubgraph loopBlocksIds | - cfg := self generateDruidIRFor: #primitiveLoopWithLoopInvariantInstructionInsideIf. + cfg := self generateDruidIRFor: + #primitiveLoopWithLoopInvariantInstructionInsideIf. loop := cfg allLoops first. - + loopSubgraph := loop loopGraph. - loopBlocksIds := { 6. 7. 8. 9 }. - self assertCollection: (loopSubgraph blocks collect: #id) hasSameElements: loopBlocksIds. + loopBlocksIds := { 5. 6. 7. 8 }. + self + assertCollection: (loopSubgraph collect: #id) + hasSameElements: loopBlocksIds ] { #category : #tests } @@ -41,14 +44,16 @@ DRLoopTest >> testCanRetrieveLoopGraphWithMultipleBodyBlocks [ | cfg loop loopSubgraph loopBlocksIds loopBodyBlock | cfg := self generateDruidIRFor: #primitiveLoopWithMultipleInvariants. - loopBodyBlock := cfg blockById: 7. + loopBodyBlock := cfg blockById: 6. loopBodyBlock second breakBasicBlock. loop := cfg allLoops anyOne. - + loopSubgraph := loop loopGraph. - loopBlocksIds := { 6. 12. 13 . 7 }. - self assertCollection: (loopSubgraph blocks collect: #id) hasSameElements: loopBlocksIds. + loopBlocksIds := { 5. 6. 12. 13 }. + self + assertCollection: (loopSubgraph collect: #id) + hasSameElements: loopBlocksIds ] { #category : #tests } @@ -58,11 +63,13 @@ DRLoopTest >> testCanRetrieveLoopGraphWithNestedLoops [ cfg := self generateDruidIRFor: #primitiveNestedLoopWithInvariant. outerLoop := cfg allLoops second. - + loopSubgraph := outerLoop loopGraph. - loopBlocksIds := { 6. 8. 9. 10 }. - self assertCollection: (loopSubgraph blocks collect: #id) hasSameElements: loopBlocksIds. + loopBlocksIds := { 5. 7. 8. 9 }. + self + assertCollection: (loopSubgraph collect: #id) + hasSameElements: loopBlocksIds ] { #category : #tests } @@ -72,11 +79,13 @@ DRLoopTest >> testCanRetrieveLoopGraphWithSingleBodyBlock [ cfg := self generateDruidIRFor: #primitiveLoopWithInvariant. loop := cfg allLoops anyOne. - + loopSubgraph := loop loopGraph. - loopBlocksIds := { 6. 7 }. - self assertCollection: (loopSubgraph blocks collect: #id) hasSameElements: loopBlocksIds. + loopBlocksIds := { 5. 6 }. + self + assertCollection: (loopSubgraph collect: #id) + hasSameElements: loopBlocksIds ] { #category : #tests } diff --git a/Druid-Tests/DRLoopUnrollingTest.class.st b/Druid-Tests/DRLoopUnrollingTest.class.st index 55078997..6019253a 100644 --- a/Druid-Tests/DRLoopUnrollingTest.class.st +++ b/Druid-Tests/DRLoopUnrollingTest.class.st @@ -84,7 +84,7 @@ DRLoopUnrollingTest >> testLoopUnrollingDuplicatesMultipleBodyBlocks [ unrollingFactor := 2. cfg := self generateDruidIRFor: #primitiveLoopWithMultipleInstructions. - loopBlock := cfg blockById: 7. + loopBlock := cfg blockById: 6. loopBlock second breakBasicBlock. loop := cfg allLoops anyOne. @@ -101,7 +101,7 @@ DRLoopUnrollingTest >> testLoopUnrollingDuplicatesMultipleBodyBlocksMultipleTime unrollingFactor := 4. cfg := self generateDruidIRFor: #primitiveLoopWithMultipleInstructions. - loopBlock := cfg blockById: 7. + loopBlock := cfg blockById: 6. loopBlock second breakBasicBlock. loop := cfg allLoops anyOne. diff --git a/Druid-Tests/DRTailDuplicationTest.class.st b/Druid-Tests/DRTailDuplicationTest.class.st index 98239a2b..41373577 100644 --- a/Druid-Tests/DRTailDuplicationTest.class.st +++ b/Druid-Tests/DRTailDuplicationTest.class.st @@ -105,8 +105,8 @@ DRTailDuplicationTest >> testTailDuplicateBlockWithOusideUsersShouldCreatePhiFun newBlocks := b7 tailDuplicate allButFirst. - phi1 := (cfg blockById: 10) firstInstruction. - phi2 := (cfg blockById: 8) firstInstruction. + phi1 := (cfg blockById: 11) firstInstruction. + phi2 := (cfg blockById: 9) firstInstruction. self assert: phi1 isPhiFunction. self @@ -180,7 +180,7 @@ DRTailDuplicationTest >> testTailDuplicateBlockWithOusideUsersShouldMergePhiFunc b5 tailDuplicate. phi := b7 firstInstruction. - newPhi := (cfg blockById: 7) firstInstruction. + newPhi := (cfg blockById: 8) firstInstruction. self assert: newPhi isPhiFunction. self @@ -279,7 +279,7 @@ DRTailDuplicationTest >> testTailDuplicateBlockWithPhiUsersShouldUpdateOperandTo newBlock := cfg b4 tailDuplicate last. phi := b6 firstInstruction. - newPhi := (cfg blockById: 6) firstInstruction. + newPhi := (cfg blockById: 7) firstInstruction. self assert: newPhi isPhiFunction. self assert: newPhi operands size equals: 2. @@ -353,14 +353,13 @@ DRTailDuplicationTest >> testTailDuplicateInsertingPhiInDegenerateControlFlow [ user := b9 copy: copy1. cfg validate. -"1halt." cfg b4 tailDuplicate. "This phi has a same value coming from two predecedors" newPhi := b9 phiFunctions unique. - self assert: newPhi operands first equals: (cfg blockById: 4) phiFunctions unique. - self assert: newPhi operands second equals: (cfg blockById: 7) phiFunctions unique. + self assert: newPhi operands first equals: (cfg blockById: 5) phiFunctions unique. + self assert: newPhi operands second equals: (cfg blockById: 8) phiFunctions unique. ] @@ -371,7 +370,7 @@ DRTailDuplicationTest >> testTailDuplicateOnLoop [ cfg := self generateDruidIRFor: #primitiveLoopIncrementing. "Duplicate loop header" - duplicatedBlocks := (cfg blockById: 4) tailDuplicate. + duplicatedBlocks := (cfg blockById: 5) tailDuplicate. "Build 1 duplication" self assert: duplicatedBlocks size equals: 2. @@ -404,7 +403,7 @@ DRTailDuplicationTest >> testTailDuplicateShouldCopyBlock [ cfg b4 tailDuplicate. cfg validate. - newBlock := cfg blockById: 4. + newBlock := cfg blockById: 5. self assertCollection: cfg b4 predecessors @@ -424,7 +423,7 @@ DRTailDuplicationTest >> testTailDuplicateShouldGenerateNewVariables [ cfg b4 tailDuplicate. cfg validate. - newBlock := cfg blockById: 4. + newBlock := cfg blockById: 5. self assert: newBlock instructions size @@ -447,7 +446,7 @@ DRTailDuplicationTest >> testTailDuplicateShouldKeepInstructionDependenciesInPhi cfg b4 tailDuplicate. cfg validate. - newBlock := cfg blockById: 4. + newBlock := cfg blockById: 5. "On splitting, phis loses one argument" self @@ -640,7 +639,7 @@ DRTailDuplicationTest >> testTailDuplicateWithFrontierAsDirectSuccessor [ phiHolders := cfg b4 successors. - frontier := cfg blockById: 5. + frontier := cfg blockById: 6. self assert: cfg blocks size equals: bocksBefore size + 3. "Duplicated + 2 phi holders" diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index 5b696043..937162b0 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -865,7 +865,7 @@ DruidTestRTLCompiler >> gen_branchingWithAssigments [ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock jump2 live | + | t0 jump1 s2 currentBlock t1 jump2 live | live := 0. self annotateBytecode: self Label. t0 := self @@ -876,14 +876,20 @@ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. (self ssValue: 0) copyToReg: t0. + self ssPop: 1. + self ssPushRegister: t0. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - (self ssValue: 0) copyToReg: t0. + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + (self ssValue: 0) copyToReg: t1. + self ssPop: 1. + self ssPushRegister: t1. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPop: 1. - self ssPushRegister: t0. ^ 0 ] @@ -905,7 +911,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimAdd [ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ "AutoGenerated by Druid" - | jump1 s57 s54 t1 jump6 jump3 b496 b500 currentBlock t0 jump5 jump2 live t2 jump4 | + | jump1 s57 s54 t1 jump6 jump3 currentBlock t0 jump5 jump2 b498 b502 live t2 jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -930,7 +936,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t2. - b500 := self Label. + b502 := self Label. self MoveR: t2 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -941,7 +947,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ jump4 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t0. self MoveR: t0 R: t2. - jump5 := self Jump: b500. + jump5 := self Jump: b502. currentBlock := self Label. jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. @@ -961,7 +967,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t2. - b496 := self Label. + b498 := self Label. self MoveR: t2 R: t1. self AndCq: 7 R: t1. self CmpCq: 0 R: t1. @@ -972,7 +978,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t1. self MoveR: t1 R: t2. - jump6 := self Jump: b496. + jump6 := self Jump: b498. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -996,10 +1002,13 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ currentBlock := self Label. jump2 jmpTarget: currentBlock. self CmpCq: 0 R: t1. - jump2 := self JumpZero: 0. - self ssPushRegister: t1. + jump2 := self JumpNonZero: 0. + jump3 := self Jump: 0. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self ssPushRegister: t1. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. ^ 0 ] @@ -1007,7 +1016,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ "AutoGenerated by Druid" - | jump1 s57 s54 t1 jump6 jump3 b496 b500 currentBlock t0 jump5 jump2 live t2 jump4 | + | jump1 s57 s54 t1 jump6 jump3 currentBlock t0 jump5 jump2 b498 b502 live t2 jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -1032,7 +1041,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t2. - b500 := self Label. + b502 := self Label. self MoveR: t2 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -1043,7 +1052,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ jump4 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t0. self MoveR: t0 R: t2. - jump5 := self Jump: b500. + jump5 := self Jump: b502. currentBlock := self Label. jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. @@ -1063,7 +1072,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t2. - b496 := self Label. + b498 := self Label. self MoveR: t2 R: t1. self AndCq: 7 R: t1. self CmpCq: 0 R: t1. @@ -1074,7 +1083,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t1. self MoveR: t1 R: t2. - jump6 := self Jump: b496. + jump6 := self Jump: b498. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -1098,10 +1107,13 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ currentBlock := self Label. jump2 jmpTarget: currentBlock. self CmpCq: 0 R: t1. - jump2 := self JumpZero: 0. - self ssPushRegister: t1. + jump2 := self JumpNonZero: 0. + jump3 := self Jump: 0. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self ssPushRegister: t1. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. ^ 0 ] @@ -1109,7 +1121,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ "AutoGenerated by Druid" - | t0 s8 jump1 s2 currentBlock jump2 live s5 | + | t0 jump1 s2 currentBlock jump2 live | live := 0. self annotateBytecode: self Label. t0 := self @@ -1119,16 +1131,13 @@ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ (self ssValue: 0) copyToReg: t0. self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. - s5 := 1. - self MoveCq: s5 R: t0. + self ssPushConstant: 1. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s8 := 2. - self MoveCq: s8 R: t0. + self ssPushConstant: 2. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPushRegister: t0. ^ 0 ] @@ -1136,7 +1145,7 @@ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock t1 jump2 live t2 | + | t0 jump1 s2 currentBlock t1 jump2 live | live := 0. self annotateBytecode: self Label. t0 := self @@ -1152,22 +1161,19 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). (self ssValue: 1) copyToReg: t1. + self ssPop: 2. + self AddR: t1 R: t0. + self ssPushRegister: t0. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. (self ssValue: 0) copyToReg: t1. - t2 := self - allocateRegNotConflictingWith: live - ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t2). - (self ssValue: 1) copyToReg: t2. - self MoveR: t1 R: t0. - self MoveR: t2 R: t1. + (self ssValue: 1) copyToReg: t0. + self ssPop: 2. + self AddR: t0 R: t1. + self ssPushRegister: t1. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPop: 2. - self AddR: t1 R: t0. - self ssPushRegister: t0. ^ 0 ] @@ -1175,7 +1181,7 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ "AutoGenerated by Druid" - | t0 s8 jump1 s2 currentBlock jump2 live s5 | + | t0 jump1 s2 currentBlock jump2 live | live := 0. self annotateBytecode: self Label. t0 := self @@ -1185,18 +1191,17 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ (self ssValue: 0) copyToReg: t0. self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. - s5 := 2. - self MoveCq: s5 R: t0. + self ssPushConstant: 2. + self ssPop: 2. + self ssPushRegister: t0. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s8 := 4. - self MoveCq: s8 R: t0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - self ssPushRegister: t0. + self ssPushConstant: 4. self ssPop: 2. self ssPushRegister: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -1297,36 +1302,19 @@ DruidTestRTLCompiler >> gen_emptyPrimitiveWithArguments [ DruidTestRTLCompiler >> gen_extBBytecode [ "AutoGenerated by Druid" - | s6 s3 s16 s10 s2 currentBlock s7 s4 s17 s11 live s9 | + | s8 s6 s4 s2 currentBlock s9 live s3 | live := 0. s2 := byte1. s3 := numExtB. s3 = 0 ifTrue: [ s2 > 127 ifTrue: [ s6 := s2 - 256. - s7 := s6. - extB := s7. - s16 := numExtB. - s17 := s16 + 1. - numExtB := s17. + extB := s6. + s8 := numExtB. + s9 := s8 + 1. + numExtB := s9. ^ 0 ]. - s9 := extB. - s10 := s9 << 8. - s11 := s10 + s2. - s7 := s11. - extB := s7. - s16 := numExtB. - s17 := s16 + 1. - numExtB := s17. ^ 0 ]. - s9 := extB. - s10 := s9 << 8. - s11 := s10 + s2. - s7 := s11. - extB := s7. - s16 := numExtB. - s17 := s16 + 1. - numExtB := s17. ^ 0 ] @@ -1440,7 +1428,7 @@ DruidTestRTLCompiler >> gen_extPushIntegerBytecode [ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ "AutoGenerated by Druid" - | s6 s3 s16 s10 s8 s5 s2 s18 currentBlock s15 s4 s17 live s9 | + | s6 s3 s16 s25 s10 s22 s8 s5 s2 s18 currentBlock s15 s24 s4 s17 live s23 s9 | live := 0. s2 := byte1. s3 := s2 >> 3. @@ -1454,30 +1442,27 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ s10 >= 64 ifTrue: [ self ssFlushStack. self deoptimize. - deadCode := false. ^ 0 ]. s15 := s2 bitAnd: 7. s16 := extB. s17 := s16 << 3. s18 := s15 + s17. - extB := 0. - numExtB := 0. self marshallSendArguments: s18. self genMarshalledSend: s6 numArgs: s18 sendTable: superSendTrampolines. ^ 0 ]. - s15 := s2 bitAnd: 7. - s16 := extB. - s17 := s16 << 3. - s18 := s15 + s17. + s22 := s2 bitAnd: 7. + s23 := extB. + s24 := s23 << 3. + s25 := s22 + s24. extB := 0. numExtB := 0. - self marshallSendArguments: s18. + self marshallSendArguments: s25. self genMarshalledSend: s6 - numArgs: s18 + numArgs: s25 sendTable: superSendTrampolines. ^ 0 ] @@ -1486,7 +1471,7 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ "AutoGenerated by Druid" - | s6 s11 s88 jump5 s55 s4 jump3 jump8 s2 s36 currentBlock s84 s58 s12 s60 t1 jump1 s82 s47 jump6 s10 s5 live jump4 jumpTrue jumpNext jump9 s3 t2 jump2 b613 jump7 t0 s50 | + | jump6 t2 s94 jump7 s82 s103 jump8 s96 s58 jump9 s107 s2 jumpTrue s3 s88 s47 s4 s60 s5 live s36 s6 b623 s77 s10 s111 s11 s50 s12 jump1 jump2 jump3 jump4 t0 currentBlock s100 jump5 t1 jumpNext s55 | live := 0. self annotateBytecode: self Label. s3 := byte1. @@ -1518,7 +1503,7 @@ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ self CmpCq: 0 R: t2. jump1 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t2. - b613 := self Label. + b623 := self Label. self MoveR: t2 R: t1. self AndCq: 7 R: t1. self CmpCq: 0 R: t1. @@ -1529,7 +1514,7 @@ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t1. self MoveR: t1 R: t2. - jump4 := self Jump: b613. + jump4 := self Jump: b623. currentBlock := self Label. jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -1604,39 +1589,73 @@ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ self LogicalShiftRightCq: 29 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump9 := self JumpNonZero: 0. + jump9 := self JumpZero: 0. + s77 := s36 << 3. + self AddCq: s77 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump8 := self Jump: 0. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. self TstCq: 7 R: t0. - jump8 := self JumpNonZero: 0. + jump9 := self JumpZero: 0. + s82 := s36 << 3. + self AddCq: s82 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump7 := self Jump: 0. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. self CmpCq: 16r20000000000 R: t1. - jump7 := self JumpBelow: 0. + jump9 := self JumpBelow: 0. self CmpCq: 16r20000000000 R: t0. - jump5 := self JumpGreaterOrEqual: 0. + jump5 := self JumpLess: 0. + s88 := s36 << 3. + self AddCq: s88 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump2 := self Jump: 0. + currentBlock := self Label. + jump5 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t0. - jump2 := self JumpBelow: 0. - s82 := objectMemory trueObject. - self CmpCq: s82 R: t0. - jump3 := self JumpBelowOrEqual: 0. + jump5 := self JumpBelow: 0. + s94 := objectMemory trueObject. + self CmpCq: s94 R: t0. + jump3 := self JumpAbove: 0. + s96 := s36 << 3. + self AddCq: s96 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump6 := self Jump: 0. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - s84 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s84 R: t0. - jump2 := self JumpBelow: 0. + jump5 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + s100 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s100 R: t0. + jump3 := self JumpBelow: 0. self MoveR: t1 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + s103 := s36 << 3. + self AddCq: s103 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump5 := self Jump: 0. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + s107 := s36 << 3. + self AddCq: s107 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump3 := self Jump: 0. currentBlock := self Label. jump9 jmpTarget: currentBlock. + s111 := s36 << 3. + self AddCq: s111 R: t1. + self MoveR: t0 M64: 8 r: t1. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. jump8 jmpTarget: currentBlock. jump7 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. jump5 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. - s88 := s36 << 3. - self AddCq: s88 R: t1. - self MoveR: t0 M64: 8 r: t1. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. ^ 0 ] @@ -1644,7 +1663,7 @@ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ "AutoGenerated by Druid" - | s6 jump5 s4 jump3 s31 s44 s14 s9 s2 t1 currentBlock jump1 s42 s67 jump6 s34 live s5 s39 jump4 s63 s3 t2 jump2 s61 jump7 t0 | + | s6 jump5 s33 s81 s46 s4 s77 jump3 s44 s69 s14 s2 s75 s36 currentBlock s58 s9 s84 t1 s89 jump1 jump6 live s5 jump4 s93 s63 s3 t2 jump9 jump2 jump7 t0 s41 | live := 0. self annotateBytecode: self Label. s3 := byte1. @@ -1669,7 +1688,7 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t2). s6 <= s9 ifTrue: [ - | jump7 jump5 jump3 jump1 jump8 jump6 jump4 jump2 | + | jump7 jump5 jump3 jump1 jump8 jump6 jump4 jump2 jump9 | self MoveM64: 0 r: t1 R: t2. self AndCq: 16r3FFFFF R: t2. s14 := ClassMethodContextCompactIndex. @@ -1694,24 +1713,24 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self AndCq: 7 R: t2. self CmpCq: 0 R: t2. jump1 := self JumpNonZero: 0. - s31 := objectMemory getMemoryMap getSpaceMaskToUse. + s33 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t1 R: t2. - self AndCq: s31 R: t2. - s34 := objectMemory getMemoryMap getOldSpaceMask. - self CmpCq: s34 R: t2. + self AndCq: s33 R: t2. + s36 := objectMemory getMemoryMap getOldSpaceMask. + self CmpCq: s36 R: t2. jump4 := self JumpNonZero: 0. self MoveR: t0 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. jump5 := self JumpNonZero: 0. - s39 := objectMemory getMemoryMap getSpaceMaskToUse. + s41 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t0 R: t2. - self AndCq: s39 R: t2. - s42 := objectMemory getMemoryMap getNewSpaceMask. - self CmpCq: s42 R: t2. + self AndCq: s41 R: t2. + s44 := objectMemory getMemoryMap getNewSpaceMask. + self CmpCq: s44 R: t2. jump6 := self JumpNonZero: 0. - s44 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s44 R: t0. + s46 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s46 R: t0. jump7 := self JumpBelow: 0. self MoveM64: 0 r: t1 R: t2. self LogicalShiftRightCq: 29 R: t2. @@ -1732,128 +1751,196 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self LogicalShiftRightCq: 29 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump8 := self JumpNonZero: 0. + jump8 := self JumpZero: 0. + s58 := s6 << 3. + self AddCq: s58 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump7 := self Jump: 0. + currentBlock := self Label. + jump8 jmpTarget: currentBlock. self TstCq: 7 R: t0. - jump7 := self JumpNonZero: 0. + jump8 := self JumpZero: 0. + s63 := s6 << 3. + self AddCq: s63 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump6 := self Jump: 0. + currentBlock := self Label. + jump8 jmpTarget: currentBlock. self CmpCq: 16r20000000000 R: t1. - jump6 := self JumpLess: 0. + jump8 := self JumpLess: 0. self CmpCq: 16r20000000000 R: t0. - jump5 := self JumpGreaterOrEqual: 0. + jump5 := self JumpLess: 0. + s69 := s6 << 3. + self AddCq: s69 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump4 := self Jump: 0. + currentBlock := self Label. + jump5 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t0. - jump4 := self JumpBelow: 0. - s61 := objectMemory trueObject. - self CmpCq: s61 R: t0. - jump1 := self JumpBelowOrEqual: 0. + jump5 := self JumpBelow: 0. + s75 := objectMemory trueObject. + self CmpCq: s75 R: t0. + jump1 := self JumpAbove: 0. + s77 := s6 << 3. + self AddCq: s77 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump9 := self Jump: 0. currentBlock := self Label. - jump4 jmpTarget: currentBlock. - s63 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s63 R: t0. - jump4 := self JumpBelow: 0. + jump5 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + s81 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s81 R: t0. + jump1 := self JumpBelow: 0. self MoveR: t1 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + s84 := s6 << 3. + self AddCq: s84 R: t1. + self MoveR: t0 M64: 8 r: t1. + extA := 0. + jump5 := self Jump: 0. currentBlock := self Label. - jump8 jmpTarget: currentBlock. - jump7 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. - s67 := s6 << 3. - self AddCq: s67 R: t1. + s89 := s6 << 3. + self AddCq: s89 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump1 := self Jump: 0. + currentBlock := self Label. + jump8 jmpTarget: currentBlock. + s93 := s6 << 3. + self AddCq: s93 R: t1. self MoveR: t0 M64: 8 r: t1. currentBlock := self Label. jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. - extA := 0. + jump7 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. + jump4 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. ^ 0 ]. self MoveM64: 0 r: t1 R: t2. self LogicalShiftRightCq: 23 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump3 := self JumpZero: 0. + jump1 := self JumpZero: 0. self deoptimize. - jump2 := self Jump: 0. + jump5 := self Jump: 0. deadCode := false. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. self MoveR: t1 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. - jump3 := self JumpNonZero: 0. - s31 := objectMemory getMemoryMap getSpaceMaskToUse. + jump1 := self JumpNonZero: 0. + s33 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t1 R: t2. - self AndCq: s31 R: t2. - s34 := objectMemory getMemoryMap getOldSpaceMask. - self CmpCq: s34 R: t2. - jump4 := self JumpNonZero: 0. + self AndCq: s33 R: t2. + s36 := objectMemory getMemoryMap getOldSpaceMask. + self CmpCq: s36 R: t2. + jump9 := self JumpNonZero: 0. self MoveR: t0 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. - jump1 := self JumpNonZero: 0. - s39 := objectMemory getMemoryMap getSpaceMaskToUse. + jump4 := self JumpNonZero: 0. + s41 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t0 R: t2. - self AndCq: s39 R: t2. - s42 := objectMemory getMemoryMap getNewSpaceMask. - self CmpCq: s42 R: t2. - jump5 := self JumpNonZero: 0. - s44 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s44 R: t0. - jump6 := self JumpBelow: 0. + self AndCq: s41 R: t2. + s44 := objectMemory getMemoryMap getNewSpaceMask. + self CmpCq: s44 R: t2. + jump6 := self JumpNonZero: 0. + s46 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s46 R: t0. + jump7 := self JumpBelow: 0. self MoveM64: 0 r: t1 R: t2. self LogicalShiftRightCq: 29 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump7 := self JumpNonZero: 0. + jump3 := self JumpNonZero: 0. self MoveR: t1 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. + jump4 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. jump7 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. self MoveM64: 0 r: t1 R: t2. self LogicalShiftRightCq: 29 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump7 := self JumpNonZero: 0. + jump3 := self JumpZero: 0. + s58 := s6 << 3. + self AddCq: s58 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump7 := self Jump: 0. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. self TstCq: 7 R: t0. - jump6 := self JumpNonZero: 0. + jump3 := self JumpZero: 0. + s63 := s6 << 3. + self AddCq: s63 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump6 := self Jump: 0. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. self CmpCq: 16r20000000000 R: t1. - jump5 := self JumpLess: 0. + jump3 := self JumpLess: 0. self CmpCq: 16r20000000000 R: t0. - jump1 := self JumpGreaterOrEqual: 0. + jump4 := self JumpLess: 0. + s69 := s6 << 3. + self AddCq: s69 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump9 := self Jump: 0. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t0. jump4 := self JumpBelow: 0. - s61 := objectMemory trueObject. - self CmpCq: s61 R: t0. - jump3 := self JumpBelowOrEqual: 0. + s75 := objectMemory trueObject. + self CmpCq: s75 R: t0. + jump1 := self JumpAbove: 0. + s77 := s6 << 3. + self AddCq: s77 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump2 := self Jump: 0. currentBlock := self Label. jump4 jmpTarget: currentBlock. - s63 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s63 R: t0. - jump4 := self JumpBelow: 0. + jump1 jmpTarget: currentBlock. + s81 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s81 R: t0. + jump1 := self JumpBelow: 0. self MoveR: t1 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + s84 := s6 << 3. + self AddCq: s84 R: t1. + self MoveR: t0 M64: 8 r: t1. + extA := 0. + jump4 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. + s89 := s6 << 3. + self AddCq: s89 R: t1. + self MoveR: t0 M64: 8 r: t1. + jump1 := self Jump: 0. + currentBlock := self Label. jump3 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. - s67 := s6 << 3. - self AddCq: s67 R: t1. + s93 := s6 << 3. + self AddCq: s93 R: t1. self MoveR: t0 M64: 8 r: t1. currentBlock := self Label. + jump5 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. - extA := 0. + jump4 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. ^ 0 ] @@ -1861,7 +1948,7 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ DruidTestRTLCompiler >> gen_extUnconditionalJump [ "AutoGenerated by Druid" - | s6 s3 s28 s10 t1 s8 s5 s2 s18 currentBlock s12 s27 t0 jump2 s4 s26 live s9 | + | s6 s33 s4 s22 s31 s38 jump3 s9 s2 s36 currentBlock t1 s42 s12 jump1 s10 s5 live s32 s23 s3 s21 s37 jump2 s43 s8 t0 s18 s41 | live := 0. self annotateBytecode: self Label. s3 := byte1. @@ -1877,7 +1964,7 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). s6 < 0 ifTrue: [ - | jump1 | + | jump1 jump2 jump3 | s8 := numExtB. s9 := s8 << 1. s10 := s9. @@ -1886,10 +1973,10 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ s18 := s6 + s10. self ssFlushStack. s18 >= 0 ifTrue: [ - s26 := bytecodePC. - s27 := s26 + s6. - s28 := s27 + 2. - self Jump: (self ensureFixupAt: s28). + s21 := bytecodePC. + s22 := s21 + s6. + s23 := s22 + 2. + self Jump: (self ensureFixupAt: s23). deadCode := true. ^ 0 ]. self MoveR: SPReg R: t0. @@ -1897,14 +1984,35 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ self CmpR: t1 R: t0. jump1 := self JumpAboveOrEqual: 0. self CallRT: ceCheckForInterruptTrampoline. + self MoveR: TempReg R: t1. + self CmpCq: 1 R: t1. + jump2 := self JumpNonZero: 0. + s31 := bytecodePC. + s32 := s31 + s6. + s33 := s32 + 2. + self Jump: (self ensureFixupAt: s33). + deadCode := true. + jump3 := self Jump: 0. + deadCode := false. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + s36 := bytecodePC. + s37 := s36 + s6. + s38 := s37 + 2. + self Jump: (self ensureFixupAt: s38). + deadCode := true. + jump2 := self Jump: 0. + deadCode := false. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s26 := bytecodePC. - s27 := s26 + s6. - s28 := s27 + 2. - self Jump: (self ensureFixupAt: s28). + s41 := bytecodePC. + s42 := s41 + s6. + s43 := s42 + 2. + self Jump: (self ensureFixupAt: s43). deadCode := true. - jump1 := self Jump: 0. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. ^ 0 ]. s12 := 0. s10 := s12. @@ -1913,10 +2021,10 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ s18 := s6 + s10. self ssFlushStack. s18 >= 0 ifTrue: [ - s26 := bytecodePC. - s27 := s26 + s6. - s28 := s27 + 2. - self Jump: (self ensureFixupAt: s28). + s21 := bytecodePC. + s22 := s21 + s6. + s23 := s22 + 2. + self Jump: (self ensureFixupAt: s23). deadCode := true. ^ 0 ]. self MoveR: SPReg R: t0. @@ -1924,14 +2032,35 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ self CmpR: t1 R: t0. jump2 := self JumpAboveOrEqual: 0. self CallRT: ceCheckForInterruptTrampoline. + self MoveR: TempReg R: t1. + self CmpCq: 1 R: t1. + jump3 := self JumpNonZero: 0. + s31 := bytecodePC. + s32 := s31 + s6. + s33 := s32 + 2. + self Jump: (self ensureFixupAt: s33). + deadCode := true. + jump1 := self Jump: 0. + deadCode := false. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + s36 := bytecodePC. + s37 := s36 + s6. + s38 := s37 + 2. + self Jump: (self ensureFixupAt: s38). + deadCode := true. + jump3 := self Jump: 0. + deadCode := false. currentBlock := self Label. jump2 jmpTarget: currentBlock. - s26 := bytecodePC. - s27 := s26 + s6. - s28 := s27 + 2. - self Jump: (self ensureFixupAt: s28). + s41 := bytecodePC. + s42 := s41 + s6. + s43 := s42 + 2. + self Jump: (self ensureFixupAt: s43). deadCode := true. - jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. ^ 0 ] @@ -1939,7 +2068,7 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ DruidTestRTLCompiler >> gen_extendedPushBytecode [ "AutoGenerated by Druid" - | s6 s3 s19 s28 s54 t1 s8 s5 s2 s30 currentBlock s21 t0 s4 s29 s55 live s20 | + | s6 s46 s4 jump3 s2 s27 currentBlock s20 s19 s51 t1 s25 jump1 b325 s47 s56 live s5 jump4 s3 jump2 s52 s8 s26 t0 s18 s57 | live := 0. s2 := byte1. s3 := s2 >> 6. @@ -1954,8 +2083,7 @@ DruidTestRTLCompiler >> gen_extendedPushBytecode [ self MoveR: ReceiverResultReg R: t0. s8 := s5 << 3. self AddCq: s8 R: t0. - self MoveM64: 8 r: t0 R: t0. - self ssPushRegister: t0. + self ssPushBase: t0 offset: 8. ^ 0 ]. s4 = 1 ifTrue: [ (self simStackTempAt: s5) copyToReg: t0. @@ -1963,65 +2091,69 @@ DruidTestRTLCompiler >> gen_extendedPushBytecode [ ^ 0 ]. s4 = 2 ifTrue: [ self genMoveConstant: methodObj R: t0. - s19 := LiteralStart. - s20 := s5 + s19. - s21 := s20 << 3. - self AddCq: s21 R: t0. - self MoveM64: 8 r: t0 R: t0. - self ssPushRegister: t0. + s18 := LiteralStart. + s19 := s5 + s18. + s20 := s19 << 3. + self AddCq: s20 R: t0. + self ssPushBase: t0 offset: 8. ^ 0 ]. + self genMoveConstant: methodObj R: t0. + s25 := LiteralStart. + s26 := s5 + s25. + s27 := s26 << 3. + self AddCq: s27 R: t0. + self MoveM64: 8 r: t0 R: t0. t1 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). - s4 = 3 ifTrue: [ - | jump3 jump1 b320 jump4 jump2 | - self genMoveConstant: methodObj R: t0. - s28 := LiteralStart. - s29 := s5 + s28. - s30 := s29 << 3. - self AddCq: s30 R: t0. - self MoveM64: 8 r: t0 R: t0. - self MoveM64: 0 r: t0 R: t1. - self AndCq: 16r3FFFF7 R: t1. - self CmpCq: 0 R: t1. - jump1 := self JumpNonZero: 0. - self MoveM64: 8 r: t0 R: t1. - b320 := self Label. - self MoveR: t1 R: t0. - self AndCq: 7 R: t0. - self CmpCq: 0 R: t0. - jump2 := self JumpNonZero: 0. - self MoveM64: 0 r: t1 R: t0. - self AndCq: 16r3FFFF7 R: t0. - self CmpCq: 0 R: t0. - jump3 := self JumpNonZero: 0. - self MoveM64: 8 r: t1 R: t0. - self MoveR: t0 R: t1. - jump4 := self Jump: b320. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. - self MoveR: t1 R: t0. - jump3 := self Jump: 0. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s54 := ValueIndex. - s55 := s54 << 3. - self AddCq: s55 R: t0. - self MoveM64: 8 r: t0 R: t0. - self ssPushRegister: t0. - ^ 0 ]. - self ssPushRegister: t0. - ^ 0 -] - -{ #category : #generated } -DruidTestRTLCompiler >> gen_failingPrimitive [ - "AutoGenerated by Druid" - + self MoveM64: 0 r: t0 R: t1. + self AndCq: 16r3FFFF7 R: t1. + self CmpCq: 0 R: t1. + jump1 := self JumpNonZero: 0. + self MoveM64: 8 r: t0 R: t1. + b325 := self Label. + self MoveR: t1 R: t0. + self AndCq: 7 R: t0. + self CmpCq: 0 R: t0. + jump2 := self JumpNonZero: 0. + self MoveM64: 0 r: t1 R: t0. + self AndCq: 16r3FFFF7 R: t0. + self CmpCq: 0 R: t0. + jump3 := self JumpNonZero: 0. + self MoveM64: 8 r: t1 R: t0. + self MoveR: t0 R: t1. + jump4 := self Jump: b325. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + s46 := ValueIndex. + s47 := s46 << 3. + self AddCq: s47 R: t1. + self ssPushBase: t1 offset: 8. + jump3 := self Jump: 0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + s51 := ValueIndex. + s52 := s51 << 3. + self AddCq: s52 R: t1. + self ssPushBase: t1 offset: 8. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + s56 := ValueIndex. + s57 := s56 << 3. + self AddCq: s57 R: t0. + self ssPushBase: t0 offset: 8. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. + ^ 0 +] + +{ #category : #generated } +DruidTestRTLCompiler >> gen_failingPrimitive [ + "AutoGenerated by Druid" + | currentBlock | ^ 0 ] @@ -2102,8 +2234,9 @@ DruidTestRTLCompiler >> gen_primitiveAdd [ self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. ^ 0 ] @@ -2111,20 +2244,21 @@ DruidTestRTLCompiler >> gen_primitiveAdd [ DruidTestRTLCompiler >> gen_primitiveAnd [ "AutoGenerated by Druid" - | jump1 jump2 jump3 currentBlock | + | jump1 jump2 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self CmpCq: 10 R: ClassReg. jump2 := self JumpLessOrEqual: 0. self MoveCq: 42 R: ReceiverResultReg. - jump3 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. self MoveCq: 10 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + self MoveCq: 10 R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -2133,7 +2267,7 @@ DruidTestRTLCompiler >> gen_primitiveAnd [ DruidTestRTLCompiler >> gen_primitiveAndIfTrue [ "AutoGenerated by Druid" - | jump1 jump2 jump3 currentBlock | + | jump1 jump2 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 1 R: ClassReg. jump1 := self JumpLessOrEqual: 0. @@ -2141,13 +2275,14 @@ DruidTestRTLCompiler >> gen_primitiveAndIfTrue [ self CmpCq: 1 R: ClassReg. jump2 := self JumpNonZero: 0. self MoveCq: 1 R: ReceiverResultReg. - jump3 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + self MoveCq: 2 R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -2169,7 +2304,7 @@ DruidTestRTLCompiler >> gen_primitiveArithmeticBitShiftRight [ DruidTestRTLCompiler >> gen_primitiveAsCharacter [ "AutoGenerated by Druid" - | s3 s13 currentBlock s2 | + | s3 s16 currentBlock s2 | s2 := self methodNumArgs. s2 = 0 ifTrue: [ | jump1 jump2 jump3 | @@ -2186,28 +2321,32 @@ DruidTestRTLCompiler >> gen_primitiveAsCharacter [ self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. ^ 0 ]. - s13 := self methodNumArgs. - s13 = 1 ifTrue: [ - | jump3 jump2 jump1 | + s16 := self methodNumArgs. + s16 = 1 ifTrue: [ + | jump1 jump2 jump3 | self MoveR: Arg0Reg R: ClassReg. self TstCq: 1 R: ClassReg. - jump3 := self JumpZero: 0. + jump1 := self JumpZero: 0. self ArithmeticShiftRightCq: 3 R: ClassReg. self CmpCq: 0 R: ClassReg. jump2 := self JumpLess: 0. self CmpCq: 16r3FFFFFFF R: ClassReg. - jump1 := self JumpGreater: 0. + jump3 := self JumpGreater: 0. self LogicalShiftLeftCq: 3 R: ClassReg. self AddCq: 2 R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. jump3 jmpTarget: currentBlock. + currentBlock := self Label. jump2 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. ^ 0 ]. ^ 0 @@ -2217,7 +2356,7 @@ DruidTestRTLCompiler >> gen_primitiveAsCharacter [ DruidTestRTLCompiler >> gen_primitiveAsFloat [ "AutoGenerated by Druid" - | jumpTrue jumpNext jump1 s42 jump3 currentBlock s45 jump2 | + | jump5 s30 jump1 jump3 s33 currentBlock jump2 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self ArithmeticShiftRightCq: 3 R: ClassReg. self ConvertR: ClassReg Rd: DPFPReg0. @@ -2228,76 +2367,59 @@ DruidTestRTLCompiler >> gen_primitiveAsFloat [ self CmpCq: 896 R: SendNumArgsReg. jump1 := self JumpBelowOrEqual: 0. self CmpCq: 1151 R: SendNumArgsReg. - jumpTrue := self JumpBelowOrEqual: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump2 := self Jump: 0. + jump2 := self JumpBelowOrEqual: 0. + jump3 := self JumpAbove: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. self AndCq: 16rFFFFFFFFFFFFF R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self CmpCq: 0 R: SendNumArgsReg. - jumpTrue := self JumpZero: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump3 := self Jump: 0. + jump4 := self JumpZero: 0. + jump5 := self JumpNonZero: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. self CmpCq: 896 R: SendNumArgsReg. - jumpTrue := self JumpZero: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 := self JumpNonZero: 0. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self CmpCq: 1 R: SendNumArgsReg. - jump2 := self JumpNonZero: 0. + jump4 jmpTarget: currentBlock. self MoveRd: DPFPReg0 R: SendNumArgsReg. self RotateLeftCq: 1 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump3 := self JumpBelowOrEqual: 0. + jump4 := self JumpBelowOrEqual: 0. self SubCq: 16r7000000000000000 R: SendNumArgsReg. - jump1 := self Jump: 0. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: 4 R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. + jump4 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 4 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump1 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: ClassReg. self AddCq: 16 R: ClassReg. - s42 := objectMemory getScavengeThreshold. - self CmpCq: s42 R: ClassReg. - jump2 := self JumpAbove: 0. - s45 := 72057594205700130. - self MoveCq: s45 R: ClassReg. + s30 := objectMemory getScavengeThreshold. + self CmpCq: s30 R: ClassReg. + jump1 := self JumpAbove: 0. + s33 := 72057594205700130. + self MoveCq: s33 R: ClassReg. self MoveR: ClassReg M64: 0 r: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: ClassReg. self AddCq: 16 R: ClassReg. self MoveR: ClassReg Aw: objectMemory freeStartAddress. self MoveRd: DPFPReg0 M64: 8 r: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. ^ 0 ] @@ -2418,14 +2540,14 @@ DruidTestRTLCompiler >> gen_primitiveAssertIsIgnored [ | currentBlock | self MoveCq: 17 R: ReceiverResultReg. self genPrimReturn. - ^ 0 + ^ CompletePrimitive ] { #category : #generated } DruidTestRTLCompiler >> gen_primitiveAt [ "AutoGenerated by Druid" - | jump1 jump7 jump10 jump9 jump6 jump3 currentBlock jump8 jump5 jump2 jump11 s70 s52 s90 jump4 | + | jump1 s72 s54 s92 jump6 jump3 currentBlock jump8 jump5 jump2 jump7 jump4 | self SubCq: 24 R: SPReg. self MoveR: ReceiverResultReg R: Extra3Reg. self MoveR: Extra3Reg Mw: 0 r: SPReg. @@ -2433,12 +2555,18 @@ DruidTestRTLCompiler >> gen_primitiveAt [ self MoveR: Extra3Reg Mw: 8 r: SPReg. self MoveMw: 0 r: SPReg R: Extra3Reg. self TstCq: 7 R: Extra3Reg. - jump1 := self JumpNonZero: 0. + jump1 := self JumpZero: 0. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. self MoveMw: 8 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: Extra0Reg. self AndCq: 1 R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. - jump2 := self JumpZero: 0. + jump1 := self JumpNonZero: 0. + jump3 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. self MoveMw: 8 r: SPReg R: Extra3Reg. self ArithmeticShiftRightCq: 3 R: Extra3Reg. self MoveR: Extra3Reg Mw: 8 r: SPReg. @@ -2453,19 +2581,19 @@ DruidTestRTLCompiler >> gen_primitiveAt [ self MoveMb: 7 r: Extra3Reg R: Extra2Reg. self AndCq: 255 R: Extra2Reg. self CmpCq: 255 R: Extra2Reg. - jump3 := self JumpNonZero: 0. + jump1 := self JumpNonZero: 0. self MoveMw: 0 r: SPReg R: Extra3Reg. self MoveM64: -8 r: Extra3Reg R: Extra2Reg. self LogicalShiftLeftCq: 8 R: Extra2Reg. self LogicalShiftRightCq: 8 R: Extra2Reg. jump4 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. currentBlock := self Label. jump4 jmpTarget: currentBlock. self CmpCq: 5 R: Extra1Reg. jump4 := self JumpAbove: 0. - jump3 := self Jump: 0. + jump1 := self Jump: 0. currentBlock := self Label. jump4 jmpTarget: currentBlock. self CmpCq: 16 R: Extra1Reg. @@ -2502,10 +2630,10 @@ DruidTestRTLCompiler >> gen_primitiveAt [ jump8 := self Jump: 0. currentBlock := self Label. jump4 jmpTarget: currentBlock. - s52 := 0. - self MoveCq: s52 R: Extra2Reg. + s54 := 0. + self MoveCq: s54 R: Extra2Reg. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. jump7 jmpTarget: currentBlock. jump8 jmpTarget: currentBlock. self CmpCq: 9 R: Extra1Reg. @@ -2523,8 +2651,8 @@ DruidTestRTLCompiler >> gen_primitiveAt [ self MoveR: Extra2Reg R: ClassReg. currentBlock := self Label. jump5 jmpTarget: currentBlock. - s70 := 0. - self MoveCq: s70 R: SendNumArgsReg. + s72 := 0. + self MoveCq: s72 R: SendNumArgsReg. jump5 := self Jump: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. @@ -2544,7 +2672,7 @@ DruidTestRTLCompiler >> gen_primitiveAt [ jump7 := self JumpNonZero: 0. self MoveMw: 0 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: ClassReg. - jump3 := self Jump: 0. + jump1 := self Jump: 0. currentBlock := self Label. jump7 jmpTarget: currentBlock. self CmpCq: 8 R: ClassReg. @@ -2556,9 +2684,9 @@ DruidTestRTLCompiler >> gen_primitiveAt [ jump7 jmpTarget: currentBlock. self MoveR: ClassReg R: SendNumArgsReg. self LogicalShiftRightCq: 10 R: SendNumArgsReg. - s90 := objectMemory hiddenRootsObject. + s92 := objectMemory hiddenRootsObject. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. - self AddCq: s90 R: SendNumArgsReg. + self AddCq: s92 R: SendNumArgsReg. self MoveM64: 8 r: SendNumArgsReg R: SendNumArgsReg. self genMoveConstant: objectMemory nilObject R: Extra0Reg. self CmpR: Extra0Reg R: SendNumArgsReg. @@ -2575,7 +2703,7 @@ DruidTestRTLCompiler >> gen_primitiveAt [ jump8 jmpTarget: currentBlock. self MoveR: Extra0Reg R: ClassReg. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. self MoveM64: 24 r: ClassReg R: Extra0Reg. self ArithmeticShiftRightCq: 3 R: Extra0Reg. @@ -2592,15 +2720,24 @@ DruidTestRTLCompiler >> gen_primitiveAt [ self MoveR: Extra3Reg Mw: 16 r: SPReg. self MoveMw: 16 r: SPReg R: Extra3Reg. self CmpCq: 36 R: Extra3Reg. - jump5 := self JumpZero: 0. + jump5 := self JumpNonZero: 0. + jump4 := self Jump: 0. currentBlock := self Label. jump6 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. self SubR: SendNumArgsReg R: ClassReg. self CmpCq: 24 R: Extra1Reg. - jump6 := self JumpAboveOrEqual: 0. + jump5 := self JumpBelow: 0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + jump4 jmpTarget: currentBlock. + jump4 := self Jump: 0. + currentBlock := self Label. + jump5 jmpTarget: currentBlock. self MoveMw: 8 r: SPReg R: Extra3Reg. self CmpCq: 1 R: Extra3Reg. - jump4 := self JumpBelow: 0. + jump5 := self JumpBelow: 0. self MoveMw: 8 r: SPReg R: Extra3Reg. self CmpR: ClassReg R: Extra3Reg. jump3 := self JumpAbove: 0. @@ -2608,7 +2745,7 @@ DruidTestRTLCompiler >> gen_primitiveAt [ self AddR: SendNumArgsReg R: Extra3Reg. self MoveR: Extra3Reg Mw: 8 r: SPReg. self CmpCq: 5 R: Extra1Reg. - jump8 := self JumpAbove: 0. + jump2 := self JumpAbove: 0. self MoveMw: 8 r: SPReg R: Extra3Reg. self SubCq: 1 R: Extra3Reg. self MoveR: Extra3Reg Mw: 8 r: SPReg. @@ -2621,12 +2758,11 @@ DruidTestRTLCompiler >> gen_primitiveAt [ self MoveR: Extra3Reg Mw: 0 r: SPReg. self MoveMw: 0 r: SPReg R: Extra3Reg. self MoveM64: 8 r: Extra3Reg R: Extra0Reg. - self MoveR: Extra0Reg R: ReceiverResultReg. - jump7 := self Jump: 0. + jump6 := self Jump: 0. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. self CmpCq: 16 R: Extra1Reg. - jump8 := self JumpBelow: 0. + jump2 := self JumpBelow: 0. self MoveMw: 8 r: SPReg R: Extra3Reg. self MoveMw: 0 r: SPReg R: Extra4Reg. self AddR: Extra4Reg R: Extra3Reg. @@ -2639,12 +2775,11 @@ DruidTestRTLCompiler >> gen_primitiveAt [ self AndCq: 255 R: Extra0Reg. self LogicalShiftLeftCq: 3 R: Extra0Reg. self AddCq: 1 R: Extra0Reg. - self MoveR: Extra0Reg R: ReceiverResultReg. - jump9 := self Jump: 0. + jump1 := self Jump: 0. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. self CmpCq: 12 R: Extra1Reg. - jump8 := self JumpBelow: 0. + jump2 := self JumpBelow: 0. self MoveMw: 8 r: SPReg R: Extra3Reg. self SubCq: 1 R: Extra3Reg. self MoveR: Extra3Reg Mw: 8 r: SPReg. @@ -2660,12 +2795,11 @@ DruidTestRTLCompiler >> gen_primitiveAt [ self AndCq: 16rFFFF R: Extra0Reg. self LogicalShiftLeftCq: 3 R: Extra0Reg. self AddCq: 1 R: Extra0Reg. - self MoveR: Extra0Reg R: ReceiverResultReg. - jump10 := self Jump: 0. + jump8 := self Jump: 0. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. self CmpCq: 9 R: Extra1Reg. - jump8 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self MoveMw: 8 r: SPReg R: Extra3Reg. self SubCq: 1 R: Extra3Reg. self MoveR: Extra3Reg Mw: 8 r: SPReg. @@ -2679,25 +2813,26 @@ DruidTestRTLCompiler >> gen_primitiveAt [ self MoveMw: 0 r: SPReg R: Extra3Reg. self MoveM64: 8 r: Extra3Reg R: Extra0Reg. self CmpCq: 16rFFFFFFFFFFFFFFF R: Extra0Reg. - jump11 := self JumpAbove: 0. + jump7 := self JumpAbove: 0. self LogicalShiftLeftCq: 3 R: Extra0Reg. self AddCq: 1 R: Extra0Reg. - self MoveR: Extra0Reg R: ReceiverResultReg. currentBlock := self Label. - jump7 jmpTarget: currentBlock. - jump9 jmpTarget: currentBlock. - jump10 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. + self MoveR: Extra0Reg R: ReceiverResultReg. self AddCq: 24 R: SPReg. self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. + currentBlock := self Label. jump3 jmpTarget: currentBlock. - jump8 jmpTarget: currentBlock. - jump11 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump5 jmpTarget: currentBlock. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self AddCq: 24 R: SPReg. ^ 0 ] @@ -3598,23 +3733,20 @@ DruidTestRTLCompiler >> gen_primitiveBitAnd [ DruidTestRTLCompiler >> gen_primitiveBitShift [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self CmpCq: 0 R: SendNumArgsReg. jump1 := self JumpLessOrEqual: 0. self LogicalShiftLeftR: SendNumArgsReg R: ClassReg. - self MoveR: ClassReg R: SendNumArgsReg. - jump2 := self Jump: 0. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: SendNumArgsReg. self NegateR: SendNumArgsReg. self LogicalShiftRightR: SendNumArgsReg R: ClassReg. - self MoveR: ClassReg R: SendNumArgsReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - self MoveR: SendNumArgsReg R: ReceiverResultReg. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -3636,17 +3768,15 @@ DruidTestRTLCompiler >> gen_primitiveBitXor [ DruidTestRTLCompiler >> gen_primitiveBranchingWithAssigments [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3736,17 +3866,15 @@ DruidTestRTLCompiler >> gen_primitiveCallingMethodReturningConstant [ DruidTestRTLCompiler >> gen_primitiveCallingMethodWithEarlyReturn [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 57 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3771,24 +3899,21 @@ DruidTestRTLCompiler >> gen_primitiveCascadedUint16AtPut [ DruidTestRTLCompiler >> gen_primitiveCaseOfOtherwiseValue [ "AutoGenerated by Druid" - | jump1 jump2 jump3 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 57 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self CmpCq: 1 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump3 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 77 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3797,10 +3922,10 @@ DruidTestRTLCompiler >> gen_primitiveCaseOfOtherwiseValue [ DruidTestRTLCompiler >> gen_primitiveClass [ "AutoGenerated by Druid" - | s81 s26 currentBlock s2 s50 s3 | + | s25 s71 s40 s2 currentBlock s3 | s2 := self methodNumArgs. s2 = 0 ifTrue: [ - | jump5 jump3 jump1 jump4 jump2 | + | jump1 jump2 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: ClassReg R: SendNumArgsReg. self AndCq: 7 R: SendNumArgsReg. @@ -3810,127 +3935,114 @@ DruidTestRTLCompiler >> gen_primitiveClass [ self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddR: SendNumArgsReg R: ClassReg. self MoveM64: 8 r: ClassReg R: ClassReg. - jump2 := self Jump: 0. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self MoveM64: 0 r: ClassReg R: SendNumArgsReg. - self AndCq: 16r3FFFFF R: SendNumArgsReg. - self CmpCq: 31 R: SendNumArgsReg. + self MoveM64: 0 r: ClassReg R: ClassReg. + self AndCq: 16r3FFFFF R: ClassReg. + self CmpCq: 31 R: ClassReg. jump1 := self JumpAbove: 0. - self CmpCq: 31 R: SendNumArgsReg. - jump3 := self JumpNonZero: 0. - self MoveR: ClassReg R: SendNumArgsReg. - jump4 := self Jump: 0. + self CmpCq: 31 R: ClassReg. + jump2 := self JumpNonZero: 0. + self genPrimReturn. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - self CmpCq: 8 R: SendNumArgsReg. - jump3 := self JumpNonZero: 0. - self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. - jump5 := self Jump: 0. + jump2 jmpTarget: currentBlock. + self CmpCq: 8 R: ClassReg. + jump2 := self JumpNonZero: 0. + self genMoveConstant: objectMemory nilObject R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. - self MoveR: SendNumArgsReg R: ClassReg. - self LogicalShiftRightCq: 10 R: ClassReg. - s26 := objectMemory hiddenRootsObject. - self LogicalShiftLeftCq: 3 R: ClassReg. - self AddCq: s26 R: ClassReg. - self MoveM64: 8 r: ClassReg R: ClassReg. + jump2 jmpTarget: currentBlock. + self MoveR: ClassReg R: SendNumArgsReg. + self LogicalShiftRightCq: 10 R: SendNumArgsReg. + s25 := objectMemory hiddenRootsObject. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: s25 R: SendNumArgsReg. + self MoveM64: 8 r: SendNumArgsReg R: SendNumArgsReg. self genMoveConstant: objectMemory nilObject R: Extra0Reg. - self CmpR: Extra0Reg R: ClassReg. - jump3 := self JumpNonZero: 0. + self CmpR: Extra0Reg R: SendNumArgsReg. + jump2 := self JumpNonZero: 0. self genMoveConstant: objectMemory nilObject R: Extra0Reg. - jump1 := self Jump: 0. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - self AndCq: 1023 R: SendNumArgsReg. - self LogicalShiftLeftCq: 3 R: SendNumArgsReg. - self AddR: SendNumArgsReg R: ClassReg. - self MoveM64: 8 r: ClassReg R: Extra0Reg. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. - self MoveR: Extra0Reg R: SendNumArgsReg. - currentBlock := self Label. - jump4 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. - self MoveR: SendNumArgsReg R: ClassReg. + self MoveR: Extra0Reg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self MoveR: ClassReg R: ReceiverResultReg. + self AndCq: 1023 R: ClassReg. + self LogicalShiftLeftCq: 3 R: ClassReg. + self AddR: ClassReg R: SendNumArgsReg. + self MoveM64: 8 r: SendNumArgsReg R: Extra0Reg. + self MoveR: Extra0Reg R: ReceiverResultReg. self genPrimReturn. ^ 0 ]. - s50 := self methodNumArgs. - s50 = 1 ifTrue: [ - | jump5 jump3 jump1 jump6 jump4 jump2 | + s40 := self methodNumArgs. + s40 = 1 ifTrue: [ + | jump2 jump1 | self MoveR: Arg0Reg R: Extra0Reg. - self MoveR: Extra0Reg R: ClassReg. - self AndCq: 7 R: ClassReg. - self CmpCq: 0 R: ClassReg. + self MoveR: Extra0Reg R: SendNumArgsReg. + self AndCq: 7 R: SendNumArgsReg. + self CmpCq: 0 R: SendNumArgsReg. jump2 := self JumpNonZero: 0. - self MoveM64: 0 r: Extra0Reg R: ClassReg. - self AndCq: 16r3FFFF7 R: ClassReg. - self CmpCq: 0 R: ClassReg. - jump5 := self JumpZero: 0. + self MoveM64: 0 r: Extra0Reg R: SendNumArgsReg. + self AndCq: 16r3FFFF7 R: SendNumArgsReg. + self CmpCq: 0 R: SendNumArgsReg. + jump1 := self JumpNonZero: 0. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self MoveR: Extra0Reg R: ClassReg. - self AndCq: 7 R: ClassReg. - self CmpCq: 0 R: ClassReg. - jump2 := self JumpZero: 0. + jump1 jmpTarget: currentBlock. + self MoveR: Extra0Reg R: SendNumArgsReg. + self AndCq: 7 R: SendNumArgsReg. + self CmpCq: 0 R: SendNumArgsReg. + jump1 := self JumpZero: 0. self MoveAw: objectMemory hiddenRootsObject + 8 R: Extra0Reg. - self LogicalShiftLeftCq: 3 R: ClassReg. - self AddR: ClassReg R: Extra0Reg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddR: SendNumArgsReg R: Extra0Reg. self MoveM64: 8 r: Extra0Reg R: Extra0Reg. - jump4 := self Jump: 0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - self MoveM64: 0 r: Extra0Reg R: ClassReg. - self AndCq: 16r3FFFFF R: ClassReg. - self CmpCq: 31 R: ClassReg. - jump2 := self JumpAbove: 0. - self CmpCq: 31 R: ClassReg. - jump1 := self JumpNonZero: 0. - self MoveR: Extra0Reg R: ClassReg. - jump3 := self Jump: 0. + self MoveR: Extra0Reg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self CmpCq: 8 R: ClassReg. - jump1 := self JumpNonZero: 0. - self genMoveConstant: objectMemory nilObject R: ClassReg. - jump6 := self Jump: 0. + self MoveM64: 0 r: Extra0Reg R: SendNumArgsReg. + self AndCq: 16r3FFFFF R: SendNumArgsReg. + self CmpCq: 31 R: SendNumArgsReg. + jump1 := self JumpAbove: 0. + self CmpCq: 31 R: SendNumArgsReg. + jump2 := self JumpNonZero: 0. + self MoveR: Extra0Reg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self CmpCq: 8 R: SendNumArgsReg. + jump2 := self JumpNonZero: 0. + self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - self MoveR: ClassReg R: Extra0Reg. + jump2 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: Extra0Reg. self LogicalShiftRightCq: 10 R: Extra0Reg. - s81 := objectMemory hiddenRootsObject. + s71 := objectMemory hiddenRootsObject. self LogicalShiftLeftCq: 3 R: Extra0Reg. - self AddCq: s81 R: Extra0Reg. + self AddCq: s71 R: Extra0Reg. self MoveM64: 8 r: Extra0Reg R: Extra0Reg. - self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. - self CmpR: SendNumArgsReg R: Extra0Reg. - jump1 := self JumpNonZero: 0. - self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. - jump2 := self Jump: 0. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. - self AndCq: 1023 R: ClassReg. - self LogicalShiftLeftCq: 3 R: ClassReg. - self AddR: ClassReg R: Extra0Reg. - self MoveM64: 8 r: Extra0Reg R: SendNumArgsReg. + self genMoveConstant: objectMemory nilObject R: ClassReg. + self CmpR: ClassReg R: Extra0Reg. + jump2 := self JumpNonZero: 0. + self genMoveConstant: objectMemory nilObject R: ClassReg. + jump1 := self Jump: 0. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self MoveR: SendNumArgsReg R: ClassReg. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. - self MoveR: ClassReg R: Extra0Reg. + self AndCq: 1023 R: SendNumArgsReg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddR: SendNumArgsReg R: Extra0Reg. + self MoveM64: 8 r: Extra0Reg R: ClassReg. currentBlock := self Label. - jump4 jmpTarget: currentBlock. - self MoveR: Extra0Reg R: ReceiverResultReg. + jump1 jmpTarget: currentBlock. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. - currentBlock := self Label. - jump5 jmpTarget: currentBlock. ^ 0 ]. ^ 0 ] @@ -3949,17 +4061,15 @@ DruidTestRTLCompiler >> gen_primitiveClassVariable [ DruidTestRTLCompiler >> gen_primitiveClassVariableWithBranch [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 35 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 36 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3968,17 +4078,15 @@ DruidTestRTLCompiler >> gen_primitiveClassVariableWithBranch [ DruidTestRTLCompiler >> gen_primitiveConditionWithAnyMask [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 1 R: ClassReg. jump1 := self JumpZero: 0. self MoveCq: 1 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3987,17 +4095,15 @@ DruidTestRTLCompiler >> gen_primitiveConditionWithAnyMask [ DruidTestRTLCompiler >> gen_primitiveConditionWithAnyMaskInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 1 R: ClassReg. jump1 := self JumpZero: 0. self MoveCq: 1 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4006,18 +4112,16 @@ DruidTestRTLCompiler >> gen_primitiveConditionWithAnyMaskInverted [ DruidTestRTLCompiler >> gen_primitiveConditionWithObjectReference [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock s3 | + | jump1 currentBlock s3 | self MoveR: ReceiverResultReg R: ClassReg. s3 := objectMemory trueObject. self CmpCq: s3 R: ClassReg. jump1 := self JumpAboveOrEqual: 0. self MoveCq: 1 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4036,7 +4140,7 @@ DruidTestRTLCompiler >> gen_primitiveConstantFloatAsInteger [ DruidTestRTLCompiler >> gen_primitiveDNA [ "AutoGenerated by Druid" - | jump3 jump1 s4 currentBlock s9 s7 s19 jump2 | + | jump3 jump1 s4 currentBlock s7 jump2 | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLessOrEqual: 0. @@ -4048,7 +4152,6 @@ DruidTestRTLCompiler >> gen_primitiveDNA [ s7 := 99. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. - s9 := 5. self CmpCq: 7 R: ClassReg. jump3 := self JumpLessOrEqual: 0. self MoveCq: s7 R: ClassReg. @@ -4056,21 +4159,14 @@ DruidTestRTLCompiler >> gen_primitiveDNA [ jump2 jmpTarget: currentBlock. self AddCq: 20 R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump3 jmpTarget: currentBlock. - self MoveCq: s9 R: ClassReg. - jump3 := self Jump: 0. + self MoveCq: 146 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s19 := 17. - self MoveCq: s19 R: ClassReg. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - self AddCq: 141 R: ClassReg. - self MoveR: ClassReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. + self MoveCq: 158 R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -4082,7 +4178,7 @@ DruidTestRTLCompiler >> gen_primitiveDeadBranchWithError [ | currentBlock | self MoveCq: 17 R: ReceiverResultReg. self genPrimReturn. - ^ 0 + ^ CompletePrimitive ] { #category : #generated } @@ -4248,17 +4344,15 @@ DruidTestRTLCompiler >> gen_primitiveDoubleDeferredInline [ DruidTestRTLCompiler >> gen_primitiveEqualsThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4309,17 +4403,15 @@ DruidTestRTLCompiler >> gen_primitiveEqualsThanFloats [ DruidTestRTLCompiler >> gen_primitiveEqualsThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4345,9 +4437,10 @@ DruidTestRTLCompiler >> gen_primitiveEqualsThanReferenceValue [ DruidTestRTLCompiler >> gen_primitiveEqualsThanValue [ "AutoGenerated by Druid" - | jumpNext currentBlock jumpTrue | + | jumpTrue jumpNext currentBlock s3 | self MoveR: ReceiverResultReg R: ClassReg. - self CmpCq: 0 R: ClassReg. + s3 := 0. + self CmpCq: s3 R: ClassReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: ClassReg. jumpNext := self Jump: 0. @@ -4419,7 +4512,7 @@ DruidTestRTLCompiler >> gen_primitiveFloat64AtPut [ DruidTestRTLCompiler >> gen_primitiveFloatAdd [ "AutoGenerated by Druid" - | jump1 jumpNext jump9 jump6 jump3 s119 s116 currentBlock jump8 jump5 jump2 jumpTrue jump7 jump4 | + | jump1 s123 jumpNext s98 s126 jump9 jump6 jump3 jump10 currentBlock s91 jump5 jump2 jump8 jumpTrue jump11 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. @@ -4518,82 +4611,89 @@ DruidTestRTLCompiler >> gen_primitiveFloatAdd [ self CmpCq: 896 R: SendNumArgsReg. jump8 := self JumpBelowOrEqual: 0. self CmpCq: 1151 R: SendNumArgsReg. - jumpTrue := self JumpBelowOrEqual: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump7 := self Jump: 0. + jump7 := self JumpBelowOrEqual: 0. + jump9 := self JumpAbove: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. self AndCq: 16rFFFFFFFFFFFFF R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. jump8 := self JumpNonZero: 0. - self CmpCq: 0 R: SendNumArgsReg. + s91 := 0. + self CmpCq: s91 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. - jump9 := self Jump: 0. + self CmpCq: 1 R: SendNumArgsReg. + jump10 := self JumpZero: 0. + jump11 := self JumpNonZero: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. - self CmpCq: 896 R: SendNumArgsReg. + s98 := 896. + self CmpCq: s98 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. + self CmpCq: 1 R: SendNumArgsReg. + jump8 := self JumpNonZero: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. currentBlock := self Label. jump7 jmpTarget: currentBlock. - self CmpCq: 1 R: SendNumArgsReg. - jump7 := self JumpNonZero: 0. self MoveRd: DPFPReg0 R: SendNumArgsReg. self RotateLeftCq: 1 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump9 := self JumpBelowOrEqual: 0. + jump7 := self JumpBelowOrEqual: 0. self SubCq: 16r7000000000000000 R: SendNumArgsReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 4 R: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump11 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. - s116 := objectMemory getScavengeThreshold. - self CmpCq: s116 R: Extra0Reg. - jump7 := self JumpAbove: 0. - s119 := 72057594205700130. - self MoveCq: s119 R: Extra0Reg. + s123 := objectMemory getScavengeThreshold. + self CmpCq: s123 R: Extra0Reg. + jump9 := self JumpAbove: 0. + s126 := 72057594205700130. + self MoveCq: s126 R: Extra0Reg. self MoveR: Extra0Reg M64: 0 r: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. self MoveR: Extra0Reg Aw: objectMemory freeStartAddress. self MoveRd: DPFPReg0 M64: 8 r: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. + currentBlock := self Label. jump5 jmpTarget: currentBlock. - jump7 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump6 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -4787,7 +4887,7 @@ DruidTestRTLCompiler >> gen_primitiveFloatDivide [ DruidTestRTLCompiler >> gen_primitiveFloatEqual [ "AutoGenerated by Druid" - | jump1 jump6 jump3 currentBlock s82 jump8 jump5 s79 jump2 jump7 jump4 | + | jump1 s86 s83 jump6 jump3 currentBlock jump8 jump5 jump2 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. @@ -4880,23 +4980,26 @@ DruidTestRTLCompiler >> gen_primitiveFloatEqual [ jump8 jmpTarget: currentBlock. self CmpRd: DPFPReg1 Rd: DPFPReg0. jump8 := self JumpFPNotEqual: 0. - s79 := objectMemory trueObject. - self MoveCq: s79 R: ReceiverResultReg. - jump7 := self Jump: 0. + s83 := objectMemory trueObject. + self MoveCq: s83 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump8 jmpTarget: currentBlock. - s82 := objectMemory falseObject. - self MoveCq: s82 R: ReceiverResultReg. - currentBlock := self Label. - jump7 jmpTarget: currentBlock. + s86 := objectMemory falseObject. + self MoveCq: s86 R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. jump6 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -4904,7 +5007,7 @@ DruidTestRTLCompiler >> gen_primitiveFloatEqual [ DruidTestRTLCompiler >> gen_primitiveFloatMultiply [ "AutoGenerated by Druid" - | jump1 jumpNext jump9 jump6 jump3 s119 s116 currentBlock jump8 jump5 jump2 jumpTrue jump7 jump4 | + | jump1 s123 jumpNext s98 s126 jump9 jump6 jump3 jump10 currentBlock s91 jump5 jump2 jump8 jumpTrue jump11 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. @@ -5003,82 +5106,89 @@ DruidTestRTLCompiler >> gen_primitiveFloatMultiply [ self CmpCq: 896 R: SendNumArgsReg. jump8 := self JumpBelowOrEqual: 0. self CmpCq: 1151 R: SendNumArgsReg. - jumpTrue := self JumpBelowOrEqual: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump7 := self Jump: 0. + jump7 := self JumpBelowOrEqual: 0. + jump9 := self JumpAbove: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. self AndCq: 16rFFFFFFFFFFFFF R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. jump8 := self JumpNonZero: 0. - self CmpCq: 0 R: SendNumArgsReg. + s91 := 0. + self CmpCq: s91 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. - jump9 := self Jump: 0. + self CmpCq: 1 R: SendNumArgsReg. + jump10 := self JumpZero: 0. + jump11 := self JumpNonZero: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. - self CmpCq: 896 R: SendNumArgsReg. + s98 := 896. + self CmpCq: s98 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. + self CmpCq: 1 R: SendNumArgsReg. + jump8 := self JumpNonZero: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. currentBlock := self Label. jump7 jmpTarget: currentBlock. - self CmpCq: 1 R: SendNumArgsReg. - jump7 := self JumpNonZero: 0. self MoveRd: DPFPReg0 R: SendNumArgsReg. self RotateLeftCq: 1 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump9 := self JumpBelowOrEqual: 0. + jump7 := self JumpBelowOrEqual: 0. self SubCq: 16r7000000000000000 R: SendNumArgsReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 4 R: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. - self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. + jump11 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. + self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. - s116 := objectMemory getScavengeThreshold. - self CmpCq: s116 R: Extra0Reg. - jump7 := self JumpAbove: 0. - s119 := 72057594205700130. - self MoveCq: s119 R: Extra0Reg. + s123 := objectMemory getScavengeThreshold. + self CmpCq: s123 R: Extra0Reg. + jump9 := self JumpAbove: 0. + s126 := 72057594205700130. + self MoveCq: s126 R: Extra0Reg. self MoveR: Extra0Reg M64: 0 r: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. self MoveR: Extra0Reg Aw: objectMemory freeStartAddress. self MoveRd: DPFPReg0 M64: 8 r: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. + currentBlock := self Label. jump5 jmpTarget: currentBlock. - jump7 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump6 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -5086,7 +5196,7 @@ DruidTestRTLCompiler >> gen_primitiveFloatMultiply [ DruidTestRTLCompiler >> gen_primitiveFloatNotEqual [ "AutoGenerated by Druid" - | jump1 jump6 jump3 currentBlock s82 jump8 jump5 s79 jump2 jump7 jump4 | + | jump1 s86 s83 jump6 jump3 currentBlock jump8 jump5 jump2 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. @@ -5179,23 +5289,26 @@ DruidTestRTLCompiler >> gen_primitiveFloatNotEqual [ jump8 jmpTarget: currentBlock. self CmpRd: DPFPReg1 Rd: DPFPReg0. jump8 := self JumpFPNotEqual: 0. - s79 := objectMemory falseObject. - self MoveCq: s79 R: ReceiverResultReg. - jump7 := self Jump: 0. + s83 := objectMemory falseObject. + self MoveCq: s83 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump8 jmpTarget: currentBlock. - s82 := objectMemory trueObject. - self MoveCq: s82 R: ReceiverResultReg. - currentBlock := self Label. - jump7 jmpTarget: currentBlock. + s86 := objectMemory trueObject. + self MoveCq: s86 R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. jump6 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -5203,7 +5316,7 @@ DruidTestRTLCompiler >> gen_primitiveFloatNotEqual [ DruidTestRTLCompiler >> gen_primitiveFloatSubtract [ "AutoGenerated by Druid" - | jump1 jumpNext jump9 jump6 jump3 s119 s116 currentBlock jump8 jump5 jump2 jumpTrue jump7 jump4 | + | jump1 s123 jumpNext s98 s126 jump9 jump6 jump3 jump10 currentBlock s91 jump5 jump2 jump8 jumpTrue jump11 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. @@ -5302,82 +5415,89 @@ DruidTestRTLCompiler >> gen_primitiveFloatSubtract [ self CmpCq: 896 R: SendNumArgsReg. jump8 := self JumpBelowOrEqual: 0. self CmpCq: 1151 R: SendNumArgsReg. - jumpTrue := self JumpBelowOrEqual: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump7 := self Jump: 0. + jump7 := self JumpBelowOrEqual: 0. + jump9 := self JumpAbove: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. self AndCq: 16rFFFFFFFFFFFFF R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. jump8 := self JumpNonZero: 0. - self CmpCq: 0 R: SendNumArgsReg. + s91 := 0. + self CmpCq: s91 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. - jump9 := self Jump: 0. + self CmpCq: 1 R: SendNumArgsReg. + jump10 := self JumpZero: 0. + jump11 := self JumpNonZero: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. - self CmpCq: 896 R: SendNumArgsReg. + s98 := 896. + self CmpCq: s98 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. + self CmpCq: 1 R: SendNumArgsReg. + jump8 := self JumpNonZero: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. currentBlock := self Label. jump7 jmpTarget: currentBlock. - self CmpCq: 1 R: SendNumArgsReg. - jump7 := self JumpNonZero: 0. self MoveRd: DPFPReg0 R: SendNumArgsReg. self RotateLeftCq: 1 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump9 := self JumpBelowOrEqual: 0. + jump7 := self JumpBelowOrEqual: 0. self SubCq: 16r7000000000000000 R: SendNumArgsReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 4 R: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump11 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. - s116 := objectMemory getScavengeThreshold. - self CmpCq: s116 R: Extra0Reg. - jump7 := self JumpAbove: 0. - s119 := 72057594205700130. - self MoveCq: s119 R: Extra0Reg. + s123 := objectMemory getScavengeThreshold. + self CmpCq: s123 R: Extra0Reg. + jump9 := self JumpAbove: 0. + s126 := 72057594205700130. + self MoveCq: s126 R: Extra0Reg. self MoveR: Extra0Reg M64: 0 r: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. self MoveR: Extra0Reg Aw: objectMemory freeStartAddress. self MoveRd: DPFPReg0 M64: 8 r: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. + currentBlock := self Label. jump5 jmpTarget: currentBlock. - jump7 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump6 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -5385,7 +5505,7 @@ DruidTestRTLCompiler >> gen_primitiveFloatSubtract [ DruidTestRTLCompiler >> gen_primitiveFullClosureValue [ "AutoGenerated by Druid" - | s2 currentBlock s22 s43 s3 | + | s51 s26 currentBlock s2 s3 | s2 := self methodNumArgs. s2 = 0 ifTrue: [ | jump1 jump2 jump3 jump4 | @@ -5413,46 +5533,52 @@ DruidTestRTLCompiler >> gen_primitiveFullClosureValue [ self JumpR: ClassReg. self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. ^ 0 ]. - s22 := self methodNumArgs. - s22 = 1 ifTrue: [ - | jump4 jump3 jump2 jump1 | + s26 := self methodNumArgs. + s26 = 1 ifTrue: [ + | jump1 jump2 jump3 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self MoveM64: 24 r: ClassReg R: SendNumArgsReg. self ArithmeticShiftRightCq: 3 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump4 := self JumpNonZero: 0. + jump1 := self JumpNonZero: 0. self MoveM64: 16 r: ClassReg R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ClassReg. self AndCq: 7 R: ClassReg. self CmpCq: 0 R: ClassReg. - jump3 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self MoveM64: 0 r: SendNumArgsReg R: ClassReg. self LogicalShiftRightCq: 24 R: ClassReg. self AndCq: 31 R: ClassReg. self CmpCq: 24 R: ClassReg. - jump2 := self JumpBelow: 0. + jump3 := self JumpBelow: 0. self MoveM64: 8 r: SendNumArgsReg R: ClassReg. self AndCq: 1 R: ClassReg. self CmpCq: 0 R: ClassReg. - jump1 := self JumpNonZero: 0. + jump4 := self JumpNonZero: 0. self MoveM64: 8 r: SendNumArgsReg R: ClassReg. self AddCq: self fullBlockEntryOffset R: ClassReg. self JumpR: ClassReg. self genPrimReturn. currentBlock := self Label. jump4 jmpTarget: currentBlock. + currentBlock := self Label. jump3 jmpTarget: currentBlock. + currentBlock := self Label. jump2 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. ^ 0 ]. - s43 := self methodNumArgs. - s43 = 2 ifTrue: [ + s51 := self methodNumArgs. + s51 = 2 ifTrue: [ | jump1 jump2 jump3 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. @@ -5480,10 +5606,13 @@ DruidTestRTLCompiler >> gen_primitiveFullClosureValue [ self JumpR: ClassReg. self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. ^ 0 ]. ^ 0 ] @@ -5528,17 +5657,15 @@ DruidTestRTLCompiler >> gen_primitiveGreaterOrEqualThanValue [ DruidTestRTLCompiler >> gen_primitiveGreaterOrEqualsThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLess: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5568,17 +5695,15 @@ DruidTestRTLCompiler >> gen_primitiveGreaterOrEqualsThanFloats [ DruidTestRTLCompiler >> gen_primitiveGreaterOrEqualsThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreater: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5587,17 +5712,15 @@ DruidTestRTLCompiler >> gen_primitiveGreaterOrEqualsThanInverted [ DruidTestRTLCompiler >> gen_primitiveGreaterThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5624,18 +5747,16 @@ DruidTestRTLCompiler >> gen_primitiveGreaterThanArgument [ DruidTestRTLCompiler >> gen_primitiveGreaterThanBitAnd [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self AndCq: 16rFFFFFFFFFFFFFFFF R: ClassReg. self CmpCq: 1 R: ClassReg. jump1 := self JumpBelowOrEqual: 0. self MoveCq: 1 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5665,17 +5786,15 @@ DruidTestRTLCompiler >> gen_primitiveGreaterThanFloats [ DruidTestRTLCompiler >> gen_primitiveGreaterThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreaterOrEqual: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5703,7 +5822,7 @@ DruidTestRTLCompiler >> gen_primitiveGreaterThanReferenceValue [ DruidTestRTLCompiler >> gen_primitiveIdentityHash [ "AutoGenerated by Druid" - | jump1 jump2 jump3 currentBlock | + | jump1 jump2 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 7 R: ClassReg. jump1 := self JumpNonZero: 0. @@ -5719,14 +5838,12 @@ DruidTestRTLCompiler >> gen_primitiveIdentityHash [ self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump3 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump2 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. @@ -5737,17 +5854,15 @@ DruidTestRTLCompiler >> gen_primitiveIdentityHash [ DruidTestRTLCompiler >> gen_primitiveIfFalseIfTrueReturningValue [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 57 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5756,17 +5871,15 @@ DruidTestRTLCompiler >> gen_primitiveIfFalseIfTrueReturningValue [ DruidTestRTLCompiler >> gen_primitiveIfTrueIfFalseAssigningValue [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 57 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5775,17 +5888,15 @@ DruidTestRTLCompiler >> gen_primitiveIfTrueIfFalseAssigningValue [ DruidTestRTLCompiler >> gen_primitiveIfTrueIfFalseReturningValue [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 57 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5794,17 +5905,15 @@ DruidTestRTLCompiler >> gen_primitiveIfTrueIfFalseReturningValue [ DruidTestRTLCompiler >> gen_primitiveIfTrueStatement [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 10 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5813,10 +5922,10 @@ DruidTestRTLCompiler >> gen_primitiveIfTrueStatement [ DruidTestRTLCompiler >> gen_primitiveImmediateAsInteger [ "AutoGenerated by Druid" - | s21 s2 s24 currentBlock s3 | + | s27 s60 s2 s24 currentBlock s63 s38 s3 | s2 := self methodNumArgs. s2 = 0 ifTrue: [ - | jump5 jump3 jump1 jump4 jump2 | + | jump1 jump2 jump3 | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 1 R: ClassReg. jump1 := self JumpZero: 0. @@ -5824,13 +5933,16 @@ DruidTestRTLCompiler >> gen_primitiveImmediateAsInteger [ self LogicalShiftLeftCq: 3 R: ClassReg. self AddCq: 1 R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self TstCq: 2 R: ClassReg. jump1 := self JumpZero: 0. self LogicalShiftRightCq: 3 R: ClassReg. - jump3 := self Jump: 0. + self LogicalShiftLeftCq: 3 R: ClassReg. + self AddCq: 1 R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self TstCq: 4 R: ClassReg. @@ -5838,25 +5950,67 @@ DruidTestRTLCompiler >> gen_primitiveImmediateAsInteger [ self MoveR: ClassReg R: SendNumArgsReg. self LogicalShiftRightCq: 4 R: SendNumArgsReg. self TstCq: 8 R: ClassReg. - jump4 := self JumpZero: 0. - s21 := -1152921504606846976. - self MoveCq: s21 R: ClassReg. - jump5 := self Jump: 0. - currentBlock := self Label. - jump4 jmpTarget: currentBlock. - s24 := 0. + jump2 := self JumpZero: 0. + s24 := -1152921504606846976. self MoveCq: s24 R: ClassReg. + jump3 := self Jump: 0. currentBlock := self Label. - jump5 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. + s27 := 0. + self MoveCq: s27 R: ClassReg. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. self AddR: ClassReg R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ClassReg. + self LogicalShiftLeftCq: 3 R: ClassReg. + self AddCq: 1 R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + ^ 0 ]. + s38 := self methodNumArgs. + s38 = 1 ifTrue: [ + | jump1 jump3 jump2 | + self MoveR: Arg0Reg R: ClassReg. + self TstCq: 1 R: ClassReg. + jump1 := self JumpZero: 0. + self ArithmeticShiftRightCq: 3 R: ClassReg. self LogicalShiftLeftCq: 3 R: ClassReg. self AddCq: 1 R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + self TstCq: 2 R: ClassReg. + jump1 := self JumpZero: 0. + self LogicalShiftRightCq: 3 R: ClassReg. + self LogicalShiftLeftCq: 3 R: ClassReg. + self AddCq: 1 R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + self TstCq: 4 R: ClassReg. + jump1 := self JumpZero: 0. + self MoveR: ClassReg R: SendNumArgsReg. + self LogicalShiftRightCq: 4 R: SendNumArgsReg. + self TstCq: 8 R: ClassReg. + jump3 := self JumpZero: 0. + s60 := -1152921504606846976. + self MoveCq: s60 R: ClassReg. + jump2 := self Jump: 0. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + s63 := 0. + self MoveCq: s63 R: ClassReg. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self AddR: ClassReg R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ClassReg. + self LogicalShiftLeftCq: 3 R: ClassReg. + self AddCq: 1 R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. @@ -5868,7 +6022,7 @@ DruidTestRTLCompiler >> gen_primitiveImmediateAsInteger [ DruidTestRTLCompiler >> gen_primitiveImplicitArgumentBitShiftLeft [ "AutoGenerated by Druid" - | jump1 s4 s10 currentBlock jump2 | + | jump1 s10 currentBlock s4 | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. @@ -5876,7 +6030,7 @@ DruidTestRTLCompiler >> gen_primitiveImplicitArgumentBitShiftLeft [ self MoveCq: s4 R: SendNumArgsReg. self LogicalShiftLeftR: ClassReg R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: ClassReg R: SendNumArgsReg. @@ -5885,8 +6039,6 @@ DruidTestRTLCompiler >> gen_primitiveImplicitArgumentBitShiftLeft [ self MoveCq: s10 R: ClassReg. self LogicalShiftRightR: SendNumArgsReg R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5973,9 +6125,9 @@ DruidTestRTLCompiler >> gen_primitiveIntegerDivide [ self DivR: SendNumArgsReg R: ClassReg - Quo: SendNumArgsReg - Rem: ClassReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. + Quo: ClassReg + Rem: SendNumArgsReg. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -6015,19 +6167,17 @@ DruidTestRTLCompiler >> gen_primitiveIntegerRawBitsAsFloat [ DruidTestRTLCompiler >> gen_primitiveIsIntegerObject [ "AutoGenerated by Druid" - | jump1 s4 currentBlock s7 jump2 | + | s7 jump1 currentBlock s4 | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 1 R: ClassReg. jump1 := self JumpZero: 0. s4 := objectMemory trueObject. self MoveCq: s4 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. s7 := objectMemory falseObject. self MoveCq: s7 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6084,17 +6234,15 @@ DruidTestRTLCompiler >> gen_primitiveLessOrEqualThanValue [ DruidTestRTLCompiler >> gen_primitiveLessOrEqualsThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreater: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6124,17 +6272,15 @@ DruidTestRTLCompiler >> gen_primitiveLessOrEqualsThanFloats [ DruidTestRTLCompiler >> gen_primitiveLessOrEqualsThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLess: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6143,17 +6289,15 @@ DruidTestRTLCompiler >> gen_primitiveLessOrEqualsThanInverted [ DruidTestRTLCompiler >> gen_primitiveLessThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreaterOrEqual: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6201,17 +6345,15 @@ DruidTestRTLCompiler >> gen_primitiveLessThanFloats [ DruidTestRTLCompiler >> gen_primitiveLessThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6337,9 +6479,9 @@ DruidTestRTLCompiler >> gen_primitiveMod [ self DivR: SendNumArgsReg R: ClassReg - Quo: ClassReg - Rem: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. + Quo: SendNumArgsReg + Rem: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -6416,7 +6558,7 @@ DruidTestRTLCompiler >> gen_primitiveMultiplyInverted [ DruidTestRTLCompiler >> gen_primitiveMultiplyWithOverflow [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self ArithmeticShiftRightCq: 3 R: ClassReg. @@ -6424,13 +6566,11 @@ DruidTestRTLCompiler >> gen_primitiveMultiplyWithOverflow [ self MulR: ClassReg R: SendNumArgsReg. jump1 := self JumpMultiplyNoOverflow: 0. self MoveCq: 99 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6452,7 +6592,7 @@ DruidTestRTLCompiler >> gen_primitiveNegated [ DruidTestRTLCompiler >> gen_primitiveNew [ "AutoGenerated by Druid" - | jump1 s28 jump6 b361 jump3 currentBlock jump8 jump5 jump2 s17 jump7 jump4 | + | s34 jump1 jump6 jump3 b349 currentBlock jump8 jump5 jump2 s23 jump7 jump4 | self SubCq: 8 R: SPReg. self MoveR: ReceiverResultReg R: ClassReg. self MoveM64: 24 r: ClassReg R: Extra3Reg. @@ -6476,21 +6616,27 @@ DruidTestRTLCompiler >> gen_primitiveNew [ self CmpCq: 0 R: ClassReg. jump1 := self JumpZero: 0. self CmpCq: 0 R: ClassReg. - jump3 := self JumpBelow: 0. + jump3 := self JumpAboveOrEqual: 0. + jump4 := self Jump: 0. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. self MoveMw: 0 r: SPReg R: Extra3Reg. self AndCq: 16rFFFF R: Extra3Reg. self MoveR: Extra3Reg Mw: 0 r: SPReg. self MoveMw: 0 r: SPReg R: Extra3Reg. self CmpCq: 255 R: Extra3Reg. - jump4 := self JumpAboveOrEqual: 0. + jump3 := self JumpBelow: 0. + jump5 := self Jump: 0. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. self MoveMw: 0 r: SPReg R: Extra3Reg. self CmpCq: 1 R: Extra3Reg. - jump5 := self JumpAboveOrEqual: 0. - s17 := 8. - self MoveCq: s17 R: Extra1Reg. + jump3 := self JumpAboveOrEqual: 0. + s23 := 8. + self MoveCq: s23 R: Extra1Reg. jump6 := self Jump: 0. currentBlock := self Label. - jump5 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. self MoveMw: 0 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: Extra1Reg. self LogicalShiftLeftCq: 3 R: Extra1Reg. @@ -6499,14 +6645,18 @@ DruidTestRTLCompiler >> gen_primitiveNew [ self AddCq: 8 R: Extra1Reg. self MoveAw: objectMemory freeStartAddress R: Extra2Reg. self AddR: Extra1Reg R: Extra2Reg. - s28 := objectMemory getScavengeThreshold. - self CmpCq: s28 R: Extra2Reg. + s34 := objectMemory getScavengeThreshold. + self CmpCq: s34 R: Extra2Reg. jump6 := self JumpBelowOrEqual: 0. - self CmpCq: s28 R: Extra2Reg. - jump5 := self JumpAbove: 0. + self CmpCq: s34 R: Extra2Reg. + jump3 := self JumpAbove: 0. + self MoveAw: objectMemory freeStartAddress R: Extra2Reg. + jump7 := self Jump: 0. currentBlock := self Label. jump6 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: Extra2Reg. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self MoveMw: 0 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: SendNumArgsReg. self LogicalShiftLeftCq: 56 R: SendNumArgsReg. @@ -6519,7 +6669,7 @@ DruidTestRTLCompiler >> gen_primitiveNew [ self AddR: Extra1Reg R: SendNumArgsReg. self MoveR: SendNumArgsReg Aw: objectMemory freeStartAddress. self CmpCq: 0 R: Extra2Reg. - jump6 := self JumpZero: 0. + jump7 := self JumpZero: 0. self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. self MoveR: Extra2Reg R: Extra1Reg. self AddCq: 8 R: Extra1Reg. @@ -6531,26 +6681,30 @@ DruidTestRTLCompiler >> gen_primitiveNew [ self AddR: Extra3Reg R: ClassReg. self AddCq: 8 R: ClassReg. self SubCq: 1 R: ClassReg. - b361 := self Label. + b349 := self Label. self CmpR: Extra1Reg R: ClassReg. - jump7 := self JumpLess: 0. + jump6 := self JumpLess: 0. self MoveR: SendNumArgsReg M64: 0 r: Extra1Reg. self MoveR: Extra1Reg R: Extra0Reg. self AddCq: 8 R: Extra0Reg. self MoveR: Extra0Reg R: Extra1Reg. - jump8 := self Jump: b361. + jump8 := self Jump: b349. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. self MoveR: Extra2Reg R: ReceiverResultReg. self AddCq: 8 R: SPReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. jump5 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. self AddCq: 8 R: SPReg. ^ 0 ] @@ -6559,7 +6713,7 @@ DruidTestRTLCompiler >> gen_primitiveNew [ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ "AutoGenerated by Druid" - | s170 jump5 jump10 s94 s55 jump3 b702 jump8 jump1 s36 currentBlock s101 s58 jump13 jump6 s73 s82 s47 jump11 jump4 s78 s159 jump9 jump2 s85 s98 jump7 jump12 | + | jump5 s169 s81 s55 jump10 s184 jump3 s86 b690 s173 jump1 jump8 currentBlock s49 s195 s90 s7 s141 s106 s233 jump6 s40 jump11 jump4 jump13 s93 s63 jump2 s109 s102 jump9 jump14 jump7 jump12 s66 | self SubCq: 32 R: SPReg. self MoveR: ReceiverResultReg R: Extra3Reg. self MoveR: Extra3Reg Mw: 0 r: SPReg. @@ -6568,7 +6722,12 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ jump1 := self JumpZero: 0. self ArithmeticShiftRightCq: 3 R: SendNumArgsReg. self CmpCq: 0 R: SendNumArgsReg. - jump2 := self JumpLess: 0. + jump2 := self JumpGreaterOrEqual: 0. + s7 := 1. + self MoveCq: s7 R: ClassReg. + jump3 := self Jump: 0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. self MoveMw: 0 r: SPReg R: Extra3Reg. self MoveM64: 24 r: Extra3Reg R: Extra0Reg. self ArithmeticShiftRightCq: 3 R: Extra0Reg. @@ -6583,64 +6742,70 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self AndCq: 16r3FFFFF R: Extra3Reg. self MoveR: Extra3Reg Mw: 8 r: SPReg. self CmpCq: 2 R: Extra1Reg. - jump3 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self genMoveConstant: objectMemory nilObject R: Extra0Reg. self MoveR: Extra0Reg R: ClassReg. jump4 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. self CmpCq: 3 R: Extra1Reg. - jump3 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self AndCq: 16rFFFF R: Extra0Reg. self AddR: SendNumArgsReg R: Extra0Reg. self genMoveConstant: objectMemory nilObject R: ClassReg. self MoveR: Extra0Reg R: SendNumArgsReg. jump5 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. self CmpCq: 4 R: Extra1Reg. - jump3 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self AndCq: 16rFFFF R: Extra0Reg. self AddR: SendNumArgsReg R: Extra0Reg. self genMoveConstant: objectMemory nilObject R: ClassReg. self MoveR: Extra0Reg R: SendNumArgsReg. jump6 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s36 := 0. + jump2 jmpTarget: currentBlock. + s40 := 0. self CmpCq: 9 R: Extra1Reg. - jump3 := self JumpNonZero: 0. - self MoveCq: s36 R: ClassReg. + jump2 := self JumpNonZero: 0. + self MoveCq: s40 R: ClassReg. jump7 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. self CmpCq: 10 R: Extra1Reg. - jump3 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self MoveMw: 8 r: SPReg R: Extra3Reg. self CmpCq: 34 R: Extra3Reg. jump8 := self JumpNonZero: 0. self CmpCq: 2 R: SendNumArgsReg. - jump9 := self JumpNonZero: 0. + jump9 := self JumpZero: 0. + s49 := 1. + self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg R: SendNumArgsReg. + self MoveCq: s49 R: ClassReg. + jump10 := self Jump: 0. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: ClassReg. self AddCq: 1 R: ClassReg. - s47 := 2. - self MoveCq: s47 R: Extra0Reg. + s55 := 2. + self MoveCq: s55 R: Extra0Reg. self DivR: Extra0Reg R: ClassReg - Quo: Extra0Reg - Rem: ClassReg. + Quo: ClassReg + Rem: Extra0Reg. self AndCq: 1 R: SendNumArgsReg. self AddR: SendNumArgsReg R: Extra1Reg. - self MoveR: Extra0Reg R: ClassReg. - jump10 := self Jump: 0. + jump9 := self Jump: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. - s55 := 0. + s63 := 0. self MoveR: SendNumArgsReg R: ClassReg. self AddCq: 1 R: ClassReg. - s58 := 2. - self MoveCq: s58 R: Extra0Reg. + s66 := 2. + self MoveCq: s66 R: Extra0Reg. self DivR: Extra0Reg R: ClassReg @@ -6651,73 +6816,66 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self MoveMw: 8 r: SPReg R: Extra3Reg. self CmpCq: 0 R: Extra3Reg. jump8 := self JumpNonZero: 0. - self MoveCq: s55 R: ClassReg. + self MoveCq: s63 R: ClassReg. jump11 := self Jump: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. self MoveR: Extra0Reg R: ClassReg. currentBlock := self Label. - jump10 jmpTarget: currentBlock. - s73 := 0. - self MoveCq: s73 R: Extra0Reg. - jump10 := self Jump: 0. + jump9 jmpTarget: currentBlock. + s81 := 0. + self MoveCq: s81 R: Extra0Reg. + jump9 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s78 := 0. + jump2 jmpTarget: currentBlock. + s86 := 0. self CmpCq: 12 R: Extra1Reg. - jump3 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self MoveR: SendNumArgsReg R: ClassReg. self AddCq: 3 R: ClassReg. - s82 := 4. - self MoveCq: s82 R: Extra0Reg. + s90 := 4. + self MoveCq: s90 R: Extra0Reg. self DivR: Extra0Reg R: ClassReg Quo: Extra2Reg Rem: Extra0Reg. - s85 := 4. - self MoveCq: s85 R: Extra0Reg. + s93 := 4. + self MoveCq: s93 R: Extra0Reg. self SubR: SendNumArgsReg R: Extra0Reg. self AndCq: 3 R: Extra0Reg. self AddR: Extra0Reg R: Extra1Reg. - self MoveCq: s78 R: ClassReg. + self MoveCq: s86 R: ClassReg. self MoveR: Extra2Reg R: SendNumArgsReg. jump8 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s94 := 0. + jump2 jmpTarget: currentBlock. + s102 := 0. self CmpCq: 16 R: Extra1Reg. - jump3 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self MoveR: SendNumArgsReg R: Extra0Reg. self AddCq: 7 R: Extra0Reg. - s98 := 8. - self MoveCq: s98 R: Extra2Reg. + s106 := 8. + self MoveCq: s106 R: Extra2Reg. self DivR: Extra2Reg R: Extra0Reg - Quo: Extra0Reg - Rem: Extra2Reg. - s101 := 8. - self MoveCq: s101 R: Extra2Reg. - self SubR: SendNumArgsReg R: Extra2Reg. - self AndCq: 7 R: Extra2Reg. - self AddR: Extra2Reg R: Extra1Reg. - self MoveCq: s94 R: ClassReg. - self MoveR: Extra0Reg R: SendNumArgsReg. + Quo: Extra2Reg + Rem: Extra0Reg. + s109 := 8. + self MoveCq: s109 R: Extra0Reg. + self SubR: SendNumArgsReg R: Extra0Reg. + self AndCq: 7 R: Extra0Reg. + self AddR: Extra0Reg R: Extra1Reg. + self MoveCq: s102 R: ClassReg. + self MoveR: Extra2Reg R: SendNumArgsReg. jump12 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. self CmpCq: 0 R: SendNumArgsReg. - jump3 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self CmpCq: 5 R: Extra1Reg. - jump13 := self JumpBelowOrEqual: 0. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - self MoveMw: 0 r: SPReg R: Extra3Reg. - self MoveR: Extra3Reg R: Extra2Reg. - jump3 := self Jump: 0. - currentBlock := self Label. - jump13 jmpTarget: currentBlock. + jump13 := self JumpAbove: 0. self AndCq: 16rFFFF R: Extra0Reg. self genMoveConstant: objectMemory nilObject R: Extra2Reg. self MoveR: Extra2Reg R: ClassReg. @@ -6742,18 +6900,25 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self CmpCq: 0 R: Extra2Reg. jump11 := self JumpZero: 0. self CmpCq: 0 R: Extra2Reg. - jump8 := self JumpBelow: 0. + jump8 := self JumpAboveOrEqual: 0. + s141 := 1. + self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg R: SendNumArgsReg. + self MoveCq: s141 R: ClassReg. + jump7 := self Jump: 0. + currentBlock := self Label. + jump8 jmpTarget: currentBlock. self MoveR: ClassReg R: Extra3Reg. self MoveR: Extra3Reg Mw: 16 r: SPReg. self MoveR: Extra0Reg R: Extra3Reg. self MoveR: Extra3Reg Mw: 24 r: SPReg. - jump7 := self Jump: 0. + jump8 := self Jump: 0. currentBlock := self Label. jump12 jmpTarget: currentBlock. self MoveR: ClassReg R: Extra0Reg. self MoveR: SendNumArgsReg R: ClassReg. currentBlock := self Label. - jump10 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. self MoveR: Extra0Reg R: Extra3Reg. self MoveR: Extra3Reg Mw: 16 r: SPReg. self MoveR: ClassReg R: Extra3Reg. @@ -6761,36 +6926,61 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self MoveMw: 8 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: Extra2Reg. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. self MoveMw: 24 r: SPReg R: Extra3Reg. self CmpCq: 16rFFFF R: Extra3Reg. - jump7 := self JumpAbove: 0. + jump8 := self JumpBelowOrEqual: 0. + self MoveMw: 24 r: SPReg R: Extra3Reg. + self CmpCq: 16r10000000000 R: Extra3Reg. + jump9 := self JumpBelowOrEqual: 0. + s169 := 1. + self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg R: SendNumArgsReg. + self MoveCq: s169 R: ClassReg. + jump12 := self Jump: 0. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. + s173 := 1. + self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg R: SendNumArgsReg. + self MoveCq: s173 R: ClassReg. + jump9 := self Jump: 0. + currentBlock := self Label. + jump8 jmpTarget: currentBlock. self MoveMw: 24 r: SPReg R: Extra3Reg. self CmpCq: 255 R: Extra3Reg. - jump10 := self JumpAboveOrEqual: 0. + jump8 := self JumpBelow: 0. + self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg R: Extra2Reg. + self MoveR: Extra2Reg R: ReceiverResultReg. + jump6 := self Jump: 0. + currentBlock := self Label. + jump8 jmpTarget: currentBlock. self MoveMw: 24 r: SPReg R: Extra3Reg. self CmpCq: 1 R: Extra3Reg. - jump12 := self JumpAboveOrEqual: 0. - s159 := 8. - self MoveCq: s159 R: ClassReg. - jump6 := self Jump: 0. + jump8 := self JumpAboveOrEqual: 0. + s184 := 8. + self MoveCq: s184 R: ClassReg. + jump5 := self Jump: 0. currentBlock := self Label. - jump12 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. self MoveMw: 24 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: ClassReg. self LogicalShiftLeftCq: 3 R: ClassReg. currentBlock := self Label. - jump6 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. self AddCq: 8 R: ClassReg. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self AddR: ClassReg R: SendNumArgsReg. - s170 := objectMemory getScavengeThreshold. - self CmpCq: s170 R: SendNumArgsReg. - jump6 := self JumpBelowOrEqual: 0. - self CmpCq: s170 R: SendNumArgsReg. - jump12 := self JumpAbove: 0. + s195 := objectMemory getScavengeThreshold. + self CmpCq: s195 R: SendNumArgsReg. + jump5 := self JumpBelowOrEqual: 0. + self CmpCq: s195 R: SendNumArgsReg. + jump8 := self JumpBelowOrEqual: 0. + jump4 := self Jump: 0. currentBlock := self Label. - jump6 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self MoveMw: 24 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: Extra0Reg. @@ -6804,15 +6994,10 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self AddR: ClassReg R: Extra0Reg. self MoveR: Extra0Reg Aw: objectMemory freeStartAddress. self CmpCq: 0 R: SendNumArgsReg. - jump6 := self JumpNonZero: 0. - self MoveMw: 0 r: SPReg R: Extra3Reg. - self MoveR: Extra3Reg R: Extra2Reg. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - self MoveR: Extra2Reg R: ReceiverResultReg. - jump3 := self Jump: 0. + jump8 := self JumpNonZero: 0. + jump5 := self Jump: 0. currentBlock := self Label. - jump6 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: Extra0Reg. self AddCq: 8 R: Extra0Reg. self MoveMw: 24 r: SPReg R: Extra3Reg. @@ -6823,30 +7008,43 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self AddR: Extra3Reg R: ClassReg. self AddCq: 8 R: ClassReg. self SubCq: 1 R: ClassReg. - b702 := self Label. + b690 := self Label. self CmpR: Extra0Reg R: ClassReg. - jump6 := self JumpLess: 0. + jump8 := self JumpLess: 0. self MoveMw: 16 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg M64: 0 r: Extra0Reg. self MoveR: Extra0Reg R: Extra2Reg. self AddCq: 8 R: Extra2Reg. self MoveR: Extra2Reg R: Extra0Reg. - jump5 := self Jump: b702. + jump14 := self Jump: b690. currentBlock := self Label. - jump6 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. + s233 := 0. + self MoveCq: s233 R: ClassReg. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. + jump12 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: ReceiverResultReg. + self CmpCq: 0 R: ClassReg. + jump9 := self JumpNonZero: 0. self AddCq: 32 R: SPReg. self genPrimReturn. currentBlock := self Label. + jump6 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. - jump9 jmpTarget: currentBlock. + currentBlock := self Label. jump11 jmpTarget: currentBlock. - jump8 jmpTarget: currentBlock. - jump7 jmpTarget: currentBlock. - jump10 jmpTarget: currentBlock. - jump12 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + jump13 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. self AddCq: 32 R: SPReg. ^ 0 ] @@ -6867,26 +7065,24 @@ DruidTestRTLCompiler >> gen_primitiveNextUint16At [ DruidTestRTLCompiler >> gen_primitiveNoopLoopWithInvariant [ "AutoGenerated by Druid" - | jump3 jump1 b17 currentBlock jump2 | + | jump3 jump1 currentBlock b18 jump2 | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreaterOrEqual: 0. - b17 := self Label. + b18 := self Label. self MoveR: ClassReg R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self CmpCq: 10 R: SendNumArgsReg. jump2 := self JumpGreaterOrEqual: 0. self MoveR: SendNumArgsReg R: ClassReg. - jump3 := self Jump: b17. + jump3 := self Jump: b18. currentBlock := self Label. jump2 jmpTarget: currentBlock. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 3 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6895,17 +7091,15 @@ DruidTestRTLCompiler >> gen_primitiveNoopLoopWithInvariant [ DruidTestRTLCompiler >> gen_primitiveNotEqualsThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpZero: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6935,17 +7129,15 @@ DruidTestRTLCompiler >> gen_primitiveNotEqualsThanFloats [ DruidTestRTLCompiler >> gen_primitiveNotEqualsThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpZero: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6954,21 +7146,21 @@ DruidTestRTLCompiler >> gen_primitiveNotEqualsThanInverted [ DruidTestRTLCompiler >> gen_primitiveOr [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 5 R: ClassReg. - jump1 := self JumpLess: 0. - self CmpCq: 10 R: ClassReg. - jump2 := self JumpLessOrEqual: 0. + jump1 := self JumpGreaterOrEqual: 0. + self MoveCq: 42 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. + self CmpCq: 10 R: ClassReg. + jump1 := self JumpLessOrEqual: 0. self MoveCq: 42 R: ReceiverResultReg. - jump1 := self Jump: 0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - self MoveCq: 10 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. + self MoveCq: 10 R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -6982,8 +7174,8 @@ DruidTestRTLCompiler >> gen_primitivePlusFloatConstant [ self ConvertR: ClassReg Rd: DPFPReg0. self MoveCq: (objectMemory rawFloatBitsOf: 3.14) R: ClassReg. self MoveR: ClassReg Rd: DPFPReg1. - self AddRd: DPFPReg0 Rd: DPFPReg1. - self MoveRd: DPFPReg1 R: ClassReg. + self AddRd: DPFPReg1 Rd: DPFPReg0. + self MoveRd: DPFPReg0 R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive @@ -7119,29 +7311,21 @@ DruidTestRTLCompiler >> gen_primitiveRotateLeftDoesNotBehavesLikeShift [ DruidTestRTLCompiler >> gen_primitiveSandclock [ "AutoGenerated by Druid" - | jump1 s4 currentBlock s7 jump2 | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLessOrEqual: 0. - s4 := 1. - self MoveCq: s4 R: ClassReg. - jump2 := self Jump: 0. + self MoveCq: 6 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s7 := 99. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. - self MoveCq: s7 R: ClassReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - self AddCq: 5 R: ClassReg. - self MoveR: ClassReg R: ReceiverResultReg. - jump2 := self Jump: 0. + self MoveCq: 104 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 116 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -7150,7 +7334,7 @@ DruidTestRTLCompiler >> gen_primitiveSandclock [ DruidTestRTLCompiler >> gen_primitiveSize [ "AutoGenerated by Druid" - | jump1 s106 jumpNext jump6 s137 jump3 currentBlock jump8 jump5 jumpTrue jump2 jump7 jump4 | + | jump1 jumpNext jump6 jump3 s108 currentBlock jump8 jump5 jumpTrue jump2 s159 s14 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: ClassReg R: Extra1Reg. self CmpCq: 7 R: Extra1Reg. @@ -7167,8 +7351,9 @@ DruidTestRTLCompiler >> gen_primitiveSize [ jump1 jmpTarget: currentBlock. self MoveM64: 0 r: ClassReg R: Extra1Reg. self AndCq: 16r3FFFF7 R: Extra1Reg. + s14 := 0. self MoveR: Extra1Reg R: Extra2Reg. - self CmpCq: 0 R: Extra2Reg. + self CmpCq: s14 R: Extra2Reg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: Extra2Reg. jumpNext := self Jump: 0. @@ -7277,8 +7462,8 @@ DruidTestRTLCompiler >> gen_primitiveSize [ jump8 := self Jump: 0. currentBlock := self Label. jump6 jmpTarget: currentBlock. - s106 := 0. - self MoveCq: s106 R: Extra2Reg. + s108 := 0. + self MoveCq: s108 R: Extra2Reg. currentBlock := self Label. jump5 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -7286,70 +7471,87 @@ DruidTestRTLCompiler >> gen_primitiveSize [ jump7 jmpTarget: currentBlock. jump8 jmpTarget: currentBlock. self CmpCq: 9 R: Extra0Reg. - jump8 := self JumpAboveOrEqual: 0. - self CmpCq: 2 R: Extra0Reg. - jump7 := self JumpNonZero: 0. + jump8 := self JumpBelow: 0. + self SubCq: 0 R: Extra2Reg. + self MoveR: Extra2Reg R: SendNumArgsReg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: 1 R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump8 jmpTarget: currentBlock. + self CmpCq: 2 R: Extra0Reg. + jump8 := self JumpNonZero: 0. self SubCq: 0 R: Extra2Reg. self MoveR: Extra2Reg R: SendNumArgsReg. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump8 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. self CmpCq: 2 R: Extra0Reg. - jump7 := self JumpAboveOrEqual: 0. + jump8 := self JumpAboveOrEqual: 0. self SubR: Extra2Reg R: Extra2Reg. self MoveR: Extra2Reg R: SendNumArgsReg. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump4 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. self MoveM64: 0 r: ClassReg R: SendNumArgsReg. self AndCq: 16r3FFFFF R: SendNumArgsReg. self CmpCq: 31 R: SendNumArgsReg. - jump7 := self JumpAbove: 0. + jump8 := self JumpAbove: 0. self CmpCq: 31 R: SendNumArgsReg. - jump3 := self JumpNonZero: 0. - self MoveR: ClassReg R: SendNumArgsReg. - jump5 := self Jump: 0. + jump7 := self JumpNonZero: 0. + self MoveM64: 24 r: ClassReg R: SendNumArgsReg. + self ArithmeticShiftRightCq: 3 R: SendNumArgsReg. + self AndCq: 16rFFFF R: SendNumArgsReg. + self SubR: SendNumArgsReg R: Extra2Reg. + self MoveR: Extra2Reg R: SendNumArgsReg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: 1 R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. self CmpCq: 8 R: SendNumArgsReg. - jump3 := self JumpNonZero: 0. + jump7 := self JumpNonZero: 0. self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. - jump6 := self Jump: 0. + self MoveM64: 24 r: SendNumArgsReg R: SendNumArgsReg. + self ArithmeticShiftRightCq: 3 R: SendNumArgsReg. + self AndCq: 16rFFFF R: SendNumArgsReg. + self SubR: SendNumArgsReg R: Extra2Reg. + self MoveR: Extra2Reg R: SendNumArgsReg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: 1 R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. + jump8 jmpTarget: currentBlock. jump7 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: ClassReg. self LogicalShiftRightCq: 10 R: ClassReg. - s137 := objectMemory hiddenRootsObject. + s159 := objectMemory hiddenRootsObject. self LogicalShiftLeftCq: 3 R: ClassReg. - self AddCq: s137 R: ClassReg. + self AddCq: s159 R: ClassReg. self MoveM64: 8 r: ClassReg R: ClassReg. self genMoveConstant: objectMemory nilObject R: Extra0Reg. self CmpR: Extra0Reg R: ClassReg. - jump3 := self JumpNonZero: 0. + jump7 := self JumpNonZero: 0. self genMoveConstant: objectMemory nilObject R: Extra0Reg. - jump7 := self Jump: 0. + jump8 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. self AndCq: 1023 R: SendNumArgsReg. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddR: SendNumArgsReg R: ClassReg. self MoveM64: 8 r: ClassReg R: Extra0Reg. currentBlock := self Label. - jump7 jmpTarget: currentBlock. - self MoveR: Extra0Reg R: SendNumArgsReg. - currentBlock := self Label. - jump5 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. - self MoveM64: 24 r: SendNumArgsReg R: Extra0Reg. + jump8 jmpTarget: currentBlock. + self MoveM64: 24 r: Extra0Reg R: Extra0Reg. self ArithmeticShiftRightCq: 3 R: Extra0Reg. self AndCq: 16rFFFF R: Extra0Reg. self SubR: Extra0Reg R: Extra2Reg. @@ -7357,13 +7559,11 @@ DruidTestRTLCompiler >> gen_primitiveSize [ self LogicalShiftLeftCq: 3 R: Extra0Reg. self AddCq: 1 R: Extra0Reg. self MoveR: Extra0Reg R: ReceiverResultReg. - currentBlock := self Label. - jump8 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -7623,19 +7823,17 @@ DruidTestRTLCompiler >> gen_primitiveSmallThan [ DruidTestRTLCompiler >> gen_primitiveSubWithOverflow [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self AddCq: -1 R: SendNumArgsReg. self SubR: SendNumArgsReg R: ClassReg. jump1 := self JumpNoOverflow: 0. self MoveCq: 99 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: ClassReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -7644,19 +7842,17 @@ DruidTestRTLCompiler >> gen_primitiveSubWithOverflow [ DruidTestRTLCompiler >> gen_primitiveSumWithOverflow [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self AddCq: -1 R: ClassReg. self AddR: SendNumArgsReg R: ClassReg. jump1 := self JumpNoOverflow: 0. self MoveCq: 99 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: ClassReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -7790,21 +7986,29 @@ DruidTestRTLCompiler >> gen_primitiveUint8AtPut [ ^ CompletePrimitive ] +{ #category : #generated } +DruidTestRTLCompiler >> gen_primitiveWithConditionalCompilation [ + "AutoGenerated by Druid" + + | currentBlock | + self MoveCq: 17 R: ReceiverResultReg. + self genPrimReturn. + ^ CompletePrimitive +] + { #category : #generated } DruidTestRTLCompiler >> gen_primitiveWithDeadCode [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 55 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -7832,17 +8036,15 @@ DruidTestRTLCompiler >> gen_primitiveWithIfAssigningValue [ DruidTestRTLCompiler >> gen_primitiveWithIfNilIfNotNilStatement [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -7851,17 +8053,15 @@ DruidTestRTLCompiler >> gen_primitiveWithIfNilIfNotNilStatement [ DruidTestRTLCompiler >> gen_primitiveWithIfNotNilIfNilStatement [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -7870,17 +8070,15 @@ DruidTestRTLCompiler >> gen_primitiveWithIfNotNilIfNilStatement [ DruidTestRTLCompiler >> gen_primitiveWithIfNotNilIfNilStatementWithArgument [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -7889,17 +8087,15 @@ DruidTestRTLCompiler >> gen_primitiveWithIfNotNilIfNilStatementWithArgument [ DruidTestRTLCompiler >> gen_primitiveWithIfNotNilStatement [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -7950,19 +8146,17 @@ DruidTestRTLCompiler >> gen_primitiveWithSequentialExitPoint [ DruidTestRTLCompiler >> gen_primitiveWithTwoArgs [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: Arg0Reg R: SendNumArgsReg. self MoveR: Arg1Reg R: Extra0Reg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveR: Extra0Reg R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -8023,7 +8217,7 @@ DruidTestRTLCompiler >> gen_pushLiteralConstantBytecode [ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ "AutoGenerated by Druid" - | jump1 s3 s28 b232 t1 jump3 currentBlock t0 jump2 s4 s29 live jump4 | + | s34 s3 jump1 s28 t1 jump3 s33 b234 currentBlock s24 t0 jump2 s4 s29 s23 live jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -8043,7 +8237,7 @@ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ self CmpCq: 0 R: t1. jump1 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t1. - b232 := self Label. + b234 := self Label. self MoveR: t1 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -8054,20 +8248,30 @@ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t0. self MoveR: t0 R: t1. - jump4 := self Jump: b232. + jump4 := self Jump: b234. currentBlock := self Label. - jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. - self MoveR: t1 R: t0. + s23 := ValueIndex. + s24 := s23 << 3. + self AddCq: s24 R: t1. + self ssPushBase: t1 offset: 8. jump3 := self Jump: 0. currentBlock := self Label. - jump1 jmpTarget: currentBlock. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. s28 := ValueIndex. s29 := s28 << 3. - self AddCq: s29 R: t0. + self AddCq: s29 R: t1. + self ssPushBase: t1 offset: 8. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + s33 := ValueIndex. + s34 := s33 << 3. + self AddCq: s34 R: t0. self ssPushBase: t0 offset: 8. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -8210,7 +8414,7 @@ DruidTestRTLCompiler >> gen_sendLiteralSelector0ArgsBytecode [ DruidTestRTLCompiler >> gen_shortConditionalJumpFalse [ "AutoGenerated by Druid" - | jump1 s8 s5 s2 currentBlock s12 t0 jump2 live s9 | + | jump1 s8 s5 s2 jump3 currentBlock s12 t0 jump2 live s9 | live := 0. self annotateBytecode: self Label. t0 := self @@ -8233,12 +8437,15 @@ DruidTestRTLCompiler >> gen_shortConditionalJumpFalse [ jump1 jmpTarget: currentBlock. s12 := objectMemory trueObject. self CmpCq: s12 R: t0. - jump1 := self JumpZero: 0. + jump1 := self JumpNonZero: 0. + jump3 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. self MoveR: t0 R: TempReg. self CallRT: ceSendMustBeBooleanTrampoline. currentBlock := self Label. jump2 jmpTarget: currentBlock. - jump1 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. ^ 0 ] @@ -8246,7 +8453,7 @@ DruidTestRTLCompiler >> gen_shortConditionalJumpFalse [ DruidTestRTLCompiler >> gen_shortConditionalJumpTrue [ "AutoGenerated by Druid" - | jump1 s8 s5 s2 currentBlock s12 t0 jump2 live s9 | + | jump1 s8 s5 s2 jump3 currentBlock s12 t0 jump2 live s9 | live := 0. self annotateBytecode: self Label. t0 := self @@ -8269,12 +8476,15 @@ DruidTestRTLCompiler >> gen_shortConditionalJumpTrue [ jump1 jmpTarget: currentBlock. s12 := objectMemory falseObject. self CmpCq: s12 R: t0. - jump1 := self JumpZero: 0. + jump1 := self JumpNonZero: 0. + jump3 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. self MoveR: t0 R: TempReg. self CallRT: ceSendMustBeBooleanTrampoline. currentBlock := self Label. jump2 jmpTarget: currentBlock. - jump1 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. ^ 0 ] @@ -8296,7 +8506,7 @@ DruidTestRTLCompiler >> gen_shortUnconditionalJump [ DruidTestRTLCompiler >> gen_storeAndPopReceiverVariableBytecode [ "AutoGenerated by Druid" - | jump5 s24 s46 s16 jump3 s29 jump1 t1 s2 currentBlock s19 s27 jump6 live jump4 jump2 t2 jump7 t0 s48 | + | jump5 s24 s16 jump3 s29 jump8 jump1 t1 s2 currentBlock s19 s27 jump6 s56 live jump4 jump2 t2 s52 jump7 t0 | live := 0. self annotateBytecode: self Label. self ensureReceiverResultRegContainsSelf. @@ -8368,37 +8578,59 @@ DruidTestRTLCompiler >> gen_storeAndPopReceiverVariableBytecode [ self LogicalShiftRightCq: 29 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump7 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 8 r: t0. + jump6 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self TstCq: 7 R: t1. - jump6 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 8 r: t0. + jump5 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self CmpCq: 16r20000000000 R: t0. - jump5 := self JumpLess: 0. + jump7 := self JumpLess: 0. self CmpCq: 16r20000000000 R: t1. - jump4 := self JumpGreaterOrEqual: 0. + jump4 := self JumpLess: 0. + self MoveR: t1 M64: 8 r: t0. + jump3 := self Jump: 0. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t1. - jump3 := self JumpBelow: 0. - s46 := objectMemory trueObject. - self CmpCq: s46 R: t1. - jump1 := self JumpBelowOrEqual: 0. + jump4 := self JumpBelow: 0. + s52 := objectMemory trueObject. + self CmpCq: s52 R: t1. + jump1 := self JumpAbove: 0. + self MoveR: t1 M64: 8 r: t0. + jump8 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s48 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s48 R: t1. - jump3 := self JumpBelow: 0. + jump4 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + s56 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s56 R: t1. + jump1 := self JumpBelow: 0. self MoveR: t0 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + self MoveR: t1 M64: 8 r: t0. + jump4 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + self MoveR: t1 M64: 8 r: t0. + jump1 := self Jump: 0. currentBlock := self Label. jump7 jmpTarget: currentBlock. + self MoveR: t1 M64: 8 r: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. jump5 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. - self MoveR: t1 M64: 8 r: t0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. ^ 0 ] diff --git a/Druid-Tests/DruidTestRTLCompilerForTest.class.st b/Druid-Tests/DruidTestRTLCompilerForTest.class.st index 680cad98..324b3156 100644 --- a/Druid-Tests/DruidTestRTLCompilerForTest.class.st +++ b/Druid-Tests/DruidTestRTLCompilerForTest.class.st @@ -72,6 +72,7 @@ DruidTestRTLCompilerForTest >> gen_PrimitiveAdd [ self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. + currentBlock := self Label. jump2 jmpTarget: currentBlock. ^ 0 ] @@ -97,7 +98,7 @@ DruidTestRTLCompilerForTest >> gen_ReturnTopFromMethod [ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode0 [ "AutoGenerated by Druid" - | jump5 s24 s46 s16 jump3 s29 jump1 t1 s2 currentBlock s19 s27 jump6 live jump4 jump2 t2 jump7 t0 s48 | + | jump5 s24 s16 jump3 s29 jump8 jump1 t1 s2 currentBlock s19 s27 jump6 s56 live jump4 jump2 t2 s52 jump7 t0 | live := 0. self annotateBytecode: self Label. self ensureReceiverResultRegContainsSelf. @@ -169,37 +170,59 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode0 [ self LogicalShiftRightCq: 29 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump7 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 8 r: t0. + jump6 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self TstCq: 7 R: t1. - jump6 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 8 r: t0. + jump5 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self CmpCq: 16r20000000000 R: t0. - jump5 := self JumpLess: 0. + jump7 := self JumpLess: 0. self CmpCq: 16r20000000000 R: t1. - jump4 := self JumpGreaterOrEqual: 0. + jump4 := self JumpLess: 0. + self MoveR: t1 M64: 8 r: t0. + jump3 := self Jump: 0. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t1. - jump3 := self JumpBelow: 0. - s46 := objectMemory trueObject. - self CmpCq: s46 R: t1. - jump1 := self JumpBelowOrEqual: 0. + jump4 := self JumpBelow: 0. + s52 := objectMemory trueObject. + self CmpCq: s52 R: t1. + jump1 := self JumpAbove: 0. + self MoveR: t1 M64: 8 r: t0. + jump8 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s48 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s48 R: t1. - jump3 := self JumpBelow: 0. + jump4 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + s56 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s56 R: t1. + jump1 := self JumpBelow: 0. self MoveR: t0 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + self MoveR: t1 M64: 8 r: t0. + jump4 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + self MoveR: t1 M64: 8 r: t0. + jump1 := self Jump: 0. currentBlock := self Label. jump7 jmpTarget: currentBlock. + self MoveR: t1 M64: 8 r: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. jump5 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. - self MoveR: t1 M64: 8 r: t0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. ^ 0 ] @@ -207,7 +230,7 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode0 [ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode1 [ "AutoGenerated by Druid" - | jump5 s24 s46 s16 jump3 s29 jump1 t1 s2 currentBlock s19 s27 jump6 live jump4 jump2 t2 jump7 t0 s48 | + | jump5 s24 s16 jump3 s29 jump8 jump1 t1 s2 currentBlock s19 s27 jump6 s56 live jump4 jump2 t2 s52 jump7 t0 | live := 0. self annotateBytecode: self Label. self ensureReceiverResultRegContainsSelf. @@ -279,37 +302,59 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode1 [ self LogicalShiftRightCq: 29 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump7 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 16 r: t0. + jump6 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self TstCq: 7 R: t1. - jump6 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 16 r: t0. + jump5 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self CmpCq: 16r20000000000 R: t0. - jump5 := self JumpLess: 0. + jump7 := self JumpLess: 0. self CmpCq: 16r20000000000 R: t1. - jump4 := self JumpGreaterOrEqual: 0. + jump4 := self JumpLess: 0. + self MoveR: t1 M64: 16 r: t0. + jump3 := self Jump: 0. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t1. - jump3 := self JumpBelow: 0. - s46 := objectMemory trueObject. - self CmpCq: s46 R: t1. - jump1 := self JumpBelowOrEqual: 0. + jump4 := self JumpBelow: 0. + s52 := objectMemory trueObject. + self CmpCq: s52 R: t1. + jump1 := self JumpAbove: 0. + self MoveR: t1 M64: 16 r: t0. + jump8 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s48 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s48 R: t1. - jump3 := self JumpBelow: 0. + jump4 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + s56 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s56 R: t1. + jump1 := self JumpBelow: 0. self MoveR: t0 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + self MoveR: t1 M64: 16 r: t0. + jump4 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + self MoveR: t1 M64: 16 r: t0. + jump1 := self Jump: 0. currentBlock := self Label. jump7 jmpTarget: currentBlock. + self MoveR: t1 M64: 16 r: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. jump5 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. - self MoveR: t1 M64: 16 r: t0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. ^ 0 ] @@ -317,7 +362,7 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode1 [ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode2 [ "AutoGenerated by Druid" - | jump5 s24 s46 s16 jump3 s29 jump1 t1 s2 currentBlock s19 s27 jump6 live jump4 jump2 t2 jump7 t0 s48 | + | jump5 s24 s16 jump3 s29 jump8 jump1 t1 s2 currentBlock s19 s27 jump6 s56 live jump4 jump2 t2 s52 jump7 t0 | live := 0. self annotateBytecode: self Label. self ensureReceiverResultRegContainsSelf. @@ -389,37 +434,59 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode2 [ self LogicalShiftRightCq: 29 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump7 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 24 r: t0. + jump6 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self TstCq: 7 R: t1. - jump6 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 24 r: t0. + jump5 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self CmpCq: 16r20000000000 R: t0. - jump5 := self JumpLess: 0. + jump7 := self JumpLess: 0. self CmpCq: 16r20000000000 R: t1. - jump4 := self JumpGreaterOrEqual: 0. + jump4 := self JumpLess: 0. + self MoveR: t1 M64: 24 r: t0. + jump3 := self Jump: 0. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t1. - jump3 := self JumpBelow: 0. - s46 := objectMemory trueObject. - self CmpCq: s46 R: t1. - jump1 := self JumpBelowOrEqual: 0. + jump4 := self JumpBelow: 0. + s52 := objectMemory trueObject. + self CmpCq: s52 R: t1. + jump1 := self JumpAbove: 0. + self MoveR: t1 M64: 24 r: t0. + jump8 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s48 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s48 R: t1. - jump3 := self JumpBelow: 0. + jump4 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + s56 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s56 R: t1. + jump1 := self JumpBelow: 0. self MoveR: t0 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + self MoveR: t1 M64: 24 r: t0. + jump4 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + self MoveR: t1 M64: 24 r: t0. + jump1 := self Jump: 0. currentBlock := self Label. jump7 jmpTarget: currentBlock. + self MoveR: t1 M64: 24 r: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. jump5 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. - self MoveR: t1 M64: 24 r: t0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. ^ 0 ] @@ -427,7 +494,7 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode2 [ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode3 [ "AutoGenerated by Druid" - | jump5 s24 s46 s16 jump3 s29 jump1 t1 s2 currentBlock s19 s27 jump6 live jump4 jump2 t2 jump7 t0 s48 | + | jump5 s24 s16 jump3 s29 jump8 jump1 t1 s2 currentBlock s19 s27 jump6 s56 live jump4 jump2 t2 s52 jump7 t0 | live := 0. self annotateBytecode: self Label. self ensureReceiverResultRegContainsSelf. @@ -499,36 +566,58 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode3 [ self LogicalShiftRightCq: 29 R: t2. self AndCq: 1 R: t2. self CmpCq: 0 R: t2. - jump7 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 32 r: t0. + jump6 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self TstCq: 7 R: t1. - jump6 := self JumpNonZero: 0. + jump7 := self JumpZero: 0. + self MoveR: t1 M64: 32 r: t0. + jump5 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self CmpCq: 16r20000000000 R: t0. - jump5 := self JumpLess: 0. + jump7 := self JumpLess: 0. self CmpCq: 16r20000000000 R: t1. - jump4 := self JumpGreaterOrEqual: 0. + jump4 := self JumpLess: 0. + self MoveR: t1 M64: 32 r: t0. + jump3 := self Jump: 0. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t1. - jump3 := self JumpBelow: 0. - s46 := objectMemory trueObject. - self CmpCq: s46 R: t1. - jump1 := self JumpBelowOrEqual: 0. + jump4 := self JumpBelow: 0. + s52 := objectMemory trueObject. + self CmpCq: s52 R: t1. + jump1 := self JumpAbove: 0. + self MoveR: t1 M64: 32 r: t0. + jump8 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s48 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s48 R: t1. - jump3 := self JumpBelow: 0. + jump4 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + s56 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s56 R: t1. + jump1 := self JumpBelow: 0. self MoveR: t0 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + self MoveR: t1 M64: 32 r: t0. + jump4 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + self MoveR: t1 M64: 32 r: t0. + jump1 := self Jump: 0. currentBlock := self Label. jump7 jmpTarget: currentBlock. + self MoveR: t1 M64: 32 r: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. jump5 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. - self MoveR: t1 M64: 32 r: t0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. ^ 0 ] diff --git a/Druid-Tests/SimpleDruidTestRTLCompiler.class.st b/Druid-Tests/SimpleDruidTestRTLCompiler.class.st index 9e4e1b5f..b5a375cd 100644 --- a/Druid-Tests/SimpleDruidTestRTLCompiler.class.st +++ b/Druid-Tests/SimpleDruidTestRTLCompiler.class.st @@ -1893,8 +1893,9 @@ SimpleDruidTestRTLCompiler >> gen_primitiveAdd [ self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. ^ 0 ] @@ -1902,20 +1903,21 @@ SimpleDruidTestRTLCompiler >> gen_primitiveAdd [ SimpleDruidTestRTLCompiler >> gen_primitiveAnd [ "AutoGenerated by Druid" - | jump1 jump2 jump3 currentBlock | + | jump1 jump2 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self CmpCq: 10 R: ClassReg. jump2 := self JumpLessOrEqual: 0. self MoveCq: 42 R: ReceiverResultReg. - jump3 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. self MoveCq: 10 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + self MoveCq: 10 R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -1924,7 +1926,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveAnd [ SimpleDruidTestRTLCompiler >> gen_primitiveAndIfTrue [ "AutoGenerated by Druid" - | jump1 jump2 jump3 currentBlock | + | jump1 jump2 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 1 R: ClassReg. jump1 := self JumpLessOrEqual: 0. @@ -1932,13 +1934,14 @@ SimpleDruidTestRTLCompiler >> gen_primitiveAndIfTrue [ self CmpCq: 1 R: ClassReg. jump2 := self JumpNonZero: 0. self MoveCq: 1 R: ReceiverResultReg. - jump3 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + self MoveCq: 2 R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -1960,7 +1963,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveArithmeticBitShiftRight [ SimpleDruidTestRTLCompiler >> gen_primitiveAsCharacter [ "AutoGenerated by Druid" - | s3 s13 currentBlock s2 | + | s3 s16 currentBlock s2 | s2 := self methodNumArgs. s2 = 0 ifTrue: [ | jump1 jump2 jump3 | @@ -1977,28 +1980,32 @@ SimpleDruidTestRTLCompiler >> gen_primitiveAsCharacter [ self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. ^ 0 ]. - s13 := self methodNumArgs. - s13 = 1 ifTrue: [ - | jump3 jump2 jump1 | + s16 := self methodNumArgs. + s16 = 1 ifTrue: [ + | jump1 jump2 jump3 | self genLoadArg: 0 into: ClassReg. self TstCq: 1 R: ClassReg. - jump3 := self JumpZero: 0. + jump1 := self JumpZero: 0. self ArithmeticShiftRightCq: 3 R: ClassReg. self CmpCq: 0 R: ClassReg. jump2 := self JumpLess: 0. self CmpCq: 16r3FFFFFFF R: ClassReg. - jump1 := self JumpGreater: 0. + jump3 := self JumpGreater: 0. self LogicalShiftLeftCq: 3 R: ClassReg. self AddCq: 2 R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. jump3 jmpTarget: currentBlock. + currentBlock := self Label. jump2 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. ^ 0 ]. ^ 0 @@ -2008,7 +2015,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveAsCharacter [ SimpleDruidTestRTLCompiler >> gen_primitiveAsFloat [ "AutoGenerated by Druid" - | jumpTrue jumpNext jump1 s42 jump3 currentBlock s45 jump2 | + | jump5 s30 jump1 jump3 s33 currentBlock jump2 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self ArithmeticShiftRightCq: 3 R: ClassReg. self ConvertR: ClassReg Rd: DPFPReg0. @@ -2019,76 +2026,59 @@ SimpleDruidTestRTLCompiler >> gen_primitiveAsFloat [ self CmpCq: 896 R: SendNumArgsReg. jump1 := self JumpBelowOrEqual: 0. self CmpCq: 1151 R: SendNumArgsReg. - jumpTrue := self JumpBelowOrEqual: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump2 := self Jump: 0. + jump2 := self JumpBelowOrEqual: 0. + jump3 := self JumpAbove: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. self AndCq: 16rFFFFFFFFFFFFF R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self CmpCq: 0 R: SendNumArgsReg. - jumpTrue := self JumpZero: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump3 := self Jump: 0. + jump4 := self JumpZero: 0. + jump5 := self JumpNonZero: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. self CmpCq: 896 R: SendNumArgsReg. - jumpTrue := self JumpZero: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump1 := self JumpNonZero: 0. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self CmpCq: 1 R: SendNumArgsReg. - jump2 := self JumpNonZero: 0. + jump4 jmpTarget: currentBlock. self MoveRd: DPFPReg0 R: SendNumArgsReg. self RotateLeftCq: 1 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump3 := self JumpBelowOrEqual: 0. + jump4 := self JumpBelowOrEqual: 0. self SubCq: 16r7000000000000000 R: SendNumArgsReg. - jump1 := self Jump: 0. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: 4 R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. + jump4 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 4 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump1 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: ClassReg. self AddCq: 16 R: ClassReg. - s42 := objectMemory getScavengeThreshold. - self CmpCq: s42 R: ClassReg. - jump2 := self JumpAbove: 0. - s45 := 72057594205700130. - self MoveCq: s45 R: ClassReg. + s30 := objectMemory getScavengeThreshold. + self CmpCq: s30 R: ClassReg. + jump1 := self JumpAbove: 0. + s33 := 72057594205700130. + self MoveCq: s33 R: ClassReg. self MoveR: ClassReg M64: 0 r: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: ClassReg. self AddCq: 16 R: ClassReg. self MoveR: ClassReg Aw: objectMemory freeStartAddress. self MoveRd: DPFPReg0 M64: 8 r: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. ^ 0 ] @@ -2209,7 +2199,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveAssertIsIgnored [ | currentBlock | self MoveCq: 17 R: ReceiverResultReg. self genPrimReturn. - ^ 0 + ^ CompletePrimitive ] { #category : #generated } @@ -2971,22 +2961,20 @@ SimpleDruidTestRTLCompiler >> gen_primitiveBitAnd [ SimpleDruidTestRTLCompiler >> gen_primitiveBitShift [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self genLoadArg: 0 into: SendNumArgsReg. self CmpCq: 0 R: SendNumArgsReg. jump1 := self JumpLessOrEqual: 0. self LogicalShiftLeftR: SendNumArgsReg R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: SendNumArgsReg. self NegateR: SendNumArgsReg. self LogicalShiftRightR: SendNumArgsReg R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3008,17 +2996,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveBitXor [ SimpleDruidTestRTLCompiler >> gen_primitiveBranchingWithAssigments [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3108,17 +3094,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveCallingMethodReturningConstant [ SimpleDruidTestRTLCompiler >> gen_primitiveCallingMethodWithEarlyReturn [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 57 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3143,24 +3127,21 @@ SimpleDruidTestRTLCompiler >> gen_primitiveCascadedUint16AtPut [ SimpleDruidTestRTLCompiler >> gen_primitiveCaseOfOtherwiseValue [ "AutoGenerated by Druid" - | jump1 jump2 jump3 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 57 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self CmpCq: 1 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump3 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 77 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3169,10 +3150,10 @@ SimpleDruidTestRTLCompiler >> gen_primitiveCaseOfOtherwiseValue [ SimpleDruidTestRTLCompiler >> gen_primitiveClass [ "AutoGenerated by Druid" - | s81 s26 currentBlock s2 s50 s3 | + | s25 s71 s40 s2 currentBlock s3 | s2 := self methodNumArgs. s2 = 0 ifTrue: [ - | jump5 jump3 jump1 jump4 jump2 | + | jump1 jump2 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: ClassReg R: SendNumArgsReg. self AndCq: 7 R: SendNumArgsReg. @@ -3182,127 +3163,114 @@ SimpleDruidTestRTLCompiler >> gen_primitiveClass [ self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddR: SendNumArgsReg R: ClassReg. self MoveM64: 8 r: ClassReg R: ClassReg. - jump2 := self Jump: 0. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self MoveM64: 0 r: ClassReg R: SendNumArgsReg. - self AndCq: 16r3FFFFF R: SendNumArgsReg. - self CmpCq: 31 R: SendNumArgsReg. + self MoveM64: 0 r: ClassReg R: ClassReg. + self AndCq: 16r3FFFFF R: ClassReg. + self CmpCq: 31 R: ClassReg. jump1 := self JumpAbove: 0. - self CmpCq: 31 R: SendNumArgsReg. - jump3 := self JumpNonZero: 0. - self MoveR: ClassReg R: SendNumArgsReg. - jump4 := self Jump: 0. + self CmpCq: 31 R: ClassReg. + jump2 := self JumpNonZero: 0. + self genPrimReturn. currentBlock := self Label. - jump3 jmpTarget: currentBlock. - self CmpCq: 8 R: SendNumArgsReg. - jump3 := self JumpNonZero: 0. - self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. - jump5 := self Jump: 0. + jump2 jmpTarget: currentBlock. + self CmpCq: 8 R: ClassReg. + jump2 := self JumpNonZero: 0. + self genMoveConstant: objectMemory nilObject R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. - self MoveR: SendNumArgsReg R: ClassReg. - self LogicalShiftRightCq: 10 R: ClassReg. - s26 := objectMemory hiddenRootsObject. - self LogicalShiftLeftCq: 3 R: ClassReg. - self AddCq: s26 R: ClassReg. - self MoveM64: 8 r: ClassReg R: ClassReg. + jump2 jmpTarget: currentBlock. + self MoveR: ClassReg R: SendNumArgsReg. + self LogicalShiftRightCq: 10 R: SendNumArgsReg. + s25 := objectMemory hiddenRootsObject. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: s25 R: SendNumArgsReg. + self MoveM64: 8 r: SendNumArgsReg R: SendNumArgsReg. self genMoveConstant: objectMemory nilObject R: Extra0Reg. - self CmpR: Extra0Reg R: ClassReg. - jump3 := self JumpNonZero: 0. + self CmpR: Extra0Reg R: SendNumArgsReg. + jump2 := self JumpNonZero: 0. self genMoveConstant: objectMemory nilObject R: Extra0Reg. - jump1 := self Jump: 0. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - self AndCq: 1023 R: SendNumArgsReg. - self LogicalShiftLeftCq: 3 R: SendNumArgsReg. - self AddR: SendNumArgsReg R: ClassReg. - self MoveM64: 8 r: ClassReg R: Extra0Reg. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. - self MoveR: Extra0Reg R: SendNumArgsReg. - currentBlock := self Label. - jump4 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. - self MoveR: SendNumArgsReg R: ClassReg. + self MoveR: Extra0Reg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self MoveR: ClassReg R: ReceiverResultReg. + self AndCq: 1023 R: ClassReg. + self LogicalShiftLeftCq: 3 R: ClassReg. + self AddR: ClassReg R: SendNumArgsReg. + self MoveM64: 8 r: SendNumArgsReg R: Extra0Reg. + self MoveR: Extra0Reg R: ReceiverResultReg. self genPrimReturn. ^ 0 ]. - s50 := self methodNumArgs. - s50 = 1 ifTrue: [ - | jump5 jump3 jump1 jump6 jump4 jump2 | + s40 := self methodNumArgs. + s40 = 1 ifTrue: [ + | jump2 jump1 | self genLoadArg: 0 into: Extra0Reg. - self MoveR: Extra0Reg R: ClassReg. - self AndCq: 7 R: ClassReg. - self CmpCq: 0 R: ClassReg. + self MoveR: Extra0Reg R: SendNumArgsReg. + self AndCq: 7 R: SendNumArgsReg. + self CmpCq: 0 R: SendNumArgsReg. jump2 := self JumpNonZero: 0. - self MoveM64: 0 r: Extra0Reg R: ClassReg. - self AndCq: 16r3FFFF7 R: ClassReg. - self CmpCq: 0 R: ClassReg. - jump5 := self JumpZero: 0. + self MoveM64: 0 r: Extra0Reg R: SendNumArgsReg. + self AndCq: 16r3FFFF7 R: SendNumArgsReg. + self CmpCq: 0 R: SendNumArgsReg. + jump1 := self JumpNonZero: 0. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self MoveR: Extra0Reg R: ClassReg. - self AndCq: 7 R: ClassReg. - self CmpCq: 0 R: ClassReg. - jump2 := self JumpZero: 0. + jump1 jmpTarget: currentBlock. + self MoveR: Extra0Reg R: SendNumArgsReg. + self AndCq: 7 R: SendNumArgsReg. + self CmpCq: 0 R: SendNumArgsReg. + jump1 := self JumpZero: 0. self MoveAw: objectMemory hiddenRootsObject + 8 R: Extra0Reg. - self LogicalShiftLeftCq: 3 R: ClassReg. - self AddR: ClassReg R: Extra0Reg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddR: SendNumArgsReg R: Extra0Reg. self MoveM64: 8 r: Extra0Reg R: Extra0Reg. - jump4 := self Jump: 0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - self MoveM64: 0 r: Extra0Reg R: ClassReg. - self AndCq: 16r3FFFFF R: ClassReg. - self CmpCq: 31 R: ClassReg. - jump2 := self JumpAbove: 0. - self CmpCq: 31 R: ClassReg. - jump1 := self JumpNonZero: 0. - self MoveR: Extra0Reg R: ClassReg. - jump3 := self Jump: 0. + self MoveR: Extra0Reg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self CmpCq: 8 R: ClassReg. - jump1 := self JumpNonZero: 0. - self genMoveConstant: objectMemory nilObject R: ClassReg. - jump6 := self Jump: 0. + self MoveM64: 0 r: Extra0Reg R: SendNumArgsReg. + self AndCq: 16r3FFFFF R: SendNumArgsReg. + self CmpCq: 31 R: SendNumArgsReg. + jump1 := self JumpAbove: 0. + self CmpCq: 31 R: SendNumArgsReg. + jump2 := self JumpNonZero: 0. + self MoveR: Extra0Reg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self CmpCq: 8 R: SendNumArgsReg. + jump2 := self JumpNonZero: 0. + self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - self MoveR: ClassReg R: Extra0Reg. + jump2 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: Extra0Reg. self LogicalShiftRightCq: 10 R: Extra0Reg. - s81 := objectMemory hiddenRootsObject. + s71 := objectMemory hiddenRootsObject. self LogicalShiftLeftCq: 3 R: Extra0Reg. - self AddCq: s81 R: Extra0Reg. + self AddCq: s71 R: Extra0Reg. self MoveM64: 8 r: Extra0Reg R: Extra0Reg. - self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. - self CmpR: SendNumArgsReg R: Extra0Reg. - jump1 := self JumpNonZero: 0. - self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. - jump2 := self Jump: 0. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. - self AndCq: 1023 R: ClassReg. - self LogicalShiftLeftCq: 3 R: ClassReg. - self AddR: ClassReg R: Extra0Reg. - self MoveM64: 8 r: Extra0Reg R: SendNumArgsReg. + self genMoveConstant: objectMemory nilObject R: ClassReg. + self CmpR: ClassReg R: Extra0Reg. + jump2 := self JumpNonZero: 0. + self genMoveConstant: objectMemory nilObject R: ClassReg. + jump1 := self Jump: 0. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self MoveR: SendNumArgsReg R: ClassReg. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. - self MoveR: ClassReg R: Extra0Reg. + self AndCq: 1023 R: SendNumArgsReg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddR: SendNumArgsReg R: Extra0Reg. + self MoveM64: 8 r: Extra0Reg R: ClassReg. currentBlock := self Label. - jump4 jmpTarget: currentBlock. - self MoveR: Extra0Reg R: ReceiverResultReg. + jump1 jmpTarget: currentBlock. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. - currentBlock := self Label. - jump5 jmpTarget: currentBlock. ^ 0 ]. ^ 0 ] @@ -3321,17 +3289,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveClassVariable [ SimpleDruidTestRTLCompiler >> gen_primitiveClassVariableWithBranch [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 35 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 36 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3340,17 +3306,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveClassVariableWithBranch [ SimpleDruidTestRTLCompiler >> gen_primitiveConditionWithAnyMask [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 1 R: ClassReg. jump1 := self JumpZero: 0. self MoveCq: 1 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3359,17 +3323,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveConditionWithAnyMask [ SimpleDruidTestRTLCompiler >> gen_primitiveConditionWithAnyMaskInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 1 R: ClassReg. jump1 := self JumpZero: 0. self MoveCq: 1 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3378,18 +3340,16 @@ SimpleDruidTestRTLCompiler >> gen_primitiveConditionWithAnyMaskInverted [ SimpleDruidTestRTLCompiler >> gen_primitiveConditionWithObjectReference [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock s3 | + | jump1 currentBlock s3 | self MoveR: ReceiverResultReg R: ClassReg. s3 := objectMemory trueObject. self CmpCq: s3 R: ClassReg. jump1 := self JumpAboveOrEqual: 0. self MoveCq: 1 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3408,7 +3368,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveConstantFloatAsInteger [ SimpleDruidTestRTLCompiler >> gen_primitiveDNA [ "AutoGenerated by Druid" - | jump3 jump1 s4 currentBlock s9 s7 s19 jump2 | + | jump3 jump1 s4 currentBlock s7 jump2 | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLessOrEqual: 0. @@ -3420,7 +3380,6 @@ SimpleDruidTestRTLCompiler >> gen_primitiveDNA [ s7 := 99. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. - s9 := 5. self CmpCq: 7 R: ClassReg. jump3 := self JumpLessOrEqual: 0. self MoveCq: s7 R: ClassReg. @@ -3428,21 +3387,14 @@ SimpleDruidTestRTLCompiler >> gen_primitiveDNA [ jump2 jmpTarget: currentBlock. self AddCq: 20 R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump3 jmpTarget: currentBlock. - self MoveCq: s9 R: ClassReg. - jump3 := self Jump: 0. + self MoveCq: 146 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s19 := 17. - self MoveCq: s19 R: ClassReg. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - self AddCq: 141 R: ClassReg. - self MoveR: ClassReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. + self MoveCq: 158 R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -3454,7 +3406,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveDeadBranchWithError [ | currentBlock | self MoveCq: 17 R: ReceiverResultReg. self genPrimReturn. - ^ 0 + ^ CompletePrimitive ] { #category : #generated } @@ -3500,13 +3452,13 @@ SimpleDruidTestRTLCompiler >> gen_primitiveDivide [ | currentBlock | self MoveR: ReceiverResultReg R: ClassReg. - self genLoadArgAtDepth: 0 into: SendNumArgsReg. + self genLoadArg: 0 into: SendNumArgsReg. self DivR: SendNumArgsReg R: ClassReg - Quo: SendNumArgsReg - Rem: ClassReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. + Quo: ClassReg + Rem: SendNumArgsReg. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -3522,9 +3474,9 @@ SimpleDruidTestRTLCompiler >> gen_primitiveDivideByConstant [ self DivR: SendNumArgsReg R: ClassReg - Quo: SendNumArgsReg - Rem: ClassReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. + Quo: ClassReg + Rem: SendNumArgsReg. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -3604,17 +3556,36 @@ SimpleDruidTestRTLCompiler >> gen_primitiveDoubleDeferredInline [ SimpleDruidTestRTLCompiler >> gen_primitiveEqualsThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. + self genPrimReturn. + ^ CompletePrimitive +] + +{ #category : #generated } +SimpleDruidTestRTLCompiler >> gen_primitiveEqualsThanFloatConstant [ + "AutoGenerated by Druid" + + | jumpNext currentBlock jumpTrue | + self MoveR: ReceiverResultReg R: ClassReg. + self ConvertR: ClassReg Rd: DPFPReg0. + self MoveCq: (objectMemory rawFloatBitsOf: 0.0) R: ClassReg. + self MoveR: ClassReg Rd: DPFPReg1. + self CmpRd: DPFPReg1 Rd: DPFPReg0. + jumpTrue := self JumpFPEqual: 0. + self MoveCq: 0 R: ClassReg. + jumpNext := self Jump: 0. + jumpTrue jmpTarget: self Label. + self MoveCq: 1 R: ClassReg. + jumpNext jmpTarget: self Label. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -3644,17 +3615,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveEqualsThanFloats [ SimpleDruidTestRTLCompiler >> gen_primitiveEqualsThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -3680,9 +3649,10 @@ SimpleDruidTestRTLCompiler >> gen_primitiveEqualsThanReferenceValue [ SimpleDruidTestRTLCompiler >> gen_primitiveEqualsThanValue [ "AutoGenerated by Druid" - | jumpNext currentBlock jumpTrue | + | jumpTrue jumpNext currentBlock s3 | self MoveR: ReceiverResultReg R: ClassReg. - self CmpCq: 0 R: ClassReg. + s3 := 0. + self CmpCq: s3 R: ClassReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: ClassReg. jumpNext := self Jump: 0. @@ -3754,9 +3724,9 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloat64AtPut [ SimpleDruidTestRTLCompiler >> gen_primitiveFloatAdd [ "AutoGenerated by Druid" - | jump1 jumpNext jump9 jump6 jump3 s119 s116 currentBlock jump8 jump5 jump2 jumpTrue jump7 jump4 | + | jump1 s123 jumpNext s98 s126 jump9 jump6 jump3 jump10 currentBlock s91 jump5 jump2 jump8 jumpTrue jump11 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. - self genLoadArgAtDepth: 0 into: SendNumArgsReg. + self genLoadArg: 0 into: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. self AndCq: 7 R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. @@ -3853,82 +3823,89 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatAdd [ self CmpCq: 896 R: SendNumArgsReg. jump8 := self JumpBelowOrEqual: 0. self CmpCq: 1151 R: SendNumArgsReg. - jumpTrue := self JumpBelowOrEqual: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump7 := self Jump: 0. + jump7 := self JumpBelowOrEqual: 0. + jump9 := self JumpAbove: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. self AndCq: 16rFFFFFFFFFFFFF R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. jump8 := self JumpNonZero: 0. - self CmpCq: 0 R: SendNumArgsReg. + s91 := 0. + self CmpCq: s91 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. - jump9 := self Jump: 0. + self CmpCq: 1 R: SendNumArgsReg. + jump10 := self JumpZero: 0. + jump11 := self JumpNonZero: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. - self CmpCq: 896 R: SendNumArgsReg. + s98 := 896. + self CmpCq: s98 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. + self CmpCq: 1 R: SendNumArgsReg. + jump8 := self JumpNonZero: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. currentBlock := self Label. jump7 jmpTarget: currentBlock. - self CmpCq: 1 R: SendNumArgsReg. - jump7 := self JumpNonZero: 0. self MoveRd: DPFPReg0 R: SendNumArgsReg. self RotateLeftCq: 1 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump9 := self JumpBelowOrEqual: 0. + jump7 := self JumpBelowOrEqual: 0. self SubCq: 16r7000000000000000 R: SendNumArgsReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 4 R: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump11 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. - s116 := objectMemory getScavengeThreshold. - self CmpCq: s116 R: Extra0Reg. - jump7 := self JumpAbove: 0. - s119 := 72057594205700130. - self MoveCq: s119 R: Extra0Reg. + s123 := objectMemory getScavengeThreshold. + self CmpCq: s123 R: Extra0Reg. + jump9 := self JumpAbove: 0. + s126 := 72057594205700130. + self MoveCq: s126 R: Extra0Reg. self MoveR: Extra0Reg M64: 0 r: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. self MoveR: Extra0Reg Aw: objectMemory freeStartAddress. self MoveRd: DPFPReg0 M64: 8 r: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. + currentBlock := self Label. jump5 jmpTarget: currentBlock. - jump7 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump6 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -3952,7 +3929,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatDivide [ SimpleDruidTestRTLCompiler >> gen_primitiveFloatEqual [ "AutoGenerated by Druid" - | jump1 jump6 jump3 currentBlock s82 jump8 jump5 s79 jump2 jump7 jump4 | + | jump1 s86 s83 jump6 jump3 currentBlock jump8 jump5 jump2 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self genLoadArg: 0 into: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. @@ -4045,23 +4022,26 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatEqual [ jump8 jmpTarget: currentBlock. self CmpRd: DPFPReg1 Rd: DPFPReg0. jump8 := self JumpFPNotEqual: 0. - s79 := objectMemory trueObject. - self MoveCq: s79 R: ReceiverResultReg. - jump7 := self Jump: 0. + s83 := objectMemory trueObject. + self MoveCq: s83 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump8 jmpTarget: currentBlock. - s82 := objectMemory falseObject. - self MoveCq: s82 R: ReceiverResultReg. - currentBlock := self Label. - jump7 jmpTarget: currentBlock. + s86 := objectMemory falseObject. + self MoveCq: s86 R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. jump6 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -4069,9 +4049,9 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatEqual [ SimpleDruidTestRTLCompiler >> gen_primitiveFloatMultiply [ "AutoGenerated by Druid" - | jump1 jumpNext jump9 jump6 jump3 s119 s116 currentBlock jump8 jump5 jump2 jumpTrue jump7 jump4 | + | jump1 s123 jumpNext s98 s126 jump9 jump6 jump3 jump10 currentBlock s91 jump5 jump2 jump8 jumpTrue jump11 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. - self genLoadArgAtDepth: 0 into: SendNumArgsReg. + self genLoadArg: 0 into: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. self AndCq: 7 R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. @@ -4168,82 +4148,89 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatMultiply [ self CmpCq: 896 R: SendNumArgsReg. jump8 := self JumpBelowOrEqual: 0. self CmpCq: 1151 R: SendNumArgsReg. - jumpTrue := self JumpBelowOrEqual: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump7 := self Jump: 0. + jump7 := self JumpBelowOrEqual: 0. + jump9 := self JumpAbove: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. self AndCq: 16rFFFFFFFFFFFFF R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. jump8 := self JumpNonZero: 0. - self CmpCq: 0 R: SendNumArgsReg. + s91 := 0. + self CmpCq: s91 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. - jump9 := self Jump: 0. + self CmpCq: 1 R: SendNumArgsReg. + jump10 := self JumpZero: 0. + jump11 := self JumpNonZero: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. - self CmpCq: 896 R: SendNumArgsReg. + s98 := 896. + self CmpCq: s98 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. + self CmpCq: 1 R: SendNumArgsReg. + jump8 := self JumpNonZero: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. currentBlock := self Label. jump7 jmpTarget: currentBlock. - self CmpCq: 1 R: SendNumArgsReg. - jump7 := self JumpNonZero: 0. self MoveRd: DPFPReg0 R: SendNumArgsReg. self RotateLeftCq: 1 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump9 := self JumpBelowOrEqual: 0. + jump7 := self JumpBelowOrEqual: 0. self SubCq: 16r7000000000000000 R: SendNumArgsReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 4 R: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump11 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. - s116 := objectMemory getScavengeThreshold. - self CmpCq: s116 R: Extra0Reg. - jump7 := self JumpAbove: 0. - s119 := 72057594205700130. - self MoveCq: s119 R: Extra0Reg. + s123 := objectMemory getScavengeThreshold. + self CmpCq: s123 R: Extra0Reg. + jump9 := self JumpAbove: 0. + s126 := 72057594205700130. + self MoveCq: s126 R: Extra0Reg. self MoveR: Extra0Reg M64: 0 r: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. self MoveR: Extra0Reg Aw: objectMemory freeStartAddress. self MoveRd: DPFPReg0 M64: 8 r: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. + currentBlock := self Label. jump5 jmpTarget: currentBlock. - jump7 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump6 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -4251,7 +4238,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatMultiply [ SimpleDruidTestRTLCompiler >> gen_primitiveFloatNotEqual [ "AutoGenerated by Druid" - | jump1 jump6 jump3 currentBlock s82 jump8 jump5 s79 jump2 jump7 jump4 | + | jump1 s86 s83 jump6 jump3 currentBlock jump8 jump5 jump2 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self genLoadArg: 0 into: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. @@ -4344,23 +4331,26 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatNotEqual [ jump8 jmpTarget: currentBlock. self CmpRd: DPFPReg1 Rd: DPFPReg0. jump8 := self JumpFPNotEqual: 0. - s79 := objectMemory falseObject. - self MoveCq: s79 R: ReceiverResultReg. - jump7 := self Jump: 0. + s83 := objectMemory falseObject. + self MoveCq: s83 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump8 jmpTarget: currentBlock. - s82 := objectMemory trueObject. - self MoveCq: s82 R: ReceiverResultReg. - currentBlock := self Label. - jump7 jmpTarget: currentBlock. + s86 := objectMemory trueObject. + self MoveCq: s86 R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump5 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. jump6 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -4368,9 +4358,9 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatNotEqual [ SimpleDruidTestRTLCompiler >> gen_primitiveFloatSubtract [ "AutoGenerated by Druid" - | jump1 jumpNext jump9 jump6 jump3 s119 s116 currentBlock jump8 jump5 jump2 jumpTrue jump7 jump4 | + | jump1 s123 jumpNext s98 s126 jump9 jump6 jump3 jump10 currentBlock s91 jump5 jump2 jump8 jumpTrue jump11 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. - self genLoadArgAtDepth: 0 into: SendNumArgsReg. + self genLoadArg: 0 into: SendNumArgsReg. self MoveR: ClassReg R: Extra0Reg. self AndCq: 7 R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. @@ -4467,82 +4457,89 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatSubtract [ self CmpCq: 896 R: SendNumArgsReg. jump8 := self JumpBelowOrEqual: 0. self CmpCq: 1151 R: SendNumArgsReg. - jumpTrue := self JumpBelowOrEqual: 0. - self MoveCq: 0 R: SendNumArgsReg. - jumpNext := self Jump: 0. - jumpTrue jmpTarget: self Label. - self MoveCq: 1 R: SendNumArgsReg. - jumpNext jmpTarget: self Label. - jump7 := self Jump: 0. + jump7 := self JumpBelowOrEqual: 0. + jump9 := self JumpAbove: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. self AndCq: 16rFFFFFFFFFFFFF R: Extra0Reg. self CmpCq: 0 R: Extra0Reg. jump8 := self JumpNonZero: 0. - self CmpCq: 0 R: SendNumArgsReg. + s91 := 0. + self CmpCq: s91 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. - jump9 := self Jump: 0. + self CmpCq: 1 R: SendNumArgsReg. + jump10 := self JumpZero: 0. + jump11 := self JumpNonZero: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. - self CmpCq: 896 R: SendNumArgsReg. + s98 := 896. + self CmpCq: s98 R: SendNumArgsReg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. jumpNext := self Jump: 0. jumpTrue jmpTarget: self Label. self MoveCq: 1 R: SendNumArgsReg. jumpNext jmpTarget: self Label. + self CmpCq: 1 R: SendNumArgsReg. + jump8 := self JumpNonZero: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. currentBlock := self Label. jump7 jmpTarget: currentBlock. - self CmpCq: 1 R: SendNumArgsReg. - jump7 := self JumpNonZero: 0. self MoveRd: DPFPReg0 R: SendNumArgsReg. self RotateLeftCq: 1 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump9 := self JumpBelowOrEqual: 0. + jump7 := self JumpBelowOrEqual: 0. self SubCq: 16r7000000000000000 R: SendNumArgsReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump9 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 4 R: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump8 := self Jump: 0. + jump10 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump11 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. + currentBlock := self Label. + jump9 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. - s116 := objectMemory getScavengeThreshold. - self CmpCq: s116 R: Extra0Reg. - jump7 := self JumpAbove: 0. - s119 := 72057594205700130. - self MoveCq: s119 R: Extra0Reg. + s123 := objectMemory getScavengeThreshold. + self CmpCq: s123 R: Extra0Reg. + jump9 := self JumpAbove: 0. + s126 := 72057594205700130. + self MoveCq: s126 R: Extra0Reg. self MoveR: Extra0Reg M64: 0 r: SendNumArgsReg. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. self AddCq: 16 R: Extra0Reg. self MoveR: Extra0Reg Aw: objectMemory freeStartAddress. self MoveRd: DPFPReg0 M64: 8 r: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. currentBlock := self Label. - jump8 jmpTarget: currentBlock. + jump10 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. + currentBlock := self Label. jump5 jmpTarget: currentBlock. - jump7 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump6 jmpTarget: currentBlock. + currentBlock := self Label. + jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -4550,7 +4547,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFloatSubtract [ SimpleDruidTestRTLCompiler >> gen_primitiveFullClosureValue [ "AutoGenerated by Druid" - | s2 currentBlock s22 s43 s3 | + | s51 s26 currentBlock s2 s3 | s2 := self methodNumArgs. s2 = 0 ifTrue: [ | jump1 jump2 jump3 jump4 | @@ -4578,46 +4575,52 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFullClosureValue [ self JumpR: ClassReg. self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. ^ 0 ]. - s22 := self methodNumArgs. - s22 = 1 ifTrue: [ - | jump4 jump3 jump2 jump1 | + s26 := self methodNumArgs. + s26 = 1 ifTrue: [ + | jump1 jump2 jump3 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self genLoadArg: 0 into: SendNumArgsReg. self MoveM64: 24 r: ClassReg R: SendNumArgsReg. self ArithmeticShiftRightCq: 3 R: SendNumArgsReg. self CmpCq: 1 R: SendNumArgsReg. - jump4 := self JumpNonZero: 0. + jump1 := self JumpNonZero: 0. self MoveM64: 16 r: ClassReg R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ClassReg. self AndCq: 7 R: ClassReg. self CmpCq: 0 R: ClassReg. - jump3 := self JumpNonZero: 0. + jump2 := self JumpNonZero: 0. self MoveM64: 0 r: SendNumArgsReg R: ClassReg. self LogicalShiftRightCq: 24 R: ClassReg. self AndCq: 31 R: ClassReg. self CmpCq: 24 R: ClassReg. - jump2 := self JumpBelow: 0. + jump3 := self JumpBelow: 0. self MoveM64: 8 r: SendNumArgsReg R: ClassReg. self AndCq: 1 R: ClassReg. self CmpCq: 0 R: ClassReg. - jump1 := self JumpNonZero: 0. + jump4 := self JumpNonZero: 0. self MoveM64: 8 r: SendNumArgsReg R: ClassReg. self AddCq: self fullBlockEntryOffset R: ClassReg. self JumpR: ClassReg. self genPrimReturn. currentBlock := self Label. jump4 jmpTarget: currentBlock. + currentBlock := self Label. jump3 jmpTarget: currentBlock. + currentBlock := self Label. jump2 jmpTarget: currentBlock. + currentBlock := self Label. jump1 jmpTarget: currentBlock. ^ 0 ]. - s43 := self methodNumArgs. - s43 = 2 ifTrue: [ + s51 := self methodNumArgs. + s51 = 2 ifTrue: [ | jump1 jump2 jump3 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self genLoadArg: 0 into: SendNumArgsReg. @@ -4645,10 +4648,13 @@ SimpleDruidTestRTLCompiler >> gen_primitiveFullClosureValue [ self JumpR: ClassReg. self genPrimReturn. currentBlock := self Label. - jump1 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. ^ 0 ]. ^ 0 ] @@ -4693,17 +4699,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterOrEqualThanValue [ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterOrEqualsThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLess: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4733,17 +4737,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterOrEqualsThanFloats [ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterOrEqualsThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreater: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4752,17 +4754,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterOrEqualsThanInverted [ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4789,18 +4789,16 @@ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterThanArgument [ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterThanBitAnd [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self AndCq: 16rFFFFFFFFFFFFFFFF R: ClassReg. self CmpCq: 1 R: ClassReg. jump1 := self JumpBelowOrEqual: 0. self MoveCq: 1 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 2 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4830,17 +4828,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterThanFloats [ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreaterOrEqual: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4868,7 +4864,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveGreaterThanReferenceValue [ SimpleDruidTestRTLCompiler >> gen_primitiveIdentityHash [ "AutoGenerated by Druid" - | jump1 jump2 jump3 currentBlock | + | jump1 jump2 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 7 R: ClassReg. jump1 := self JumpNonZero: 0. @@ -4884,14 +4880,12 @@ SimpleDruidTestRTLCompiler >> gen_primitiveIdentityHash [ self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump3 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump2 jmpTarget: currentBlock. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. @@ -4902,17 +4896,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveIdentityHash [ SimpleDruidTestRTLCompiler >> gen_primitiveIfFalseIfTrueReturningValue [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 57 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4921,17 +4913,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveIfFalseIfTrueReturningValue [ SimpleDruidTestRTLCompiler >> gen_primitiveIfTrueIfFalseAssigningValue [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 57 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4940,17 +4930,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveIfTrueIfFalseAssigningValue [ SimpleDruidTestRTLCompiler >> gen_primitiveIfTrueIfFalseReturningValue [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 57 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4959,17 +4947,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveIfTrueIfFalseReturningValue [ SimpleDruidTestRTLCompiler >> gen_primitiveIfTrueStatement [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 10 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -4978,23 +4964,27 @@ SimpleDruidTestRTLCompiler >> gen_primitiveIfTrueStatement [ SimpleDruidTestRTLCompiler >> gen_primitiveImmediateAsInteger [ "AutoGenerated by Druid" - | s59 s21 s40 s2 s24 currentBlock s56 s3 | + | s27 s60 s2 s24 currentBlock s63 s38 s3 | s2 := self methodNumArgs. s2 = 0 ifTrue: [ - | jump5 jump3 jump1 jump4 jump2 | + | jump1 jump2 jump3 | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 1 R: ClassReg. jump1 := self JumpZero: 0. self ArithmeticShiftRightCq: 3 R: ClassReg. self LogicalShiftLeftCq: 3 R: ClassReg. self AddCq: 1 R: ClassReg. - jump2 := self Jump: 0. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self TstCq: 2 R: ClassReg. jump1 := self JumpZero: 0. self LogicalShiftRightCq: 3 R: ClassReg. - jump3 := self Jump: 0. + self LogicalShiftLeftCq: 3 R: ClassReg. + self AddCq: 1 R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self TstCq: 4 R: ClassReg. @@ -5002,43 +4992,45 @@ SimpleDruidTestRTLCompiler >> gen_primitiveImmediateAsInteger [ self MoveR: ClassReg R: SendNumArgsReg. self LogicalShiftRightCq: 4 R: SendNumArgsReg. self TstCq: 8 R: ClassReg. - jump4 := self JumpZero: 0. - s21 := -1152921504606846976. - self MoveCq: s21 R: ClassReg. - jump5 := self Jump: 0. - currentBlock := self Label. - jump4 jmpTarget: currentBlock. - s24 := 0. + jump2 := self JumpZero: 0. + s24 := -1152921504606846976. self MoveCq: s24 R: ClassReg. + jump3 := self Jump: 0. currentBlock := self Label. - jump5 jmpTarget: currentBlock. - self AddR: ClassReg R: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ClassReg. + jump2 jmpTarget: currentBlock. + s27 := 0. + self MoveCq: s27 R: ClassReg. currentBlock := self Label. jump3 jmpTarget: currentBlock. + self AddR: ClassReg R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ClassReg. self LogicalShiftLeftCq: 3 R: ClassReg. self AddCq: 1 R: ClassReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. ^ 0 ]. - s40 := self methodNumArgs. - s40 = 1 ifTrue: [ - | jump5 jump3 jump1 jump4 jump2 | + s38 := self methodNumArgs. + s38 = 1 ifTrue: [ + | jump1 jump3 jump2 | self genLoadArg: 0 into: ClassReg. self TstCq: 1 R: ClassReg. jump1 := self JumpZero: 0. self ArithmeticShiftRightCq: 3 R: ClassReg. - jump2 := self Jump: 0. + self LogicalShiftLeftCq: 3 R: ClassReg. + self AddCq: 1 R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self TstCq: 2 R: ClassReg. jump1 := self JumpZero: 0. self LogicalShiftRightCq: 3 R: ClassReg. - jump3 := self Jump: 0. + self LogicalShiftLeftCq: 3 R: ClassReg. + self AddCq: 1 R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self TstCq: 4 R: ClassReg. @@ -5046,22 +5038,18 @@ SimpleDruidTestRTLCompiler >> gen_primitiveImmediateAsInteger [ self MoveR: ClassReg R: SendNumArgsReg. self LogicalShiftRightCq: 4 R: SendNumArgsReg. self TstCq: 8 R: ClassReg. - jump5 := self JumpZero: 0. - s56 := -1152921504606846976. - self MoveCq: s56 R: ClassReg. - jump4 := self Jump: 0. - currentBlock := self Label. - jump5 jmpTarget: currentBlock. - s59 := 0. - self MoveCq: s59 R: ClassReg. - currentBlock := self Label. - jump4 jmpTarget: currentBlock. - self AddR: ClassReg R: SendNumArgsReg. - self MoveR: SendNumArgsReg R: ClassReg. + jump3 := self JumpZero: 0. + s60 := -1152921504606846976. + self MoveCq: s60 R: ClassReg. + jump2 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. + s63 := 0. + self MoveCq: s63 R: ClassReg. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self AddR: ClassReg R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ClassReg. self LogicalShiftLeftCq: 3 R: ClassReg. self AddCq: 1 R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. @@ -5076,7 +5064,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveImmediateAsInteger [ SimpleDruidTestRTLCompiler >> gen_primitiveImplicitArgumentBitShiftLeft [ "AutoGenerated by Druid" - | jump1 s4 s10 currentBlock jump2 | + | jump1 s10 currentBlock s4 | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. @@ -5084,7 +5072,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveImplicitArgumentBitShiftLeft [ self MoveCq: s4 R: SendNumArgsReg. self LogicalShiftLeftR: ClassReg R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: ClassReg R: SendNumArgsReg. @@ -5093,8 +5081,6 @@ SimpleDruidTestRTLCompiler >> gen_primitiveImplicitArgumentBitShiftLeft [ self MoveCq: s10 R: ClassReg. self LogicalShiftRightR: SendNumArgsReg R: ClassReg. self MoveR: ClassReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5177,13 +5163,13 @@ SimpleDruidTestRTLCompiler >> gen_primitiveIntegerDivide [ | currentBlock | self MoveR: ReceiverResultReg R: ClassReg. - self genLoadArgAtDepth: 0 into: SendNumArgsReg. + self genLoadArg: 0 into: SendNumArgsReg. self DivR: SendNumArgsReg R: ClassReg - Quo: SendNumArgsReg - Rem: ClassReg. - self MoveR: SendNumArgsReg R: ReceiverResultReg. + Quo: ClassReg + Rem: SendNumArgsReg. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -5223,19 +5209,17 @@ SimpleDruidTestRTLCompiler >> gen_primitiveIntegerRawBitsAsFloat [ SimpleDruidTestRTLCompiler >> gen_primitiveIsIntegerObject [ "AutoGenerated by Druid" - | jump1 s4 currentBlock s7 jump2 | + | s7 jump1 currentBlock s4 | self MoveR: ReceiverResultReg R: ClassReg. self TstCq: 1 R: ClassReg. jump1 := self JumpZero: 0. s4 := objectMemory trueObject. self MoveCq: s4 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. s7 := objectMemory falseObject. self MoveCq: s7 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5292,17 +5276,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveLessOrEqualThanValue [ SimpleDruidTestRTLCompiler >> gen_primitiveLessOrEqualsThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreater: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5332,17 +5314,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveLessOrEqualsThanFloats [ SimpleDruidTestRTLCompiler >> gen_primitiveLessOrEqualsThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLess: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5351,17 +5331,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveLessOrEqualsThanInverted [ SimpleDruidTestRTLCompiler >> gen_primitiveLessThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreaterOrEqual: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5409,17 +5387,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveLessThanFloats [ SimpleDruidTestRTLCompiler >> gen_primitiveLessThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5541,13 +5517,13 @@ SimpleDruidTestRTLCompiler >> gen_primitiveMod [ | currentBlock | self MoveR: ReceiverResultReg R: ClassReg. - self genLoadArgAtDepth: 0 into: SendNumArgsReg. + self genLoadArg: 0 into: SendNumArgsReg. self DivR: SendNumArgsReg R: ClassReg - Quo: SendNumArgsReg - Rem: ClassReg. - self MoveR: ClassReg R: ReceiverResultReg. + Quo: ClassReg + Rem: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -5563,9 +5539,9 @@ SimpleDruidTestRTLCompiler >> gen_primitiveModByConstant [ self DivR: SendNumArgsReg R: ClassReg - Quo: SendNumArgsReg - Rem: ClassReg. - self MoveR: ClassReg R: ReceiverResultReg. + Quo: ClassReg + Rem: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -5624,7 +5600,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveMultiplyInverted [ SimpleDruidTestRTLCompiler >> gen_primitiveMultiplyWithOverflow [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self genLoadArg: 0 into: SendNumArgsReg. self ArithmeticShiftRightCq: 3 R: ClassReg. @@ -5632,13 +5608,11 @@ SimpleDruidTestRTLCompiler >> gen_primitiveMultiplyWithOverflow [ self MulR: ClassReg R: SendNumArgsReg. jump1 := self JumpMultiplyNoOverflow: 0. self MoveCq: 99 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -5660,7 +5634,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveNegated [ SimpleDruidTestRTLCompiler >> gen_primitiveNew [ "AutoGenerated by Druid" - | jump1 s28 jump6 b361 jump3 currentBlock jump8 jump5 jump2 s17 jump7 jump4 | + | s34 jump1 jump6 jump3 b349 currentBlock jump8 jump5 jump2 s23 jump7 jump4 | self SubCq: 8 R: SPReg. self MoveR: ReceiverResultReg R: ClassReg. self MoveM64: 24 r: ClassReg R: Extra3Reg. @@ -5684,21 +5658,27 @@ SimpleDruidTestRTLCompiler >> gen_primitiveNew [ self CmpCq: 0 R: ClassReg. jump1 := self JumpZero: 0. self CmpCq: 0 R: ClassReg. - jump3 := self JumpBelow: 0. + jump3 := self JumpAboveOrEqual: 0. + jump4 := self Jump: 0. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. self MoveMw: 0 r: SPReg R: Extra3Reg. self AndCq: 16rFFFF R: Extra3Reg. self MoveR: Extra3Reg Mw: 0 r: SPReg. self MoveMw: 0 r: SPReg R: Extra3Reg. self CmpCq: 255 R: Extra3Reg. - jump4 := self JumpAboveOrEqual: 0. + jump3 := self JumpBelow: 0. + jump5 := self Jump: 0. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. self MoveMw: 0 r: SPReg R: Extra3Reg. self CmpCq: 1 R: Extra3Reg. - jump5 := self JumpAboveOrEqual: 0. - s17 := 8. - self MoveCq: s17 R: Extra1Reg. + jump3 := self JumpAboveOrEqual: 0. + s23 := 8. + self MoveCq: s23 R: Extra1Reg. jump6 := self Jump: 0. currentBlock := self Label. - jump5 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. self MoveMw: 0 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: Extra1Reg. self LogicalShiftLeftCq: 3 R: Extra1Reg. @@ -5707,14 +5687,18 @@ SimpleDruidTestRTLCompiler >> gen_primitiveNew [ self AddCq: 8 R: Extra1Reg. self MoveAw: objectMemory freeStartAddress R: Extra2Reg. self AddR: Extra1Reg R: Extra2Reg. - s28 := objectMemory getScavengeThreshold. - self CmpCq: s28 R: Extra2Reg. + s34 := objectMemory getScavengeThreshold. + self CmpCq: s34 R: Extra2Reg. jump6 := self JumpBelowOrEqual: 0. - self CmpCq: s28 R: Extra2Reg. - jump5 := self JumpAbove: 0. + self CmpCq: s34 R: Extra2Reg. + jump3 := self JumpAbove: 0. + self MoveAw: objectMemory freeStartAddress R: Extra2Reg. + jump7 := self Jump: 0. currentBlock := self Label. jump6 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: Extra2Reg. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. self MoveMw: 0 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: SendNumArgsReg. self LogicalShiftLeftCq: 56 R: SendNumArgsReg. @@ -5727,7 +5711,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveNew [ self AddR: Extra1Reg R: SendNumArgsReg. self MoveR: SendNumArgsReg Aw: objectMemory freeStartAddress. self CmpCq: 0 R: Extra2Reg. - jump6 := self JumpZero: 0. + jump7 := self JumpZero: 0. self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. self MoveR: Extra2Reg R: Extra1Reg. self AddCq: 8 R: Extra1Reg. @@ -5739,26 +5723,30 @@ SimpleDruidTestRTLCompiler >> gen_primitiveNew [ self AddR: Extra3Reg R: ClassReg. self AddCq: 8 R: ClassReg. self SubCq: 1 R: ClassReg. - b361 := self Label. + b349 := self Label. self CmpR: Extra1Reg R: ClassReg. - jump7 := self JumpLess: 0. + jump6 := self JumpLess: 0. self MoveR: SendNumArgsReg M64: 0 r: Extra1Reg. self MoveR: Extra1Reg R: Extra0Reg. self AddCq: 8 R: Extra0Reg. self MoveR: Extra0Reg R: Extra1Reg. - jump8 := self Jump: b361. + jump8 := self Jump: b349. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. self MoveR: Extra2Reg R: ReceiverResultReg. self AddCq: 8 R: SPReg. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. jump5 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. self AddCq: 8 R: SPReg. ^ 0 ] @@ -6103,26 +6091,24 @@ SimpleDruidTestRTLCompiler >> gen_primitiveNextUint16At [ SimpleDruidTestRTLCompiler >> gen_primitiveNoopLoopWithInvariant [ "AutoGenerated by Druid" - | jump3 jump1 b17 currentBlock jump2 | + | jump3 jump1 currentBlock b18 jump2 | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpGreaterOrEqual: 0. - b17 := self Label. + b18 := self Label. self MoveR: ClassReg R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self CmpCq: 10 R: SendNumArgsReg. jump2 := self JumpGreaterOrEqual: 0. self MoveR: SendNumArgsReg R: ClassReg. - jump3 := self Jump: b17. + jump3 := self Jump: b18. currentBlock := self Label. jump2 jmpTarget: currentBlock. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 3 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6131,17 +6117,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveNoopLoopWithInvariant [ SimpleDruidTestRTLCompiler >> gen_primitiveNotEqualsThan [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpZero: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6171,17 +6155,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveNotEqualsThanFloats [ SimpleDruidTestRTLCompiler >> gen_primitiveNotEqualsThanInverted [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpZero: 0. self MoveCq: 5 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 11 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6190,21 +6172,37 @@ SimpleDruidTestRTLCompiler >> gen_primitiveNotEqualsThanInverted [ SimpleDruidTestRTLCompiler >> gen_primitiveOr [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 5 R: ClassReg. - jump1 := self JumpLess: 0. - self CmpCq: 10 R: ClassReg. - jump2 := self JumpLessOrEqual: 0. + jump1 := self JumpGreaterOrEqual: 0. + self MoveCq: 42 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. + self CmpCq: 10 R: ClassReg. + jump1 := self JumpLessOrEqual: 0. self MoveCq: 42 R: ReceiverResultReg. - jump1 := self Jump: 0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - self MoveCq: 10 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. + self MoveCq: 10 R: ReceiverResultReg. + self genPrimReturn. + ^ CompletePrimitive +] + +{ #category : #generated } +SimpleDruidTestRTLCompiler >> gen_primitivePlusFloatConstant [ + "AutoGenerated by Druid" + + | currentBlock | + self MoveR: ReceiverResultReg R: ClassReg. + self ConvertR: ClassReg Rd: DPFPReg0. + self MoveCq: (objectMemory rawFloatBitsOf: 3.14) R: ClassReg. + self MoveR: ClassReg Rd: DPFPReg1. + self AddRd: DPFPReg1 Rd: DPFPReg0. + self MoveRd: DPFPReg0 R: ClassReg. + self MoveR: ClassReg R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive ] @@ -6293,8 +6291,8 @@ SimpleDruidTestRTLCompiler >> gen_primitiveReturnOneWithArguments [ "AutoGenerated by Druid" | currentBlock | - self genLoadArgAtDepth: 0 into: ClassReg. - self genLoadArgAtDepth: 1 into: ClassReg. + self genLoadArg: 0 into: ClassReg. + self genLoadArg: 1 into: ClassReg. self MoveCq: 1 R: ReceiverResultReg. self genPrimReturn. ^ CompletePrimitive @@ -6327,29 +6325,21 @@ SimpleDruidTestRTLCompiler >> gen_primitiveRotateLeft [ SimpleDruidTestRTLCompiler >> gen_primitiveSandclock [ "AutoGenerated by Druid" - | jump1 s4 currentBlock s7 jump2 | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 10 R: ClassReg. jump1 := self JumpLessOrEqual: 0. - s4 := 1. - self MoveCq: s4 R: ClassReg. - jump2 := self Jump: 0. + self MoveCq: 6 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s7 := 99. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. - self MoveCq: s7 R: ClassReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - self AddCq: 5 R: ClassReg. - self MoveR: ClassReg R: ReceiverResultReg. - jump2 := self Jump: 0. + self MoveCq: 104 R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 116 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6358,7 +6348,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveSandclock [ SimpleDruidTestRTLCompiler >> gen_primitiveSize [ "AutoGenerated by Druid" - | jump1 s120 s89 jumpNext jump6 jump3 currentBlock jump8 jump5 jumpTrue jump2 jump7 jump4 | + | jump1 jumpNext jump6 jump3 s108 currentBlock jump8 jump5 jumpTrue jump2 s159 s14 jump7 jump4 | self MoveR: ReceiverResultReg R: ClassReg. self MoveR: ClassReg R: Extra1Reg. self CmpCq: 7 R: Extra1Reg. @@ -6375,8 +6365,9 @@ SimpleDruidTestRTLCompiler >> gen_primitiveSize [ jump1 jmpTarget: currentBlock. self MoveM64: 0 r: ClassReg R: Extra1Reg. self AndCq: 16r3FFFF7 R: Extra1Reg. + s14 := 0. self MoveR: Extra1Reg R: Extra2Reg. - self CmpCq: 0 R: Extra2Reg. + self CmpCq: s14 R: Extra2Reg. jumpTrue := self JumpZero: 0. self MoveCq: 0 R: Extra2Reg. jumpNext := self Jump: 0. @@ -6415,9 +6406,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveSize [ self MoveMb: 7 r: ClassReg R: Extra2Reg. self AndCq: 255 R: Extra2Reg. self CmpCq: 255 R: Extra2Reg. - jump4 := self JumpZero: 0. + jump4 := self JumpNonZero: 0. + self MoveM64: -8 r: ClassReg R: Extra2Reg. + self LogicalShiftLeftCq: 8 R: Extra2Reg. + self LogicalShiftRightCq: 8 R: Extra2Reg. jump5 := self Jump: 0. currentBlock := self Label. + jump4 jmpTarget: currentBlock. + jump4 := self Jump: 0. + currentBlock := self Label. jump3 jmpTarget: currentBlock. self MoveMb: 7 r: ClassReg R: Extra2Reg. self AndCq: 255 R: Extra2Reg. @@ -6427,127 +6424,148 @@ SimpleDruidTestRTLCompiler >> gen_primitiveSize [ self LogicalShiftLeftCq: 8 R: Extra2Reg. self LogicalShiftRightCq: 8 R: Extra2Reg. self CmpCq: 5 R: Extra0Reg. - jump6 := self JumpBelowOrEqual: 0. - jump7 := self Jump: 0. + jump6 := self JumpAbove: 0. + currentBlock := self Label. + jump5 jmpTarget: currentBlock. + jump5 := self Jump: 0. + currentBlock := self Label. + jump6 jmpTarget: currentBlock. + jump6 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. self CmpCq: 5 R: Extra0Reg. jump3 := self JumpAbove: 0. currentBlock := self Label. - jump5 jmpTarget: currentBlock. - currentBlock := self Label. jump4 jmpTarget: currentBlock. - jump6 jmpTarget: currentBlock. - jump6 := self Jump: 0. + currentBlock := self Label. + jump5 jmpTarget: currentBlock. + jump5 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. self CmpCq: 16 R: Extra0Reg. - jump7 := self JumpBelow: 0. + jump6 := self JumpBelow: 0. self LogicalShiftLeftCq: 3 R: Extra2Reg. self MoveR: Extra0Reg R: SendNumArgsReg. self AndCq: 7 R: SendNumArgsReg. self SubR: SendNumArgsReg R: Extra2Reg. jump3 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. self CmpCq: 12 R: Extra0Reg. - jump7 := self JumpBelow: 0. + jump6 := self JumpBelow: 0. self LogicalShiftLeftCq: 2 R: Extra2Reg. self MoveR: Extra0Reg R: SendNumArgsReg. self AndCq: 3 R: SendNumArgsReg. self SubR: SendNumArgsReg R: Extra2Reg. jump4 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. self CmpCq: 10 R: Extra0Reg. - jump7 := self JumpBelow: 0. + jump6 := self JumpBelow: 0. self LogicalShiftLeftCq: 1 R: Extra2Reg. self MoveR: Extra0Reg R: SendNumArgsReg. self AndCq: 1 R: SendNumArgsReg. self SubR: SendNumArgsReg R: Extra2Reg. - jump5 := self Jump: 0. + jump7 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. + jump6 jmpTarget: currentBlock. self CmpCq: 9 R: Extra0Reg. - jump7 := self JumpNonZero: 0. + jump6 := self JumpNonZero: 0. jump8 := self Jump: 0. currentBlock := self Label. - jump7 jmpTarget: currentBlock. - s89 := 0. - self MoveCq: s89 R: Extra2Reg. - currentBlock := self Label. jump6 jmpTarget: currentBlock. + s108 := 0. + self MoveCq: s108 R: Extra2Reg. + currentBlock := self Label. + jump5 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. - jump5 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. jump8 jmpTarget: currentBlock. self CmpCq: 9 R: Extra0Reg. - jump8 := self JumpAboveOrEqual: 0. - self CmpCq: 2 R: Extra0Reg. - jump5 := self JumpNonZero: 0. + jump8 := self JumpBelow: 0. + self SubCq: 0 R: Extra2Reg. + self MoveR: Extra2Reg R: SendNumArgsReg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: 1 R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. jump8 jmpTarget: currentBlock. + self CmpCq: 2 R: Extra0Reg. + jump8 := self JumpNonZero: 0. self SubCq: 0 R: Extra2Reg. self MoveR: Extra2Reg R: SendNumArgsReg. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump8 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump5 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. self CmpCq: 2 R: Extra0Reg. - jump5 := self JumpAboveOrEqual: 0. + jump8 := self JumpAboveOrEqual: 0. self SubR: Extra2Reg R: Extra2Reg. self MoveR: Extra2Reg R: SendNumArgsReg. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddCq: 1 R: SendNumArgsReg. self MoveR: SendNumArgsReg R: ReceiverResultReg. - jump4 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. - jump5 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. self MoveM64: 0 r: ClassReg R: SendNumArgsReg. self AndCq: 16r3FFFFF R: SendNumArgsReg. self CmpCq: 31 R: SendNumArgsReg. - jump5 := self JumpAbove: 0. + jump8 := self JumpAbove: 0. self CmpCq: 31 R: SendNumArgsReg. - jump3 := self JumpNonZero: 0. - self MoveR: ClassReg R: SendNumArgsReg. - jump6 := self Jump: 0. + jump7 := self JumpNonZero: 0. + self MoveM64: 24 r: ClassReg R: SendNumArgsReg. + self ArithmeticShiftRightCq: 3 R: SendNumArgsReg. + self AndCq: 16rFFFF R: SendNumArgsReg. + self SubR: SendNumArgsReg R: Extra2Reg. + self MoveR: Extra2Reg R: SendNumArgsReg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: 1 R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. self CmpCq: 8 R: SendNumArgsReg. - jump3 := self JumpNonZero: 0. + jump7 := self JumpNonZero: 0. self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. - jump7 := self Jump: 0. + self MoveM64: 24 r: SendNumArgsReg R: SendNumArgsReg. + self ArithmeticShiftRightCq: 3 R: SendNumArgsReg. + self AndCq: 16rFFFF R: SendNumArgsReg. + self SubR: SendNumArgsReg R: Extra2Reg. + self MoveR: Extra2Reg R: SendNumArgsReg. + self LogicalShiftLeftCq: 3 R: SendNumArgsReg. + self AddCq: 1 R: SendNumArgsReg. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + self genPrimReturn. currentBlock := self Label. - jump5 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. + jump8 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: ClassReg. self LogicalShiftRightCq: 10 R: ClassReg. - s120 := objectMemory hiddenRootsObject. + s159 := objectMemory hiddenRootsObject. self LogicalShiftLeftCq: 3 R: ClassReg. - self AddCq: s120 R: ClassReg. + self AddCq: s159 R: ClassReg. self MoveM64: 8 r: ClassReg R: ClassReg. self genMoveConstant: objectMemory nilObject R: Extra0Reg. self CmpR: Extra0Reg R: ClassReg. - jump3 := self JumpNonZero: 0. + jump7 := self JumpNonZero: 0. self genMoveConstant: objectMemory nilObject R: Extra0Reg. - jump5 := self Jump: 0. + jump8 := self Jump: 0. currentBlock := self Label. - jump3 jmpTarget: currentBlock. + jump7 jmpTarget: currentBlock. self AndCq: 1023 R: SendNumArgsReg. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. self AddR: SendNumArgsReg R: ClassReg. self MoveM64: 8 r: ClassReg R: Extra0Reg. currentBlock := self Label. - jump5 jmpTarget: currentBlock. - self MoveR: Extra0Reg R: SendNumArgsReg. - currentBlock := self Label. - jump6 jmpTarget: currentBlock. - jump7 jmpTarget: currentBlock. - self MoveM64: 24 r: SendNumArgsReg R: Extra0Reg. + jump8 jmpTarget: currentBlock. + self MoveM64: 24 r: Extra0Reg R: Extra0Reg. self ArithmeticShiftRightCq: 3 R: Extra0Reg. self AndCq: 16rFFFF R: Extra0Reg. self SubR: Extra0Reg R: Extra2Reg. @@ -6555,13 +6573,11 @@ SimpleDruidTestRTLCompiler >> gen_primitiveSize [ self LogicalShiftLeftCq: 3 R: Extra0Reg. self AddCq: 1 R: Extra0Reg. self MoveR: Extra0Reg R: ReceiverResultReg. - currentBlock := self Label. - jump8 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. self genPrimReturn. currentBlock := self Label. - jump2 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. ^ 0 ] @@ -6633,19 +6649,17 @@ SimpleDruidTestRTLCompiler >> gen_primitiveSmallThan [ SimpleDruidTestRTLCompiler >> gen_primitiveSubWithOverflow [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self genLoadArg: 0 into: SendNumArgsReg. self AddCq: -1 R: SendNumArgsReg. self SubR: SendNumArgsReg R: ClassReg. jump1 := self JumpNoOverflow: 0. self MoveCq: 99 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: ClassReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6654,19 +6668,17 @@ SimpleDruidTestRTLCompiler >> gen_primitiveSubWithOverflow [ SimpleDruidTestRTLCompiler >> gen_primitiveSumWithOverflow [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self genLoadArg: 0 into: SendNumArgsReg. self AddCq: -1 R: ClassReg. self AddR: SendNumArgsReg R: ClassReg. jump1 := self JumpNoOverflow: 0. self MoveCq: 99 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: ClassReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6800,21 +6812,29 @@ SimpleDruidTestRTLCompiler >> gen_primitiveUint8AtPut [ ^ CompletePrimitive ] +{ #category : #generated } +SimpleDruidTestRTLCompiler >> gen_primitiveWithConditionalCompilation [ + "AutoGenerated by Druid" + + | currentBlock | + self MoveCq: 17 R: ReceiverResultReg. + self genPrimReturn. + ^ CompletePrimitive +] + { #category : #generated } SimpleDruidTestRTLCompiler >> gen_primitiveWithDeadCode [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpNonZero: 0. self MoveCq: 42 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 55 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6842,17 +6862,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveWithIfAssigningValue [ SimpleDruidTestRTLCompiler >> gen_primitiveWithIfNilIfNotNilStatement [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6861,17 +6879,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveWithIfNilIfNotNilStatement [ SimpleDruidTestRTLCompiler >> gen_primitiveWithIfNotNilIfNilStatement [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6880,17 +6896,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveWithIfNotNilIfNilStatement [ SimpleDruidTestRTLCompiler >> gen_primitiveWithIfNotNilIfNilStatementWithArgument [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6899,17 +6913,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveWithIfNotNilIfNilStatementWithArgumen SimpleDruidTestRTLCompiler >> gen_primitiveWithIfNotNilStatement [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveCq: 17 R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveCq: 42 R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] @@ -6960,19 +6972,17 @@ SimpleDruidTestRTLCompiler >> gen_primitiveWithSequentialExitPoint [ SimpleDruidTestRTLCompiler >> gen_primitiveWithTwoArgs [ "AutoGenerated by Druid" - | jump1 jump2 currentBlock | + | jump1 currentBlock | self MoveR: ReceiverResultReg R: ClassReg. self genLoadArg: 0 into: SendNumArgsReg. self genLoadArg: 1 into: Extra0Reg. self CmpCq: 0 R: ClassReg. jump1 := self JumpLessOrEqual: 0. self MoveR: Extra0Reg R: ReceiverResultReg. - jump2 := self Jump: 0. + self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. self MoveR: SendNumArgsReg R: ReceiverResultReg. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. self genPrimReturn. ^ CompletePrimitive ] diff --git a/Druid/DRAbstractInstruction.class.st b/Druid/DRAbstractInstruction.class.st index 789d13af..1bc52026 100644 --- a/Druid/DRAbstractInstruction.class.st +++ b/Druid/DRAbstractInstruction.class.st @@ -150,6 +150,12 @@ DRAbstractInstruction >> isNegate [ ^ false ] +{ #category : #testing } +DRAbstractInstruction >> isPrimitiveFail [ + + ^ false +] + { #category : #testing } DRAbstractInstruction >> isStackEffect [ diff --git a/Druid/DRBasicBlock.class.st b/Druid/DRBasicBlock.class.st index 498090eb..5c1e06f1 100644 --- a/Druid/DRBasicBlock.class.st +++ b/Druid/DRBasicBlock.class.st @@ -1378,15 +1378,14 @@ DRBasicBlock >> successors [ { #category : #transformations } DRBasicBlock >> tailDuplicate [ - "Duplicate the receiver so there is a different copy of it for each predecessor" | duplicatedBlocks | - duplicatedBlocks := self predecessors allButFirst collect: [ - :predecessorToRewire | + duplicatedBlocks := self predecessors allButFirst collect: [ + :predecessorToRewire | self splitTo: predecessorToRewire ]. - self assert: (duplicatedBlocks allSatisfy: [ :b | + self assert: (duplicatedBlocks allSatisfy: [ :b | b instructions size = self instructions size ]). controlFlowGraph validate. diff --git a/Druid/DRBlockDuplicator.class.st b/Druid/DRBlockDuplicator.class.st index 3b038b79..8f1e7c43 100644 --- a/Druid/DRBlockDuplicator.class.st +++ b/Druid/DRBlockDuplicator.class.st @@ -80,7 +80,6 @@ DRBlockDuplicator >> patchControlFlowIn: aBasicBlock [ { #category : #'editing keys' } DRBlockDuplicator >> patchInstructionsIn: aBasicBlock [ "Replace all users and dependencies of block instructions using the instructionMap" - aBasicBlock instructions do: [ :newInstruction | newInstruction users copy do: [ :user | | replacement | "If an user comes from another block, keep using it" diff --git a/Druid/DRBytecodeIRGenerator.class.st b/Druid/DRBytecodeIRGenerator.class.st index b147b9d1..c6ede80e 100644 --- a/Druid/DRBytecodeIRGenerator.class.st +++ b/Druid/DRBytecodeIRGenerator.class.st @@ -19,8 +19,10 @@ DRBytecodeIRGenerator >> addAnnotateBytecode: aRBMethodNode [ { #category : #visiting } DRBytecodeIRGenerator >> finishCodeInterpretation: lastFrame [ -1halt. - currentBasicBlock jumpTo: controlFlowGraph exitBasicBlock + + "If this is the base frame, it should continue with the next bytecode at the end" + currentBasicBlock endInstruction: + (self instantiateNoResultInstruction: DRContinueNextBytecode) ] { #category : #initialization } @@ -466,20 +468,6 @@ DRBytecodeIRGenerator >> push: aValue [ ^ self popOperand ] -{ #category : #'stack management' } -DRBytecodeIRGenerator >> pushFrameForCode: aDRCode receiver: aReceiver [ - - | frame | - frame := super pushFrameForCode: aDRCode receiver: aReceiver. -1halt. - "If this is the base frame, it should continue with the next bytecode at the end" - executionState baseFrame = frame ifTrue: [ - frame exitBasicBlock endInstruction: - (self instantiateNoResultInstruction: DRContinueNextBytecode) ]. - - ^ frame -] - { #category : #accessing } DRBytecodeIRGenerator >> receiver: aDRValue [ ] diff --git a/Druid/DRCogitPrimitiveCodeGenerator.class.st b/Druid/DRCogitPrimitiveCodeGenerator.class.st index e6d240d3..1076ab81 100644 --- a/Druid/DRCogitPrimitiveCodeGenerator.class.st +++ b/Druid/DRCogitPrimitiveCodeGenerator.class.st @@ -22,10 +22,8 @@ DRCogitPrimitiveCodeGenerator >> linearizeBlocksInCFG: aControlFlowGraph [ linearizedBlocks := super linearizeBlocksInCFG: aControlFlowGraph. "Make sure the failure exit block is at the end, so it works as a fallthrough with the following bytecode" - (linearizedBlocks includes: aControlFlowGraph failureExitBlock) - ifTrue: [ - linearizedBlocks remove: aControlFlowGraph failureExitBlock. - linearizedBlocks addLast: aControlFlowGraph failureExitBlock ]. + linearizedBlocks removeAll: aControlFlowGraph failureExitBlocks. + linearizedBlocks addAllLast: aControlFlowGraph failureExitBlocks. ^ linearizedBlocks ] @@ -33,10 +31,12 @@ DRCogitPrimitiveCodeGenerator >> linearizeBlocksInCFG: aControlFlowGraph [ { #category : #'ir-to-ast' } DRCogitPrimitiveCodeGenerator >> returnNodeForCompiledMethod: aDRControlFlowGraph [ - | primitiveFail isCompletePrimitive | - primitiveFail := aDRControlFlowGraph failureExitBlock instructions - unique. - isCompletePrimitive := primitiveFail operand1 value. + | isCompletePrimitive | + isCompletePrimitive := aDRControlFlowGraph failureExitBlocks + allSatisfy: [ :b | + | primitiveFail | + primitiveFail := b endInstruction. + primitiveFail operand1 value ]. isCompletePrimitive ifTrue: [ ^ RBVariableNode named: 'CompletePrimitive' ]. diff --git a/Druid/DRControlFlowGraph.class.st b/Druid/DRControlFlowGraph.class.st index 588ce085..d3d12d86 100644 --- a/Druid/DRControlFlowGraph.class.st +++ b/Druid/DRControlFlowGraph.class.st @@ -518,7 +518,7 @@ DRControlFlowGraph >> initialize [ "How many spill slots we need in memory to execute the compiled method" numberOfSpillSlots := 0. - nextBasicBlockId := -1. + nextBasicBlockId := 0. initialBasicBlock := self privateNewBasicBlock ] diff --git a/Druid/DRDivision.class.st b/Druid/DRDivision.class.st index 13425c72..f2c5ae89 100644 --- a/Druid/DRDivision.class.st +++ b/Druid/DRDivision.class.st @@ -22,12 +22,6 @@ DRDivision >> opcode [ ^ 'DIV' ] -{ #category : #accessing } -DRDivision >> operands: aCollection [ - - super operands: aCollection asOrderedCollection -] - { #category : #SCCP } DRDivision >> sccpOperateOnLattice: operand and: operand2 [ diff --git a/Druid/DRInstruction.class.st b/Druid/DRInstruction.class.st index 6ae241e1..aa110a7a 100644 --- a/Druid/DRInstruction.class.st +++ b/Druid/DRInstruction.class.st @@ -441,7 +441,7 @@ DRInstruction >> operands [ DRInstruction >> operands: aCollection [ operands asSet do: [ :each | each removeUser: self ]. - operands := aCollection collect: [:e | e asDRValue ]. + operands := aCollection collect: [:e | e asDRValue ] as: OrderedCollection. self dependencies asSet do: [ :each | each addUser: self ] ] diff --git a/Druid/DRInstructionFactory.class.st b/Druid/DRInstructionFactory.class.st index 710ea6ca..3d0b499d 100644 --- a/Druid/DRInstructionFactory.class.st +++ b/Druid/DRInstructionFactory.class.st @@ -279,7 +279,7 @@ DRInstructionFactory >> push: operand [ ^ DRPush operands: { operand asDRValue } - result: self allocateTemporaryRegister + result: DRNoRegister new ] { #category : #factory } @@ -290,7 +290,7 @@ DRInstructionFactory >> pushBase: base offset: offset [ base: base; offset: offset; yourself) } - result: self allocateTemporaryRegister + result: DRNoRegister new ] { #category : #building } diff --git a/Druid/DRLoop.class.st b/Druid/DRLoop.class.st index 3f9087f3..9b9808a5 100644 --- a/Druid/DRLoop.class.st +++ b/Druid/DRLoop.class.st @@ -233,7 +233,8 @@ DRLoop >> loopConditional [ DRLoop >> loopGraph [ ^ self controlFlowGraph - subgraphBetween: self headerBlock and: self latchBlock + blocksBetween: self headerBlock + and: self latchBlock ] { #category : #'cfg manipulation' } diff --git a/Druid/DRPhiFunction.class.st b/Druid/DRPhiFunction.class.st index ddd648eb..b61e189f 100644 --- a/Druid/DRPhiFunction.class.st +++ b/Druid/DRPhiFunction.class.st @@ -152,12 +152,6 @@ DRPhiFunction >> opcode [ ] -{ #category : #accessing } -DRPhiFunction >> operands: aCollection [ - - super operands: aCollection asOrderedCollection -] - { #category : #accessing } DRPhiFunction >> predecessorAtOperand: anOperand [ diff --git a/Druid/DRPrimitiveCompilerCompiler.class.st b/Druid/DRPrimitiveCompilerCompiler.class.st index 9730c8fc..a150f900 100644 --- a/Druid/DRPrimitiveCompilerCompiler.class.st +++ b/Druid/DRPrimitiveCompilerCompiler.class.st @@ -69,7 +69,7 @@ DRPrimitiveCompilerCompiler >> generateCheckForNumArgs: numArgs [ block jumpIf: checkArgCount to: irGenerator newBasicBlock "Continue the interpretation from here" - ifFalseTo: block controlFlowGraph failureExitBlock. + ifFalseTo: irGenerator failureExitBlock. ^ block ] diff --git a/Druid/DRPrimitiveControlFlowGraph.class.st b/Druid/DRPrimitiveControlFlowGraph.class.st index 356c6209..efd98759 100644 --- a/Druid/DRPrimitiveControlFlowGraph.class.st +++ b/Druid/DRPrimitiveControlFlowGraph.class.st @@ -8,7 +8,6 @@ Class { #superclass : #DRControlFlowGraph, #instVars : [ 'successExitBlock', - 'failureExitBlock', 'primitiveExitBlock' ], #category : #'Druid-IR' @@ -17,13 +16,16 @@ Class { { #category : #accessing } DRPrimitiveControlFlowGraph >> failureExitBlock [ - ^ failureExitBlock + | blocks | + blocks := self failureExitBlocks. + self assert: blocks size = 1. + ^ blocks anyOne ] { #category : #accessing } -DRPrimitiveControlFlowGraph >> failureExitBlock: anObject [ +DRPrimitiveControlFlowGraph >> failureExitBlocks [ - failureExitBlock := anObject + ^ self blocks select: [ :e | e endInstruction isPrimitiveFail ] ] { #category : #accessing } diff --git a/Druid/DRPrimitiveFail.class.st b/Druid/DRPrimitiveFail.class.st index 01e98255..bb060d07 100644 --- a/Druid/DRPrimitiveFail.class.st +++ b/Druid/DRPrimitiveFail.class.st @@ -10,6 +10,12 @@ DRPrimitiveFail >> isMandatoryInstruction [ ^ true ] +{ #category : #testing } +DRPrimitiveFail >> isPrimitiveFail [ + + ^ true +] + { #category : #testing } DRPrimitiveFail >> opcode [ diff --git a/Druid/DRPrimitiveIRGenerator.class.st b/Druid/DRPrimitiveIRGenerator.class.st index d4ba7a5d..60dabbd0 100644 --- a/Druid/DRPrimitiveIRGenerator.class.st +++ b/Druid/DRPrimitiveIRGenerator.class.st @@ -7,7 +7,8 @@ Class { #name : #DRPrimitiveIRGenerator, #superclass : #DRMetaCompilerIRGenerator, #instVars : [ - 'completePrimitive' + 'completePrimitive', + 'failureExitBlock' ], #category : #'Druid-CompilerCompiler' } @@ -33,6 +34,11 @@ DRPrimitiveIRGenerator >> executeFullCogBlockClosureMayContextSwitchWith: aRBMes offsetSelector } ] +{ #category : #accessing } +DRPrimitiveIRGenerator >> failureExitBlock [ + ^ failureExitBlock +] + { #category : #visiting } DRPrimitiveIRGenerator >> finishCodeInterpretation: lastFrame [ "Plug the IR with the two exit blocks" @@ -53,8 +59,8 @@ DRPrimitiveIRGenerator >> finishCodeInterpretation: lastFrame [ conditionalJump trueBranch: controlFlowGraph successExitBlock. controlFlowGraph successExitBlock addPredecessor: currentBasicBlock. - conditionalJump falseBranch: controlFlowGraph failureExitBlock. - controlFlowGraph failureExitBlock addPredecessor: currentBasicBlock. + conditionalJump falseBranch: failureExitBlock. + failureExitBlock addPredecessor: currentBasicBlock. "Return N elements in the stack" controlFlowGraph successExitBlock endInstruction: (self @@ -62,7 +68,7 @@ DRPrimitiveIRGenerator >> finishCodeInterpretation: lastFrame [ operands: { (DRConstantValue value: numberOfArguments + 1) }). "Return failure (compilation) code" - controlFlowGraph failureExitBlock endInstruction: (self + failureExitBlock endInstruction: (self instantiateNoResultInstruction: DRPrimitiveFail operands: { completePrimitive asDRValue }) ] @@ -81,8 +87,8 @@ DRPrimitiveIRGenerator >> initialize [ completePrimitive := true. controlFlowGraph successExitBlock:controlFlowGraph newBasicBlock. controlFlowGraph successExitBlock beExitBlock. - controlFlowGraph failureExitBlock: controlFlowGraph newBasicBlock. - controlFlowGraph failureExitBlock beExitBlock. + failureExitBlock := controlFlowGraph newBasicBlock. + failureExitBlock beExitBlock. ] { #category : #'special cases' } diff --git a/Druid/DRPush.class.st b/Druid/DRPush.class.st index 483df15b..51e57d27 100644 --- a/Druid/DRPush.class.st +++ b/Druid/DRPush.class.st @@ -22,6 +22,14 @@ DRPush >> opcode [ ^ 'Push' ] +{ #category : #copying } +DRPush >> postCopy [ + + super postCopy. + self operand1 isMemoryAddress ifTrue: [ + self operand1: self operand1 copy ] +] + { #category : #removing } DRPush >> removeFromCFG [ From a1d7450e48ca503acf736503c069395e7141f460 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Thu, 25 Apr 2024 13:58:06 +0200 Subject: [PATCH 17/33] Fix tail duplication in presence of staged registers --- Druid-Tests/DRLinearizationTest.class.st | 6 +++--- Druid-Tests/DRTailDuplicationTest.class.st | 15 +++++++++++++++ Druid-Tests/DruidTestRTLCompiler.class.st | 16 +++++++++++++++- Druid/DRInstruction.class.st | 7 +++---- Druid/DRLinearScanRegisterAllocator.class.st | 10 +++++----- Druid/DRSCCP.class.st | 2 +- Druid/DRSSARegister.class.st | 12 ++++++------ Druid/DRStager.class.st | 2 +- Druid/DRValue.class.st | 12 ++++++------ 9 files changed, 55 insertions(+), 27 deletions(-) diff --git a/Druid-Tests/DRLinearizationTest.class.st b/Druid-Tests/DRLinearizationTest.class.st index 1868526d..f0f12350 100644 --- a/Druid-Tests/DRLinearizationTest.class.st +++ b/Druid-Tests/DRLinearizationTest.class.st @@ -181,7 +181,7 @@ DRLinearizationTest >> testBuildCFGHasAllBlocks [ cfg applyOptimisation: DRCleanControlFlow new. self assert: cfg reversePostOrderBlocks size equals: 7 + 1. - self assert: cfg instructions size equals: 21 + self assert: cfg instructions size equals: 22 ] { #category : #'tests-building' } @@ -196,7 +196,7 @@ DRLinearizationTest >> testBuildCFGHasAllBlocksWhenEarlyMethodReturns [ cfg applyOptimisation: DRCleanControlFlow new. self assert: cfg reversePostOrderBlocks size equals: 8. - self assert: cfg instructions size equals: 21 + self assert: cfg instructions size equals: 22 ] { #category : #'tests-building' } @@ -213,7 +213,7 @@ DRLinearizationTest >> testBuildCFGHasAllBlocksWithTwoNonLocalReturns [ DRDeadBlockElimination new applyTo: cfg. self assert: cfg reversePostOrderBlocks size equals: 8. - self assert: cfg instructions size equals: 21 + self assert: cfg instructions size equals: 22 ] { #category : #'tests-building' } diff --git a/Druid-Tests/DRTailDuplicationTest.class.st b/Druid-Tests/DRTailDuplicationTest.class.st index 41373577..71458b4b 100644 --- a/Druid-Tests/DRTailDuplicationTest.class.st +++ b/Druid-Tests/DRTailDuplicationTest.class.st @@ -363,6 +363,21 @@ DRTailDuplicationTest >> testTailDuplicateInsertingPhiInDegenerateControlFlow [ ] +{ #category : #tests } +DRTailDuplicationTest >> testTailDuplicateMaintainsStagedRegisters [ + + | cfg newBlock stagedRegister duplicated | + cfg := self setUpCFGWithConditional. + stagedRegister := DRStagedRegister name: 'staged'. + (cfg b4 copy: 1) result: stagedRegister. + + duplicated := cfg b4 tailDuplicate. + cfg validate. + + self assert: duplicated first firstInstruction result equals: stagedRegister. + self assert: duplicated second firstInstruction result equals: stagedRegister. +] + { #category : #tests } DRTailDuplicationTest >> testTailDuplicateOnLoop [ diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index 937162b0..89ca4ebd 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -1302,7 +1302,7 @@ DruidTestRTLCompiler >> gen_emptyPrimitiveWithArguments [ DruidTestRTLCompiler >> gen_extBBytecode [ "AutoGenerated by Druid" - | s8 s6 s4 s2 currentBlock s9 live s3 | + | s6 s3 s16 s13 s22 s25 s8 s2 currentBlock s12 s21 s24 s4 s17 s14 live s20 s9 | live := 0. s2 := byte1. s3 := numExtB. @@ -1314,7 +1314,21 @@ DruidTestRTLCompiler >> gen_extBBytecode [ s9 := s8 + 1. numExtB := s9. ^ 0 ]. + s12 := extB. + s13 := s12 << 8. + s14 := s13 + s2. + extB := s14. + s16 := numExtB. + s17 := s16 + 1. + numExtB := s17. ^ 0 ]. + s20 := extB. + s21 := s20 << 8. + s22 := s21 + s2. + extB := s22. + s24 := numExtB. + s25 := s24 + 1. + numExtB := s25. ^ 0 ] diff --git a/Druid/DRInstruction.class.st b/Druid/DRInstruction.class.st index aa110a7a..ff347292 100644 --- a/Druid/DRInstruction.class.st +++ b/Druid/DRInstruction.class.st @@ -492,14 +492,13 @@ DRInstruction >> originAST: aNode [ DRInstruction >> postCopy [ super postCopy. - + operands := operands copy. operands do: [ :e | e addUser: self ]. users := users copy. - - ((result isKindOf: DRNoRegister) not and: [ result isPhysicalRegister not ]) ifTrue: [ - result := basicBlock controlFlowGraph allocateTemporaryRegister ]. + result isSSARegister ifTrue: [ + result := basicBlock controlFlowGraph allocateTemporaryRegister ] ] { #category : #printing } diff --git a/Druid/DRLinearScanRegisterAllocator.class.st b/Druid/DRLinearScanRegisterAllocator.class.st index 46ae7c7e..dc3d3487 100644 --- a/Druid/DRLinearScanRegisterAllocator.class.st +++ b/Druid/DRLinearScanRegisterAllocator.class.st @@ -142,7 +142,7 @@ DRLinearScanRegisterAllocator >> assignRegisterToResultInInstruction: i [ This means that we should reserve at least 1 registers for spilled results. Do not add stores for phi functions " - i result isVirtualRegister ifFalse: [ ^ self ]. + i result isSSARegister ifFalse: [ ^ self ]. i isPhiFunction ifTrue: [ i result: (self allocatedRegisterFor: i). ^ self ]. @@ -229,7 +229,7 @@ DRLinearScanRegisterAllocator >> assignRegistersToOperandsInInstruction: i [ i replaceDependency: op by: load ] ]. "Special case for temporary registers created during register allocation." - op isVirtualRegister ifTrue: [ + op isSSARegister ifTrue: [ op physicalRegister: allocatedRegister ] ]. usedSpillRegisters do: [ :each | registerPool returnSpillRegister: each ] @@ -322,10 +322,10 @@ DRLinearScanRegisterAllocator >> computeLiveSets [ { #category : #'live-analysis' } DRLinearScanRegisterAllocator >> computeLivenessOfInstruction: i inBlock: b withLiveSet: live [ - i result isVirtualRegister ifTrue: [ + i result isSSARegister ifTrue: [ live remove: i ifAbsent: [ self initializeLiveSetOfInstruction: i ] ]. ^ i dependencies do: [ :op | - (op result isVirtualRegister and: [ + (op result isSSARegister and: [ op isStaged not and: [ (live includes: op) not ] ]) ifTrue: [ self @@ -395,7 +395,7 @@ DRLinearScanRegisterAllocator >> linearizeBlocks: aDRControlFlowGraph [ { #category : #accessing } DRLinearScanRegisterAllocator >> liveSetOf: aDependency [ - aDependency isVirtualRegister ifFalse: [ + aDependency isSSARegister ifFalse: [ "If it is not an instruction that requires allocation, do not record the live set" (aDependency isInstruction not or: [ aDependency isStaged ]) ifTrue: [ ^ DRLiveSet definition: aDependency ] ]. diff --git a/Druid/DRSCCP.class.st b/Druid/DRSCCP.class.st index c87284aa..a164c9a0 100644 --- a/Druid/DRSCCP.class.st +++ b/Druid/DRSCCP.class.st @@ -194,7 +194,7 @@ DRSCCP >> latticeForLoad: aDRLoad [ DRSCCP >> latticeValue: aValue [ "Return the lattice value for the register" - (aValue isRegister and: [ aValue isVirtualRegister not ]) ifTrue: [ + (aValue isRegister and: [ aValue isSSARegister not ]) ifTrue: [ ^ self bottom ]. aValue isConstant ifTrue: [ ^ aValue ]. diff --git a/Druid/DRSSARegister.class.st b/Druid/DRSSARegister.class.st index 734497c1..81db8d2b 100644 --- a/Druid/DRSSARegister.class.st +++ b/Druid/DRSSARegister.class.st @@ -30,18 +30,18 @@ DRSSARegister >> isRegister [ ^ true ] +{ #category : #testing } +DRSSARegister >> isSSARegister [ + + ^ true +] + { #category : #testing } DRSSARegister >> isValue [ ^ false ] -{ #category : #accessing } -DRSSARegister >> isVirtualRegister [ - - ^ true -] - { #category : #accessing } DRSSARegister >> physicalRegister: anObject [ diff --git a/Druid/DRStager.class.st b/Druid/DRStager.class.st index 007476ea..adc35f35 100644 --- a/Druid/DRStager.class.st +++ b/Druid/DRStager.class.st @@ -61,7 +61,7 @@ DRStager >> canStage: anInstruction modulo: aSetOfPotentiallyStagedInstructions anInstruction isJump ifTrue: [ ^ false ]. anInstruction isReturn ifTrue: [ ^ false ]. anInstruction isCopy ifTrue: [ - ^ (anInstruction result isVirtualRegister or: [ + ^ (anInstruction result isSSARegister or: [ anInstruction result isStagedRegister ]) and: [ self canStageOneLevel: anInstruction operand1 ] ]. (anInstruction isArithmeticInstruction or: [ anInstruction isNegate ]) diff --git a/Druid/DRValue.class.st b/Druid/DRValue.class.st index ca17d54c..ede47cc9 100644 --- a/Druid/DRValue.class.st +++ b/Druid/DRValue.class.st @@ -350,6 +350,12 @@ DRValue >> isReturn [ ^ false ] +{ #category : #testing } +DRValue >> isSSARegister [ + + ^ false +] + { #category : #testing } DRValue >> isSetConditionCode [ @@ -392,12 +398,6 @@ DRValue >> isValue [ ^ true ] -{ #category : #testing } -DRValue >> isVirtualRegister [ - - ^ false -] - { #category : #joining } DRValue >> joinNonNull: anotherValue onIRGenerator: aBuilder from: originBlocks [ From 19a742205d50eb109b6cbe5280eac0546d7999e0 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Fri, 26 Apr 2024 16:21:45 +0200 Subject: [PATCH 18/33] Do not tail duplicate stack effect instructions... --- Druid-Tests/DRProductionBytecodeTest.class.st | 6 +- Druid-Tests/DruidTestRTLCompiler.class.st | 82 ++++++++++--------- Druid/DRCogitStackCoalescing.class.st | 1 + ...DRFailureCodeBasedTailDuplication.class.st | 3 +- 4 files changed, 50 insertions(+), 42 deletions(-) diff --git a/Druid-Tests/DRProductionBytecodeTest.class.st b/Druid-Tests/DRProductionBytecodeTest.class.st index 076ee277..f4b754bf 100644 --- a/Druid-Tests/DRProductionBytecodeTest.class.st +++ b/Druid-Tests/DRProductionBytecodeTest.class.st @@ -1043,7 +1043,7 @@ DRProductionBytecodeTest >> testBytecodePushLiteralVariableDoesOverrideTopAlloca { #category : #tests } DRProductionBytecodeTest >> testBytecodePushLiteralVariableDoesOverrideTopAllocatedRegister: n [ - | method | + | method x | method := methodBuilder newMethod literals: (((1 to: 16) collect: [ :e | nil -> (e + 16rFF - 1) ]) @@ -1070,9 +1070,9 @@ DRProductionBytecodeTest >> testBytecodePushLiteralVariableDoesOverrideTopAlloca generator value. "Flush the stack" - cogit ssFlushTo: cogit simStackPointer. + cogit ssFlushStack. - "Pop the top 4 elements, the fourth should be the first pushed constant" + "Pop the top n + 1 elements, the last should be the first pushed constant" 1 to: n + 1 do: [ :i | cogit ssPopTopToReg: ReceiverResultReg ]. cogit genUpArrowReturn ]. diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index 89ca4ebd..752c1593 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -877,19 +877,19 @@ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ jump1 := self JumpLessOrEqual: 0. (self ssValue: 0) copyToReg: t0. self ssPop: 1. - self ssPushRegister: t0. - jump2 := self Jump: 0. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. t1 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). + self MoveR: t0 R: t1. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. (self ssValue: 0) copyToReg: t1. self ssPop: 1. - self ssPushRegister: t1. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self ssPushRegister: t1. ^ 0 ] @@ -1145,7 +1145,7 @@ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock t1 jump2 live | + | t0 jump1 s2 currentBlock t1 jump2 live t2 | live := 0. self annotateBytecode: self Label. t0 := self @@ -1156,24 +1156,31 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. (self ssValue: 0) copyToReg: t0. + self ssPop: 1. t1 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). - (self ssValue: 1) copyToReg: t1. - self ssPop: 2. - self AddR: t1 R: t0. - self ssPushRegister: t0. + (self ssValue: 0) copyToReg: t1. + self ssPop: 1. + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + self MoveR: t0 R: t2. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. (self ssValue: 0) copyToReg: t1. - (self ssValue: 1) copyToReg: t0. - self ssPop: 2. - self AddR: t0 R: t1. - self ssPushRegister: t1. + self ssPop: 1. + (self ssValue: 0) copyToReg: t0. + self ssPop: 1. + self MoveR: t1 R: t2. + self MoveR: t0 R: t1. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self AddR: t1 R: t2. + self ssPushRegister: t2. ^ 0 ] @@ -1181,7 +1188,7 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock jump2 live | + | t0 jump1 s2 currentBlock t1 jump2 live | live := 0. self annotateBytecode: self Label. t0 := self @@ -1189,19 +1196,28 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. + self ssPop: 1. self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. + self ssPushConstant: 1. self ssPushConstant: 2. - self ssPop: 2. - self ssPushRegister: t0. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. + self ssPushConstant: 3. self ssPushConstant: 4. - self ssPop: 2. - self ssPushRegister: t0. currentBlock := self Label. jump2 jmpTarget: currentBlock. + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + (self ssValue: 0) copyToReg: t1. + self ssPop: 1. + (self ssValue: 0) copyToReg: t0. + self ssPop: 1. + self AddR: t0 R: t1. + self ssPushRegister: t1. ^ 0 ] @@ -8231,7 +8247,7 @@ DruidTestRTLCompiler >> gen_pushLiteralConstantBytecode [ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ "AutoGenerated by Druid" - | s34 s3 jump1 s28 t1 jump3 s33 b234 currentBlock s24 t0 jump2 s4 s29 s23 live jump4 | + | jump1 s3 s28 t1 jump3 currentBlock t0 jump2 s4 s29 b233 live jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -8251,7 +8267,7 @@ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ self CmpCq: 0 R: t1. jump1 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t1. - b234 := self Label. + b233 := self Label. self MoveR: t1 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -8262,30 +8278,20 @@ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ jump3 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t0. self MoveR: t0 R: t1. - jump4 := self Jump: b234. + jump4 := self Jump: b233. currentBlock := self Label. + jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. - s23 := ValueIndex. - s24 := s23 << 3. - self AddCq: s24 R: t1. - self ssPushBase: t1 offset: 8. + self MoveR: t1 R: t0. jump3 := self Jump: 0. currentBlock := self Label. - jump2 jmpTarget: currentBlock. - s28 := ValueIndex. - s29 := s28 << 3. - self AddCq: s29 R: t1. - self ssPushBase: t1 offset: 8. - jump2 := self Jump: 0. - currentBlock := self Label. jump1 jmpTarget: currentBlock. - s33 := ValueIndex. - s34 := s33 << 3. - self AddCq: s34 R: t0. - self ssPushBase: t0 offset: 8. currentBlock := self Label. jump3 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. + s28 := ValueIndex. + s29 := s28 << 3. + self AddCq: s29 R: t0. + self ssPushBase: t0 offset: 8. ^ 0 ] diff --git a/Druid/DRCogitStackCoalescing.class.st b/Druid/DRCogitStackCoalescing.class.st index 04449bef..7ad2ecc9 100644 --- a/Druid/DRCogitStackCoalescing.class.st +++ b/Druid/DRCogitStackCoalescing.class.st @@ -11,6 +11,7 @@ DRCogitStackCoalescing >> applyTo: cfg [ Effects that apply the same operation on different branches get coallesced into a single effect (one push on each branch turns into a single push down in the CFG)" | commonPostDominator basicBlock instructionsByStackDepth stackEffects | + true ifTrue: [^ self]. stackEffects := cfg instructions select: [ :e | e isStackEffect ]. 1 haltIf: [ stackEffects anySatisfy: [ :p | p hasUsers ] ]. instructionsByStackDepth := stackEffects groupedBy: [ :effect | diff --git a/Druid/DRFailureCodeBasedTailDuplication.class.st b/Druid/DRFailureCodeBasedTailDuplication.class.st index 4b491929..7aaa8e6f 100644 --- a/Druid/DRFailureCodeBasedTailDuplication.class.st +++ b/Druid/DRFailureCodeBasedTailDuplication.class.st @@ -8,7 +8,8 @@ Class { DRFailureCodeBasedTailDuplication >> applyTo: aDRControlFlowGraph [ aDRControlFlowGraph exitBasicBlocks do: [ :bb | - bb predecessors size > 1 ifTrue: [ + (bb predecessors size > 1 and: [ + bb instructions noneSatisfy: [ :e | e isStackEffect ] ]) ifTrue: [ bb tailDuplicate ] ] ] From 793ec52b6e06e6c4ec86a598ac674c073ea592b8 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Fri, 26 Apr 2024 16:44:28 +0200 Subject: [PATCH 19/33] Fix stack coalescing test --- ...DRBytecodeScenarioCompilationTest.class.st | 3 +- Druid-Tests/DruidTestRTLCompiler.class.st | 71 ++++++++----------- Druid/DRCogitStackCoalescing.class.st | 1 - 3 files changed, 30 insertions(+), 45 deletions(-) diff --git a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st index f1384d5e..ad212aaf 100644 --- a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st +++ b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st @@ -82,7 +82,8 @@ DRBytecodeScenarioCompilationTest >> testPopsAreCoallesced [ thenDo: [ :generator | "Push the receiver" cogit ssPushRegister: ReceiverResultReg. "Then execute the druid's compiled code" - generator value ]. + generator value. + cogit genReturnTopFromMethod ]. self executePrimitiveWithReceiver: 17. diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index 752c1593..6ca11a84 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -865,7 +865,7 @@ DruidTestRTLCompiler >> gen_branchingWithAssigments [ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock t1 jump2 live | + | t0 jump1 s2 currentBlock jump2 live | live := 0. self annotateBytecode: self Label. t0 := self @@ -876,20 +876,14 @@ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. (self ssValue: 0) copyToReg: t0. - self ssPop: 1. - t1 := self - allocateRegNotConflictingWith: live - ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t1). - self MoveR: t0 R: t1. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - (self ssValue: 0) copyToReg: t1. - self ssPop: 1. + (self ssValue: 0) copyToReg: t0. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPushRegister: t1. + self ssPop: 1. + self ssPushRegister: t0. ^ 0 ] @@ -1121,7 +1115,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock jump2 live | + | t0 s8 jump1 s2 currentBlock jump2 live s5 | live := 0. self annotateBytecode: self Label. t0 := self @@ -1131,13 +1125,16 @@ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ (self ssValue: 0) copyToReg: t0. self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. - self ssPushConstant: 1. + s5 := 1. + self MoveCq: s5 R: t0. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self ssPushConstant: 2. + s8 := 2. + self MoveCq: s8 R: t0. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self ssPushRegister: t0. ^ 0 ] @@ -1156,31 +1153,27 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. (self ssValue: 0) copyToReg: t0. - self ssPop: 1. t1 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). + (self ssValue: 1) copyToReg: t1. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. (self ssValue: 0) copyToReg: t1. - self ssPop: 1. t2 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t2). - self MoveR: t0 R: t2. - jump2 := self Jump: 0. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. - (self ssValue: 0) copyToReg: t1. - self ssPop: 1. - (self ssValue: 0) copyToReg: t0. - self ssPop: 1. - self MoveR: t1 R: t2. - self MoveR: t0 R: t1. + (self ssValue: 1) copyToReg: t2. + self MoveR: t1 R: t0. + self MoveR: t2 R: t1. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self AddR: t1 R: t2. - self ssPushRegister: t2. + self ssPop: 2. + self AddR: t1 R: t0. + self ssPushRegister: t0. ^ 0 ] @@ -1188,7 +1181,7 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock t1 jump2 live | + | t0 s8 jump1 s2 currentBlock jump2 live s5 | live := 0. self annotateBytecode: self Label. t0 := self @@ -1196,28 +1189,20 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. - self ssPop: 1. self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. - self ssPushConstant: 1. - self ssPushConstant: 2. + s5 := 2. + self MoveCq: s5 R: t0. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self ssPushConstant: 3. - self ssPushConstant: 4. + s8 := 4. + self MoveCq: s8 R: t0. currentBlock := self Label. jump2 jmpTarget: currentBlock. - t1 := self - allocateRegNotConflictingWith: live - ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t1). - (self ssValue: 0) copyToReg: t1. - self ssPop: 1. - (self ssValue: 0) copyToReg: t0. - self ssPop: 1. - self AddR: t0 R: t1. - self ssPushRegister: t1. + self ssPushRegister: t0. + self ssPop: 2. + self ssPushRegister: t0. ^ 0 ] diff --git a/Druid/DRCogitStackCoalescing.class.st b/Druid/DRCogitStackCoalescing.class.st index 7ad2ecc9..04449bef 100644 --- a/Druid/DRCogitStackCoalescing.class.st +++ b/Druid/DRCogitStackCoalescing.class.st @@ -11,7 +11,6 @@ DRCogitStackCoalescing >> applyTo: cfg [ Effects that apply the same operation on different branches get coallesced into a single effect (one push on each branch turns into a single push down in the CFG)" | commonPostDominator basicBlock instructionsByStackDepth stackEffects | - true ifTrue: [^ self]. stackEffects := cfg instructions select: [ :e | e isStackEffect ]. 1 haltIf: [ stackEffects anySatisfy: [ :p | p hasUsers ] ]. instructionsByStackDepth := stackEffects groupedBy: [ :effect | From efae63e5774643773ba5922a70b6996f777234cd Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Fri, 26 Apr 2024 17:02:27 +0200 Subject: [PATCH 20/33] Rename stack dependency accessor --- Druid-Tests/DRLinearizationTest.class.st | 4 ++-- Druid-Tests/DRStackEffectTest.class.st | 10 +++++----- Druid/DRBasicBlock.class.st | 2 +- Druid/DRControlFlowGraph.class.st | 2 +- Druid/DRLoadStackValue.class.st | 4 ++-- Druid/DRMetaCompilerIRGenerator.class.st | 2 +- Druid/DRPop.class.st | 4 ++-- Druid/DRPush.class.st | 4 ++-- Druid/DRStackInstruction.class.st | 18 +++++++++--------- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Druid-Tests/DRLinearizationTest.class.st b/Druid-Tests/DRLinearizationTest.class.st index f0f12350..a8762fc2 100644 --- a/Druid-Tests/DRLinearizationTest.class.st +++ b/Druid-Tests/DRLinearizationTest.class.st @@ -79,7 +79,7 @@ DRLinearizationTest >> testBranchingControlFlowWithStackDependency [ firstPush := b2 push: 1. secondPush := b3 push: 2. - secondPush stackDependency: {firstPush}. + secondPush stackDependencies: {firstPush}. self assert: cfg reversePostOrderBlocks asArray equals: { b1. @@ -113,7 +113,7 @@ DRLinearizationTest >> testBranchingControlFlowWithStackDependencyReversed [ firstPush := b3 push: 1. secondPush := b2 push: 2. - secondPush stackDependency: {firstPush}. + secondPush stackDependencies: {firstPush}. self assert: cfg reversePostOrderBlocks asArray equals: { b1. diff --git a/Druid-Tests/DRStackEffectTest.class.st b/Druid-Tests/DRStackEffectTest.class.st index 3e06c779..7eb6ef2d 100644 --- a/Druid-Tests/DRStackEffectTest.class.st +++ b/Druid-Tests/DRStackEffectTest.class.st @@ -14,7 +14,7 @@ DRStackEffectTest >> testInitialStackInstructionHasNoStackDependencies [ push := irBuilder addInstructionFrom: nil instructionKind: DRPush operands: { 17 }. pop := irBuilder addInstructionFrom: nil instructionKind: DRPop. - self assert: push stackDependency isEmpty + self assert: push stackDependencies isEmpty ] { #category : #tests } @@ -40,7 +40,7 @@ DRStackEffectTest >> testPopDependsOnPush [ push := irBuilder addInstructionFrom: nil instructionKind: DRPush operands: { 17 }. pop := irBuilder addInstructionFrom: nil instructionKind: DRPop. - self assert: pop stackDependency asArray equals: { push }. + self assert: pop stackDependencies asArray equals: { push }. self assert: push stackDependents asArray equals: { pop } ] @@ -63,7 +63,7 @@ DRStackEffectTest >> testPopInMergePointDependsOnBothBranches [ instructionKind: DRPush operands: { 17 }. - self assert: finalStackInstruction stackDependency asArray equals: { + self assert: finalStackInstruction stackDependencies asArray equals: { pop1. pop2 } ] @@ -78,7 +78,7 @@ DRStackEffectTest >> testPushDependsOnPop [ pop := irBuilder addInstructionFrom: nil instructionKind: DRPop. push := irBuilder addInstructionFrom: nil instructionKind: DRPush operands: { 17 }. - self assert: push stackDependency asArray equals: { pop }. + self assert: push stackDependencies asArray equals: { pop }. self assert: pop stackDependents asArray equals: { push } ] @@ -102,7 +102,7 @@ DRStackEffectTest >> testRebuildStackDependenciesReconstructsOriginalGraph [ operands: { 17 }. irBuilder ir rebuildStackDependencies. - self assert: finalStackInstruction stackDependency asArray equals: { + self assert: finalStackInstruction stackDependencies asArray equals: { pop1. pop2 } ] diff --git a/Druid/DRBasicBlock.class.st b/Druid/DRBasicBlock.class.st index 5c1e06f1..85ea092d 100644 --- a/Druid/DRBasicBlock.class.st +++ b/Druid/DRBasicBlock.class.st @@ -232,7 +232,7 @@ DRBasicBlock >> canBeLinearizedBefore: aDRBasicBlock [ "Pops and Pushes are constraints for linearization" controlFlowGraph stackInstructions do: [ :stackInstruction | "There is a stack instruction in my path ..." (stackInstruction basicBlock isDominatedBy: self) ifTrue: [ - stackInstruction stackDependency do: [ :dependency | "... with a dependecy in the other path ..." + stackInstruction stackDependencies do: [ :dependency | "... with a dependecy in the other path ..." (dependency basicBlock isDominatedBy: aDRBasicBlock) ifTrue: [ "... then the other path must be linearized before" ^ false ] ] ] ]. diff --git a/Druid/DRControlFlowGraph.class.st b/Druid/DRControlFlowGraph.class.st index d3d12d86..4d212f16 100644 --- a/Druid/DRControlFlowGraph.class.st +++ b/Druid/DRControlFlowGraph.class.st @@ -733,7 +733,7 @@ DRControlFlowGraph >> rebuildStackDependencies [ e instructions do: [ :i | i isStackInstruction ifTrue: [ i clearStackDependencies. - i stackDependency: incomingStackInstructions. + i stackDependencies: incomingStackInstructions. incomingStackInstructions do: [ :s | s addStackDependent: i ]. incomingStackInstructions := { i } ] ]. lastStackInstructionPerBlock at: e put: incomingStackInstructions ] diff --git a/Druid/DRLoadStackValue.class.st b/Druid/DRLoadStackValue.class.st index 87d6907a..e1e9cf89 100644 --- a/Druid/DRLoadStackValue.class.st +++ b/Druid/DRLoadStackValue.class.st @@ -41,6 +41,6 @@ DRLoadStackValue >> shiftStackAccessBy: anInteger [ DRLoadStackValue >> stackDepth [ "I don't change the stack depth, so just return the stack depth of my stack dependant" - stackDependency ifEmpty: [ ^ 0 ]. - ^ stackDependency anyOne stackDepth + stackDependencies ifEmpty: [ ^ 0 ]. + ^ stackDependencies anyOne stackDepth ] diff --git a/Druid/DRMetaCompilerIRGenerator.class.st b/Druid/DRMetaCompilerIRGenerator.class.st index 5e059255..730860c4 100644 --- a/Druid/DRMetaCompilerIRGenerator.class.st +++ b/Druid/DRMetaCompilerIRGenerator.class.st @@ -179,7 +179,7 @@ DRMetaCompilerIRGenerator >> resolveMessageSend: aRBMessageNode receiver: receiv { #category : #visiting } DRMetaCompilerIRGenerator >> trackStackInstruction: aDRStrackInstruction [ - aDRStrackInstruction stackDependency: executionState lastStackInstruction. + aDRStrackInstruction stackDependencies: executionState lastStackInstruction. executionState lastStackInstruction: aDRStrackInstruction. ] diff --git a/Druid/DRPop.class.st b/Druid/DRPop.class.st index 02c5a9c4..d1be48fa 100644 --- a/Druid/DRPop.class.st +++ b/Druid/DRPop.class.st @@ -55,7 +55,7 @@ DRPop >> stackDepth [ "Return the stack depth left on the stack after applying this operation. Pop will remove one element from the stack depth of the previous stack instruction" - stackDependency ifEmpty: [ ^ 0 ]. - ^ stackDependency anyOne stackDepth - 1 + stackDependencies ifEmpty: [ ^ 0 ]. + ^ stackDependencies anyOne stackDepth - 1 ] diff --git a/Druid/DRPush.class.st b/Druid/DRPush.class.st index 51e57d27..fabaa19b 100644 --- a/Druid/DRPush.class.st +++ b/Druid/DRPush.class.st @@ -69,6 +69,6 @@ DRPush >> stackDepth [ "Return the stack depth left on the stack after applying this operation. Push will add one element to the stack depth of the previous stack instruction" - stackDependency ifEmpty: [ ^ 1 ]. - ^ stackDependency anyOne stackDepth + 1 + stackDependencies ifEmpty: [ ^ 1 ]. + ^ stackDependencies anyOne stackDepth + 1 ] diff --git a/Druid/DRStackInstruction.class.st b/Druid/DRStackInstruction.class.st index 16cd10cd..35e6dadd 100644 --- a/Druid/DRStackInstruction.class.st +++ b/Druid/DRStackInstruction.class.st @@ -2,8 +2,8 @@ Class { #name : #DRStackInstruction, #superclass : #DRInstruction, #instVars : [ - 'stackDependency', - 'stackDependents' + 'stackDependents', + 'stackDependencies' ], #category : #'Druid-IR' } @@ -17,7 +17,7 @@ DRStackInstruction >> addStackDependent: aStackInstruction [ { #category : #dependencies } DRStackInstruction >> clearStackDependencies [ - stackDependency := OrderedCollection new. + stackDependencies := OrderedCollection new. stackDependents := OrderedCollection new ] @@ -38,7 +38,7 @@ DRStackInstruction >> isStackInstruction [ { #category : #removing } DRStackInstruction >> removeStackDependency: aStackDependency [ - stackDependency := stackDependency copyWithout: aStackDependency + stackDependencies := stackDependencies copyWithout: aStackDependency ] { #category : #removing } @@ -55,16 +55,16 @@ DRStackInstruction >> shiftStackAccessBy: anInteger [ ] { #category : #accessing } -DRStackInstruction >> stackDependency [ +DRStackInstruction >> stackDependencies [ - ^ stackDependency + ^ stackDependencies ] { #category : #accessing } -DRStackInstruction >> stackDependency: anObject [ +DRStackInstruction >> stackDependencies: anObject [ - stackDependency := anObject. - stackDependency do: [ :e | e addStackDependent: self ] + stackDependencies := anObject. + stackDependencies do: [ :e | e addStackDependent: self ] ] { #category : #accessing } From 381feb1c98c7b79c28de57f7bb961ba9a9afc4ee Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Mon, 6 May 2024 11:51:38 +0200 Subject: [PATCH 21/33] Properly sorting coalesced stack instructions using a topo sort between stack effect instructions --- Druid-Tests/DruidTestRTLCompiler.class.st | 327 +++++++++++++--------- Druid/DRCogitStackCoalescing.class.st | 39 ++- Druid/DRIRGenerator.class.st | 1 + Druid/DRStackInstruction.class.st | 36 ++- 4 files changed, 249 insertions(+), 154 deletions(-) diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index 6ca11a84..fdc370f2 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -865,7 +865,7 @@ DruidTestRTLCompiler >> gen_branchingWithAssigments [ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock jump2 live | + | t0 jump1 s2 currentBlock t1 jump2 live t2 | live := 0. self annotateBytecode: self Label. t0 := self @@ -875,11 +875,21 @@ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ (self ssValue: 0) copyToReg: t0. self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. - (self ssValue: 0) copyToReg: t0. + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + (self ssValue: 0) copyToReg: t1. + self MoveR: t1 R: t0. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - (self ssValue: 0) copyToReg: t0. + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + (self ssValue: 0) copyToReg: t2. + self MoveR: t2 R: t0. currentBlock := self Label. jump2 jmpTarget: currentBlock. self ssPop: 1. @@ -1115,7 +1125,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ "AutoGenerated by Druid" - | t0 s8 jump1 s2 currentBlock jump2 live s5 | + | t0 s8 jump1 s2 currentBlock t1 jump2 live s5 | live := 0. self annotateBytecode: self Label. t0 := self @@ -1126,15 +1136,19 @@ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. s5 := 1. - self MoveCq: s5 R: t0. + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + self MoveCq: s5 R: t1. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. s8 := 2. - self MoveCq: s8 R: t0. + self MoveCq: s8 R: t1. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPushRegister: t0. + self ssPushRegister: t1. ^ 0 ] @@ -1142,7 +1156,7 @@ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock t1 jump2 live t2 | + | t0 jump1 t3 s2 currentBlock t1 jump2 live t2 | live := 0. self annotateBytecode: self Label. t0 := self @@ -1158,21 +1172,26 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). (self ssValue: 1) copyToReg: t1. + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + self MoveR: t1 R: t2. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - (self ssValue: 0) copyToReg: t1. - t2 := self + (self ssValue: 0) copyToReg: t2. + t3 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t2). - (self ssValue: 1) copyToReg: t2. - self MoveR: t1 R: t0. - self MoveR: t2 R: t1. + live := live bitOr: (self registerMaskFor: t3). + (self ssValue: 1) copyToReg: t3. + self MoveR: t2 R: t0. + self MoveR: t3 R: t2. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPop: 2. - self AddR: t1 R: t0. + self ssPop: 1. + self AddR: t2 R: t0. self ssPushRegister: t0. ^ 0 ] @@ -1181,7 +1200,7 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ "AutoGenerated by Druid" - | t0 s8 jump1 s2 currentBlock jump2 live s5 | + | s6 jump1 t1 s2 currentBlock s12 t0 s7 jump2 s11 live | live := 0. self annotateBytecode: self Label. t0 := self @@ -1189,20 +1208,34 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. + self ssPop: 1. self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. - s5 := 2. - self MoveCq: s5 R: t0. + s6 := 1. + s7 := 2. + self MoveCq: s7 R: t0. + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + self MoveCq: s6 R: t1. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s8 := 4. - self MoveCq: s8 R: t0. + s11 := 3. + s12 := 4. + self MoveCq: s12 R: t0. + self MoveCq: s11 R: t1. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self ssPushRegister: t1. self ssPushRegister: t0. - self ssPop: 2. - self ssPushRegister: t0. + (self ssValue: 0) copyToReg: t1. + self ssPop: 1. + (self ssValue: 0) copyToReg: t0. + self ssPop: 1. + self AddR: t0 R: t1. + self ssPushRegister: t1. ^ 0 ] @@ -1443,7 +1476,7 @@ DruidTestRTLCompiler >> gen_extPushIntegerBytecode [ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ "AutoGenerated by Druid" - | s6 s3 s16 s25 s10 s22 s8 s5 s2 s18 currentBlock s15 s24 s4 s17 live s23 s9 | + | s6 s3 s16 s25 s10 s8 s5 s2 s18 currentBlock s15 s24 s27 s4 s17 s26 live s9 | live := 0. s2 := byte1. s3 := s2 >> 3. @@ -1462,22 +1495,24 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ s16 := extB. s17 := s16 << 3. s18 := s15 + s17. + extB := 0. + numExtB := 0. self marshallSendArguments: s18. self genMarshalledSend: s6 numArgs: s18 sendTable: superSendTrampolines. ^ 0 ]. - s22 := s2 bitAnd: 7. - s23 := extB. - s24 := s23 << 3. - s25 := s22 + s24. + s24 := s2 bitAnd: 7. + s25 := extB. + s26 := s25 << 3. + s27 := s24 + s26. extB := 0. numExtB := 0. - self marshallSendArguments: s25. + self marshallSendArguments: s27. self genMarshalledSend: s6 - numArgs: s25 + numArgs: s27 sendTable: superSendTrampolines. ^ 0 ] @@ -1678,7 +1713,7 @@ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ "AutoGenerated by Druid" - | s6 jump5 s33 s81 s46 s4 s77 jump3 s44 s69 s14 s2 s75 s36 currentBlock s58 s9 s84 t1 s89 jump1 jump6 live s5 jump4 s93 s63 s3 t2 jump9 jump2 jump7 t0 s41 | + | s6 jump5 s88 s81 s4 jump3 s44 s14 s9 s2 s36 currentBlock s49 s101 s67 t1 jump1 jump6 s47 live s5 s39 jump4 jump9 s3 t2 jump2 s91 s61 jump7 s74 s83 t0 s96 | live := 0. self annotateBytecode: self Label. s3 := byte1. @@ -1710,6 +1745,7 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self CmpCq: s14 R: t2. jump1 := self JumpNonZero: 0. self deoptimize. + extA := 0. jump2 := self Jump: 0. deadCode := false. currentBlock := self Label. @@ -1720,6 +1756,7 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self CmpCq: 0 R: t2. jump1 := self JumpZero: 0. self deoptimize. + extA := 0. jump3 := self Jump: 0. deadCode := false. currentBlock := self Label. @@ -1728,24 +1765,24 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self AndCq: 7 R: t2. self CmpCq: 0 R: t2. jump1 := self JumpNonZero: 0. - s33 := objectMemory getMemoryMap getSpaceMaskToUse. + s36 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t1 R: t2. - self AndCq: s33 R: t2. - s36 := objectMemory getMemoryMap getOldSpaceMask. - self CmpCq: s36 R: t2. + self AndCq: s36 R: t2. + s39 := objectMemory getMemoryMap getOldSpaceMask. + self CmpCq: s39 R: t2. jump4 := self JumpNonZero: 0. self MoveR: t0 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. jump5 := self JumpNonZero: 0. - s41 := objectMemory getMemoryMap getSpaceMaskToUse. + s44 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t0 R: t2. - self AndCq: s41 R: t2. - s44 := objectMemory getMemoryMap getNewSpaceMask. - self CmpCq: s44 R: t2. + self AndCq: s44 R: t2. + s47 := objectMemory getMemoryMap getNewSpaceMask. + self CmpCq: s47 R: t2. jump6 := self JumpNonZero: 0. - s46 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s46 R: t0. + s49 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s49 R: t0. jump7 := self JumpBelow: 0. self MoveM64: 0 r: t1 R: t2. self LogicalShiftRightCq: 29 R: t2. @@ -1767,17 +1804,19 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self AndCq: 1 R: t2. self CmpCq: 0 R: t2. jump8 := self JumpZero: 0. - s58 := s6 << 3. - self AddCq: s58 R: t1. + s61 := s6 << 3. + self AddCq: s61 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump7 := self Jump: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. self TstCq: 7 R: t0. jump8 := self JumpZero: 0. - s63 := s6 << 3. - self AddCq: s63 R: t1. + s67 := s6 << 3. + self AddCq: s67 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump6 := self Jump: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. @@ -1785,47 +1824,51 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ jump8 := self JumpLess: 0. self CmpCq: 16r20000000000 R: t0. jump5 := self JumpLess: 0. - s69 := s6 << 3. - self AddCq: s69 R: t1. + s74 := s6 << 3. + self AddCq: s74 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump4 := self Jump: 0. currentBlock := self Label. jump5 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t0. jump5 := self JumpBelow: 0. - s75 := objectMemory trueObject. - self CmpCq: s75 R: t0. + s81 := objectMemory trueObject. + self CmpCq: s81 R: t0. jump1 := self JumpAbove: 0. - s77 := s6 << 3. - self AddCq: s77 R: t1. + s83 := s6 << 3. + self AddCq: s83 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump9 := self Jump: 0. currentBlock := self Label. jump5 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. - s81 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s81 R: t0. + s88 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s88 R: t0. jump1 := self JumpBelow: 0. self MoveR: t1 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. - s84 := s6 << 3. - self AddCq: s84 R: t1. + s91 := s6 << 3. + self AddCq: s91 R: t1. self MoveR: t0 M64: 8 r: t1. extA := 0. jump5 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s89 := s6 << 3. - self AddCq: s89 R: t1. + s96 := s6 << 3. + self AddCq: s96 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump1 := self Jump: 0. currentBlock := self Label. jump8 jmpTarget: currentBlock. - s93 := s6 << 3. - self AddCq: s93 R: t1. + s101 := s6 << 3. + self AddCq: s101 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. currentBlock := self Label. jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -1842,6 +1885,7 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self CmpCq: 0 R: t2. jump1 := self JumpZero: 0. self deoptimize. + extA := 0. jump5 := self Jump: 0. deadCode := false. currentBlock := self Label. @@ -1850,24 +1894,24 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self AndCq: 7 R: t2. self CmpCq: 0 R: t2. jump1 := self JumpNonZero: 0. - s33 := objectMemory getMemoryMap getSpaceMaskToUse. + s36 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t1 R: t2. - self AndCq: s33 R: t2. - s36 := objectMemory getMemoryMap getOldSpaceMask. - self CmpCq: s36 R: t2. + self AndCq: s36 R: t2. + s39 := objectMemory getMemoryMap getOldSpaceMask. + self CmpCq: s39 R: t2. jump9 := self JumpNonZero: 0. self MoveR: t0 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. jump4 := self JumpNonZero: 0. - s41 := objectMemory getMemoryMap getSpaceMaskToUse. + s44 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t0 R: t2. - self AndCq: s41 R: t2. - s44 := objectMemory getMemoryMap getNewSpaceMask. - self CmpCq: s44 R: t2. + self AndCq: s44 R: t2. + s47 := objectMemory getMemoryMap getNewSpaceMask. + self CmpCq: s47 R: t2. jump6 := self JumpNonZero: 0. - s46 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s46 R: t0. + s49 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s49 R: t0. jump7 := self JumpBelow: 0. self MoveM64: 0 r: t1 R: t2. self LogicalShiftRightCq: 29 R: t2. @@ -1889,17 +1933,19 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self AndCq: 1 R: t2. self CmpCq: 0 R: t2. jump3 := self JumpZero: 0. - s58 := s6 << 3. - self AddCq: s58 R: t1. + s61 := s6 << 3. + self AddCq: s61 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump7 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. self TstCq: 7 R: t0. jump3 := self JumpZero: 0. - s63 := s6 << 3. - self AddCq: s63 R: t1. + s67 := s6 << 3. + self AddCq: s67 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump6 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. @@ -1907,47 +1953,51 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ jump3 := self JumpLess: 0. self CmpCq: 16r20000000000 R: t0. jump4 := self JumpLess: 0. - s69 := s6 << 3. - self AddCq: s69 R: t1. + s74 := s6 << 3. + self AddCq: s74 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump9 := self Jump: 0. currentBlock := self Label. jump4 jmpTarget: currentBlock. self genMoveConstant: objectMemory nilObject R: t2. self CmpR: t2 R: t0. jump4 := self JumpBelow: 0. - s75 := objectMemory trueObject. - self CmpCq: s75 R: t0. + s81 := objectMemory trueObject. + self CmpCq: s81 R: t0. jump1 := self JumpAbove: 0. - s77 := s6 << 3. - self AddCq: s77 R: t1. + s83 := s6 << 3. + self AddCq: s83 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump2 := self Jump: 0. currentBlock := self Label. jump4 jmpTarget: currentBlock. jump1 jmpTarget: currentBlock. - s81 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s81 R: t0. + s88 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s88 R: t0. jump1 := self JumpBelow: 0. self MoveR: t1 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. - s84 := s6 << 3. - self AddCq: s84 R: t1. + s91 := s6 << 3. + self AddCq: s91 R: t1. self MoveR: t0 M64: 8 r: t1. extA := 0. jump4 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - s89 := s6 << 3. - self AddCq: s89 R: t1. + s96 := s6 << 3. + self AddCq: s96 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. jump1 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. - s93 := s6 << 3. - self AddCq: s93 R: t1. + s101 := s6 << 3. + self AddCq: s101 R: t1. self MoveR: t0 M64: 8 r: t1. + extA := 0. currentBlock := self Label. jump5 jmpTarget: currentBlock. jump7 jmpTarget: currentBlock. @@ -2083,7 +2133,7 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ DruidTestRTLCompiler >> gen_extendedPushBytecode [ "AutoGenerated by Druid" - | s6 s46 s4 jump3 s2 s27 currentBlock s20 s19 s51 t1 s25 jump1 b325 s47 s56 live s5 jump4 s3 jump2 s52 s8 s26 t0 s18 s57 | + | s6 s3 s19 s28 s54 t1 s8 s5 s2 s30 currentBlock s21 t0 s4 s29 s55 live s20 | live := 0. s2 := byte1. s3 := s2 >> 6. @@ -2098,7 +2148,8 @@ DruidTestRTLCompiler >> gen_extendedPushBytecode [ self MoveR: ReceiverResultReg R: t0. s8 := s5 << 3. self AddCq: s8 R: t0. - self ssPushBase: t0 offset: 8. + self MoveM64: 8 r: t0 R: t0. + self ssPushRegister: t0. ^ 0 ]. s4 = 1 ifTrue: [ (self simStackTempAt: s5) copyToReg: t0. @@ -2106,62 +2157,58 @@ DruidTestRTLCompiler >> gen_extendedPushBytecode [ ^ 0 ]. s4 = 2 ifTrue: [ self genMoveConstant: methodObj R: t0. - s18 := LiteralStart. - s19 := s5 + s18. - s20 := s19 << 3. - self AddCq: s20 R: t0. - self ssPushBase: t0 offset: 8. + s19 := LiteralStart. + s20 := s5 + s19. + s21 := s20 << 3. + self AddCq: s21 R: t0. + self MoveM64: 8 r: t0 R: t0. + self ssPushRegister: t0. ^ 0 ]. - self genMoveConstant: methodObj R: t0. - s25 := LiteralStart. - s26 := s5 + s25. - s27 := s26 << 3. - self AddCq: s27 R: t0. - self MoveM64: 8 r: t0 R: t0. t1 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). - self MoveM64: 0 r: t0 R: t1. - self AndCq: 16r3FFFF7 R: t1. - self CmpCq: 0 R: t1. - jump1 := self JumpNonZero: 0. - self MoveM64: 8 r: t0 R: t1. - b325 := self Label. - self MoveR: t1 R: t0. - self AndCq: 7 R: t0. - self CmpCq: 0 R: t0. - jump2 := self JumpNonZero: 0. - self MoveM64: 0 r: t1 R: t0. - self AndCq: 16r3FFFF7 R: t0. - self CmpCq: 0 R: t0. - jump3 := self JumpNonZero: 0. - self MoveM64: 8 r: t1 R: t0. - self MoveR: t0 R: t1. - jump4 := self Jump: b325. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - s46 := ValueIndex. - s47 := s46 << 3. - self AddCq: s47 R: t1. - self ssPushBase: t1 offset: 8. - jump3 := self Jump: 0. - currentBlock := self Label. - jump2 jmpTarget: currentBlock. - s51 := ValueIndex. - s52 := s51 << 3. - self AddCq: s52 R: t1. - self ssPushBase: t1 offset: 8. - jump2 := self Jump: 0. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. - s56 := ValueIndex. - s57 := s56 << 3. - self AddCq: s57 R: t0. - self ssPushBase: t0 offset: 8. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. + s4 = 3 ifTrue: [ + | jump3 jump1 b320 jump4 jump2 | + self genMoveConstant: methodObj R: t0. + s28 := LiteralStart. + s29 := s5 + s28. + s30 := s29 << 3. + self AddCq: s30 R: t0. + self MoveM64: 8 r: t0 R: t0. + self MoveM64: 0 r: t0 R: t1. + self AndCq: 16r3FFFF7 R: t1. + self CmpCq: 0 R: t1. + jump1 := self JumpNonZero: 0. + self MoveM64: 8 r: t0 R: t1. + b320 := self Label. + self MoveR: t1 R: t0. + self AndCq: 7 R: t0. + self CmpCq: 0 R: t0. + jump2 := self JumpNonZero: 0. + self MoveM64: 0 r: t1 R: t0. + self AndCq: 16r3FFFF7 R: t0. + self CmpCq: 0 R: t0. + jump3 := self JumpNonZero: 0. + self MoveM64: 8 r: t1 R: t0. + self MoveR: t0 R: t1. + jump4 := self Jump: b320. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. + self MoveR: t1 R: t0. + jump3 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + s54 := ValueIndex. + s55 := s54 << 3. + self AddCq: s55 R: t0. + self MoveM64: 8 r: t0 R: t0. + self ssPushRegister: t0. + ^ 0 ]. + self ssPushRegister: t0. ^ 0 ] diff --git a/Druid/DRCogitStackCoalescing.class.st b/Druid/DRCogitStackCoalescing.class.st index 04449bef..a35bd024 100644 --- a/Druid/DRCogitStackCoalescing.class.st +++ b/Druid/DRCogitStackCoalescing.class.st @@ -10,21 +10,36 @@ DRCogitStackCoalescing >> applyTo: cfg [ We should move them down to their common post dominator. Effects that apply the same operation on different branches get coallesced into a single effect (one push on each branch turns into a single push down in the CFG)" - | commonPostDominator basicBlock instructionsByStackDepth stackEffects | + | commonPostDominator basicBlock stackEffects currentStackEffects stackEffectsInReverseOrder | + cfg rebuildStackDependencies. stackEffects := cfg instructions select: [ :e | e isStackEffect ]. 1 haltIf: [ stackEffects anySatisfy: [ :p | p hasUsers ] ]. - instructionsByStackDepth := stackEffects groupedBy: [ :effect | - {effect stackDepth . effect class} ]. - instructionsByStackDepth keysAndValuesDo: [ :depth :instructionsAtDepth | - instructionsAtDepth size > 1 ifTrue: [ - commonPostDominator := cfg postDominatorTree dominatorOfAll: - instructionsAtDepth. - basicBlock := commonPostDominator block. - instructionsAtDepth anyOne isPush - ifTrue: [ - self coalescePushes: instructionsAtDepth in: basicBlock ] - ifFalse: [ self coalescePops: instructionsAtDepth in: basicBlock ] ] ] + stackEffectsInReverseOrder := Stack new. + currentStackEffects := #( ). + currentStackEffects := stackEffects select: [ :e | + (stackEffects intersection: + e stackEffectDependencies) isEmpty ]. + + [ stackEffects notEmpty ] whileTrue: [ + stackEffects removeAll: currentStackEffects. + currentStackEffects size > 1 ifTrue: [ + stackEffectsInReverseOrder push: currentStackEffects ]. + currentStackEffects := stackEffects select: [ :e | + (stackEffects intersection: + e stackEffectDependencies) isEmpty ] ]. + + [ stackEffectsInReverseOrder isEmpty ] whileFalse: [ + currentStackEffects := stackEffectsInReverseOrder pop. + commonPostDominator := cfg postDominatorTree dominatorOfAll: + currentStackEffects. + basicBlock := commonPostDominator block. + + currentStackEffects anyOne isPush + ifTrue: [ self coalescePushes: currentStackEffects in: basicBlock ] + ifFalse: [ self coalescePops: currentStackEffects in: basicBlock ] ]. + + cfg rebuildStackDependencies ] { #category : #accessing } diff --git a/Druid/DRIRGenerator.class.st b/Druid/DRIRGenerator.class.st index b23d1bfb..19963548 100644 --- a/Druid/DRIRGenerator.class.st +++ b/Druid/DRIRGenerator.class.st @@ -378,6 +378,7 @@ DRIRGenerator >> initializeSpecialCases [ specialCases at: #druidIf:do: put: #druidConditionalCompilationWith:. specialCases at: #interpreterIgnore: put: #interpretBlockArgumentValueWith:. specialCases at: #druidFail put: #interpretDruidFailWith:. + specialCases at: #value put: #interpretBlockValueWith:. specialCases at: #value: put: #interpretBlockValueWith:. specialCases at: #cull: put: #interpretBlockCullWith:. diff --git a/Druid/DRStackInstruction.class.st b/Druid/DRStackInstruction.class.st index 35e6dadd..0875e8b2 100644 --- a/Druid/DRStackInstruction.class.st +++ b/Druid/DRStackInstruction.class.st @@ -17,8 +17,20 @@ DRStackInstruction >> addStackDependent: aStackInstruction [ { #category : #dependencies } DRStackInstruction >> clearStackDependencies [ - stackDependencies := OrderedCollection new. - stackDependents := OrderedCollection new + stackDependencies := Set new. + stackDependents := Set new +] + +{ #category : #validation } +DRStackInstruction >> dataDependencies [ + + ^ super dependencies +] + +{ #category : #accessing } +DRStackInstruction >> dependencies [ + + ^ super dependencies , self stackDependencies ] { #category : #testing } @@ -72,8 +84,28 @@ DRStackInstruction >> stackDependents [ ^ stackDependents ] +{ #category : #accessing } +DRStackInstruction >> stackEffectDependencies [ + "Return the closest stack effect dependencies following the stack dependencies" + + ^ self stackDependencies flatCollect: [ :e | + e isStackEffect + ifTrue: [ { e } ] + ifFalse: [ e stackEffectDependencies ] ] +] + { #category : #validation } DRStackInstruction >> validate [ super validate ] + +{ #category : #validation } +DRStackInstruction >> validateDependenciesAreUsedByMyself [ + + self dataDependencies do: [ :op | + (op hasUser: self) ifFalse: [ + DRError signal: + 'Dependency-user mismatch between: ' , self asString , ' and: ' + , op asString ] ] +] From 4f6a6064e72682e58395c875f438034d23a4b96a Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Mon, 6 May 2024 13:03:37 +0200 Subject: [PATCH 22/33] Extend register allocation to take into account staged stack. Push instructions extend register lifes until pops or end of code. --- Druid-Tests/DRStackEffectTest.class.st | 44 ++++++++++++++++ Druid-Tests/DruidTestRTLCompiler.class.st | 12 +++-- ...RCogitLinearScanRegisterAllocator.class.st | 52 +++++++++---------- Druid/DRLinearScanRegisterAllocator.class.st | 21 +++++--- Druid/DRLoadStackValue.class.st | 12 +++++ Druid/DRPush.class.st | 14 +++++ Druid/DRStackInstruction.class.st | 27 ++++++++++ 7 files changed, 143 insertions(+), 39 deletions(-) diff --git a/Druid-Tests/DRStackEffectTest.class.st b/Druid-Tests/DRStackEffectTest.class.st index 7eb6ef2d..db2fc77c 100644 --- a/Druid-Tests/DRStackEffectTest.class.st +++ b/Druid-Tests/DRStackEffectTest.class.st @@ -68,6 +68,28 @@ DRStackEffectTest >> testPopInMergePointDependsOnBothBranches [ pop2 } ] +{ #category : #tests } +DRStackEffectTest >> testPopKnowsDefiningInstruction [ + + | irBuilder push pop push2 pop2 | + irBuilder := DRMetaCompilerIRGenerator new. + irBuilder pushFrame: DRStackFrame new. + + push := irBuilder + addInstructionFrom: nil + instructionKind: DRPush + operands: { 17 }. + push2 := irBuilder + addInstructionFrom: nil + instructionKind: DRPush + operands: { 17 }. + pop := irBuilder addInstructionFrom: nil instructionKind: DRPop. + pop2 := irBuilder addInstructionFrom: nil instructionKind: DRPop. + + self assert: pop definingStackInstruction equals: push2. + self assert: pop2 definingStackInstruction equals: push +] + { #category : #tests } DRStackEffectTest >> testPushDependsOnPop [ @@ -106,3 +128,25 @@ DRStackEffectTest >> testRebuildStackDependenciesReconstructsOriginalGraph [ pop1. pop2 } ] + +{ #category : #tests } +DRStackEffectTest >> testStackValueKnowsDefiningInstruction [ + + | irBuilder push push2 loadPrev loadTop | + irBuilder := DRMetaCompilerIRGenerator new. + irBuilder pushFrame: DRStackFrame new. + + push := irBuilder + addInstructionFrom: nil + instructionKind: DRPush + operands: { 17 }. + push2 := irBuilder + addInstructionFrom: nil + instructionKind: DRPush + operands: { 17 }. + loadPrev := irBuilder addInstructionFrom: nil instructionKind: DRLoadStackValue operands: { 1 }. + loadTop := irBuilder addInstructionFrom: nil instructionKind: DRLoadStackValue operands: { 0 }. + + self assert: loadTop definingStackInstruction equals: push2. + self assert: loadPrev definingStackInstruction equals: push +] diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index fdc370f2..ff91a886 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -1200,7 +1200,7 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ "AutoGenerated by Druid" - | s6 jump1 t1 s2 currentBlock s12 t0 s7 jump2 s11 live | + | s6 jump1 t1 s2 currentBlock s12 t0 s7 jump2 s11 live t2 | live := 0. self annotateBytecode: self Label. t0 := self @@ -1230,12 +1230,16 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ jump2 jmpTarget: currentBlock. self ssPushRegister: t1. self ssPushRegister: t0. - (self ssValue: 0) copyToReg: t1. + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + (self ssValue: 0) copyToReg: t2. self ssPop: 1. (self ssValue: 0) copyToReg: t0. self ssPop: 1. - self AddR: t0 R: t1. - self ssPushRegister: t1. + self AddR: t0 R: t2. + self ssPushRegister: t2. ^ 0 ] diff --git a/Druid/DRCogitLinearScanRegisterAllocator.class.st b/Druid/DRCogitLinearScanRegisterAllocator.class.st index 66f17211..9a0a2b27 100644 --- a/Druid/DRCogitLinearScanRegisterAllocator.class.st +++ b/Druid/DRCogitLinearScanRegisterAllocator.class.st @@ -84,34 +84,30 @@ DRCogitLinearScanRegisterAllocator >> coalesceIntervalsForTwoAddressCode [ ] { #category : #'live-analysis' } -DRCogitLinearScanRegisterAllocator >> computeLivenessOfInstruction: anInstruction inBlock: b withLiveSet: live [ - - "If the instruction is an integer division or modulo, this will be translated in cogit's DIVR:R:Quo:Rem: instruction. - This instruction requires 4 different registers and not three (operands + destination). - We model this by adding an extra operand at this point." - - "Then regiter the live interval for the new synthetic operand" - - ((anInstruction isDivision or: [ anInstruction isModulo ]) and: [ - anInstruction type isFloatType not ]) ifTrue: [ - | newOperand | - anInstruction operands size = 2 - ifTrue: [ - newOperand := anInstruction basicBlock controlFlowGraph - allocateTemporaryRegister. - anInstruction addOperand: newOperand ] - ifFalse: [ newOperand := anInstruction operands last ]. - - - "This live set starts in the next instruction, but it is not used so it will be freed" - (self liveSetOf: newOperand) - addRangeFrom: anInstruction - to: anInstruction nextInstruction ]. - - ^ super - computeLivenessOfInstruction: anInstruction - inBlock: b - withLiveSet: live +DRCogitLinearScanRegisterAllocator >> computeLivenessOfInstruction: i inBlock: b withLiveSet: live [ + + (i isStackInstruction and: [ i isPush not ]) ifTrue: [ + | definingStackInstruction | + definingStackInstruction := i definingStackInstruction. + definingStackInstruction ifNotNil: [ + self assert: definingStackInstruction isPush. + self + updateLiveSet: live + ofOperand: definingStackInstruction operand1 + ofInstruction: i + inBlock: b ] ]. + + "If i defines an SSA register, remove it from the live set from now on" + i result isSSARegister ifTrue: [ + live remove: i ifAbsent: [ self initializeLiveSetOfInstruction: i ] ]. + ^ i dependencies do: [ :op | + (op result isSSARegister and: [ + op isStaged not and: [ (live includes: op) not ] ]) ifTrue: [ + self + updateLiveSet: live + ofOperand: op + ofInstruction: i + inBlock: b ] ] ] { #category : #initialization } diff --git a/Druid/DRLinearScanRegisterAllocator.class.st b/Druid/DRLinearScanRegisterAllocator.class.st index dc3d3487..450d3f50 100644 --- a/Druid/DRLinearScanRegisterAllocator.class.st +++ b/Druid/DRLinearScanRegisterAllocator.class.st @@ -322,17 +322,24 @@ DRLinearScanRegisterAllocator >> computeLiveSets [ { #category : #'live-analysis' } DRLinearScanRegisterAllocator >> computeLivenessOfInstruction: i inBlock: b withLiveSet: live [ + "If this is a pop, it may implicitly be using a register (the one it's popping)" + i isPop ifTrue: [ + self + updateLiveSet: live + ofOperand: i definingStackInstruction + ofInstruction: i + inBlock: b ]. + i result isSSARegister ifTrue: [ live remove: i ifAbsent: [ self initializeLiveSetOfInstruction: i ] ]. ^ i dependencies do: [ :op | (op result isSSARegister and: [ - op isStaged not and: [ (live includes: op) not ] ]) - ifTrue: [ - self - updateLiveSet: live - ofOperand: op - ofInstruction: i - inBlock: b ] ] + op isStaged not and: [ (live includes: op) not ] ]) ifTrue: [ + self + updateLiveSet: live + ofOperand: op + ofInstruction: i + inBlock: b ] ] ] { #category : #accessing } diff --git a/Druid/DRLoadStackValue.class.st b/Druid/DRLoadStackValue.class.st index e1e9cf89..6954c5bf 100644 --- a/Druid/DRLoadStackValue.class.st +++ b/Druid/DRLoadStackValue.class.st @@ -10,6 +10,12 @@ DRLoadStackValue >> acceptVisitor: aVisitor [ ^ aVisitor visitLoadStackValue: self ] +{ #category : #visiting } +DRLoadStackValue >> definingStackInstruction [ + + ^ self stackSlotDefiningAtDepth: operands first value ifNone: [ nil ] +] + { #category : #testing } DRLoadStackValue >> isLoadStackValue [ @@ -37,6 +43,12 @@ DRLoadStackValue >> shiftStackAccessBy: anInteger [ super shiftStackAccessBy: anInteger ] +{ #category : #accessing } +DRLoadStackValue >> stackDelta [ + + ^ 0 +] + { #category : #testing } DRLoadStackValue >> stackDepth [ diff --git a/Druid/DRPush.class.st b/Druid/DRPush.class.st index fabaa19b..8dd10673 100644 --- a/Druid/DRPush.class.st +++ b/Druid/DRPush.class.st @@ -63,6 +63,13 @@ DRPush >> size [ ^ 8 "bytes" ] +{ #category : #accessing } +DRPush >> stackDelta [ + + "I add one element to the stack" + ^ -1 +] + { #category : #testing } DRPush >> stackDepth [ @@ -72,3 +79,10 @@ DRPush >> stackDepth [ stackDependencies ifEmpty: [ ^ 1 ]. ^ stackDependencies anyOne stackDepth + 1 ] + +{ #category : #'as yet unclassified' } +DRPush >> stackSlotsDefiningAtDepth: anInteger [ + + anInteger = 0 ifTrue: [ ^ { self } ]. + ^ super stackSlotsDefiningAtDepth: anInteger +] diff --git a/Druid/DRStackInstruction.class.st b/Druid/DRStackInstruction.class.st index 0875e8b2..0ab4eca4 100644 --- a/Druid/DRStackInstruction.class.st +++ b/Druid/DRStackInstruction.class.st @@ -27,6 +27,13 @@ DRStackInstruction >> dataDependencies [ ^ super dependencies ] +{ #category : #'as yet unclassified' } +DRStackInstruction >> definingStackInstruction [ + + "Return the stack instruction defining the stack slot I'm popping" + ^ self stackSlotDefiningAtDepth: -1 ifNone: [ nil ] +] + { #category : #accessing } DRStackInstruction >> dependencies [ @@ -94,6 +101,26 @@ DRStackInstruction >> stackEffectDependencies [ ifFalse: [ e stackEffectDependencies ] ] ] +{ #category : #'as yet unclassified' } +DRStackInstruction >> stackSlotDefiningAtDepth: anInteger ifNone: aBlock [ + "The only stack instructions defining stack slots are the push instructions" + + | definingSlots | + definingSlots := self stackSlotsDefiningAtDepth: anInteger. + definingSlots ifEmpty: [ ^ aBlock value ]. + ^ definingSlots unique +] + +{ #category : #'as yet unclassified' } +DRStackInstruction >> stackSlotsDefiningAtDepth: anInteger [ + "The only stack instructions defining stack slots are the push instructions" + + | definingSlots | + definingSlots := self stackDependencies flatCollect: [ :s | + s stackSlotsDefiningAtDepth: anInteger + self stackDelta ]. + ^ definingSlots +] + { #category : #validation } DRStackInstruction >> validate [ From 4726372a704b6661d17529f7128475355b1dcf27 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Mon, 6 May 2024 14:20:28 +0200 Subject: [PATCH 23/33] Extract push and pop instructions from marshalling methods --- .../DRBytecodeCompilationTest.class.st | 15 ++++- Druid-Tests/DRProductionBytecodeTest.class.st | 3 + Druid-Tests/DruidTestRTLCompiler.class.st | 61 +++++++++++++++---- Druid/DRAbstractCompilerCompiler.class.st | 6 ++ Druid/DRBytecodeIRGenerator.class.st | 25 +++++--- Druid/DRCPSEdge.class.st | 6 ++ Druid/DRCogitSendMarshallInsertion.class.st | 12 ---- ...itStackToRegisterMappingGenerator.class.st | 4 +- .../StackToRegisterMappingCogit.extension.st | 3 +- 9 files changed, 96 insertions(+), 39 deletions(-) delete mode 100644 Druid/DRCogitSendMarshallInsertion.class.st diff --git a/Druid-Tests/DRBytecodeCompilationTest.class.st b/Druid-Tests/DRBytecodeCompilationTest.class.st index e4bcd8a8..17539549 100644 --- a/Druid-Tests/DRBytecodeCompilationTest.class.st +++ b/Druid-Tests/DRBytecodeCompilationTest.class.st @@ -5,7 +5,7 @@ Class { } { #category : #tests } -DRBytecodeCompilationTest >> compileBytecode: bytecode selector: aSelector thenDo: aBlock [ +DRBytecodeCompilationTest >> compileBytecode: bytecode selector: aSelector options: options thenDo: aBlock [ | generatorSelector compiler | generatorSelector := (#gen, '_' , aSelector) asSymbol. @@ -15,7 +15,8 @@ DRBytecodeCompilationTest >> compileBytecode: bytecode selector: aSelector thenD compiler := DRBytecodeCompilerCompiler new sourceName: aSelector; interpreter: self interpreter; - configureForCompilerClass: DruidTestRTLCompiler. + configureForCompilerClass: DruidTestRTLCompiler; + addCompilerOptions: options. compiler compile. "Then generate the machine code for that method" @@ -32,6 +33,16 @@ DRBytecodeCompilationTest >> compileBytecode: bytecode selector: aSelector thenD ] bytecodes: 100 ] +{ #category : #tests } +DRBytecodeCompilationTest >> compileBytecode: bytecode selector: aSelector thenDo: aBlock [ + + ^ self + compileBytecode: bytecode + selector: aSelector + options: #( ) + thenDo: aBlock +] + { #category : #tests } DRBytecodeCompilationTest >> doCompileBytecode: bytecode selector: aSelector [ diff --git a/Druid-Tests/DRProductionBytecodeTest.class.st b/Druid-Tests/DRProductionBytecodeTest.class.st index f4b754bf..e7e55f13 100644 --- a/Druid-Tests/DRProductionBytecodeTest.class.st +++ b/Druid-Tests/DRProductionBytecodeTest.class.st @@ -15,6 +15,7 @@ DRProductionBytecodeTest >> testBytecodeAdd [ self compileBytecode: 96 selector: #bytecodePrimAdd + options: #( staticTypePrediction ) thenDo: [ :generator | cogit ssPushRegister: ReceiverResultReg. cogit ssPushRegister: Arg0Reg. @@ -45,6 +46,7 @@ DRProductionBytecodeTest >> testBytecodeAddOverflow [ self compileBytecode: 96 selector: #bytecodePrimAdd + options: #( staticTypePrediction ) thenDo: [ :generator | cogit ssPushRegister: ReceiverResultReg. cogit ssPushRegister: Arg0Reg. @@ -812,6 +814,7 @@ DRProductionBytecodeTest >> testBytecodePrimSendAdd [ self compileBytecode: 96 selector: #bytecodePrimAdd + options: #( staticTypePrediction ) thenDo: [ :generator | cogit methodObj: method. "The receiver of the send!" diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index ff91a886..d4dfa427 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -901,13 +901,44 @@ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodePrimAdd [ "AutoGenerated by Druid" - | live currentBlock | + | t0 jump3 jump1 t1 currentBlock jump2 live t2 | live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + (self ssValue: 1) copyToReg: t0. + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + (self ssValue: 0) copyToReg: t1. + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + self MoveR: t0 R: t2. + self AndR: t1 R: t2. + self TstCq: 1 R: t2. + jump1 := self JumpZero: 0. + self AddR: t1 R: t0. + self AddCq: -1 R: t0. + jump2 := self JumpOverflow: 0. + self MoveR: t0 R: t2. + jump3 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. self marshallSendArguments: 1. self - genMarshalledSend: -1 + genMarshalledSendNoPush: -1 numArgs: 1 sendTable: ordinarySendTrampolines. + self MoveR: ReceiverResultReg R: t2. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + self ssPop: 2. + self ssPushRegister: t2. ^ 0 ] @@ -1480,7 +1511,7 @@ DruidTestRTLCompiler >> gen_extPushIntegerBytecode [ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ "AutoGenerated by Druid" - | s6 s3 s16 s25 s10 s8 s5 s2 s18 currentBlock s15 s24 s27 s4 s17 s26 live s9 | + | s6 s3 s16 s10 s8 s5 s2 s18 currentBlock s15 s4 s17 live s9 | live := 0. s2 := byte1. s3 := s2 >> 3. @@ -1503,21 +1534,23 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ numExtB := 0. self marshallSendArguments: s18. self - genMarshalledSend: s6 + genMarshalledSendNoPush: s6 numArgs: s18 sendTable: superSendTrampolines. + self ssPushConstant: ReceiverResultReg. ^ 0 ]. - s24 := s2 bitAnd: 7. - s25 := extB. - s26 := s25 << 3. - s27 := s24 + s26. + s15 := s2 bitAnd: 7. + s16 := extB. + s17 := s16 << 3. + s18 := s15 + s17. extB := 0. numExtB := 0. - self marshallSendArguments: s27. + self marshallSendArguments: s18. self - genMarshalledSend: s6 - numArgs: s27 + genMarshalledSendNoPush: s6 + numArgs: s18 sendTable: superSendTrampolines. + self ssPushConstant: ReceiverResultReg. ^ 0 ] @@ -8458,11 +8491,13 @@ DruidTestRTLCompiler >> gen_sendLiteralSelector0ArgsBytecode [ | live currentBlock | live := 0. - self marshallSendArguments: 0. + self marshallSendArgumentsNoPush: 0. self - genMarshalledSend: 1 + genMarshalledSendNoPush: 0 numArgs: 0 sendTable: ordinarySendTrampolines. + self ssPop: 1. + self ssPushConstant: ReceiverResultReg. ^ 0 ] diff --git a/Druid/DRAbstractCompilerCompiler.class.st b/Druid/DRAbstractCompilerCompiler.class.st index ab87cfa7..f7dd5e4b 100644 --- a/Druid/DRAbstractCompilerCompiler.class.st +++ b/Druid/DRAbstractCompilerCompiler.class.st @@ -30,6 +30,12 @@ DRAbstractCompilerCompiler >> addCompilerOption: anOption [ compilerOptions add: anOption ] +{ #category : #adding } +DRAbstractCompilerCompiler >> addCompilerOptions: aCollection [ + + aCollection do: [ :e | self addCompilerOption: e ] +] + { #category : #api } DRAbstractCompilerCompiler >> allocateRegistersIn: druidIR [ diff --git a/Druid/DRBytecodeIRGenerator.class.st b/Druid/DRBytecodeIRGenerator.class.st index c6ede80e..82681db6 100644 --- a/Druid/DRBytecodeIRGenerator.class.st +++ b/Druid/DRBytecodeIRGenerator.class.st @@ -331,7 +331,7 @@ DRBytecodeIRGenerator >> interpretSendWith: aRBMessageNode specialSelector: isSp Translate this as a send instruction" - | selectorIndex argumentCount | + | selectorIndex argumentCount send marshall | selectorIndex := self visitOperand: aRBMessageNode arguments first. argumentCount := self visitOperand: aRBMessageNode arguments second. @@ -352,13 +352,22 @@ DRBytecodeIRGenerator >> interpretSendWith: aRBMessageNode specialSelector: isSp "DRJITMessageSend will be translated using a instrinsic that already annotate the bytecode" self assert: controlFlowGraph hasAnnotatedBytecode not. - ^ self - addInstructionWithNoResultFrom: aRBMessageNode - instructionKind: DRJITMessageSend - operands: { - selectorIndex asDRValue. - argumentCount asDRValue. - sendTableName asDRValue } + send := self + addInstructionWithNoResultFrom: aRBMessageNode + instructionKind: DRJITMessageSend + operands: { + selectorIndex asDRValue. + argumentCount asDRValue. + sendTableName asDRValue }. + send addBefore: (marshall := DRCogitSendMarshall send: send). + argumentCount simpleConstantFold asDRValue isConstant + ifTrue: [ + argumentCount simpleConstantFold + 1 "Receiver" + timesRepeat: [ + self pop"ShouldPopSpilled: + argumentCount simpleConstantFold > self numRegArgs" ] ] + ifFalse: [ marshall "doPop: true" ]. + ^ self push: DRPhysicalGeneralPurposeRegister receiverResultReg ] { #category : #'special cases' } diff --git a/Druid/DRCPSEdge.class.st b/Druid/DRCPSEdge.class.st index ad49083f..15d2dba8 100644 --- a/Druid/DRCPSEdge.class.st +++ b/Druid/DRCPSEdge.class.st @@ -281,6 +281,12 @@ DRCPSEdge >> visitClosureCreation: aDRClosureCreation [ "Nothing" ] +{ #category : #visiting } +DRCPSEdge >> visitCogitSendMarshall: aDRCogitSendMarshall [ + + ^ nil +] + { #category : #visiting } DRCPSEdge >> visitComparison: aDRComparison ofBranch: aDRBranch andDo: aClosure [ diff --git a/Druid/DRCogitSendMarshallInsertion.class.st b/Druid/DRCogitSendMarshallInsertion.class.st deleted file mode 100644 index 7e88dc22..00000000 --- a/Druid/DRCogitSendMarshallInsertion.class.st +++ /dev/null @@ -1,12 +0,0 @@ -Class { - #name : #DRCogitSendMarshallInsertion, - #superclass : #DROptimisation, - #category : #'Druid-BytecodeToJITCompilation' -} - -{ #category : #accessing } -DRCogitSendMarshallInsertion >> applyTo: cfg [ - - cfg instructionsDo: [ :e | - e isJITMessageSend ifTrue: [ e addBefore: (DRCogitSendMarshall send: e) ] ] -] diff --git a/Druid/DRCogitStackToRegisterMappingGenerator.class.st b/Druid/DRCogitStackToRegisterMappingGenerator.class.st index fb1cb738..65f2459f 100644 --- a/Druid/DRCogitStackToRegisterMappingGenerator.class.st +++ b/Druid/DRCogitStackToRegisterMappingGenerator.class.st @@ -134,7 +134,7 @@ DRCogitStackToRegisterMappingGenerator >> visitCogitSendMarshall: aDRCogitSendMa generatorMethodBuilder addStatement: (RBMessageNode receiver: RBVariableNode selfNode - selector: #marshallSendArguments: + selector: #marshallSendArgumentsNoPush: arguments: (aDRCogitSendMarshall numberOfArguments rtlPushArgumentExpressions: self)) @@ -153,7 +153,7 @@ DRCogitStackToRegisterMappingGenerator >> visitJITMessageSend: aDRMessageSend [ generatorMethodBuilder addStatement: (RBMessageNode receiver: RBVariableNode selfNode - selector: #genMarshalledSend:numArgs:sendTable: + selector: #genMarshalledSendNoPush:numArgs:sendTable: arguments: { (aDRMessageSend operand1 rtlPushArgumentExpressions: self) first. (aDRMessageSend operand2 rtlPushArgumentExpressions: self) first. diff --git a/Druid/StackToRegisterMappingCogit.extension.st b/Druid/StackToRegisterMappingCogit.extension.st index c9b5320e..26131a7c 100644 --- a/Druid/StackToRegisterMappingCogit.extension.st +++ b/Druid/StackToRegisterMappingCogit.extension.st @@ -33,8 +33,7 @@ StackToRegisterMappingCogit class >> druidNewOptimizationList [ optimisations add: DRCogitOperandSorter new. optimisations add: DRCogitStager new. optimisations add: DRCogitOperandSorter new. - - optimisations add: DRCogitSendMarshallInsertion new. + optimisations add: DRCogitStackToRegisterFlushHoisting new. optimisations add: DRDeadCodeElimination new. ^ optimisations From c7da5757b27832823576048bdbc5c4ec4d7e6bd1 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Mon, 6 May 2024 14:47:48 +0200 Subject: [PATCH 24/33] Recover register allocation of division --- ...RCogitLinearScanRegisterAllocator.class.st | 63 ++++++++++++------- Druid/DRLinearScanRegisterAllocator.class.st | 21 +++---- 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/Druid/DRCogitLinearScanRegisterAllocator.class.st b/Druid/DRCogitLinearScanRegisterAllocator.class.st index 9a0a2b27..13a33364 100644 --- a/Druid/DRCogitLinearScanRegisterAllocator.class.st +++ b/Druid/DRCogitLinearScanRegisterAllocator.class.st @@ -84,30 +84,45 @@ DRCogitLinearScanRegisterAllocator >> coalesceIntervalsForTwoAddressCode [ ] { #category : #'live-analysis' } -DRCogitLinearScanRegisterAllocator >> computeLivenessOfInstruction: i inBlock: b withLiveSet: live [ - - (i isStackInstruction and: [ i isPush not ]) ifTrue: [ - | definingStackInstruction | - definingStackInstruction := i definingStackInstruction. - definingStackInstruction ifNotNil: [ - self assert: definingStackInstruction isPush. - self - updateLiveSet: live - ofOperand: definingStackInstruction operand1 - ofInstruction: i - inBlock: b ] ]. - - "If i defines an SSA register, remove it from the live set from now on" - i result isSSARegister ifTrue: [ - live remove: i ifAbsent: [ self initializeLiveSetOfInstruction: i ] ]. - ^ i dependencies do: [ :op | - (op result isSSARegister and: [ - op isStaged not and: [ (live includes: op) not ] ]) ifTrue: [ - self - updateLiveSet: live - ofOperand: op - ofInstruction: i - inBlock: b ] ] +DRCogitLinearScanRegisterAllocator >> computeLivenessOfInstruction: anInstruction inBlock: b withLiveSet: live [ + + (anInstruction isStackInstruction and: [ anInstruction isPush not ]) + ifTrue: [ + | definingStackInstruction | + definingStackInstruction := anInstruction definingStackInstruction. + definingStackInstruction ifNotNil: [ + self assert: definingStackInstruction isPush. + self + updateLiveSet: live + ofOperand: definingStackInstruction operand1 + ofInstruction: anInstruction + inBlock: b ] ]. + + "If the instruction is an integer division or modulo, this will be translated in cogit's DIVR:R:Quo:Rem: instruction. + This instruction requires 4 different registers and not three (operands + destination). + We model this by adding an extra operand at this point." + + "Then register the live interval for the new synthetic operand" + ((anInstruction isDivision or: [ anInstruction isModulo ]) and: [ + anInstruction type isFloatType not ]) ifTrue: [ + | newOperand | + anInstruction operands size = 2 + ifTrue: [ + newOperand := anInstruction basicBlock controlFlowGraph + allocateTemporaryRegister. + anInstruction addOperand: newOperand ] + ifFalse: [ newOperand := anInstruction operands last ]. + + + "This live set starts in the next instruction, but it is not used so it will be freed" + (self liveSetOf: newOperand) + addRangeFrom: anInstruction + to: anInstruction nextInstruction ]. + + ^ super + computeLivenessOfInstruction: anInstruction + inBlock: b + withLiveSet: live ] { #category : #initialization } diff --git a/Druid/DRLinearScanRegisterAllocator.class.st b/Druid/DRLinearScanRegisterAllocator.class.st index 450d3f50..dc3d3487 100644 --- a/Druid/DRLinearScanRegisterAllocator.class.st +++ b/Druid/DRLinearScanRegisterAllocator.class.st @@ -322,24 +322,17 @@ DRLinearScanRegisterAllocator >> computeLiveSets [ { #category : #'live-analysis' } DRLinearScanRegisterAllocator >> computeLivenessOfInstruction: i inBlock: b withLiveSet: live [ - "If this is a pop, it may implicitly be using a register (the one it's popping)" - i isPop ifTrue: [ - self - updateLiveSet: live - ofOperand: i definingStackInstruction - ofInstruction: i - inBlock: b ]. - i result isSSARegister ifTrue: [ live remove: i ifAbsent: [ self initializeLiveSetOfInstruction: i ] ]. ^ i dependencies do: [ :op | (op result isSSARegister and: [ - op isStaged not and: [ (live includes: op) not ] ]) ifTrue: [ - self - updateLiveSet: live - ofOperand: op - ofInstruction: i - inBlock: b ] ] + op isStaged not and: [ (live includes: op) not ] ]) + ifTrue: [ + self + updateLiveSet: live + ofOperand: op + ofInstruction: i + inBlock: b ] ] ] { #category : #accessing } From 96379dc91902a40ab8d63cc722474771e6e86633 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Mon, 6 May 2024 17:26:02 +0200 Subject: [PATCH 25/33] Add support for unspilling slots --- ...DRBytecodeScenarioCompilationTest.class.st | 182 ++++++++++++++++++ .../DRCogitStackCoalescingTest.class.st | 5 + Druid-Tests/DRProductionBytecodeTest.class.st | 49 ++--- Druid-Tests/DruidTestRTLCompiler.class.st | 53 +++-- Druid/DRBasicBlock.class.st | 18 ++ Druid/DRBranchIfCondition.class.st | 2 +- Druid/DRBytecodeIRGenerator.class.st | 26 ++- Druid/DRCPSEdge.class.st | 6 + Druid/DRCogitCanonicaliser.class.st | 20 +- Druid/DRCogitOperandSorter.class.st | 6 + Druid/DRCogitSendMarshall.class.st | 22 +++ Druid/DRCogitStackCanonicaliser.class.st | 6 + Druid/DRCogitStackCoalescing.class.st | 12 +- ...itStackToRegisterMappingGenerator.class.st | 21 +- Druid/DRInstructionFactory.class.st | 18 +- Druid/DRMetaCompilerIRGenerator.class.st | 6 + Druid/DRPop.class.st | 6 + Druid/DRUnspillStackSlot.class.st | 30 +++ 18 files changed, 414 insertions(+), 74 deletions(-) create mode 100644 Druid-Tests/DRCogitStackCoalescingTest.class.st create mode 100644 Druid/DRUnspillStackSlot.class.st diff --git a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st index ad212aaf..c7f513b2 100644 --- a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st +++ b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st @@ -4,6 +4,188 @@ Class { #category : #'Druid-Tests' } +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testCoalesceOneSpilledAndOneUnspilledPopInsertsUnspill [ + + | cfg basicBlock1 basicBlock2 mergeBlock popToUnspill popStackDepth | + cfg := DRControlFlowGraph new. + basicBlock1 := cfg newBasicBlockWith: [ :block | + block popUnspilled + ]. + basicBlock2 := cfg newBasicBlockWith: [ :block | + popToUnspill := block pop + ]. + cfg initialBasicBlock jumpIf: true to: basicBlock1 ifFalseTo: basicBlock2. + mergeBlock := cfg newBasicBlock. + basicBlock1 jumpTo: mergeBlock. + basicBlock2 jumpTo: mergeBlock. + + popStackDepth := popToUnspill stackDepth. + + DRCogitStackCoalescing applyTo: cfg. + + self assert: basicBlock2 firstInstruction isUnspill. + self assert: basicBlock2 firstInstruction operand1 value equals: popStackDepth +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testCoalesceOneSpilledAndOneUnspilledPopsIntoSingleUnpilledPop [ + + | cfg basicBlock1 basicBlock2 mergeBlock | + cfg := DRControlFlowGraph new. + basicBlock1 := cfg newBasicBlockWith: [ :block | + block popUnspilled + ]. + basicBlock2 := cfg newBasicBlockWith: [ :block | + block pop + ]. + cfg initialBasicBlock jumpIf: true to: basicBlock1 ifFalseTo: basicBlock2. + mergeBlock := cfg newBasicBlock. + basicBlock1 jumpTo: mergeBlock. + basicBlock2 jumpTo: mergeBlock. + + DRCogitStackCoalescing applyTo: cfg. + + self assert: mergeBlock firstInstruction isPop. + self assert: mergeBlock firstInstruction isUnspilled +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testCoalesceOneUnspilledAndOneSpilledPopInsertsUnspill [ + + | cfg basicBlock1 basicBlock2 mergeBlock popToUnspill popStackDepth | + cfg := DRControlFlowGraph new. + basicBlock2 := cfg newBasicBlockWith: [ :block | + popToUnspill := block pop + ]. + basicBlock1 := cfg newBasicBlockWith: [ :block | + block popUnspilled + ]. + cfg initialBasicBlock jumpIf: true to: basicBlock1 ifFalseTo: basicBlock2. + mergeBlock := cfg newBasicBlock. + basicBlock1 jumpTo: mergeBlock. + basicBlock2 jumpTo: mergeBlock. + + popStackDepth := popToUnspill stackDepth. + + DRCogitStackCoalescing applyTo: cfg. + + self assert: basicBlock2 firstInstruction isUnspill. + self assert: basicBlock2 firstInstruction operand1 value equals: popStackDepth +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testCoalesceOneUnspilledAndOnespilledPopsIntoSingleUnpilledPop [ + + | cfg basicBlock1 basicBlock2 mergeBlock | + cfg := DRControlFlowGraph new. + basicBlock2 := cfg newBasicBlockWith: [ :block | + block pop + ]. + basicBlock1 := cfg newBasicBlockWith: [ :block | + block popUnspilled + ]. + cfg initialBasicBlock jumpIf: true to: basicBlock1 ifFalseTo: basicBlock2. + mergeBlock := cfg newBasicBlock. + basicBlock1 jumpTo: mergeBlock. + basicBlock2 jumpTo: mergeBlock. + + DRCogitStackCoalescing applyTo: cfg. + + self assert: mergeBlock firstInstruction isPop. + self assert: mergeBlock firstInstruction isUnspilled +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testCoalesceTwoSpilledPopsDoesNotReplaceMovedInstructions [ + + | cfg basicBlock1 basicBlock2 mergeBlock | + cfg := DRControlFlowGraph new. + basicBlock1 := cfg newBasicBlockWith: [ :block | + block pop + ]. + basicBlock2 := cfg newBasicBlockWith: [ :block | + block pop + ]. + cfg initialBasicBlock jumpIf: true to: basicBlock1 ifFalseTo: basicBlock2. + mergeBlock := cfg newBasicBlock. + basicBlock1 jumpTo: mergeBlock. + basicBlock2 jumpTo: mergeBlock. + + DRCogitStackCoalescing applyTo: cfg. + + "Blocks only contain the jumps" + self assert: basicBlock1 instructions size equals: 1. + self assert: basicBlock2 instructions size equals: 1. +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testCoalesceTwoSpilledPopsIntoSingleSpilledPop [ + + | cfg basicBlock1 basicBlock2 mergeBlock | + cfg := DRControlFlowGraph new. + basicBlock1 := cfg newBasicBlockWith: [ :block | + block pop + ]. + basicBlock2 := cfg newBasicBlockWith: [ :block | + block pop + ]. + cfg initialBasicBlock jumpIf: true to: basicBlock1 ifFalseTo: basicBlock2. + mergeBlock := cfg newBasicBlock. + basicBlock1 jumpTo: mergeBlock. + basicBlock2 jumpTo: mergeBlock. + + DRCogitStackCoalescing applyTo: cfg. + + self assert: mergeBlock firstInstruction isPop. + self deny: mergeBlock firstInstruction isUnspilled +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testCoalesceTwoUnspilledPopsDoesNotReplaceMovedInstructions [ + + | cfg basicBlock1 basicBlock2 mergeBlock | + cfg := DRControlFlowGraph new. + basicBlock1 := cfg newBasicBlockWith: [ :block | + block popUnspilled + ]. + basicBlock2 := cfg newBasicBlockWith: [ :block | + block popUnspilled + ]. + cfg initialBasicBlock jumpIf: true to: basicBlock1 ifFalseTo: basicBlock2. + mergeBlock := cfg newBasicBlock. + basicBlock1 jumpTo: mergeBlock. + basicBlock2 jumpTo: mergeBlock. + + DRCogitStackCoalescing applyTo: cfg. + + "Blocks only contain the jumps" + self assert: basicBlock1 instructions size equals: 1. + self assert: basicBlock2 instructions size equals: 1. +] + +{ #category : #tests } +DRBytecodeScenarioCompilationTest >> testCoalesceTwoUnspilledPopsIntoSingleUnspilledPop [ + + | cfg basicBlock1 basicBlock2 mergeBlock | + cfg := DRControlFlowGraph new. + basicBlock1 := cfg newBasicBlockWith: [ :block | + block popUnspilled + ]. + basicBlock2 := cfg newBasicBlockWith: [ :block | + block popUnspilled + ]. + cfg initialBasicBlock jumpIf: true to: basicBlock1 ifFalseTo: basicBlock2. + mergeBlock := cfg newBasicBlock. + basicBlock1 jumpTo: mergeBlock. + basicBlock2 jumpTo: mergeBlock. + + DRCogitStackCoalescing applyTo: cfg. + + self assert: mergeBlock firstInstruction isPop. + self assert: mergeBlock firstInstruction isUnspilled +] + { #category : #tests } DRBytecodeScenarioCompilationTest >> testFlushStackOnBranch1 [ diff --git a/Druid-Tests/DRCogitStackCoalescingTest.class.st b/Druid-Tests/DRCogitStackCoalescingTest.class.st new file mode 100644 index 00000000..5601e54a --- /dev/null +++ b/Druid-Tests/DRCogitStackCoalescingTest.class.st @@ -0,0 +1,5 @@ +Class { + #name : #DRCogitStackCoalescingTest, + #superclass : #DROptimisationTest, + #category : #'Druid-Tests' +} diff --git a/Druid-Tests/DRProductionBytecodeTest.class.st b/Druid-Tests/DRProductionBytecodeTest.class.st index e7e55f13..35e3d787 100644 --- a/Druid-Tests/DRProductionBytecodeTest.class.st +++ b/Druid-Tests/DRProductionBytecodeTest.class.st @@ -55,14 +55,16 @@ DRProductionBytecodeTest >> testBytecodeAddOverflow [ generator value. "Then return without druid's compiled code" - cogit ssPopTopToReg: ReceiverResultReg. - cogit genUpArrowReturn ]. + cogit Stop ]. - "Should run, overflow, jump to the trampoline, and 17" + "Should run, overflow, jump to the trampoline and leave the registers as they are" self - executePrimitiveWithReceiver: - (memory integerObjectOf: memory maxSmallInteger) - withArguments: { (memory integerObjectOf: 1) }. + prepareStackForPrimitiveReceiver: (memory integerObjectOf: memory maxSmallInteger) + arguments: { memory integerObjectOf: 1 } + method: memory nilObject. + + "Check it arrives to trampoline ceSend: ClassReg above: true to: ReceiverReg numArgs: numArgs" + self runFrom: cogInitialAddress until: sendTrampolineAddress. self assert: (memory integerValueOf: machineSimulator receiverRegisterValue) @@ -799,23 +801,21 @@ DRProductionBytecodeTest >> testBytecodeNotIdenticalOfNonIdenticalObjectsWithFor { #category : #tests } DRProductionBytecodeTest >> testBytecodePrimSendAdd [ - "Setup the send trampoline" + | method selector | sendTrampolineAddress := self compile: [ cogit RetN: 0 ]. - cogit ordinarySendTrampolineAt: 1 "arg" put: sendTrampolineAddress. - + cogit ordinarySendTrampolineAt: 1 put: sendTrampolineAddress. "arg" + method := methodBuilder - newMethod; - literals: { - selector := (memory integerObjectOf: 42) }; - buildMethod. + newMethod; + literals: { (selector := memory integerObjectOf: 42) }; + buildMethod. self compileBytecode: 96 selector: #bytecodePrimAdd - options: #( staticTypePrediction ) - thenDo: [ :generator | + thenDo: [ :generator | cogit methodObj: method. "The receiver of the send!" cogit ssPushRegister: ReceiverResultReg. @@ -828,20 +828,23 @@ DRProductionBytecodeTest >> testBytecodePrimSendAdd [ self prepareStackForPrimitiveReceiver: (memory integerObjectOf: 17) - arguments: #() + arguments: #( ) method: method. "Check it arrives to trampoline ceSend: ClassReg above: true to: ReceiverReg numArgs: numArgs" self runFrom: cogInitialAddress until: sendTrampolineAddress. + "First argument: the selector" - self assert: machineSimulator classRegisterValue equals: (-1 twoComplementOfBitSize: 64) "+ selector index". + self + assert: machineSimulator classRegisterValue + equals: (-1 twoComplementOfBitSize: 64). "+ selector index" "Third argument: the receiver, then the argument is on the stack" - self assert: machineSimulator receiverRegisterValue equals: (memory integerObjectOf: 17). - self assert: machineSimulator arg0RegisterValue equals: (memory integerObjectOf: 42) - - - - + self + assert: machineSimulator receiverRegisterValue + equals: (memory integerObjectOf: 17). + self + assert: machineSimulator arg0RegisterValue + equals: (memory integerObjectOf: 42) ] { #category : #tests } diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index d4dfa427..c2a658fe 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -892,8 +892,8 @@ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ self MoveR: t2 R: t0. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPop: 1. self ssPushRegister: t0. + self ssPop: 1. ^ 0 ] @@ -921,15 +921,17 @@ DruidTestRTLCompiler >> gen_bytecodePrimAdd [ self AndR: t1 R: t2. self TstCq: 1 R: t2. jump1 := self JumpZero: 0. - self AddR: t1 R: t0. self AddCq: -1 R: t0. + self AddR: t1 R: t0. jump2 := self JumpOverflow: 0. + self ssUnspillStackSlotAt: 0. + self ssUnspillStackSlotAt: 1. self MoveR: t0 R: t2. jump3 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. - self marshallSendArguments: 1. + self marshallSendArgumentsNoPush: 1. self genMarshalledSendNoPush: -1 numArgs: 1 @@ -937,7 +939,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimAdd [ self MoveR: ReceiverResultReg R: t2. currentBlock := self Label. jump3 jmpTarget: currentBlock. - self ssPop: 2. + self ssPop: 2 popSpilled: false. self ssPushRegister: t2. ^ 0 ] @@ -1024,7 +1026,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ jump2 jmpTarget: currentBlock. currentBlock := self Label. jump3 jmpTarget: currentBlock. - self ssPop: 2. + self ssPop: 2 popSpilled: true. self CmpR: t1 R: t0. jump3 := self JumpNonZero: 0. s54 := objectMemory trueObject. @@ -1129,7 +1131,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ jump2 jmpTarget: currentBlock. currentBlock := self Label. jump3 jmpTarget: currentBlock. - self ssPop: 2. + self ssPop: 2 popSpilled: true. self CmpR: t1 R: t0. jump3 := self JumpZero: 0. s54 := objectMemory trueObject. @@ -1187,7 +1189,7 @@ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 t3 s2 currentBlock t1 jump2 live t2 | + | t0 jump1 s2 currentBlock t1 jump2 live t2 | live := 0. self annotateBytecode: self Label. t0 := self @@ -1203,26 +1205,21 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). (self ssValue: 1) copyToReg: t1. - t2 := self - allocateRegNotConflictingWith: live - ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t2). - self MoveR: t1 R: t2. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - (self ssValue: 0) copyToReg: t2. - t3 := self + (self ssValue: 0) copyToReg: t1. + t2 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t3). - (self ssValue: 1) copyToReg: t3. - self MoveR: t2 R: t0. - self MoveR: t3 R: t2. + live := live bitOr: (self registerMaskFor: t2). + (self ssValue: 1) copyToReg: t2. + self MoveR: t1 R: t0. + self MoveR: t2 R: t1. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPop: 1. - self AddR: t2 R: t0. + self ssPop: 2. + self AddR: t1 R: t0. self ssPushRegister: t0. ^ 0 ] @@ -1532,7 +1529,7 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ s18 := s15 + s17. extB := 0. numExtB := 0. - self marshallSendArguments: s18. + self marshallSendArgumentsNoPush: s18. self genMarshalledSendNoPush: s6 numArgs: s18 @@ -1545,7 +1542,7 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ s18 := s15 + s17. extB := 0. numExtB := 0. - self marshallSendArguments: s18. + self marshallSendArgumentsNoPush: s18. self genMarshalledSendNoPush: s6 numArgs: s18 @@ -8467,7 +8464,7 @@ DruidTestRTLCompiler >> gen_returnTopFromMethod [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. - self ssPop: 1. + self ssPop: 1 popSpilled: true. self MoveR: t0 R: ReceiverResultReg. self genUpArrowReturn. ^ 0 @@ -8493,10 +8490,10 @@ DruidTestRTLCompiler >> gen_sendLiteralSelector0ArgsBytecode [ live := 0. self marshallSendArgumentsNoPush: 0. self - genMarshalledSendNoPush: 0 + genMarshalledSendNoPush: 1 numArgs: 0 sendTable: ordinarySendTrampolines. - self ssPop: 1. + self ssPop: 1 popSpilled: false. self ssPushConstant: ReceiverResultReg. ^ 0 ] @@ -8513,7 +8510,7 @@ DruidTestRTLCompiler >> gen_shortConditionalJumpFalse [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. - self ssPop: 1. + self ssPop: 1 popSpilled: true. s5 := objectMemory falseObject. self ssFlushStack. self CmpCq: s5 R: t0. @@ -8552,7 +8549,7 @@ DruidTestRTLCompiler >> gen_shortConditionalJumpTrue [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. - self ssPop: 1. + self ssPop: 1 popSpilled: true. s5 := objectMemory trueObject. self ssFlushStack. self CmpCq: s5 R: t0. @@ -8626,7 +8623,7 @@ DruidTestRTLCompiler >> gen_storeAndPopReceiverVariableBytecode [ deadCode := false. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self ssPop: 1. + self ssPop: 1 popSpilled: true. self MoveR: t0 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. diff --git a/Druid/DRBasicBlock.class.st b/Druid/DRBasicBlock.class.st index 85ea092d..c83fa028 100644 --- a/Druid/DRBasicBlock.class.st +++ b/Druid/DRBasicBlock.class.st @@ -1061,6 +1061,24 @@ DRBasicBlock >> phiWithVariables: variables [ ^ self addInstruction: phi ] +{ #category : #building } +DRBasicBlock >> pop [ + + ^ self pop: 1 unspilled: false +] + +{ #category : #building } +DRBasicBlock >> pop: anInteger unspilled: aBoolean [ + + ^ self addInstruction: (self instructionFactory pop: anInteger unspilled: aBoolean) +] + +{ #category : #building } +DRBasicBlock >> popUnspilled [ + + ^ self pop: 1 unspilled: true +] + { #category : #dominance } DRBasicBlock >> postDominatedBlocks [ "Return true if the blocks in the argument are the only dominated blocks of the receiver. diff --git a/Druid/DRBranchIfCondition.class.st b/Druid/DRBranchIfCondition.class.st index 1420ff7e..6dae5d48 100644 --- a/Druid/DRBranchIfCondition.class.st +++ b/Druid/DRBranchIfCondition.class.st @@ -84,7 +84,7 @@ DRBranchIfCondition >> falseBranch: aDRBasicBlock [ { #category : #accessing } DRBranchIfCondition >> hasOverflowCheck [ - ^ condition isOverflow + ^ condition isOverflow or: [ condition isNoOverflow ] ] { #category : #initialization } diff --git a/Druid/DRBytecodeIRGenerator.class.st b/Druid/DRBytecodeIRGenerator.class.st index 82681db6..3d0fa8a6 100644 --- a/Druid/DRBytecodeIRGenerator.class.st +++ b/Druid/DRBytecodeIRGenerator.class.st @@ -360,13 +360,15 @@ DRBytecodeIRGenerator >> interpretSendWith: aRBMessageNode specialSelector: isSp argumentCount asDRValue. sendTableName asDRValue }. send addBefore: (marshall := DRCogitSendMarshall send: send). + + "If all arguments pass on registers, then we need to pop them from the stack, but the marshall already unspill them if spilled" argumentCount simpleConstantFold asDRValue isConstant ifTrue: [ - argumentCount simpleConstantFold + 1 "Receiver" - timesRepeat: [ - self pop"ShouldPopSpilled: - argumentCount simpleConstantFold > self numRegArgs" ] ] - ifFalse: [ marshall "doPop: true" ]. + argumentCount simpleConstantFold + 1 timesRepeat: [ + self + pop: 1 + unspilled: argumentCount simpleConstantFold <= self numRegArgs ] "Receiver" ] + ifFalse: [ marshall doPop: true ]. ^ self push: DRPhysicalGeneralPurposeRegister receiverResultReg ] @@ -457,13 +459,23 @@ DRBytecodeIRGenerator >> numberOfArguments: aValue [ self push: (self argRegisterNumber: i) ]" ] -{ #category : #accessing } +{ #category : #'pharo-stack' } DRBytecodeIRGenerator >> pop [ self addInstructionFrom: nil instructionKind: DRPop - operands: #( 1 ). + operands: #( 1 false ). + ^ self popOperand +] + +{ #category : #accessing } +DRBytecodeIRGenerator >> pop: n unspilled: aBoolean [ + + self + addInstructionFrom: nil + instructionKind: DRPop + operands: { n . aBoolean}. ^ self popOperand ] diff --git a/Druid/DRCPSEdge.class.st b/Druid/DRCPSEdge.class.st index 15d2dba8..a00757a8 100644 --- a/Druid/DRCPSEdge.class.st +++ b/Druid/DRCPSEdge.class.st @@ -710,3 +710,9 @@ DRCPSEdge >> visitUnsignedRightShift: aDRRightShift [ ^ nil ] + +{ #category : #visiting } +DRCPSEdge >> visitUnspillStackSlot: aDRUnspillStackSlot [ + + ^ nil +] diff --git a/Druid/DRCogitCanonicaliser.class.st b/Druid/DRCogitCanonicaliser.class.st index d1f4845c..840574be 100644 --- a/Druid/DRCogitCanonicaliser.class.st +++ b/Druid/DRCogitCanonicaliser.class.st @@ -358,19 +358,21 @@ DRCogitCanonicaliser >> visitPhiFunction: aDRPhiFunction [ { #category : #visiting } DRCogitCanonicaliser >> visitPop: aDRPop [ - "If I have no users, and my previous instruction is also a pop without users, merge us in a single PopMany instruction" | canBeMerged previous | previous := aDRPop previousInstruction ifNil: [ ^ self ]. canBeMerged := aDRPop hasUsers not and: [ - previous isPop and: [ previous hasUsers not ] ]. - canBeMerged ifTrue: [ - aDRPop previousInstruction removeFromCFG. - aDRPop replaceBy: (DRPop - operands: - { (previous numberOfPoppedElements - + aDRPop numberOfPoppedElements) asDRValue } - result: DRNoRegister new) ] + previous isPop and: [ + previous hasUsers not and: [ + previous isUnspilled = aDRPop isUnspilled ] ] ]. + canBeMerged ifFalse: [ ^ self ]. + aDRPop previousInstruction removeFromCFG. + aDRPop replaceBy: (DRPop + operands: { + (previous numberOfPoppedElements + aDRPop numberOfPoppedElements) + asDRValue. + aDRPop isUnspilled } + result: DRNoRegister new) ] { #category : #visiting } diff --git a/Druid/DRCogitOperandSorter.class.st b/Druid/DRCogitOperandSorter.class.st index dd4210ef..73bba31f 100644 --- a/Druid/DRCogitOperandSorter.class.st +++ b/Druid/DRCogitOperandSorter.class.st @@ -390,3 +390,9 @@ DRCogitOperandSorter >> visitUnsignedRightShift: aDRRightShift [ => extract its first operand into a copy instruction" self extractFirstOperandInCopyIfNecessaryFrom: aDRRightShift ] + +{ #category : #visiting } +DRCogitOperandSorter >> visitUnspillStackSlot: aDRUnspillStackSlot [ + + "Nothing" +] diff --git a/Druid/DRCogitSendMarshall.class.st b/Druid/DRCogitSendMarshall.class.st index 56113f8a..3cb77562 100644 --- a/Druid/DRCogitSendMarshall.class.st +++ b/Druid/DRCogitSendMarshall.class.st @@ -1,6 +1,9 @@ Class { #name : #DRCogitSendMarshall, #superclass : #DRInstruction, + #instVars : [ + 'doPop' + ], #category : #'Druid-BytecodeToJITCompilation' } @@ -16,6 +19,19 @@ DRCogitSendMarshall >> acceptVisitor: aVisitor [ aVisitor visitCogitSendMarshall: self ] +{ #category : #accessing } +DRCogitSendMarshall >> doPop: aBoolean [ + + doPop := aBoolean +] + +{ #category : #testing } +DRCogitSendMarshall >> initialize [ + + super initialize. + doPop := false +] + { #category : #testing } DRCogitSendMarshall >> isCogitSendMarshall [ @@ -58,3 +74,9 @@ DRCogitSendMarshall >> send [ ^ self operand1 ] + +{ #category : #asserting } +DRCogitSendMarshall >> shouldPop [ + + ^ doPop +] diff --git a/Druid/DRCogitStackCanonicaliser.class.st b/Druid/DRCogitStackCanonicaliser.class.st index 225b2038..ae6cddc8 100644 --- a/Druid/DRCogitStackCanonicaliser.class.st +++ b/Druid/DRCogitStackCanonicaliser.class.st @@ -15,3 +15,9 @@ DRCogitStackCanonicaliser >> visitPush: aDRPush [ ^ self ]. aDRPush replaceDependency: pushedValue by: pushedValue address ] + +{ #category : #visiting } +DRCogitStackCanonicaliser >> visitUnspillStackSlot: aDRUnspillStackSlot [ + + "Nothing for now" +] diff --git a/Druid/DRCogitStackCoalescing.class.st b/Druid/DRCogitStackCoalescing.class.st index a35bd024..9751d56a 100644 --- a/Druid/DRCogitStackCoalescing.class.st +++ b/Druid/DRCogitStackCoalescing.class.st @@ -44,10 +44,18 @@ DRCogitStackCoalescing >> applyTo: cfg [ { #category : #accessing } DRCogitStackCoalescing >> coalescePops: pops in: postDominator [ + "If two pops have different spilling value, we need to unspill the spilled one" + + (pops collect: [ :e | e isUnspilled ] as: Set) size > 1 ifTrue: [ + pops + reject: [ :e | e isUnspilled ] + thenDo: [ :e | + e addBefore: (e instructionFactory unspill: e stackDepth negated - 1) ] ]. - postDominator addInstructionFirst: - postDominator instructionFactory pop. + postDominator addInstructionFirst: (postDominator instructionFactory + pop: 1 + unspilled: (pops anySatisfy: [ :e | e isUnspilled ])). pops do: [ :p | p removeFromCFG ] ] diff --git a/Druid/DRCogitStackToRegisterMappingGenerator.class.st b/Druid/DRCogitStackToRegisterMappingGenerator.class.st index 65f2459f..88d53094 100644 --- a/Druid/DRCogitStackToRegisterMappingGenerator.class.st +++ b/Druid/DRCogitStackToRegisterMappingGenerator.class.st @@ -134,7 +134,10 @@ DRCogitStackToRegisterMappingGenerator >> visitCogitSendMarshall: aDRCogitSendMa generatorMethodBuilder addStatement: (RBMessageNode receiver: RBVariableNode selfNode - selector: #marshallSendArgumentsNoPush: + selector: + #marshallSendArguments , (aDRCogitSendMarshall shouldPop + ifTrue: [ #NoPush ] + ifFalse: [ '' ]) , ':' arguments: (aDRCogitSendMarshall numberOfArguments rtlPushArgumentExpressions: self)) @@ -193,8 +196,10 @@ DRCogitStackToRegisterMappingGenerator >> visitPop: aDRPop [ generatorMethodBuilder addStatement: (RBMessageNode receiver: RBVariableNode selfNode - selector: #ssPop: - arguments: { (RBLiteralValueNode value: aDRPop numberOfPoppedElements) }) + selector: #ssPop:popSpilled: + arguments: { + (RBLiteralValueNode value: aDRPop numberOfPoppedElements). + (RBLiteralValueNode value: aDRPop isUnspilled not) }) ] { #category : #visiting } @@ -236,3 +241,13 @@ DRCogitStackToRegisterMappingGenerator >> visitTemporaryVariable: aDRLoadTempora self moveToReg: sourceDescriptorAST from: aDRLoadTemporaryVariable ] + +{ #category : #visiting } +DRCogitStackToRegisterMappingGenerator >> visitUnspillStackSlot: aDRUnspillStackSlot [ + + generatorMethodBuilder addStatement: (RBMessageNode + receiver: RBVariableNode selfNode + selector: #ssUnspillStackSlotAt: + arguments: + { (RBLiteralValueNode value: aDRUnspillStackSlot operand1 value) }) +] diff --git a/Druid/DRInstructionFactory.class.st b/Druid/DRInstructionFactory.class.st index 3d0b499d..5ee45941 100644 --- a/Druid/DRInstructionFactory.class.st +++ b/Druid/DRInstructionFactory.class.st @@ -271,7 +271,17 @@ DRInstructionFactory >> phiWithVariables: variables [ { #category : #factory } DRInstructionFactory >> pop [ - ^ DRPop operands: #( 1 ) result: self allocateTemporaryRegister + ^ self pop: 1 unspilled: false +] + +{ #category : #building } +DRInstructionFactory >> pop: anInteger unspilled: aBoolean [ + + ^ DRPop + operands: { + anInteger. + aBoolean } + result: self allocateTemporaryRegister ] { #category : #factory } @@ -345,3 +355,9 @@ DRInstructionFactory >> subtract: subtrahend from: minuend [ operands: { minuend asDRValue. subtrahend asDRValue } result: self allocateTemporaryRegister ] + +{ #category : #building } +DRInstructionFactory >> unspill: anInteger [ + + ^ DRUnspillStackSlot operands: { anInteger } result: DRNoRegister new +] diff --git a/Druid/DRMetaCompilerIRGenerator.class.st b/Druid/DRMetaCompilerIRGenerator.class.st index 730860c4..dd412d3c 100644 --- a/Druid/DRMetaCompilerIRGenerator.class.st +++ b/Druid/DRMetaCompilerIRGenerator.class.st @@ -109,6 +109,12 @@ DRMetaCompilerIRGenerator >> methodFor: aRBMessageNode withReceiver: receiver [ ^ methodFound ] +{ #category : #'calling convention' } +DRMetaCompilerIRGenerator >> numRegArgs [ + + ^ executionState baseFrame receiver value cogit numRegArgs +] + { #category : #accessing } DRMetaCompilerIRGenerator >> numberOfArguments: aValue [ diff --git a/Druid/DRPop.class.st b/Druid/DRPop.class.st index d1be48fa..b973f9a1 100644 --- a/Druid/DRPop.class.st +++ b/Druid/DRPop.class.st @@ -16,6 +16,12 @@ DRPop >> isPop [ ^ true ] +{ #category : #testing } +DRPop >> isUnspilled [ + + ^ operands second value +] + { #category : #accessing } DRPop >> numberOfPoppedElements [ diff --git a/Druid/DRUnspillStackSlot.class.st b/Druid/DRUnspillStackSlot.class.st new file mode 100644 index 00000000..1bde4a23 --- /dev/null +++ b/Druid/DRUnspillStackSlot.class.st @@ -0,0 +1,30 @@ +Class { + #name : #DRUnspillStackSlot, + #superclass : #DRInstruction, + #category : #'Druid-IR' +} + +{ #category : #visiting } +DRUnspillStackSlot >> acceptVisitor: aVisitor [ + + ^ aVisitor visitUnspillStackSlot: self +] + +{ #category : #visiting } +DRUnspillStackSlot >> isMandatoryInstruction [ + + ^ true +] + +{ #category : #testing } +DRUnspillStackSlot >> isUnspill [ + + ^ true +] + +{ #category : #SCCP } +DRUnspillStackSlot >> sccpLatticeValueFor: sccp [ + + "We know that we know nothing about the frame pointer" + ^ sccp bottom +] From 0787ff652bc6c338f90ef109af97284055855c34 Mon Sep 17 00:00:00 2001 From: Guille Polito Date: Thu, 20 Jun 2024 17:06:58 +0200 Subject: [PATCH 26/33] Rework data and stack dependencies for stack operation coallescing --- ...DRBytecodeScenarioCompilationTest.class.st | 6 +- Druid-Tests/DRProductionBytecodeTest.class.st | 80 ++++++++ Druid-Tests/DruidTestRTLCompiler.class.st | 157 ++++++++------- Druid/DRAbstractCompilerBuilder.class.st | 21 +- Druid/DRBytecodeIRGenerator.class.st | 22 +-- Druid/DRBytecodeObject.class.st | 24 ++- Druid/DRCogitCanonicaliser.class.st | 1 + Druid/DRCogitCodeGenerator.class.st | 7 +- Druid/DRCogitSimpleStackGenerator.class.st | 6 +- Druid/DRCogitStackCoalescing.class.st | 12 +- ...itStackToRegisterMappingGenerator.class.st | 32 +++- Druid/DRControlFlowGraph.class.st | 32 +++- Druid/DRControlFlowOptimisation.class.st | 1 + Druid/DRDeadCodeElimination.class.st | 2 +- Druid/DRIRGenerator.class.st | 2 +- Druid/DRInstruction.class.st | 6 + Druid/DRInstructionFactory.class.st | 2 +- Druid/DRInterpreterCompilationUnit.class.st | 6 +- Druid/DRInterpreterInstruction.class.st | 4 +- Druid/DRInterpreterToCompiler.class.st | 181 +++++++++--------- Druid/DRJITPrimitiveObject.class.st | 1 + ...LocalVariableInstructionScheluder.class.st | 1 - Druid/DRMethod.class.st | 13 +- Druid/DRMethodIRGenerator.class.st | 2 +- Druid/DRPop.class.st | 6 +- Druid/DRPrimitiveCompilerCompiler.class.st | 2 +- Druid/DRRegister.class.st | 8 +- Druid/DRSSARegister.class.st | 5 + Druid/DRStackInstruction.class.st | 4 +- Druid/SimpleStackBasedCogit.extension.st | 2 +- .../StackToRegisterMappingCogit.extension.st | 2 +- 31 files changed, 419 insertions(+), 231 deletions(-) diff --git a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st index c7f513b2..e7730159 100644 --- a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st +++ b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st @@ -21,11 +21,11 @@ DRBytecodeScenarioCompilationTest >> testCoalesceOneSpilledAndOneUnspilledPopIns basicBlock2 jumpTo: mergeBlock. popStackDepth := popToUnspill stackDepth. - + DRCogitStackCoalescing applyTo: cfg. self assert: basicBlock2 firstInstruction isUnspill. - self assert: basicBlock2 firstInstruction operand1 value equals: popStackDepth + self assert: basicBlock2 firstInstruction operand1 value equals: popStackDepth negated ] { #category : #tests } @@ -71,7 +71,7 @@ DRBytecodeScenarioCompilationTest >> testCoalesceOneUnspilledAndOneSpilledPopIns DRCogitStackCoalescing applyTo: cfg. self assert: basicBlock2 firstInstruction isUnspill. - self assert: basicBlock2 firstInstruction operand1 value equals: popStackDepth + self assert: basicBlock2 firstInstruction operand1 value equals: popStackDepth negated ] { #category : #tests } diff --git a/Druid-Tests/DRProductionBytecodeTest.class.st b/Druid-Tests/DRProductionBytecodeTest.class.st index 35e3d787..a9c53999 100644 --- a/Druid-Tests/DRProductionBytecodeTest.class.st +++ b/Druid-Tests/DRProductionBytecodeTest.class.st @@ -36,6 +36,46 @@ DRProductionBytecodeTest >> testBytecodeAdd [ equals: 42 + 17 ] +{ #category : #tests } +DRProductionBytecodeTest >> testBytecodeAddOneSpilledArg [ + + "We do not support the static type prediction yet" + + sendTrampolineAddress := self compile: [ cogit RetN: 0 ]. + cogit ordinarySendTrampolineAt: 1 put: sendTrampolineAddress. + + self + compileBytecode: 96 + selector: #bytecodePrimAdd + options: #( staticTypePrediction ) + thenDo: [ :generator | + + cogit methodOrBlockNumArgs: 0. "Hack" + cogit methodOrBlockNumTemps: 0. "Hack" + "Initialize the simulated stack" + cogit initSimStackForFramefulMethod: 0. + + cogit ssPushRegister: ReceiverResultReg. + cogit ssFlushStack. + + cogit ssPushRegister: Arg0Reg. + + "Execute the druid's compiled code" + generator value. + + "Then return without druid's compiled code" + cogit ssPopTopToReg: ReceiverResultReg. + cogit genUpArrowReturn ]. + + self + executePrimitiveWithReceiver: (memory integerObjectOf: 17) + withArguments: { (memory integerObjectOf: 42) }. + self + assert: + (memory integerValueOf: machineSimulator receiverRegisterValue) + equals: 42 + 17 +] + { #category : #tests } DRProductionBytecodeTest >> testBytecodeAddOverflow [ @@ -71,6 +111,46 @@ DRProductionBytecodeTest >> testBytecodeAddOverflow [ equals: memory maxSmallInteger ] +{ #category : #tests } +DRProductionBytecodeTest >> testBytecodeAddWithSpilledArgs [ + + "We do not support the static type prediction yet" + + sendTrampolineAddress := self compile: [ cogit RetN: 0 ]. + cogit ordinarySendTrampolineAt: 1 put: sendTrampolineAddress. + + self + compileBytecode: 96 + selector: #bytecodePrimAdd + options: #( staticTypePrediction ) + thenDo: [ :generator | + + cogit methodOrBlockNumArgs: 0. "Hack" + cogit methodOrBlockNumTemps: 0. "Hack" + "Initialize the simulated stack" + cogit initSimStackForFramefulMethod: 0. + + cogit ssPushRegister: ReceiverResultReg. + cogit ssPushRegister: Arg0Reg. + cogit ssFlushStack. + + "Execute the druid's compiled code" + 1halt. + generator value. + + "Then return without druid's compiled code" + cogit ssPopTopToReg: ReceiverResultReg. + cogit genUpArrowReturn ]. +1halt. + self + executePrimitiveWithReceiver: (memory integerObjectOf: 17) + withArguments: { (memory integerObjectOf: 42) }. + self + assert: + (memory integerValueOf: machineSimulator receiverRegisterValue) + equals: 42 + 17 +] + { #category : #tests } DRProductionBytecodeTest >> testBytecodeDuplicateTop [ diff --git a/Druid-Tests/DruidTestRTLCompiler.class.st b/Druid-Tests/DruidTestRTLCompiler.class.st index c2a658fe..df1055ca 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -892,8 +892,8 @@ DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ self MoveR: t2 R: t0. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self ssPop: 1 popSpilled: false. self ssPushRegister: t0. - self ssPop: 1. ^ 0 ] @@ -948,7 +948,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimAdd [ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ "AutoGenerated by Druid" - | jump1 s57 s54 t1 jump6 jump3 currentBlock t0 jump5 jump2 b498 b502 live t2 jump4 | + | jump1 s57 s54 t1 jump6 jump3 b496 b500 currentBlock t0 jump5 jump2 t3 live t2 jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -973,7 +973,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t2. - b502 := self Label. + b500 := self Label. self MoveR: t2 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -984,7 +984,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ jump4 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t0. self MoveR: t0 R: t2. - jump5 := self Jump: b502. + jump5 := self Jump: b500. currentBlock := self Label. jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. @@ -1004,48 +1004,50 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t2. - b498 := self Label. - self MoveR: t2 R: t1. - self AndCq: 7 R: t1. - self CmpCq: 0 R: t1. + b496 := self Label. + t3 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t3). + self MoveR: t2 R: t3. + self AndCq: 7 R: t3. + self CmpCq: 0 R: t3. jump1 := self JumpNonZero: 0. - self MoveM64: 0 r: t2 R: t1. - self AndCq: 16r3FFFF7 R: t1. - self CmpCq: 0 R: t1. + self MoveM64: 0 r: t2 R: t3. + self AndCq: 16r3FFFF7 R: t3. + self CmpCq: 0 R: t3. jump3 := self JumpNonZero: 0. - self MoveM64: 8 r: t2 R: t1. - self MoveR: t1 R: t2. - jump6 := self Jump: b498. + self MoveM64: 8 r: t2 R: t3. + self MoveR: t3 R: t2. + jump6 := self Jump: b496. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. - self MoveR: t2 R: t1. + self MoveR: t2 R: t3. jump3 := self Jump: 0. currentBlock := self Label. jump4 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. + self MoveR: t1 R: t3. currentBlock := self Label. jump3 jmpTarget: currentBlock. self ssPop: 2 popSpilled: true. - self CmpR: t1 R: t0. + self CmpR: t3 R: t0. jump3 := self JumpNonZero: 0. s54 := objectMemory trueObject. - self MoveCq: s54 R: t1. + self MoveCq: s54 R: t3. jump2 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. s57 := objectMemory falseObject. - self MoveCq: s57 R: t1. + self MoveCq: s57 R: t3. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self CmpCq: 0 R: t1. - jump2 := self JumpNonZero: 0. - jump3 := self Jump: 0. + self CmpCq: 0 R: t3. + jump2 := self JumpZero: 0. + self ssPushRegister: t3. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPushRegister: t1. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. ^ 0 ] @@ -1053,7 +1055,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ "AutoGenerated by Druid" - | jump1 s57 s54 t1 jump6 jump3 currentBlock t0 jump5 jump2 b498 b502 live t2 jump4 | + | jump1 s57 s54 t1 jump6 jump3 b496 b500 currentBlock t0 jump5 jump2 t3 live t2 jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -1078,7 +1080,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t2. - b502 := self Label. + b500 := self Label. self MoveR: t2 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -1089,7 +1091,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ jump4 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t0. self MoveR: t0 R: t2. - jump5 := self Jump: b502. + jump5 := self Jump: b500. currentBlock := self Label. jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. @@ -1109,48 +1111,50 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t2. - b498 := self Label. - self MoveR: t2 R: t1. - self AndCq: 7 R: t1. - self CmpCq: 0 R: t1. + b496 := self Label. + t3 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t3). + self MoveR: t2 R: t3. + self AndCq: 7 R: t3. + self CmpCq: 0 R: t3. jump1 := self JumpNonZero: 0. - self MoveM64: 0 r: t2 R: t1. - self AndCq: 16r3FFFF7 R: t1. - self CmpCq: 0 R: t1. + self MoveM64: 0 r: t2 R: t3. + self AndCq: 16r3FFFF7 R: t3. + self CmpCq: 0 R: t3. jump3 := self JumpNonZero: 0. - self MoveM64: 8 r: t2 R: t1. - self MoveR: t1 R: t2. - jump6 := self Jump: b498. + self MoveM64: 8 r: t2 R: t3. + self MoveR: t3 R: t2. + jump6 := self Jump: b496. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. - self MoveR: t2 R: t1. + self MoveR: t2 R: t3. jump3 := self Jump: 0. currentBlock := self Label. jump4 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. + self MoveR: t1 R: t3. currentBlock := self Label. jump3 jmpTarget: currentBlock. self ssPop: 2 popSpilled: true. - self CmpR: t1 R: t0. + self CmpR: t3 R: t0. jump3 := self JumpZero: 0. s54 := objectMemory trueObject. - self MoveCq: s54 R: t1. + self MoveCq: s54 R: t3. jump2 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. s57 := objectMemory falseObject. - self MoveCq: s57 R: t1. + self MoveCq: s57 R: t3. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self CmpCq: 0 R: t1. - jump2 := self JumpNonZero: 0. - jump3 := self Jump: 0. + self CmpCq: 0 R: t3. + jump2 := self JumpZero: 0. + self ssPushRegister: t3. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPushRegister: t1. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. ^ 0 ] @@ -1189,7 +1193,7 @@ DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ "AutoGenerated by Druid" - | t0 jump1 s2 currentBlock t1 jump2 live t2 | + | t0 jump1 t3 s2 currentBlock t1 jump2 live t2 | live := 0. self annotateBytecode: self Label. t0 := self @@ -1205,21 +1209,26 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t1). (self ssValue: 1) copyToReg: t1. + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + self MoveR: t1 R: t2. jump2 := self Jump: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - (self ssValue: 0) copyToReg: t1. - t2 := self + (self ssValue: 0) copyToReg: t2. + t3 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t2). - (self ssValue: 1) copyToReg: t2. - self MoveR: t1 R: t0. - self MoveR: t2 R: t1. + live := live bitOr: (self registerMaskFor: t3). + (self ssValue: 1) copyToReg: t3. + self MoveR: t2 R: t0. + self MoveR: t3 R: t2. currentBlock := self Label. jump2 jmpTarget: currentBlock. - self ssPop: 2. - self AddR: t1 R: t0. + self ssPop: 2 popSpilled: false. + self AddR: t2 R: t0. self ssPushRegister: t0. ^ 0 ] @@ -1236,7 +1245,7 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. - self ssPop: 1. + self ssPop: 1 popSpilled: false. self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. s6 := 1. @@ -1263,9 +1272,9 @@ DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t2). (self ssValue: 0) copyToReg: t2. - self ssPop: 1. + self ssPop: 1 popSpilled: false. (self ssValue: 0) copyToReg: t0. - self ssPop: 1. + self ssPop: 1 popSpilled: false. self AddR: t0 R: t2. self ssPushRegister: t2. ^ 0 @@ -1316,7 +1325,7 @@ DruidTestRTLCompiler >> gen_bytecodeWithPop [ | live currentBlock | live := 0. - self ssPop: 1. + self ssPop: 1 popSpilled: false. ^ 0 ] @@ -1368,7 +1377,7 @@ DruidTestRTLCompiler >> gen_emptyPrimitiveWithArguments [ DruidTestRTLCompiler >> gen_extBBytecode [ "AutoGenerated by Druid" - | s6 s3 s16 s13 s22 s25 s8 s2 currentBlock s12 s21 s24 s4 s17 s14 live s20 s9 | + | s6 s24 s16 s4 s22 s14 s9 s2 s20 currentBlock s12 s25 s17 live s5 s3 s21 s13 s8 | live := 0. s2 := byte1. s3 := numExtB. @@ -1508,7 +1517,7 @@ DruidTestRTLCompiler >> gen_extPushIntegerBytecode [ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ "AutoGenerated by Druid" - | s6 s3 s16 s10 s8 s5 s2 s18 currentBlock s15 s4 s17 live s9 | + | s6 s3 s16 s10 s8 s5 s2 s18 currentBlock s15 s4 s17 live s11 s9 | live := 0. s2 := byte1. s3 := s2 >> 3. @@ -1529,7 +1538,7 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ s18 := s15 + s17. extB := 0. numExtB := 0. - self marshallSendArgumentsNoPush: s18. + self marshallSendArguments: s18. self genMarshalledSendNoPush: s6 numArgs: s18 @@ -1542,7 +1551,7 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ s18 := s15 + s17. extB := 0. numExtB := 0. - self marshallSendArgumentsNoPush: s18. + self marshallSendArguments: s18. self genMarshalledSendNoPush: s6 numArgs: s18 @@ -1747,7 +1756,7 @@ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ "AutoGenerated by Druid" - | s6 jump5 s88 s81 s4 jump3 s44 s14 s9 s2 s36 currentBlock s49 s101 s67 t1 jump1 jump6 s47 live s5 s39 jump4 jump9 s3 t2 jump2 s91 s61 jump7 s74 s83 t0 s96 | + | s6 jump5 s88 s81 s4 jump3 s44 s14 s9 s2 s36 currentBlock s49 s101 s67 t1 jump1 jump6 s47 live s5 s39 jump4 jump9 s3 t2 jump2 s91 s61 jump7 s74 s83 t0 s96 s11 | live := 0. self annotateBytecode: self Label. s3 := byte1. @@ -2047,7 +2056,7 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ DruidTestRTLCompiler >> gen_extUnconditionalJump [ "AutoGenerated by Druid" - | s6 s33 s4 s22 s31 s38 jump3 s9 s2 s36 currentBlock t1 s42 s12 jump1 s10 s5 live s32 s23 s3 s21 s37 jump2 s43 s8 t0 s18 s41 | + | s6 s24 s33 s4 s22 s31 s38 jump3 s9 s2 s20 currentBlock s36 s42 s12 s7 t1 jump1 s10 s5 s23 live s32 s3 s21 s37 jump2 s43 s8 t0 s18 s41 | live := 0. self annotateBytecode: self Label. s3 := byte1. @@ -2167,7 +2176,7 @@ DruidTestRTLCompiler >> gen_extUnconditionalJump [ DruidTestRTLCompiler >> gen_extendedPushBytecode [ "AutoGenerated by Druid" - | s6 s3 s19 s28 s54 t1 s8 s5 s2 s30 currentBlock s21 t0 s4 s29 s55 live s20 | + | s6 s55 s4 s29 s2 s20 currentBlock t1 s19 s17 live s5 s54 s3 s28 s30 s21 s13 s8 s26 t0 | live := 0. s2 := byte1. s3 := s2 >> 6. @@ -8464,7 +8473,7 @@ DruidTestRTLCompiler >> gen_returnTopFromMethod [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. - self ssPop: 1 popSpilled: true. + self ssPop: 1 popSpilled: false. self MoveR: t0 R: ReceiverResultReg. self genUpArrowReturn. ^ 0 @@ -8493,7 +8502,7 @@ DruidTestRTLCompiler >> gen_sendLiteralSelector0ArgsBytecode [ genMarshalledSendNoPush: 1 numArgs: 0 sendTable: ordinarySendTrampolines. - self ssPop: 1 popSpilled: false. + self ssPop: 1 popSpilled: true. self ssPushConstant: ReceiverResultReg. ^ 0 ] @@ -8502,7 +8511,7 @@ DruidTestRTLCompiler >> gen_sendLiteralSelector0ArgsBytecode [ DruidTestRTLCompiler >> gen_shortConditionalJumpFalse [ "AutoGenerated by Druid" - | jump1 s8 s5 s2 jump3 currentBlock s12 t0 jump2 live s9 | + | jump1 s10 s8 s5 s2 jump3 currentBlock s12 t0 jump2 live s9 | live := 0. self annotateBytecode: self Label. t0 := self @@ -8510,7 +8519,7 @@ DruidTestRTLCompiler >> gen_shortConditionalJumpFalse [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. - self ssPop: 1 popSpilled: true. + self ssPop: 1 popSpilled: false. s5 := objectMemory falseObject. self ssFlushStack. self CmpCq: s5 R: t0. @@ -8541,7 +8550,7 @@ DruidTestRTLCompiler >> gen_shortConditionalJumpFalse [ DruidTestRTLCompiler >> gen_shortConditionalJumpTrue [ "AutoGenerated by Druid" - | jump1 s8 s5 s2 jump3 currentBlock s12 t0 jump2 live s9 | + | jump1 s10 s8 s5 s2 jump3 currentBlock s12 t0 jump2 live s9 | live := 0. self annotateBytecode: self Label. t0 := self @@ -8549,7 +8558,7 @@ DruidTestRTLCompiler >> gen_shortConditionalJumpTrue [ ifNone: [ ^ self unknownBytecode ]. live := live bitOr: (self registerMaskFor: t0). (self ssValue: 0) copyToReg: t0. - self ssPop: 1 popSpilled: true. + self ssPop: 1 popSpilled: false. s5 := objectMemory trueObject. self ssFlushStack. self CmpCq: s5 R: t0. @@ -8623,7 +8632,7 @@ DruidTestRTLCompiler >> gen_storeAndPopReceiverVariableBytecode [ deadCode := false. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self ssPop: 1 popSpilled: true. + self ssPop: 1 popSpilled: false. self MoveR: t0 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. diff --git a/Druid/DRAbstractCompilerBuilder.class.st b/Druid/DRAbstractCompilerBuilder.class.st index 84afb035..d0d7947b 100644 --- a/Druid/DRAbstractCompilerBuilder.class.st +++ b/Druid/DRAbstractCompilerBuilder.class.st @@ -11,7 +11,8 @@ Class { #superclass : #Object, #instVars : [ 'compilationUnit', - 'interpreterClass' + 'interpreterClass', + 'compilerOptions' ], #category : #'Druid-CompilerBuilder' } @@ -35,6 +36,17 @@ DRAbstractCompilerBuilder >> compilationUnitClass [ ^ DRInterpreterCompilationUnit ] +{ #category : #accessing } +DRAbstractCompilerBuilder >> compilerOptions [ + ^ compilerOptions +] + +{ #category : #options } +DRAbstractCompilerBuilder >> compilerOptions: aCollection [ + + compilerOptions := aCollection +] + { #category : #accessing } DRAbstractCompilerBuilder >> environmentAt: aClass [ "Answer the class named aClass. Create if it doesn't exist" @@ -57,6 +69,13 @@ DRAbstractCompilerBuilder >> handleErrorDuring: aFullBlockClosure [ self shouldBeImplemented. ] +{ #category : #initialization } +DRAbstractCompilerBuilder >> initialize [ + + super initialize. + compilerOptions := #( ) +] + { #category : #accessing } DRAbstractCompilerBuilder >> newClassNamed: aString superclass: aSuperclass [ "Answer a new subclass named aString" diff --git a/Druid/DRBytecodeIRGenerator.class.st b/Druid/DRBytecodeIRGenerator.class.st index 3d0fa8a6..0f36d2b5 100644 --- a/Druid/DRBytecodeIRGenerator.class.st +++ b/Druid/DRBytecodeIRGenerator.class.st @@ -11,9 +11,9 @@ Class { DRBytecodeIRGenerator >> addAnnotateBytecode: aRBMethodNode [ self - addInstructionWithNoResultFrom: aRBMethodNode - instructionKind: DRAnnotateBytecode - operands: #( ). + addInstructionWithNoResultFrom: aRBMethodNode + instructionKind: DRAnnotateBytecode + operands: #( ). ^ self popOperand "Let the stack empty" ] @@ -213,7 +213,7 @@ DRBytecodeIRGenerator >> interpretITemporaryInPutWith: aRBMessageNode [ value := (self visitOperand: aRBMessageNode arguments third) simpleConstantFold. ^ self - addInstructionFrom: aRBMessageNode + addInstructionWithNoResultFrom: aRBMessageNode instructionKind: DRStoreTemporaryVariable operands: { index asDRValue . value asDRValue } ] @@ -360,14 +360,15 @@ DRBytecodeIRGenerator >> interpretSendWith: aRBMessageNode specialSelector: isSp argumentCount asDRValue. sendTableName asDRValue }. send addBefore: (marshall := DRCogitSendMarshall send: send). + marshall addBefore: controlFlowGraph instructionFactory flushStack. "If all arguments pass on registers, then we need to pop them from the stack, but the marshall already unspill them if spilled" argumentCount simpleConstantFold asDRValue isConstant ifTrue: [ - argumentCount simpleConstantFold + 1 timesRepeat: [ + argumentCount simpleConstantFold + 1 timesRepeat: [ "Receiver" self pop: 1 - unspilled: argumentCount simpleConstantFold <= self numRegArgs ] "Receiver" ] + unspilled: argumentCount simpleConstantFold <= self numRegArgs ] ] ifFalse: [ marshall doPop: true ]. ^ self push: DRPhysicalGeneralPurposeRegister receiverResultReg ] @@ -463,7 +464,7 @@ DRBytecodeIRGenerator >> numberOfArguments: aValue [ DRBytecodeIRGenerator >> pop [ self - addInstructionFrom: nil + addInstructionWithNoResultFrom: nil instructionKind: DRPop operands: #( 1 false ). ^ self popOperand @@ -472,10 +473,9 @@ DRBytecodeIRGenerator >> pop [ { #category : #accessing } DRBytecodeIRGenerator >> pop: n unspilled: aBoolean [ - self - addInstructionFrom: nil - instructionKind: DRPop - operands: { n . aBoolean}. + self addInstructionWithNoResultFrom: nil instructionKind: DRPop operands: { + n. + aBoolean }. ^ self popOperand ] diff --git a/Druid/DRBytecodeObject.class.st b/Druid/DRBytecodeObject.class.st index 8ba0525a..b470f413 100644 --- a/Druid/DRBytecodeObject.class.st +++ b/Druid/DRBytecodeObject.class.st @@ -97,9 +97,23 @@ DRBytecodeObject >> compileUnitUsing: aCompiler [ sourceName: self sourceSelector; interpreter: interpreter; configureForCompilerClass: aCompiler targetClass; + addCompilerOptions: aCompiler compilerOptions; compile ] ] +{ #category : #translating } +DRBytecodeObject >> generate [ + + | compilerCompiler | + compilerCompiler := DRInterpreterToCompiler fromInterpreterClass: + CogVMSimulatorLSB. + compilerCompiler + doFailOnFirst; + targetClass: DruidJIT. + + ^ self compileUsing: compilerCompiler +] + { #category : #accessing } DRBytecodeObject >> notSupportedSelector [ @@ -114,13 +128,17 @@ DRBytecodeObject >> printOn: aStream [ << self bytecodeSize asString; << $); space; - << self bytecodeNumberStart asString; - << ' - '; - << self bytecodeNumberEnd asString; + << self range asString; space; << self genSelector ] +{ #category : #printing } +DRBytecodeObject >> range [ + + ^ self bytecodeNumberStart to: self bytecodeNumberEnd +] + { #category : #accessing } DRBytecodeObject >> targetSelector [ diff --git a/Druid/DRCogitCanonicaliser.class.st b/Druid/DRCogitCanonicaliser.class.st index 840574be..4d41eca8 100644 --- a/Druid/DRCogitCanonicaliser.class.st +++ b/Druid/DRCogitCanonicaliser.class.st @@ -406,6 +406,7 @@ DRCogitCanonicaliser >> visitStore: aDRStore [ | address addressExpression addressOperands offsetOperand baseOperand | address := aDRStore address. + (address isAbsolute and: [ address expression isAdd ]) ifFalse: [ ^ self ]. addressExpression := address expression. diff --git a/Druid/DRCogitCodeGenerator.class.st b/Druid/DRCogitCodeGenerator.class.st index 6834d53c..20c2172d 100644 --- a/Druid/DRCogitCodeGenerator.class.st +++ b/Druid/DRCogitCodeGenerator.class.st @@ -255,6 +255,9 @@ DRCogitCodeGenerator >> generateCodeForCFG: aDRControlFlowGraph [ generatorMethodBuilder addVariableNamed: e prettyPrint ]. blocks := self linearizeBlocksInCFG: aDRControlFlowGraph. + blocks do: [ :b | + b instructionsDo: [ :i | + i isStaged ifFalse: [ self allocateVariable: i result ] ] ]. self generateCodeFromBlocks. "Generate the postamble in the fallthrough case" @@ -701,10 +704,8 @@ DRCogitCodeGenerator >> twoOperandCogitRTL: aMnemonic operands: operands instruc { #category : #visiting } DRCogitCodeGenerator >> twoOperandMoveCogitRTL: anInstruction operands: operands [ - self allocateVariable: anInstruction result. (operands first isInterpreterReference and: [ - anInstruction type isObjectReference ]) ifTrue: [ - "It's moving a constant to a register. This constant could be an oop, so we need to annotate it." + anInstruction type isObjectReference ]) ifTrue: [ "It's moving a constant to a register. This constant could be an oop, so we need to annotate it." ^ self generateMessage: #genMoveConstant:R: operands: operands ]. self twoOperandCogitRTL: #Move diff --git a/Druid/DRCogitSimpleStackGenerator.class.st b/Druid/DRCogitSimpleStackGenerator.class.st index 7e87fc2d..743cff0f 100644 --- a/Druid/DRCogitSimpleStackGenerator.class.st +++ b/Druid/DRCogitSimpleStackGenerator.class.st @@ -16,11 +16,12 @@ DRCogitSimpleStackGenerator >> allocateVariable: aDRResult [ parent ifNotNil: [ ^ parent allocateVariable: aDRResult ]. aDRResult isNoResult ifTrue: [ ^ self ]. + variables at: aDRResult ifPresent: [ :var | ^ var ]. variableIndex := nextVariableIndex. nextVariableIndex := nextVariableIndex + 1. - +self haltIf: [ variableIndex = 4 ]. temporaryVariableNode := RBVariableNode named: 't' , variableIndex asString. variables at: aDRResult put: temporaryVariableNode name. @@ -207,7 +208,6 @@ DRCogitSimpleStackGenerator >> visitLoadReceiver: aDRLoadReceiver [ (RBVariableNode named: 'needsFrame ifTrue: [self putSelfInReceiverResultReg].'). - self allocateVariable: aDRLoadReceiver result. self twoOperandMoveCogitRTL: aDRLoadReceiver operands: { (DRPhysicalGeneralPurposeRegister name: 'ReceiverResultReg'). aDRLoadReceiver } @@ -268,7 +268,7 @@ DRCogitSimpleStackGenerator >> visitStoreTempVar: aDRStoreTemporaryVariable [ receiver: RBVariableNode selfNode selector: #MoveR:Mw:r: arguments: { - (self rtlExpressionForValue: aDRStoreTemporaryVariable result). + (self rtlExpressionForValue: aDRStoreTemporaryVariable operand2). (RBMessageNode receiver: RBVariableNode selfNode selector: #frameOffsetOfTemporary: diff --git a/Druid/DRCogitStackCoalescing.class.st b/Druid/DRCogitStackCoalescing.class.st index 9751d56a..83036593 100644 --- a/Druid/DRCogitStackCoalescing.class.st +++ b/Druid/DRCogitStackCoalescing.class.st @@ -10,7 +10,7 @@ DRCogitStackCoalescing >> applyTo: cfg [ We should move them down to their common post dominator. Effects that apply the same operation on different branches get coallesced into a single effect (one push on each branch turns into a single push down in the CFG)" - | commonPostDominator basicBlock stackEffects currentStackEffects stackEffectsInReverseOrder | + | commonPostDominator basicBlock stackEffects currentStackEffects stackEffectsInReverseOrder previous | cfg rebuildStackDependencies. stackEffects := cfg instructions select: [ :e | e isStackEffect ]. 1 haltIf: [ stackEffects anySatisfy: [ :p | p hasUsers ] ]. @@ -21,7 +21,9 @@ DRCogitStackCoalescing >> applyTo: cfg [ (stackEffects intersection: e stackEffectDependencies) isEmpty ]. - [ stackEffects notEmpty ] whileTrue: [ + previous := nil. + [ stackEffects notEmpty and: [ stackEffects ~= previous ] ] whileTrue: [ + previous := stackEffects copy. stackEffects removeAll: currentStackEffects. currentStackEffects size > 1 ifTrue: [ stackEffectsInReverseOrder push: currentStackEffects ]. @@ -47,10 +49,8 @@ DRCogitStackCoalescing >> coalescePops: pops in: postDominator [ "If two pops have different spilling value, we need to unspill the spilled one" (pops collect: [ :e | e isUnspilled ] as: Set) size > 1 ifTrue: [ - pops - reject: [ :e | e isUnspilled ] - thenDo: [ :e | - e addBefore: (e instructionFactory unspill: e stackDepth negated - 1) ] ]. + pops reject: [ :e | e isUnspilled ] thenDo: [ :e | + e addBefore: (e instructionFactory unspill: (e stackDepth + 1) negated) ] ]. postDominator addInstructionFirst: (postDominator instructionFactory diff --git a/Druid/DRCogitStackToRegisterMappingGenerator.class.st b/Druid/DRCogitStackToRegisterMappingGenerator.class.st index 88d53094..87bf7ad2 100644 --- a/Druid/DRCogitStackToRegisterMappingGenerator.class.st +++ b/Druid/DRCogitStackToRegisterMappingGenerator.class.st @@ -7,6 +7,19 @@ Class { #category : #'Druid-Cogit' } +{ #category : #helpers } +DRCogitStackToRegisterMappingGenerator >> freeRegisterLiveMask: temporaryVariableNode [ + + generatorMethodBuilder addStatement: + (RBAssignmentNode variable: (RBVariableNode named: 'live') value: (RBMessageNode + receiver: (RBVariableNode named: 'live') + selector: #bitClear: + arguments: { (RBMessageNode + receiver: RBVariableNode selfNode + selector: #registerMaskFor: + arguments: { temporaryVariableNode copy }) })) +] + { #category : #'ir-to-ast' } DRCogitStackToRegisterMappingGenerator >> generatePreambleForCFG: aDRControlFlowGraph [ @@ -125,7 +138,12 @@ DRCogitStackToRegisterMappingGenerator >> visitClosureCreation: aDRClosureCreati (RBVariableNode named: DRPhysicalGeneralPurposeRegister classReg name) }). - super visitClosureCreation: aDRClosureCreation + super visitClosureCreation: aDRClosureCreation. + self freeRegisterLiveMask: (RBVariableNode named: + DRPhysicalGeneralPurposeRegister sendNumArgsReg name). + self freeRegisterLiveMask: + (RBVariableNode named: + DRPhysicalGeneralPurposeRegister classReg name) ] { #category : #visiting } @@ -136,8 +154,8 @@ DRCogitStackToRegisterMappingGenerator >> visitCogitSendMarshall: aDRCogitSendMa receiver: RBVariableNode selfNode selector: #marshallSendArguments , (aDRCogitSendMarshall shouldPop - ifTrue: [ #NoPush ] - ifFalse: [ '' ]) , ':' + ifTrue: [ #'' ] + ifFalse: [ 'NoPush' ]) , ':' arguments: (aDRCogitSendMarshall numberOfArguments rtlPushArgumentExpressions: self)) @@ -170,10 +188,9 @@ DRCogitStackToRegisterMappingGenerator >> visitLoadReceiver: aDRLoadReceiver [ receiver: RBVariableNode selfNode selector: #ensureReceiverResultRegContainsSelf). - self allocateVariable: aDRLoadReceiver result. - self twoOperandMoveCogitRTL: aDRLoadReceiver operands: { - (DRPhysicalGeneralPurposeRegister name: 'ReceiverResultReg'). - aDRLoadReceiver } + self twoOperandMoveCogitRTL: aDRLoadReceiver operands: { + (DRPhysicalGeneralPurposeRegister name: 'ReceiverResultReg'). + aDRLoadReceiver } ] { #category : #visiting } @@ -224,6 +241,7 @@ DRCogitStackToRegisterMappingGenerator >> visitStoreTempVar: aDRStoreTemporaryVa arguments: (aDRStoreTemporaryVariable operand1 rtlPushArgumentExpressions: self)). + super visitStoreTempVar: aDRStoreTemporaryVariable ] diff --git a/Druid/DRControlFlowGraph.class.st b/Druid/DRControlFlowGraph.class.st index 4d212f16..74445db7 100644 --- a/Druid/DRControlFlowGraph.class.st +++ b/Druid/DRControlFlowGraph.class.st @@ -722,21 +722,35 @@ DRControlFlowGraph >> privateNewBasicBlock [ { #category : #building } DRControlFlowGraph >> rebuildStackDependencies [ - | lastStackInstructionPerBlock incomingStackInstructions | - lastStackInstructionPerBlock := Dictionary new. + | lastStackInstructionPerBlock incomingStackInstructions blocks | + lastStackInstructionPerBlock := Dictionary new. - self reversePostOrderBlocks do: [ :e | - incomingStackInstructions := e predecessors flatCollect: [ :p | + blocks := self reversePostOrderBlocks. + + [ blocks isEmpty ] whileFalse: [ | e previousDependencies | + e := blocks removeFirst. + incomingStackInstructions := e predecessors + flatCollect: [ :p | lastStackInstructionPerBlock at: p - ifAbsent: [ #( ) ] ]. + ifAbsent: [ #( ) ] ] + as: Set. e instructions do: [ :i | - i isStackInstruction ifTrue: [ + i isStackInstruction ifTrue: [ | thisIncomingStackInstructions | i clearStackDependencies. - i stackDependencies: incomingStackInstructions. - incomingStackInstructions do: [ :s | s addStackDependent: i ]. + thisIncomingStackInstructions := incomingStackInstructions select: [ :d | (d stackEffectDependencies includes: i) not ]. + i stackDependencies: thisIncomingStackInstructions. + thisIncomingStackInstructions do: [ :s | s addStackDependent: i ]. incomingStackInstructions := { i } ] ]. - lastStackInstructionPerBlock at: e put: incomingStackInstructions ] + + previousDependencies := lastStackInstructionPerBlock + at: e + ifAbsent: [ Set new ]. + previousDependencies ~= incomingStackInstructions ifTrue: [ + lastStackInstructionPerBlock at: e put: incomingStackInstructions. + e successors do: [ :succ | + (blocks includes: succ) + ifFalse: [ blocks add: succ ] ] ] ]. ] { #category : #removing } diff --git a/Druid/DRControlFlowOptimisation.class.st b/Druid/DRControlFlowOptimisation.class.st index 6c94dc07..898d178c 100644 --- a/Druid/DRControlFlowOptimisation.class.st +++ b/Druid/DRControlFlowOptimisation.class.st @@ -7,6 +7,7 @@ Class { { #category : #accessing } DRControlFlowOptimisation >> applyTo: cfg [ + cfg rebuildStackDependencies. self doApply: cfg. DRDeadBlockElimination applyTo: cfg. cfg fixBackJumps diff --git a/Druid/DRDeadCodeElimination.class.st b/Druid/DRDeadCodeElimination.class.st index 1b44cb72..d29e9b74 100644 --- a/Druid/DRDeadCodeElimination.class.st +++ b/Druid/DRDeadCodeElimination.class.st @@ -63,7 +63,7 @@ DRDeadCodeElimination >> canBeAppliedIn: aDRControlFlowGraph [ { #category : #operations } DRDeadCodeElimination >> dependenciesOf: anInstruction [ - ^ anInstruction dependencies select: [ :op | op isInstruction ] + ^ anInstruction dataDependencies select: [ :op | op isInstruction ] ] { #category : #operations } diff --git a/Druid/DRIRGenerator.class.st b/Druid/DRIRGenerator.class.st index 19963548..c5189eac 100644 --- a/Druid/DRIRGenerator.class.st +++ b/Druid/DRIRGenerator.class.st @@ -958,7 +958,7 @@ DRIRGenerator >> interpretFreeStartAssignmentWith: aRBAssignmentNode [ | byteSize valueToStore | aRBAssignmentNode value acceptVisitor: self. valueToStore := self popOperand. -1halt. + byteSize := 8. self addInstructionWithNoResultFrom: aRBAssignmentNode diff --git a/Druid/DRInstruction.class.st b/Druid/DRInstruction.class.st index ff347292..fe251819 100644 --- a/Druid/DRInstruction.class.st +++ b/Druid/DRInstruction.class.st @@ -126,6 +126,12 @@ DRInstruction >> copyToVariableIn: aDRPrimitiveIRGenerator inNode: aRBReturnNode ^ self ] +{ #category : #validation } +DRInstruction >> dataDependencies [ + + ^ self dependencies +] + { #category : #testing } DRInstruction >> hasDependency: anInstruction [ diff --git a/Druid/DRInstructionFactory.class.st b/Druid/DRInstructionFactory.class.st index 5ee45941..d7e16374 100644 --- a/Druid/DRInstructionFactory.class.st +++ b/Druid/DRInstructionFactory.class.st @@ -281,7 +281,7 @@ DRInstructionFactory >> pop: anInteger unspilled: aBoolean [ operands: { anInteger. aBoolean } - result: self allocateTemporaryRegister + result: DRNoRegister new ] { #category : #factory } diff --git a/Druid/DRInterpreterCompilationUnit.class.st b/Druid/DRInterpreterCompilationUnit.class.st index 49536dcc..b04f20ee 100644 --- a/Druid/DRInterpreterCompilationUnit.class.st +++ b/Druid/DRInterpreterCompilationUnit.class.st @@ -88,12 +88,12 @@ DRInterpreterCompilationUnit >> compileUsing: aCompiler [ self addPrimitiveEntries. self addBytecodeEntries. - primitives - do: [ :e | aCompiler handleErrorDuring: [ e compileUsing: aCompiler ] ] - displayingProgress: [ :e | 'Compiling primitive ' , e genSelector ]. self bytecodes do: [ :e | aCompiler handleErrorDuring: [ e compileUsing: aCompiler ] ] displayingProgress: [ :e | 'Compiling bytecode ' , e genSelector ]. + primitives + do: [ :e | aCompiler handleErrorDuring: [ e compileUsing: aCompiler ] ] + displayingProgress: [ :e | 'Compiling primitive ' , e genSelector ]. self dispatchTableGenerator installAllMethodsOn: realTargetClass class ] diff --git a/Druid/DRInterpreterInstruction.class.st b/Druid/DRInterpreterInstruction.class.st index cf3a1889..a9b654eb 100644 --- a/Druid/DRInterpreterInstruction.class.st +++ b/Druid/DRInterpreterInstruction.class.st @@ -69,7 +69,9 @@ DRInterpreterInstruction >> sourceMethod: anObject [ { #category : #accessing } DRInterpreterInstruction >> sourceSelector [ - ^ self sourceMethod selector + ^ self sourceMethod + ifNil: [ self notSupportedSelector ] + ifNotNil: [ :m | m selector ] ] { #category : #accessing } diff --git a/Druid/DRInterpreterToCompiler.class.st b/Druid/DRInterpreterToCompiler.class.st index 58a70327..b24b9aa8 100644 --- a/Druid/DRInterpreterToCompiler.class.st +++ b/Druid/DRInterpreterToCompiler.class.st @@ -58,104 +58,113 @@ DRInterpreterToCompiler class >> generateDruidJITModelOn: targetClass [ { #category : #'instance creation' } DRInterpreterToCompiler class >> generateDruidJITModelOn: targetClass superclass: aSuperclass [ - | primitives bytecodes | - primitives := #( - #primitiveAdd #primitiveSubtract #primitiveMultiply #primitiveDivide #primitiveMod - #primitiveLessThan #primitiveLessOrEqual #primitiveGreaterThan #primitiveGreaterOrEqual - #primitiveEqual #primitiveNotEqual #primitiveIdentical #primitiveNotIdentical - #primitiveDiv #primitiveQuo primitiveBitShift primitiveBitAnd primitiveBitXor primitiveBitOr - - primitiveSmallFloatAdd primitiveSmallFloatSubtract #primitiveSmallFloatMultiply primitiveSmallFloatDivide primitiveSmallFloatEqual primitiveSmallFloatNotEqual primitiveSmallFloatGreaterOrEqual primitiveSmallFloatGreaterThan primitiveSmallFloatLessThan primitiveSmallFloatLessOrEqual - - primitiveFloatAdd primitiveFloatSubtract #primitiveFloatMultiply "primitiveFloatDivide (Fix float comparison)" - primitiveFloatEqual primitiveFloatNotEqual primitiveFloatGreaterThan primitiveFloatGreaterOrEqual primitiveFloatLessThan primitiveFloatLessOrEqual + ^ self generateDruidJITModelOn: targetClass superclass: aSuperclass compilerOptions: #() +] - primitiveAsFloat primitiveAsCharacter #primitiveImmediateAsInteger - "primitiveStringReplace (More than 2 args)" +{ #category : #'instance creation' } +DRInterpreterToCompiler class >> generateDruidJITModelOn: targetClass superclass: aSuperclass compilerOptions: options [ - primitiveClass #primitiveSize #primitiveAt #primitiveStringAt #primitiveAtPut #primitiveStringAtPut "#primitiveBehaviorHash" #primitiveIdentityHash - primitiveNew #primitiveNewWithArg - primitiveFullClosureValue - primitiveFullClosureValueNoContextSwitch - ). - -bytecodes := #( - "pushReceiverVariableBytecode" - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - "pushLiteralVariable16CasesBytecode" - 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - "pushLiteralConstantBytecode" - 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - "pushTemporaryVariableBytecode" - 64 65 66 67 68 69 70 71 72 73 74 75 - "pushReceiverBytecode" - 76 - "pushConstantTrue/False/Nil/Zero/OneBytecode" - 77 78 79 80 81 - "duplicateTop" - 83 - "returnReceiver/True/False/Nil" - 88 89 90 91 - "return top from method/nil from block/top from block" - 92 93 94 - "Nop" - 95 - "Special sends (+)" - 96 97 98 99 100 101 102 103 104 105 - 106 107 108 109 110 111 112 113 114 115 - 116 117 118 "119" 120 121 122 123 124 125 126 127 - "sendLiteralSelector0ArgsBytecode" - 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 - "sendLiteralSelector1ArgBytecode" - 144 145 146 147 148 149 150 150 151 152 153 154 155 156 157 158 159 - "sendLiteralSelector2ArgsBytecode" - 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 - "shortUnconditionalJump" - 176 177 178 179 180 181 182 183 - "shortConditionalJumpTrue" - 184 185 186 187 188 189 190 191 - "shortConditionalJumpFalse" - 192 193 194 195 196 197 198 199 - "store and pop into inst var" - 200 201 202 203 204 205 206 207 - "store and pop into temp" - 208 209 210 211 212 213 214 215 - "popStackBytecode" - 216 - "extension bytecodes" - 224 225 - "extended receiver/literal/temporary/constant variable bytecode" - 226 - 227 228 229 - 231 "pushNewArrayBytecode" - 232 233 - "extended send" - 234 - "extSendSuperBytecode" - 235 - "extended conditional jump" - 237 238 239 - "extended store&pop (receiver var / literal / temp)" - 240 241 242 - "extended store (receiver var / literal / temp)" - 243 244 245 - - "call primitive" 248 - "push closure" 249 - "remote temp (push / store / store&pop)" - 251 252 253 - ). + | primitives bytecodes | + primitives := #( #primitiveAdd #primitiveSubtract #primitiveMultiply + ')' expected -> #primitiveDivide #primitiveMod + #primitiveLessThan #primitiveLessOrEqual + #primitiveGreaterThan #primitiveGreaterOrEqual + #primitiveEqual #primitiveNotEqual + #primitiveIdentical #primitiveNotIdentical + #primitiveDiv #primitiveQuo primitiveBitShift + primitiveBitAnd primitiveBitXor primitiveBitOr + primitiveSmallFloatAdd primitiveSmallFloatSubtract + #primitiveSmallFloatMultiply + primitiveSmallFloatDivide primitiveSmallFloatEqual + primitiveSmallFloatNotEqual + primitiveSmallFloatGreaterOrEqual + primitiveSmallFloatGreaterThan + primitiveSmallFloatLessThan + primitiveSmallFloatLessOrEqual + primitiveFloatAdd primitiveFloatSubtract + #primitiveFloatMultiply primitiveFloatEqual + primitiveFloatNotEqual primitiveFloatGreaterThan + primitiveFloatGreaterOrEqual + primitiveFloatLessThan primitiveFloatLessOrEqual + primitiveAsFloat primitiveAsCharacter + #primitiveImmediateAsInteger + primitiveClass #primitiveSize #primitiveAt + #primitiveStringAt #primitiveAtPut #primitiveIdentityHash + primitiveNew #primitiveNewWithArg + primitiveFullClosureValue primitiveFullClosureValueNoContextSwitch ). "primitiveFloatDivide (Fix float comparison)" + "primitiveStringReplace (More than 2 args)" "#primitiveStringAtPut" "#primitiveBehaviorHash" + + bytecodes := #( 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 + 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 + 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 + 75 76 77 78 79 80 81 83 88 89 90 91 92 93 94 95 96 97 + 98 99 100 101 102 103 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 120 121 122 123 124 125 + 126 127 128 129 130 131 132 133 134 135 136 137 138 + 139 140 141 142 143 144 145 146 147 148 149 150 150 + 151 152 153 154 155 156 157 158 159 160 161 162 163 + 164 165 166 167 168 169 170 171 172 173 174 175 176 + 177 178 179 180 181 182 183 184 185 186 187 188 189 + 190 191 192 193 194 195 196 197 198 199 200 201 202 + 203 204 205 206 207 208 209 210 211 212 213 214 215 + 216 224 225 226 227 228 229 231 232 233 234 235 237 + 238 239 240 241 242 243 244 245 248 249 251 252 253 ). + "pushReceiverVariableBytecode" + "pushLiteralVariable16CasesBytecode" + "pushLiteralConstantBytecode" + "pushTemporaryVariableBytecode" + "pushReceiverBytecode" + "pushConstantTrue/False/Nil/Zero/OneBytecode" + "duplicateTop" + "returnReceiver/True/False/Nil" + "return top from method/nil from block/top from block" + "Nop" + "Special sends (+)" "119" + "sendLiteralSelector0ArgsBytecode" + "sendLiteralSelector1ArgBytecode" + "sendLiteralSelector2ArgsBytecode" + "shortUnconditionalJump" + "shortConditionalJumpTrue" + "shortConditionalJumpFalse" + "store and pop into inst var" + "store and pop into temp" + "popStackBytecode" + "extension bytecodes" + "extended receiver/literal/temporary/constant variable bytecode" "pushNewArrayBytecode" + "extended send" + "extSendSuperBytecode" + "extended conditional jump" + "extended store&pop (receiver var / literal / temp)" + "extended store (receiver var / literal / temp)" + + "call primitive" + "push closure" + "remote temp (push / store / store&pop)" (self fromInterpreterClass: CogVMSimulatorLSB) doFailOnFirst; selectPrimitives: [ :e | false "primitives includes: e selector" ]; - selectBytecodes: [ :e | "bytecodes includes:" e bytecodeNumberStart = 253 ]; + selectBytecodes: [ :e | + (e bytecodeNumberStart between: 0 and: 96) and: [ + bytecodes includes: e bytecodeNumberStart ] ]; targetClass: targetClass; targetSuperclass: aSuperclass; + compilerOptions: options; build ] +{ #category : #'instance creation' } +DRInterpreterToCompiler class >> generateDruidStaticTypePredictionJITModel [ + +