diff --git a/Druid-Tests/DRBytecodeCompilationTest.class.st b/Druid-Tests/DRBytecodeCompilationTest.class.st index a3026662..1091b37b 100644 --- a/Druid-Tests/DRBytecodeCompilationTest.class.st +++ b/Druid-Tests/DRBytecodeCompilationTest.class.st @@ -37,7 +37,7 @@ DRBytecodeCompilationTest >> compileBytecode: bytecode1 selector: selector1 andB ] { #category : #tests } -DRBytecodeCompilationTest >> compileBytecode: bytecode selector: aSelector thenDo: aBlock [ +DRBytecodeCompilationTest >> compileBytecode: bytecode selector: aSelector options: options thenDo: aBlock [ | generatorSelector compiler | generatorSelector := (#gen, '_' , aSelector) asSymbol. @@ -45,23 +45,36 @@ DRBytecodeCompilationTest >> compileBytecode: bytecode selector: aSelector thenD "First generate druid code" self interpreter currentBytecode: bytecode. compiler := DRBytecodeCompilerCompiler new - bytecodes: { bytecode -> aSelector }; - interpreter: self interpreter; - configureForCompilerClass: DruidTestRTLCompiler. + bytecodes: { (bytecode -> aSelector) }; + interpreter: self interpreter; + configureForCompilerClass: DruidTestRTLCompiler; + addCompilerOptions: options. compiler compile. "Then generate the machine code for that method" - cogInitialAddress := self compile: [ - cogit needsFrame: true. - cogit byte0: bytecode. - cogit methodOrBlockNumArgs: 3. "Hack" - cogit methodOrBlockNumTemps: 2. "Hack" - "Initialize the simulated stack" - cogit initSimStackForFramefulMethod: 2. - cogit zeroOpcodeIndexForNewOpcodes. - - aBlock value: [ cogit perform: generatorSelector ]. - ] bytecodes: 100 + cogInitialAddress := self + compile: [ + cogit needsFrame: true. + cogit byte0: bytecode. + cogit methodOrBlockNumArgs: 3. "Hack" + cogit methodOrBlockNumTemps: 2. "Hack" + "Initialize the simulated stack" + cogit initSimStackForFramefulMethod: 2. + cogit zeroOpcodeIndexForNewOpcodes. + + aBlock value: [ + cogit perform: generatorSelector ] ] + bytecodes: 100 +] + +{ #category : #tests } +DRBytecodeCompilationTest >> compileBytecode: bytecode selector: aSelector thenDo: aBlock [ + + ^ self + compileBytecode: bytecode + selector: aSelector + options: #( ) + thenDo: aBlock ] { #category : #tests } diff --git a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st index c8cc0a8f..ea9d545c 100644 --- a/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st +++ b/Druid-Tests/DRBytecodeScenarioCompilationTest.class.st @@ -21,7 +21,7 @@ DRBytecodeScenarioCompilationTest >> testBytecodePrimIdenticalAndJumpFalse [ "Force failing test if tries to compile the trampoline call: Should be removed due to super-instruction." - cogit ceSendMustBeBooleanTrampoline: nil. + cogit ceSendMustBeBooleanTrampoline: fakeTrampoline. self compileBytecode: 118 @@ -60,6 +60,188 @@ DRBytecodeScenarioCompilationTest >> testBytecodePrimIdenticalAndJumpFalse [ self assert: machineSimulator receiverRegisterValue equals: 0 ] +{ #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 negated - 1 +] + +{ #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 negated - 1 +] + +{ #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 [ @@ -129,6 +311,57 @@ 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. + cogit genReturnTopFromMethod ]. + + 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 >> testPushTrueAndJumpFalse [ @@ -255,9 +488,59 @@ DRBytecodeScenarioCompilationTest >> testSuperInstructionCompilation [ returns := compiledMethod ast allChildren select: [ :n | n isReturn ]. self assert: returns size equals: 2. - self assert: returns first value selector equals: #gen_pushConstantTrueBytecode_returnTopFromMethod + self assert: returns first value selector equals: #gen_pushConstantTrueBytecode_returnTopFromMethod_1 +] + +{ #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 >> 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 } 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/DRCogitStackToRegisterGeneratorTest.class.st b/Druid-Tests/DRCogitStackToRegisterGeneratorTest.class.st index bd24c311..da1e9f3c 100644 --- a/Druid-Tests/DRCogitStackToRegisterGeneratorTest.class.st +++ b/Druid-Tests/DRCogitStackToRegisterGeneratorTest.class.st @@ -65,5 +65,5 @@ DRCogitStackToRegisterGeneratorTest >> testGenerateWhile [ DRStager new applyTo: cfg. generator generateCodeForCFG: cfg. - self assert: self statements sixth selector equals: #whileTrue: + self assert: (self statements at: 10) selector equals: #whileTrue: ] 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 6f131e2c..abf8828e 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. 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..14afb650 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 exitBasicBlocks anyOne. + 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. ] @@ -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: 'ssa_7'. self assertConstraint: (DRGreaterOrEqualsConstraint withValue: 15) includes: conditionalConstraint @@ -81,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: [ @@ -90,49 +88,52 @@ DRDeadPathEliminationTest >> testEliminateDoubleDeadPaths [ 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. + 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 } 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 } DRDeadPathEliminationTest >> testEliminateInnerDeadPaths [ | cfg lastBlocks | + cfg := self generateDruidIRFor: #primitiveInnerBranchingWithDeadBranch. optimisation applyTo: cfg. self optimize: cfg. cfg generatePaths. - lastBlocks := cfg lastBasicBlock predecessors. + lastBlocks := cfg exitBasicBlocks. self assert: cfg deadPaths isEmpty. self assert: lastBlocks first firstInstruction isCopy. @@ -151,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. @@ -172,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/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 363ad985..3aea772c 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/DRLinearizationTest.class.st b/Druid-Tests/DRLinearizationTest.class.st index 25118325..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. @@ -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/DRLoopInvariantCodeMotionTest.class.st b/Druid-Tests/DRLoopInvariantCodeMotionTest.class.st index f532a6f2..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: 7. + 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: 8. + 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: 7. + 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/DRPathGenerationTest.class.st b/Druid-Tests/DRPathGenerationTest.class.st index f0d3172c..a6383bde 100644 --- a/Druid-Tests/DRPathGenerationTest.class.st +++ b/Druid-Tests/DRPathGenerationTest.class.st @@ -56,11 +56,11 @@ DRPathGenerationTest >> testConstraintsFromComplexConditionalOnDifferentRegs [ cfg := self generateDruidIRFor: #primitiveBranchingWithAndConditionOnDifferentVariables. "n ~= 2 AND m < 5" edges := cfg lastBasicBlock predecessors flatCollect: [ :b | cfg incomingEdgesFor: b ]. - trueNDomain := edges first constraintFor: 1. "n ~= 2" - trueMDomain := edges first constraintFor: 2. "m < 5" - firstFalseNDomain := edges second constraintFor: 1. "n = 2" - secondFalseNDomain := edges third constraintFor: 1. "n ~= 2" - secondFalseMDomain := edges third constraintFor: 2. "m >= 5" + trueNDomain := edges first constraintFor: 'ssa_1'. "n ~= 2" + trueMDomain := edges first constraintFor: 'ssa_2'. "m < 5" + firstFalseNDomain := edges second constraintFor: 'ssa_1'. "n = 2" + secondFalseNDomain := edges third constraintFor: 'ssa_1'. "n ~= 2" + secondFalseMDomain := edges third constraintFor: 'ssa_2'. "m >= 5" self assert: (trueNDomain includes: (DRNotEqualsConstraint withValue: 2)). self assert: (trueMDomain includes: (DRLessConstraint withValue: 5)). @@ -77,9 +77,9 @@ DRPathGenerationTest >> testConstraintsFromComplexConditionalOnSameReg [ cfg := self generateDruidIRFor: #primitiveBranchingWithAndConditionOnSameVariable. "n ~= 2 AND n < 5" edges := cfg lastBasicBlock predecessors flatCollect: [ :b | cfg incomingEdgesFor: b ]. - trueRegDomain := edges second constraintFor: 1. "n ~= 2 AND n < 5" - firstFalseRegDomain := edges first constraintFor: 1. "n = 2" - secondFalseRegDomain := edges third constraintFor: 1. "n >= 5" + trueRegDomain := edges second constraintFor: 'ssa_1'. "n ~= 2 AND n < 5" + firstFalseRegDomain := edges first constraintFor: 'ssa_1'. "n = 2" + secondFalseRegDomain := edges third constraintFor: 'ssa_1'. "n >= 5" self assert: (trueRegDomain includes: (DRIntersectionConstraint constraints: { DRNotEqualsConstraint withValue: 2. @@ -98,8 +98,8 @@ DRPathGenerationTest >> testConstraintsInferenceFromBranchIfCondition [ cfg := self generateDruidIRFor: #primitiveGreaterOrEqualsThan. edges := cfg outgoingEdgesFor: cfg firstBasicBlock. - trueConstraint := edges first constraintFor: 1. ">= 10" - falseConstraint := edges second constraintFor: 1. "< 10" + trueConstraint := edges first constraintFor: 'ssa_1'. ">= 10" + falseConstraint := edges second constraintFor: 'ssa_1'. "< 10" self assertConstraint: trueConstraint includes: (DRGreaterOrEqualsConstraint withValue: 10). self assertConstraint: falseConstraint includes: (DRLessConstraint withValue: 10). @@ -112,8 +112,8 @@ DRPathGenerationTest >> testConstraintsInferenceFromBranchIfConditionInverted [ cfg := self generateDruidIRFor: #primitiveGreaterOrEqualsThanInverted. edges := cfg outgoingEdgesFor: cfg firstBasicBlock. - trueConstraint := edges first constraintFor: 1. "<= 10" - falseConstraint := edges second constraintFor: 1. "> 10" + trueConstraint := edges first constraintFor: 'ssa_1'. "<= 10" + falseConstraint := edges second constraintFor: 'ssa_1'. "> 10" self assertConstraint: trueConstraint includes: (DRLessOrEqualsConstraint withValue: 10). self assertConstraint: falseConstraint includes: (DRGreaterConstraint withValue: 10). @@ -212,8 +212,8 @@ DRPathGenerationTest >> testConstraintsInferenceFromInnerBranches [ innerMergeBlock := cfg mergeBlocks first. edges := cfg incomingEdgesFor: innerMergeBlock. - trueConstraint := edges first constraintFor: 1. "10 < Reg < 20" - falseConstraint := edges second constraintFor: 1. ">= 20" + trueConstraint := edges first constraintFor: 'ssa_1'. "10 < Reg < 20" + falseConstraint := edges second constraintFor: 'ssa_1'. ">= 20" self assertConstraint: trueConstraint includes: (DRIntersectionConstraint between: 10 and: 20). self assertConstraint: falseConstraint includes: (DRGreaterOrEqualsConstraint withValue: 20) 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/DRProductionBytecodeTest.class.st b/Druid-Tests/DRProductionBytecodeTest.class.st index 91cfdf8e..79589c4a 100644 --- a/Druid-Tests/DRProductionBytecodeTest.class.st +++ b/Druid-Tests/DRProductionBytecodeTest.class.st @@ -26,16 +26,14 @@ DRProductionBytecodeTest >> setUp [ { #category : #tests } DRProductionBytecodeTest >> testBytecodeAdd [ - "We do not support the static type prediction yet" - self skip. + "We need the send trampoline to compile even though it is not called" + cogit ordinarySendTrampolineAt: 1 put: fakeTrampoline. - sendTrampolineAddress := self compile: [ cogit RetN: 0 ]. - cogit ordinarySendTrampolineAt: 1 put: sendTrampolineAddress. - self compileBytecode: 96 selector: #bytecodePrimAdd - thenDo: [ :generator | + options: #( staticTypePrediction ) + thenDo: [ :generator | cogit ssPushRegister: ReceiverResultReg. cogit ssPushRegister: Arg0Reg. @@ -55,6 +53,44 @@ DRProductionBytecodeTest >> testBytecodeAdd [ equals: 42 + 17 ] +{ #category : #tests } +DRProductionBytecodeTest >> testBytecodeAddOneSpilledArg [ + + "We need the send trampoline to compile even though it is not called" + cogit ordinarySendTrampolineAt: 1 put: fakeTrampoline. + + 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 [ @@ -65,6 +101,7 @@ DRProductionBytecodeTest >> testBytecodeAddOverflow [ self compileBytecode: 96 selector: #bytecodePrimAdd + options: #( staticTypePrediction ) thenDo: [ :generator | cogit ssPushRegister: ReceiverResultReg. cogit ssPushRegister: Arg0Reg. @@ -73,20 +110,59 @@ 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) equals: memory maxSmallInteger ] +{ #category : #tests } +DRProductionBytecodeTest >> testBytecodeAddWithSpilledArgs [ + + "We need the send trampoline to compile even though it is not called" + cogit ordinarySendTrampolineAt: 1 put: fakeTrampoline. + + 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" + 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 >> testBytecodeDuplicateTop [ @@ -252,6 +328,10 @@ DRProductionBytecodeTest >> testBytecodeExtendedSuperSend [ self compileBytecode: 235 selector: #extSendSuperBytecode thenDo: [ :generator | cogit methodObj: method. + cogit methodOrBlockNumArgs: 1. "Hack" + cogit methodOrBlockNumTemps: 1. "Hack" + cogit initSimStackForFramefulMethod: 2 "fake Bytecode pc". + "The receiver of the send!" cogit ssPushRegister: ReceiverResultReg. cogit ssPushRegister: Arg0Reg. @@ -261,17 +341,20 @@ DRProductionBytecodeTest >> testBytecodeExtendedSuperSend [ cogit Stop ]. + "Execute the method with receiver smi 17 and argument smi 53" + "Check it arrives to trampoline ceSend: ClassReg above: true to: ReceiverReg numArgs: numArgs" self prepareStackForPrimitiveReceiver: (memory integerObjectOf: 17) - arguments: #( ) + arguments: { (memory integerObjectOf: 53) } 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: selectorIndex. "Third argument: the receiver" - self assert: machineSimulator receiverRegisterValue equals: (memory integerObjectOf: 17) + self assert: machineSimulator receiverRegisterValue equals: (memory integerObjectOf: 17). + self assert: machineSimulator arg0RegisterValue equals: (memory integerObjectOf: 53). ] { #category : #tests } @@ -817,22 +900,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 - thenDo: [ :generator | + thenDo: [ :generator | cogit methodObj: method. "The receiver of the send!" cogit ssPushRegister: ReceiverResultReg. @@ -845,20 +927,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 } @@ -1063,7 +1148,7 @@ DRProductionBytecodeTest >> testBytecodePushLiteralVariableDoesOverrideTopAlloca { #category : #tests } DRProductionBytecodeTest >> testBytecodePushLiteralVariableDoesOverrideTopAllocatedRegister: n [ - | method | + | method x | method := methodBuilder newMethod literals: (((1 to: 16) collect: [ :e | nil -> (e + 16rFF - 1) ]) @@ -1090,9 +1175,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/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..5f80fc2b 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 copyOfLoad | 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. + copyOfLoad := cfg b1 copy: load. optimisation applyTo: cfg. "T3 := T2" - self assert: cfg instructions nextToLast operand1 equals: load + self assert: copyOfLoad 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/DRStackEffectTest.class.st b/Druid-Tests/DRStackEffectTest.class.st new file mode 100644 index 00000000..db2fc77c --- /dev/null +++ b/Druid-Tests/DRStackEffectTest.class.st @@ -0,0 +1,152 @@ +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 stackDependencies 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 stackDependencies 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 stackDependencies asArray equals: { + pop1. + 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 [ + + | 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 stackDependencies 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 stackDependencies asArray equals: { + 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/DRTailDuplicationTest.class.st b/Druid-Tests/DRTailDuplicationTest.class.st index a85cd74a..71458b4b 100644 --- a/Druid-Tests/DRTailDuplicationTest.class.st +++ b/Druid-Tests/DRTailDuplicationTest.class.st @@ -353,7 +353,6 @@ DRTailDuplicationTest >> testTailDuplicateInsertingPhiInDegenerateControlFlow [ user := b9 copy: copy1. cfg validate. -"1halt." cfg b4 tailDuplicate. "This phi has a same value coming from two predecedors" @@ -364,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 [ @@ -371,7 +385,7 @@ DRTailDuplicationTest >> testTailDuplicateOnLoop [ cfg := self generateDruidIRFor: #primitiveLoopIncrementing. "Duplicate loop header" - duplicatedBlocks := (cfg blockById: 6) tailDuplicate. + duplicatedBlocks := (cfg blockById: 5) tailDuplicate. "Build 1 duplication" self assert: duplicatedBlocks size equals: 2. diff --git a/Druid-Tests/DruidTestInterpreter.class.st b/Druid-Tests/DruidTestInterpreter.class.st index 1ec54a0c..93ae447c 100644 --- a/Druid-Tests/DruidTestInterpreter.class.st +++ b/Druid-Tests/DruidTestInterpreter.class.st @@ -23,6 +23,55 @@ 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 >> 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 63edc2e6..f581161e 100644 --- a/Druid-Tests/DruidTestRTLCompiler.class.st +++ b/Druid-Tests/DruidTestRTLCompiler.class.st @@ -861,17 +861,87 @@ DruidTestRTLCompiler >> gen_branchingWithAssigments [ ^ CompletePrimitive ] +{ #category : #generated } +DruidTestRTLCompiler >> gen_bytecodePopOnTwoBranches [ + "AutoGenerated by Druid" + + | t0 jump1 t1 currentBlock s2 jump2 live t2 | + live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + self annotateBytecode: self Label. + (self ssValue: 0) copyToReg: t0. + self CmpCq: 0 R: t0. + jump1 := self JumpLessOrEqual: 0. + (self ssValue: 0) copyToReg: t1. + self MoveR: t1 R: t0. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + (self ssValue: 0) copyToReg: t2. + self MoveR: t2 R: t0. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + self ssPop: 1 popSpilled: true. + self ssPushRegister: t0. + ^ 0 +] + { #category : #generated } DruidTestRTLCompiler >> gen_bytecodePrimAdd [ "AutoGenerated by Druid" - | live currentBlock | + | t0 jump3 jump1 t1 currentBlock jump2 live t2 | live := 0. - self marshallSendArguments: 1. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + (self ssValue: 1) copyToReg: t0. + (self ssValue: 0) copyToReg: t1. + self MoveR: t0 R: t2. + self AndR: t1 R: t2. + self ssFlushStackExceptTop: 2. + self TstCq: 1 R: t2. + jump1 := self JumpZero: 0. + 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 marshallSendArgumentsNoPush: 1. self - genMarshalledSend: -1 + genMarshalledSendNoPush: -1 numArgs: 1 sendTable: ordinarySendTrampolines. + self MoveR: ReceiverResultReg R: t2. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + self ssPop: 2 popSpilled: false. + self ssPushRegister: t2. ^ 0 ] @@ -983,22 +1053,22 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1 [ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1_shortConditionalJumpFalse [ "AutoGenerated by Druid" - | jump1 t1 jump6 b562 jump3 s59 currentBlock t0 jump5 jump2 b558 s58 s55 t2 live jump4 | + | jump5 b554 jump3 jump1 t1 currentBlock s49 jump6 live jump4 s45 jump2 t2 s43 s52 b558 t0 s48 s50 | 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 ssValue: 1) copyToReg: t0. + (self ssValue: 0) copyToReg: t1. self MoveR: t0 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. @@ -1008,7 +1078,7 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1_shortConditionalJumpFal self CmpCq: 0 R: t2. jump2 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t2. - b562 := self Label. + b558 := self Label. self MoveR: t2 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -1019,64 +1089,61 @@ DruidTestRTLCompiler >> gen_bytecodePrimIdenticalSistaV1_shortConditionalJumpFal jump4 := self JumpNonZero: 0. self MoveM64: 8 r: t2 R: t0. self MoveR: t0 R: t2. - jump5 := self Jump: b562. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - jump4 jmpTarget: currentBlock. - self MoveR: t2 R: t0. - jump4 := self Jump: 0. + jump5 := self Jump: b558. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. - currentBlock := self Label. + jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. - self MoveR: t1 R: t2. + self MoveR: t1 R: t0. + self AndCq: 7 R: t0. + self CmpCq: 0 R: t0. + jump4 := 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. + b554 := self Label. + self MoveR: t0 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. - jump4 := self JumpNonZero: 0. - self MoveM64: 0 r: t1 R: t2. + jump2 := self JumpNonZero: 0. + self MoveM64: 0 r: t0 R: t2. self AndCq: 16r3FFFF7 R: t2. self CmpCq: 0 R: t2. - jump2 := self JumpNonZero: 0. - self MoveM64: 8 r: t1 R: t2. - b558 := self Label. - self MoveR: t2 R: t1. - self AndCq: 7 R: t1. - self CmpCq: 0 R: t1. jump1 := self JumpNonZero: 0. - self MoveM64: 0 r: t2 R: t1. - self AndCq: 16r3FFFF7 R: t1. - self CmpCq: 0 R: t1. - jump3 := self JumpNonZero: 0. - self MoveM64: 8 r: t2 R: t1. - self MoveR: t1 R: t2. - jump6 := self Jump: b558. - currentBlock := self Label. - jump1 jmpTarget: currentBlock. - jump3 jmpTarget: currentBlock. - self MoveR: t2 R: t1. - jump3 := self Jump: 0. + self MoveM64: 8 r: t0 R: t2. + self MoveR: t2 R: t0. + jump6 := self Jump: b554. currentBlock := self Label. jump4 jmpTarget: currentBlock. - jump2 jmpTarget: currentBlock. - currentBlock := self Label. - jump3 jmpTarget: currentBlock. - self ssPop: 2. - self ssFlushStack. - self CmpR: t1 R: t0. - jump3 := self JumpNonZero: 0. - self annotateBytecode: self Label. - jump2 := self Jump: 0. - currentBlock := self Label. jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. + self ssPop: 2 popSpilled: true. self annotateBytecode: self Label. - s58 := bytecodePC. - s59 := s58 + 2. - self Jump: (self ensureFixupAt: s59). + (self ssValue: 1) copyToReg: t2. + s45 := objectMemory falseObject. + self ssFlushStackExceptTop: 0. + self CmpCq: s45 R: t2. + jump1 := self JumpNonZero: 0. + s48 := bytecodePC. + s49 := s48 + 2. + self Jump: (self ensureFixupAt: s49). deadCode := true. + jump2 := self Jump: 0. deadCode := false. currentBlock := self Label. + jump1 jmpTarget: currentBlock. + s52 := objectMemory trueObject. + self CmpCq: s52 R: t2. + jump1 := self JumpZero: 0. + self MoveR: t2 R: TempReg. + self CallRT: ceSendMustBeBooleanTrampoline. + currentBlock := self Label. jump2 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. ^ 0 ] @@ -1279,13 +1346,129 @@ DruidTestRTLCompiler >> gen_bytecodePrimNotIdenticalSistaV1 [ ^ 0 ] +{ #category : #generated } +DruidTestRTLCompiler >> gen_bytecodePushOnTwoBranches [ + "AutoGenerated by Druid" + + | t0 s8 jump1 s2 currentBlock t1 jump2 live s5 | + live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + self annotateBytecode: self Label. + (self ssValue: 0) copyToReg: t0. + self CmpCq: 0 R: t0. + jump1 := self JumpLessOrEqual: 0. + s5 := 1. + self MoveCq: s5 R: t1. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + s8 := 2. + self MoveCq: s8 R: t1. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + self ssPushRegister: t1. + ^ 0 +] + +{ #category : #generated } +DruidTestRTLCompiler >> gen_bytecodeTwoPopOnTwoBranches [ + "AutoGenerated by Druid" + + | t0 jump1 t3 t1 currentBlock s2 jump2 live t2 | + live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). + t3 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t3). + self annotateBytecode: self Label. + (self ssValue: 0) copyToReg: t0. + self CmpCq: 0 R: t0. + jump1 := self JumpLessOrEqual: 0. + (self ssValue: 0) copyToReg: t0. + (self ssValue: 1) copyToReg: t1. + self MoveR: t1 R: t2. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + (self ssValue: 0) copyToReg: t2. + (self ssValue: 1) copyToReg: t3. + self MoveR: t2 R: t0. + self MoveR: t3 R: t2. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + self ssPop: 2 popSpilled: true. + self AddR: t2 R: t0. + self ssPushRegister: t0. + ^ 0 +] + +{ #category : #generated } +DruidTestRTLCompiler >> gen_bytecodeTwoPushOnTwoBranches [ + "AutoGenerated by Druid" + + | s6 jump1 t1 s2 currentBlock s12 t0 s7 jump2 s11 live | + live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + self annotateBytecode: self Label. + (self ssValue: 0) copyToReg: t0. + self ssPop: 1 popSpilled: true. + self CmpCq: 0 R: t0. + jump1 := self JumpLessOrEqual: 0. + s6 := 1. + s7 := 2. + self MoveCq: s7 R: t0. + self MoveCq: s6 R: t1. + jump2 := self Jump: 0. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + s11 := 3. + s12 := 4. + self MoveCq: s12 R: t0. + self MoveCq: s11 R: t1. + currentBlock := self Label. + jump2 jmpTarget: currentBlock. + self AddR: t1 R: t0. + self ssPushRegister: t0. + ^ 0 +] + { #category : #generated } DruidTestRTLCompiler >> gen_bytecodeWithDeoptimisation [ "AutoGenerated by Druid" - | live currentBlock | + | live currentBlock t0 | live := 0. - self ssFlushStack. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + self ssFlushStackExceptTop: 0. self deoptimize. ^ 0 ] @@ -1296,13 +1479,13 @@ DruidTestRTLCompiler >> gen_bytecodeWithFlushStackOnDominator [ | 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 annotateBytecode: self Label. (self ssValue: 0) copyToReg: t0. - self ssFlushStack. + self ssFlushStackExceptTop: 0. self CmpCq: 0 R: t0. jump1 := self JumpLessOrEqual: 0. self deoptimize. @@ -1324,7 +1507,7 @@ DruidTestRTLCompiler >> gen_bytecodeWithPop [ | live currentBlock | live := 0. - self ssPop: 1. + self ssPop: 1 popSpilled: true. ^ 0 ] @@ -1376,36 +1559,33 @@ DruidTestRTLCompiler >> gen_emptyPrimitiveWithArguments [ DruidTestRTLCompiler >> gen_extBBytecode [ "AutoGenerated by Druid" - | s6 s3 s16 s10 s2 currentBlock s7 s4 s17 s11 live 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. 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. + s12 := extB. + s13 := s12 << 8. + s14 := s13 + s2. + extB := s14. 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. + s20 := extB. + s21 := s20 << 8. + s22 := s21 + s2. + extB := s22. + s24 := numExtB. + s25 := s24 + 1. + numExtB := s25. ^ 0 ] @@ -1519,8 +1699,12 @@ 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 s12 s15 t0 s4 s17 s11 live | live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). s2 := byte1. s3 := s2 >> 3. s4 := extA. @@ -1528,12 +1712,11 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ s6 := s3 + s5. extA := 0. s8 := BytecodeSetHasDirectedSuperSend. + self ssFlushStackExceptTop: 0. s8 ifTrue: [ - s10 := extB. - s10 >= 64 ifTrue: [ - self ssFlushStack. + s11 := extB. + s11 >= 64 ifTrue: [ self deoptimize. - deadCode := false. ^ 0 ]. s15 := s2 bitAnd: 7. s16 := extB. @@ -1543,9 +1726,10 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ numExtB := 0. self marshallSendArguments: s18. self - genMarshalledSend: s6 + genMarshalledSendNoPush: s6 numArgs: s18 sendTable: superSendTrampolines. + self ssPushRegister: ReceiverResultReg. ^ 0 ]. s15 := s2 bitAnd: 7. s16 := extB. @@ -1555,9 +1739,10 @@ DruidTestRTLCompiler >> gen_extSendSuperBytecode [ numExtB := 0. self marshallSendArguments: s18. self - genMarshalledSend: s6 + genMarshalledSendNoPush: s6 numArgs: s18 sendTable: superSendTrampolines. + self ssPushRegister: ReceiverResultReg. ^ 0 ] @@ -1565,7 +1750,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 | + | 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. @@ -1597,7 +1782,7 @@ DruidTestRTLCompiler >> gen_extStoreLiteralVariableBytecode [ self CmpCq: 0 R: t2. jump1 := self JumpNonZero: 0. self MoveM64: 8 r: t1 R: t2. - b617 := self Label. + b623 := self Label. self MoveR: t2 R: t1. self AndCq: 7 R: t1. self CmpCq: 0 R: t1. @@ -1608,7 +1793,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: b623. currentBlock := self Label. jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -1683,39 +1868,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 ] @@ -1723,7 +1942,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 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. @@ -1748,13 +1967,14 @@ 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. self CmpCq: s14 R: t2. jump1 := self JumpNonZero: 0. self deoptimize. + extA := 0. jump2 := self Jump: 0. deadCode := false. currentBlock := self Label. @@ -1765,6 +1985,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. @@ -1773,24 +1994,24 @@ DruidTestRTLCompiler >> gen_extStoreReceiverVariableBytecode [ self AndCq: 7 R: t2. self CmpCq: 0 R: t2. jump1 := self JumpNonZero: 0. - s31 := objectMemory getMemoryMap getSpaceMaskToUse. + s36 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t1 R: t2. - self AndCq: s31 R: t2. - s34 := objectMemory getMemoryMap getOldSpaceMask. - self CmpCq: s34 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. - s39 := objectMemory getMemoryMap getSpaceMaskToUse. + s44 := objectMemory getMemoryMap getSpaceMaskToUse. self MoveR: t0 R: t2. - self AndCq: s39 R: t2. - s42 := objectMemory getMemoryMap getNewSpaceMask. - self CmpCq: s42 R: t2. + self AndCq: s44 R: t2. + s47 := objectMemory getMemoryMap getNewSpaceMask. + self CmpCq: s47 R: t2. jump6 := self JumpNonZero: 0. - s44 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s44 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. @@ -1811,128 +2032,209 @@ 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. + 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. - jump7 := self JumpNonZero: 0. + jump8 := self JumpZero: 0. + 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. 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. + 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. - jump4 := self JumpBelow: 0. - s61 := objectMemory trueObject. - self CmpCq: s61 R: t0. - jump1 := self JumpBelowOrEqual: 0. + jump5 := self JumpBelow: 0. + s81 := objectMemory trueObject. + self CmpCq: s81 R: t0. + jump1 := self JumpAbove: 0. + s83 := s6 << 3. + self AddCq: s83 R: t1. + self MoveR: t0 M64: 8 r: t1. + extA := 0. + 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. + s88 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s88 R: t0. + jump1 := self JumpBelow: 0. self MoveR: t1 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + s91 := s6 << 3. + self AddCq: s91 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. + 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. + 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. - 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. + extA := 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. + s36 := 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: 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. - jump1 := self JumpNonZero: 0. - s39 := objectMemory getMemoryMap getSpaceMaskToUse. + jump4 := self JumpNonZero: 0. + s44 := 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: s44 R: t2. + s47 := objectMemory getMemoryMap getNewSpaceMask. + self CmpCq: s47 R: t2. + jump6 := self JumpNonZero: 0. + 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. 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. + 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. - jump6 := self JumpNonZero: 0. + jump3 := self JumpZero: 0. + 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. 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. + 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. - s61 := objectMemory trueObject. - self CmpCq: s61 R: t0. - jump3 := self JumpBelowOrEqual: 0. + s81 := objectMemory trueObject. + self CmpCq: s81 R: t0. + jump1 := self JumpAbove: 0. + 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. - s63 := objectMemory getMemoryMap getNewSpaceStart. - self CmpCq: s63 R: t0. - jump4 := self JumpBelow: 0. + jump1 jmpTarget: currentBlock. + s88 := objectMemory getMemoryMap getNewSpaceStart. + self CmpCq: s88 R: t0. + jump1 := self JumpBelow: 0. self MoveR: t1 R: TempReg. backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + s91 := s6 << 3. + self AddCq: s91 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. + 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. - jump4 jmpTarget: currentBlock. - s67 := s6 << 3. - self AddCq: s67 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. + jump6 jmpTarget: currentBlock. + jump9 jmpTarget: currentBlock. jump2 jmpTarget: currentBlock. - extA := 0. + jump4 jmpTarget: currentBlock. + jump1 jmpTarget: currentBlock. ^ 0 ] @@ -1940,7 +2242,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 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. @@ -1956,7 +2258,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. @@ -1965,10 +2267,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. @@ -1976,13 +2278,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. + currentBlock := self Label. + jump3 jmpTarget: currentBlock. + jump2 jmpTarget: currentBlock. ^ 0 ]. s12 := 0. s10 := s12. @@ -1991,24 +2315,46 @@ 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. self MoveAw: coInterpreter stackLimitAddress R: t1. self CmpR: t1 R: t0. - jump1 := self JumpAboveOrEqual: 0. + 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. - jump1 jmpTarget: currentBlock. - s26 := bytecodePC. - s27 := s26 + s6. - s28 := s27 + 2. - self Jump: (self ensureFixupAt: s28). + 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. + s41 := bytecodePC. + s42 := s41 + s6. + s43 := s42 + 2. + self Jump: (self ensureFixupAt: s43). + deadCode := true. + currentBlock := self Label. + jump1 jmpTarget: currentBlock. + jump3 jmpTarget: currentBlock. ^ 0 ] @@ -2016,7 +2362,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 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. @@ -2031,7 +2377,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. @@ -2039,30 +2386,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. @@ -2073,7 +2421,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. @@ -2083,11 +2431,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 ] @@ -2133,7 +2483,7 @@ DruidTestRTLCompiler >> gen_fakePushConstantTrueBytecode [ ofObject: methodObj. nextBytecode = 92 ifTrue: [ bytecodePC := bytecodePC + 1. - ^ self gen_pushConstantTrueBytecode_returnTopFromMethod ]. + ^ self gen_pushConstantTrueBytecode_returnTopFromMethod_1 ]. live := 0. s2 := objectMemory trueObject. self ssPushConstant: s2. @@ -2192,8 +2542,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 ] @@ -2201,20 +2552,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 ] @@ -2223,7 +2575,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. @@ -2231,13 +2583,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 ] @@ -2259,7 +2612,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 | @@ -2276,28 +2629,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 @@ -2510,7 +2867,7 @@ DruidTestRTLCompiler >> gen_primitiveAssertIsIgnored [ | currentBlock | self MoveCq: 17 R: ReceiverResultReg. self genPrimReturn. - ^ 0 + ^ CompletePrimitive ] { #category : #generated } @@ -3655,22 +4012,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: 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 ] @@ -3692,17 +4047,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 ] @@ -3792,17 +4145,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 ] @@ -3827,24 +4178,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 ] @@ -4017,17 +4365,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 ] @@ -4036,17 +4382,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 ] @@ -4055,17 +4399,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 ] @@ -4074,18 +4416,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 ] @@ -4104,7 +4444,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. @@ -4116,7 +4456,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. @@ -4124,21 +4463,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 ] @@ -4150,7 +4482,7 @@ DruidTestRTLCompiler >> gen_primitiveDeadBranchWithError [ | currentBlock | self MoveCq: 17 R: ReceiverResultReg. self genPrimReturn. - ^ 0 + ^ CompletePrimitive ] { #category : #generated } @@ -4200,9 +4532,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 ] @@ -4316,17 +4648,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 ] @@ -4377,17 +4707,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 ] @@ -4858,7 +5186,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. @@ -4951,23 +5279,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 ] @@ -5159,7 +5490,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. @@ -5252,23 +5583,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 ] @@ -5460,7 +5794,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 | @@ -5488,46 +5822,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. @@ -5555,10 +5895,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 ] @@ -5603,17 +5946,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 ] @@ -5643,17 +5984,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 ] @@ -5662,17 +6001,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 ] @@ -5699,18 +6036,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 ] @@ -5740,17 +6075,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 ] @@ -5817,17 +6150,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 ] @@ -5836,17 +6167,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 ] @@ -5855,17 +6184,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 ] @@ -5874,17 +6201,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 ] @@ -5991,7 +6316,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. @@ -5999,7 +6324,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. @@ -6008,8 +6333,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 ] @@ -6138,19 +6461,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 ] @@ -6207,17 +6528,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 ] @@ -6247,17 +6566,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 ] @@ -6266,17 +6583,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 ] @@ -6324,17 +6639,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 ] @@ -6460,9 +6773,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 ] @@ -6539,7 +6852,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. @@ -6547,13 +6860,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 ] @@ -6575,15 +6886,17 @@ DruidTestRTLCompiler >> gen_primitiveNegated [ DruidTestRTLCompiler >> gen_primitiveNew [ "AutoGenerated by Druid" - | jump1 s28 jump6 b361 jump3 currentBlock jump5 jump2 s17 jump7 jump4 | - self SubCq: 8 R: SPReg. - self MoveR: ReceiverResultReg R: ClassReg. - self MoveM64: 24 r: ClassReg R: Extra3Reg. + | jump1 s28 jump6 jump3 b349 currentBlock jump8 jump5 jump2 s17 jump7 jump4 | + self SubCq: 16 R: SPReg. + self MoveR: ReceiverResultReg R: Extra3Reg. self MoveR: Extra3Reg Mw: 0 r: SPReg. self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveM64: 24 r: Extra3Reg R: Extra3Reg. + self MoveR: Extra3Reg Mw: 8 r: SPReg. + self MoveMw: 8 r: SPReg R: Extra3Reg. self ArithmeticShiftRightCq: 3 R: Extra3Reg. - self MoveR: Extra3Reg Mw: 0 r: SPReg. - self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg Mw: 8 r: SPReg. + self MoveMw: 8 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: Extra0Reg. self LogicalShiftRightCq: 16 R: Extra0Reg. self AndCq: 31 R: Extra0Reg. @@ -6593,85 +6906,103 @@ DruidTestRTLCompiler >> gen_primitiveNew [ jump2 := self JumpNonZero: 0. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self MoveM32: 4 r: ClassReg R: ClassReg. - self AndCq: 16rFFFFFFFF R: ClassReg. - self AndCq: 16r3FFFFF R: ClassReg. - self CmpCq: 0 R: ClassReg. + self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveM32: 4 r: Extra3Reg R: Extra1Reg. + self AndCq: 16rFFFFFFFF R: Extra1Reg. + self AndCq: 16r3FFFFF R: Extra1Reg. + self CmpCq: 0 R: Extra1Reg. jump1 := self JumpZero: 0. - self CmpCq: 0 R: ClassReg. + self CmpCq: 0 R: Extra1Reg. jump3 := self JumpBelow: 0. - self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveMw: 8 r: SPReg R: Extra3Reg. self AndCq: 16rFFFF R: Extra3Reg. - self MoveR: Extra3Reg Mw: 0 r: SPReg. - self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg Mw: 8 r: SPReg. + self MoveMw: 8 r: SPReg R: Extra3Reg. self CmpCq: 255 R: Extra3Reg. jump4 := self JumpAboveOrEqual: 0. - self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveMw: 8 r: SPReg R: Extra3Reg. self CmpCq: 1 R: Extra3Reg. jump5 := self JumpAboveOrEqual: 0. s17 := 8. - self MoveCq: s17 R: Extra1Reg. + self MoveCq: s17 R: Extra2Reg. jump6 := self Jump: 0. currentBlock := self Label. jump5 jmpTarget: currentBlock. - self MoveMw: 0 r: SPReg R: Extra3Reg. - self MoveR: Extra3Reg R: Extra1Reg. - self LogicalShiftLeftCq: 3 R: Extra1Reg. + self MoveMw: 8 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg R: Extra2Reg. + self LogicalShiftLeftCq: 3 R: Extra2Reg. currentBlock := self Label. jump6 jmpTarget: currentBlock. - self AddCq: 8 R: Extra1Reg. - self MoveAw: objectMemory freeStartAddress R: Extra2Reg. - self AddR: Extra1Reg R: Extra2Reg. + self AddCq: 8 R: Extra2Reg. + self MoveAw: objectMemory freeStartAddress R: ClassReg. + self AddR: Extra2Reg R: ClassReg. s28 := objectMemory getScavengeThreshold. - self CmpCq: s28 R: Extra2Reg. + self CmpCq: s28 R: ClassReg. jump6 := self JumpBelowOrEqual: 0. - self CmpCq: s28 R: Extra2Reg. + self CmpCq: s28 R: ClassReg. jump5 := self JumpAbove: 0. + self MoveAw: objectMemory freeStartAddress R: ClassReg. + jump7 := self Jump: 0. currentBlock := self Label. jump6 jmpTarget: currentBlock. - self MoveAw: objectMemory freeStartAddress R: Extra2Reg. - self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveAw: objectMemory freeStartAddress R: ClassReg. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. + self MoveMw: 8 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: SendNumArgsReg. self LogicalShiftLeftCq: 56 R: SendNumArgsReg. self LogicalShiftLeftCq: 24 R: Extra0Reg. self AddR: Extra0Reg R: SendNumArgsReg. - self AddR: ClassReg R: SendNumArgsReg. + self AddR: Extra1Reg R: SendNumArgsReg. self OrCq: 0 R: SendNumArgsReg. - self MoveR: SendNumArgsReg M64: 0 r: Extra2Reg. + self MoveR: SendNumArgsReg M64: 0 r: ClassReg. self MoveAw: objectMemory freeStartAddress R: SendNumArgsReg. - self AddR: Extra1Reg R: SendNumArgsReg. + self AddR: Extra2Reg R: SendNumArgsReg. self MoveR: SendNumArgsReg Aw: objectMemory freeStartAddress. - self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. - self MoveR: Extra2Reg R: Extra1Reg. - self AddCq: 8 R: Extra1Reg. + self CmpCq: 0 R: ClassReg. + jump7 := self JumpNonZero: 0. self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg R: SendNumArgsReg. + jump6 := self Jump: 0. + currentBlock := self Label. + jump7 jmpTarget: currentBlock. + self genMoveConstant: objectMemory nilObject R: SendNumArgsReg. + self MoveR: ClassReg R: Extra2Reg. + self AddCq: 8 R: Extra2Reg. + self MoveMw: 8 r: SPReg R: Extra3Reg. self LogicalShiftLeftCq: 3 R: Extra3Reg. - self MoveR: Extra3Reg Mw: 0 r: SPReg. - self MoveR: Extra2Reg R: ClassReg. - self MoveMw: 0 r: SPReg R: Extra3Reg. - self AddR: Extra3Reg R: ClassReg. - self AddCq: 8 R: ClassReg. - self SubCq: 1 R: ClassReg. - b361 := self Label. - self CmpR: Extra1Reg R: ClassReg. - jump6 := self JumpLess: 0. - self MoveR: SendNumArgsReg M64: 0 r: Extra1Reg. - self MoveR: Extra1Reg R: Extra0Reg. + self MoveR: Extra3Reg Mw: 8 r: SPReg. + self MoveR: ClassReg R: Extra1Reg. + self MoveMw: 8 r: SPReg R: Extra3Reg. + self AddR: Extra3Reg R: Extra1Reg. + self AddCq: 8 R: Extra1Reg. + self SubCq: 1 R: Extra1Reg. + b349 := self Label. + self CmpR: Extra2Reg R: Extra1Reg. + jump7 := self JumpLess: 0. + self MoveR: SendNumArgsReg M64: 0 r: Extra2Reg. + self MoveR: Extra2Reg R: Extra0Reg. self AddCq: 8 R: Extra0Reg. - self MoveR: Extra0Reg R: Extra1Reg. - jump7 := self Jump: b361. + self MoveR: Extra0Reg R: Extra2Reg. + jump8 := self Jump: b349. currentBlock := self Label. - jump6 jmpTarget: currentBlock. - self MoveR: Extra2Reg R: ReceiverResultReg. - self AddCq: 8 R: SPReg. + jump7 jmpTarget: currentBlock. + self MoveR: ClassReg R: ReceiverResultReg. + self AddCq: 16 R: SPReg. self genPrimReturn. currentBlock := self Label. jump2 jmpTarget: currentBlock. + self MoveMw: 0 r: SPReg R: Extra3Reg. + self MoveR: Extra3Reg R: SendNumArgsReg. + currentBlock := self Label. + jump6 jmpTarget: currentBlock. + self MoveR: SendNumArgsReg R: ReceiverResultReg. + currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. jump4 jmpTarget: currentBlock. jump5 jmpTarget: currentBlock. - self AddCq: 8 R: SPReg. + self AddCq: 16 R: SPReg. ^ 0 ] @@ -6679,8 +7010,8 @@ DruidTestRTLCompiler >> gen_primitiveNew [ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ "AutoGenerated by Druid" - | jump5 jump10 s94 s55 jump3 b702 jump8 jump1 s36 currentBlock s101 s58 jump13 jump6 s73 s82 s47 jump11 jump4 s78 s168 jump9 jump2 s85 s157 s98 jump7 jump12 | - self SubCq: 32 R: SPReg. + | jump5 jump10 s94 s55 jump3 b690 jump8 jump1 s36 currentBlock s101 s58 jump13 jump6 s73 s82 s47 jump11 jump4 s78 s168 jump9 jump2 s85 s157 s98 jump7 jump12 | + self SubCq: 24 R: SPReg. self MoveR: ReceiverResultReg R: Extra3Reg. self MoveR: Extra3Reg Mw: 0 r: SPReg. self MoveR: Arg0Reg R: SendNumArgsReg. @@ -6696,12 +7027,9 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self LogicalShiftRightCq: 16 R: Extra1Reg. self AndCq: 31 R: Extra1Reg. self MoveMw: 0 r: SPReg R: Extra3Reg. - self MoveM32: 4 r: Extra3Reg R: Extra3Reg. - self AndCq: 16rFFFFFFFF R: Extra3Reg. - self MoveR: Extra3Reg Mw: 8 r: SPReg. - self MoveMw: 8 r: SPReg R: Extra3Reg. - self AndCq: 16r3FFFFF R: Extra3Reg. - self MoveR: Extra3Reg Mw: 8 r: SPReg. + self MoveM32: 4 r: Extra3Reg R: Extra2Reg. + self AndCq: 16rFFFFFFFF R: Extra2Reg. + self AndCq: 16r3FFFFF R: Extra2Reg. self CmpCq: 2 R: Extra1Reg. jump3 := self JumpNonZero: 0. self genMoveConstant: objectMemory nilObject R: Extra0Reg. @@ -6736,8 +7064,7 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ jump3 jmpTarget: currentBlock. self CmpCq: 10 R: Extra1Reg. jump3 := self JumpNonZero: 0. - self MoveMw: 8 r: SPReg R: Extra3Reg. - self CmpCq: 34 R: Extra3Reg. + self CmpCq: 34 R: Extra2Reg. jump8 := self JumpNonZero: 0. self CmpCq: 2 R: SendNumArgsReg. jump9 := self JumpNonZero: 0. @@ -6768,8 +7095,7 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ Rem: Extra0Reg. self AndCq: 1 R: SendNumArgsReg. self AddR: SendNumArgsReg R: Extra1Reg. - self MoveMw: 8 r: SPReg R: Extra3Reg. - self CmpCq: 0 R: Extra3Reg. + self CmpCq: 0 R: Extra2Reg. jump8 := self JumpNonZero: 0. self MoveCq: s55 R: Extra0Reg. jump11 := self Jump: 0. @@ -6792,37 +7118,37 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self DivR: Extra0Reg R: ClassReg - Quo: Extra2Reg - Rem: Extra0Reg. + Quo: Extra0Reg + Rem: ClassReg. s85 := 4. - self MoveCq: s85 R: Extra0Reg. - self SubR: SendNumArgsReg R: Extra0Reg. - self AndCq: 3 R: Extra0Reg. - self AddR: Extra0Reg R: Extra1Reg. + self MoveCq: s85 R: ClassReg. + self SubR: SendNumArgsReg R: ClassReg. + self AndCq: 3 R: ClassReg. + self AddR: ClassReg R: Extra1Reg. self MoveCq: s78 R: ClassReg. - self MoveR: Extra2Reg R: SendNumArgsReg. + self MoveR: Extra0Reg R: SendNumArgsReg. jump8 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. s94 := 0. self CmpCq: 16 R: Extra1Reg. jump3 := self JumpNonZero: 0. - self MoveR: SendNumArgsReg R: Extra0Reg. - self AddCq: 7 R: Extra0Reg. + self MoveR: SendNumArgsReg R: ClassReg. + self AddCq: 7 R: ClassReg. s98 := 8. - self MoveCq: s98 R: Extra2Reg. + self MoveCq: s98 R: Extra0Reg. self - DivR: Extra2Reg - R: Extra0Reg - Quo: Extra2Reg - Rem: Extra0Reg. + DivR: Extra0Reg + R: ClassReg + Quo: Extra0Reg + Rem: ClassReg. s101 := 8. - self MoveCq: s101 R: Extra0Reg. - self SubR: SendNumArgsReg R: Extra0Reg. - self AndCq: 7 R: Extra0Reg. - self AddR: Extra0Reg R: Extra1Reg. + self MoveCq: s101 R: ClassReg. + self SubR: SendNumArgsReg R: ClassReg. + self AndCq: 7 R: ClassReg. + self AddR: ClassReg R: Extra1Reg. self MoveCq: s94 R: ClassReg. - self MoveR: Extra2Reg R: SendNumArgsReg. + self MoveR: Extra0Reg R: SendNumArgsReg. jump12 := self Jump: 0. currentBlock := self Label. jump3 jmpTarget: currentBlock. @@ -6831,8 +7157,7 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self CmpCq: 5 R: Extra1Reg. jump13 := self JumpAbove: 0. self AndCq: 16rFFFF R: Extra0Reg. - self genMoveConstant: objectMemory nilObject R: Extra2Reg. - self MoveR: Extra2Reg R: ClassReg. + self genMoveConstant: objectMemory nilObject R: ClassReg. self MoveR: Extra0Reg R: SendNumArgsReg. currentBlock := self Label. jump4 jmpTarget: currentBlock. @@ -6841,8 +7166,7 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ jump7 jmpTarget: currentBlock. jump8 jmpTarget: currentBlock. jump12 jmpTarget: currentBlock. - self MoveMw: 8 r: SPReg R: Extra3Reg. - self CmpCq: 0 R: Extra3Reg. + self CmpCq: 0 R: Extra2Reg. jump12 := self JumpNonZero: 0. self MoveR: ClassReg R: Extra0Reg. self MoveR: SendNumArgsReg R: ClassReg. @@ -6857,9 +7181,9 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self CmpCq: 0 R: Extra2Reg. jump8 := self JumpBelow: 0. self MoveR: Extra0Reg R: Extra3Reg. - self MoveR: Extra3Reg Mw: 16 r: SPReg. + self MoveR: Extra3Reg Mw: 8 r: SPReg. self MoveR: ClassReg R: Extra3Reg. - self MoveR: Extra3Reg Mw: 24 r: SPReg. + self MoveR: Extra3Reg Mw: 16 r: SPReg. jump7 := self Jump: 0. currentBlock := self Label. jump12 jmpTarget: currentBlock. @@ -6868,20 +7192,18 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ currentBlock := self Label. jump10 jmpTarget: currentBlock. self MoveR: Extra0Reg R: Extra3Reg. - self MoveR: Extra3Reg Mw: 16 r: SPReg. + self MoveR: Extra3Reg Mw: 8 r: SPReg. self MoveR: ClassReg R: Extra3Reg. - self MoveR: Extra3Reg Mw: 24 r: SPReg. - self MoveMw: 8 r: SPReg R: Extra3Reg. - self MoveR: Extra3Reg R: Extra2Reg. + self MoveR: Extra3Reg Mw: 16 r: SPReg. currentBlock := self Label. jump7 jmpTarget: currentBlock. - self MoveMw: 24 r: SPReg R: Extra3Reg. + self MoveMw: 16 r: SPReg R: Extra3Reg. self CmpCq: 16rFFFF R: Extra3Reg. jump7 := self JumpAbove: 0. - self MoveMw: 24 r: SPReg R: Extra3Reg. + self MoveMw: 16 r: SPReg R: Extra3Reg. self CmpCq: 255 R: Extra3Reg. jump10 := self JumpAboveOrEqual: 0. - self MoveMw: 24 r: SPReg R: Extra3Reg. + self MoveMw: 16 r: SPReg R: Extra3Reg. self CmpCq: 1 R: Extra3Reg. jump12 := self JumpAboveOrEqual: 0. s157 := 8. @@ -6889,7 +7211,7 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ jump6 := self Jump: 0. currentBlock := self Label. jump12 jmpTarget: currentBlock. - self MoveMw: 24 r: SPReg R: Extra3Reg. + self MoveMw: 16 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: SendNumArgsReg. self LogicalShiftLeftCq: 3 R: SendNumArgsReg. currentBlock := self Label. @@ -6905,7 +7227,7 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ currentBlock := self Label. jump6 jmpTarget: currentBlock. self MoveAw: objectMemory freeStartAddress R: Extra0Reg. - self MoveMw: 24 r: SPReg R: Extra3Reg. + self MoveMw: 16 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg R: ClassReg. self LogicalShiftLeftCq: 56 R: ClassReg. self LogicalShiftLeftCq: 24 R: Extra1Reg. @@ -6918,27 +7240,27 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ self MoveR: ClassReg Aw: objectMemory freeStartAddress. self MoveR: Extra0Reg R: ClassReg. self AddCq: 8 R: ClassReg. - self MoveMw: 24 r: SPReg R: Extra3Reg. + self MoveMw: 16 r: SPReg R: Extra3Reg. self LogicalShiftLeftCq: 3 R: Extra3Reg. - self MoveR: Extra3Reg Mw: 24 r: SPReg. + self MoveR: Extra3Reg Mw: 16 r: SPReg. self MoveR: Extra0Reg R: SendNumArgsReg. - self MoveMw: 24 r: SPReg R: Extra3Reg. + self MoveMw: 16 r: SPReg R: Extra3Reg. self AddR: Extra3Reg R: SendNumArgsReg. self AddCq: 8 R: SendNumArgsReg. self SubCq: 1 R: SendNumArgsReg. - b702 := self Label. + b690 := self Label. self CmpR: ClassReg R: SendNumArgsReg. jump6 := self JumpLess: 0. - self MoveMw: 16 r: SPReg R: Extra3Reg. + self MoveMw: 8 r: SPReg R: Extra3Reg. self MoveR: Extra3Reg M64: 0 r: ClassReg. self MoveR: ClassReg R: Extra2Reg. self AddCq: 8 R: Extra2Reg. self MoveR: Extra2Reg R: ClassReg. - jump5 := self Jump: b702. + jump5 := self Jump: b690. currentBlock := self Label. jump6 jmpTarget: currentBlock. self MoveR: Extra0Reg R: ReceiverResultReg. - self AddCq: 32 R: SPReg. + self AddCq: 24 R: SPReg. self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. @@ -6951,7 +7273,7 @@ DruidTestRTLCompiler >> gen_primitiveNewWithArg [ jump7 jmpTarget: currentBlock. jump10 jmpTarget: currentBlock. jump12 jmpTarget: currentBlock. - self AddCq: 32 R: SPReg. + self AddCq: 24 R: SPReg. ^ 0 ] @@ -6971,26 +7293,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 ] @@ -6999,17 +7319,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 ] @@ -7039,17 +7357,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 ] @@ -7058,21 +7374,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 ] @@ -7223,29 +7539,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 ] @@ -7728,19 +8036,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 ] @@ -7749,19 +8055,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 ] @@ -7909,17 +8213,15 @@ DruidTestRTLCompiler >> gen_primitiveWithConditionalCompilation [ 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 ] @@ -7947,17 +8249,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 ] @@ -7966,17 +8266,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 ] @@ -7985,17 +8283,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 ] @@ -8004,17 +8300,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 ] @@ -8065,19 +8359,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 ] @@ -8116,6 +8408,18 @@ DruidTestRTLCompiler >> gen_pushConstantTrueBytecode_returnTopFromMethod [ ^ 0 ] +{ #category : #generated } +DruidTestRTLCompiler >> gen_pushConstantTrueBytecode_returnTopFromMethod_1 [ + "AutoGenerated by Druid" + + | live currentBlock s2 | + live := 0. + s2 := objectMemory trueObject. + self MoveCq: s2 R: ReceiverResultReg. + self genUpArrowReturn. + ^ 0 +] + { #category : #generated } DruidTestRTLCompiler >> gen_pushConstantTrueBytecode_shortConditionalJumpFalse [ "AutoGenerated by Druid" @@ -8130,13 +8434,13 @@ DruidTestRTLCompiler >> gen_pushConstantTrueBytecode_shortConditionalJumpFalse [ DruidTestRTLCompiler >> gen_pushConstantTrueBytecode_shortConditionalJumpTrue [ "AutoGenerated by Druid" - | s4 s2 currentBlock live s3 | + | s3 s6 s4 currentBlock live s5 | live := 0. + self ssFlushStackExceptTop: 0. self annotateBytecode: self Label. - s3 := bytecodePC. - s4 := s3 + 2. - self ssFlushStack. - self Jump: (self ensureFixupAt: s4). + s4 := bytecodePC. + s5 := s4 + 2. + self Jump: (self ensureFixupAt: s5). deadCode := true. ^ 0 ] @@ -8175,7 +8479,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 t1 jump3 currentBlock t0 jump2 s4 s29 b233 live jump4 | live := 0. t0 := self allocateRegNotConflictingWith: live @@ -8195,7 +8499,7 @@ DruidTestRTLCompiler >> gen_pushLiteralVariable16CasesBytecode [ self CmpCq: 0 R: t1. jump1 := self JumpNonZero: 0. self MoveM64: 8 r: t0 R: t1. - b237 := self Label. + b233 := self Label. self MoveR: t1 R: t0. self AndCq: 7 R: t0. self CmpCq: 0 R: t0. @@ -8206,7 +8510,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: b233. currentBlock := self Label. jump2 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -8326,7 +8630,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: false. self MoveR: t0 R: ReceiverResultReg. self genUpArrowReturn. ^ 0 @@ -8350,11 +8654,13 @@ DruidTestRTLCompiler >> gen_sendLiteralSelector0ArgsBytecode [ | live currentBlock | live := 0. - self marshallSendArguments: 0. + self marshallSendArgumentsNoPush: 0. self - genMarshalledSend: 1 + genMarshalledSendNoPush: 1 numArgs: 0 sendTable: ordinarySendTrampolines. + self ssPop: 1 popSpilled: true. + self ssPushConstant: ReceiverResultReg. ^ 0 ] @@ -8362,7 +8668,7 @@ DruidTestRTLCompiler >> gen_sendLiteralSelector0ArgsBytecode [ DruidTestRTLCompiler >> gen_shortConditionalJumpFalse [ "AutoGenerated by Druid" - | jump1 s8 s5 s2 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 @@ -8370,7 +8676,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: false. s5 := objectMemory falseObject. self ssFlushStack. self CmpCq: s5 R: t0. @@ -8385,12 +8691,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 ] @@ -8398,7 +8707,7 @@ DruidTestRTLCompiler >> gen_shortConditionalJumpFalse [ DruidTestRTLCompiler >> gen_shortConditionalJumpTrue [ "AutoGenerated by Druid" - | jump1 s8 s5 s2 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 @@ -8406,7 +8715,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: false. s5 := objectMemory trueObject. self ssFlushStack. self CmpCq: s5 R: t0. @@ -8421,12 +8730,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 ] @@ -8448,7 +8760,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. @@ -8477,7 +8789,7 @@ DruidTestRTLCompiler >> gen_storeAndPopReceiverVariableBytecode [ deadCode := false. currentBlock := self Label. jump1 jmpTarget: currentBlock. - self ssPop: 1. + self ssPop: 1 popSpilled: false. self MoveR: t0 R: t2. self AndCq: 7 R: t2. self CmpCq: 0 R: t2. @@ -8520,37 +8832,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 c6ec7f6f..eaac8b5e 100644 --- a/Druid-Tests/DruidTestRTLCompilerForTest.class.st +++ b/Druid-Tests/DruidTestRTLCompilerForTest.class.st @@ -11,8 +11,19 @@ Class { DruidTestRTLCompilerForTest class >> bytecodeTable [ - ^ { { 1. 0. 0. #gen_BytecodeWithNoFrameInstVarRefAnnotation. - #isInstVarRef. #needsFrameNever:. 1 } } + ^ { + { 2. 3. 3. #unknownBytecode }. + { 2. 4. 4. #unknownBytecode }. + { 2. 5. 5. #unknownBytecode }. + { 1. 200. 200. #gen_StoreAndPopReceiverVariableBytecode0. + #isInstVarRef. #isMappedIfImmutability. #needsFrameIfImmutability:. + -1 }. + { 1. 201. 201. #gen_StoreAndPopReceiverVariableBytecode1. + #isInstVarRef. #isMappedIfImmutability. #needsFrameIfImmutability:. + -1 }. + { 1. 202. 202. #gen_StoreAndPopReceiverVariableBytecode2. + #isInstVarRef. #isMappedIfImmutability. #needsFrameIfImmutability:. + -1 } } ] { #category : #'class initialization' } @@ -33,7 +44,8 @@ DruidTestRTLCompilerForTest class >> initializePrimitiveTable [ MaxCompiledPrimitiveIndex := 0. - primitiveTable := CArrayAccessor on: (Array new: MaxCompiledPrimitiveIndex + 1). + primitiveTable := CArrayAccessor on: + (Array new: MaxCompiledPrimitiveIndex + 1). self table: primitiveTable from: self primitiveTableArray. ^ primitiveTable ] @@ -71,6 +83,7 @@ DruidTestRTLCompilerForTest >> gen_PrimitiveAdd [ self genPrimReturn. currentBlock := self Label. jump1 jmpTarget: currentBlock. + currentBlock := self Label. jump2 jmpTarget: currentBlock. ^ 0 ] @@ -96,20 +109,26 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode0 [ | jump5 s24 s46 s16 jump3 s29 jump1 t1 s2 currentBlock s19 s27 jump6 live jump4 jump2 t2 jump7 t0 s48 | live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). self annotateBytecode: self Label. self ensureReceiverResultRegContainsSelf. - t0 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t0). self MoveR: ReceiverResultReg R: 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 MoveM64: 0 r: t0 R: t2. self LogicalShiftRightCq: 23 R: t2. self AndCq: 1 R: t2. - self ssFlushStack. + self ssFlushStackExceptTop: 0. self CmpCq: 0 R: t2. jump1 := self JumpZero: 0. self deoptimize. @@ -117,7 +136,7 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode0 [ 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. @@ -147,7 +166,8 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode0 [ self CmpCq: 0 R: t2. jump7 := self JumpNonZero: 0. self MoveR: t0 R: TempReg. - backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + backEnd saveAndRestoreLinkRegAround: [ + self CallRT: ceStoreCheckTrampoline ]. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -178,7 +198,8 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode0 [ self CmpCq: s48 R: t1. jump3 := self JumpBelow: 0. self MoveR: t0 R: TempReg. - backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + backEnd saveAndRestoreLinkRegAround: [ + self CallRT: ceStoreCheckTrampoline ]. currentBlock := self Label. jump7 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. @@ -198,20 +219,26 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode1 [ | jump5 s24 s46 s16 jump3 s29 jump1 t1 s2 currentBlock s19 s27 jump6 live jump4 jump2 t2 jump7 t0 s48 | live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). self annotateBytecode: self Label. self ensureReceiverResultRegContainsSelf. - t0 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t0). self MoveR: ReceiverResultReg R: 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 MoveM64: 0 r: t0 R: t2. self LogicalShiftRightCq: 23 R: t2. self AndCq: 1 R: t2. - self ssFlushStack. + self ssFlushStackExceptTop: 0. self CmpCq: 0 R: t2. jump1 := self JumpZero: 0. self deoptimize. @@ -219,7 +246,7 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode1 [ 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. @@ -249,7 +276,8 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode1 [ self CmpCq: 0 R: t2. jump7 := self JumpNonZero: 0. self MoveR: t0 R: TempReg. - backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + backEnd saveAndRestoreLinkRegAround: [ + self CallRT: ceStoreCheckTrampoline ]. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -280,7 +308,8 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode1 [ self CmpCq: s48 R: t1. jump3 := self JumpBelow: 0. self MoveR: t0 R: TempReg. - backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + backEnd saveAndRestoreLinkRegAround: [ + self CallRT: ceStoreCheckTrampoline ]. currentBlock := self Label. jump7 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. @@ -300,20 +329,26 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode2 [ | jump5 s24 s46 s16 jump3 s29 jump1 t1 s2 currentBlock s19 s27 jump6 live jump4 jump2 t2 jump7 t0 s48 | live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). self annotateBytecode: self Label. self ensureReceiverResultRegContainsSelf. - t0 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t0). self MoveR: ReceiverResultReg R: 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 MoveM64: 0 r: t0 R: t2. self LogicalShiftRightCq: 23 R: t2. self AndCq: 1 R: t2. - self ssFlushStack. + self ssFlushStackExceptTop: 0. self CmpCq: 0 R: t2. jump1 := self JumpZero: 0. self deoptimize. @@ -321,7 +356,7 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode2 [ 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. @@ -351,7 +386,8 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode2 [ self CmpCq: 0 R: t2. jump7 := self JumpNonZero: 0. self MoveR: t0 R: TempReg. - backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + backEnd saveAndRestoreLinkRegAround: [ + self CallRT: ceStoreCheckTrampoline ]. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -382,7 +418,8 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode2 [ self CmpCq: s48 R: t1. jump3 := self JumpBelow: 0. self MoveR: t0 R: TempReg. - backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + backEnd saveAndRestoreLinkRegAround: [ + self CallRT: ceStoreCheckTrampoline ]. currentBlock := self Label. jump7 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. @@ -402,20 +439,26 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode3 [ | jump5 s24 s46 s16 jump3 s29 jump1 t1 s2 currentBlock s19 s27 jump6 live jump4 jump2 t2 jump7 t0 s48 | live := 0. + t0 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t0). + t1 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t1). + t2 := self + allocateRegNotConflictingWith: live + ifNone: [ ^ self unknownBytecode ]. + live := live bitOr: (self registerMaskFor: t2). self annotateBytecode: self Label. self ensureReceiverResultRegContainsSelf. - t0 := self allocateRegNotConflictingWith: live ifNone: [ ^ self unknownBytecode ]. - live := live bitOr: (self registerMaskFor: t0). self MoveR: ReceiverResultReg R: 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 MoveM64: 0 r: t0 R: t2. self LogicalShiftRightCq: 23 R: t2. self AndCq: 1 R: t2. - self ssFlushStack. + self ssFlushStackExceptTop: 0. self CmpCq: 0 R: t2. jump1 := self JumpZero: 0. self deoptimize. @@ -423,7 +466,7 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode3 [ 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. @@ -453,7 +496,8 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode3 [ self CmpCq: 0 R: t2. jump7 := self JumpNonZero: 0. self MoveR: t0 R: TempReg. - backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + backEnd saveAndRestoreLinkRegAround: [ + self CallRT: ceStoreCheckTrampoline ]. currentBlock := self Label. jump1 jmpTarget: currentBlock. jump3 jmpTarget: currentBlock. @@ -484,7 +528,8 @@ DruidTestRTLCompilerForTest >> gen_StoreAndPopReceiverVariableBytecode3 [ self CmpCq: s48 R: t1. jump3 := self JumpBelow: 0. self MoveR: t0 R: TempReg. - backEnd saveAndRestoreLinkRegAround: [ self CallRT: ceStoreCheckTrampoline ]. + backEnd saveAndRestoreLinkRegAround: [ + self CallRT: ceStoreCheckTrampoline ]. currentBlock := self Label. jump7 jmpTarget: currentBlock. jump6 jmpTarget: currentBlock. diff --git a/Druid-Tests/SimpleDruidTestRTLCompiler.class.st b/Druid-Tests/SimpleDruidTestRTLCompiler.class.st index c1e5174a..9b54ba4b 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 @@ -2211,7 +2218,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveAssertIsIgnored [ | currentBlock | self MoveCq: 17 R: ReceiverResultReg. self genPrimReturn. - ^ 0 + ^ CompletePrimitive ] { #category : #generated } @@ -2973,22 +2980,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 ] @@ -3010,17 +3015,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 ] @@ -3110,17 +3113,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 ] @@ -3145,24 +3146,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 ] @@ -3335,17 +3333,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 ] @@ -3354,17 +3350,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 ] @@ -3373,17 +3367,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 ] @@ -3392,18 +3384,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 ] @@ -3422,7 +3412,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. @@ -3434,7 +3424,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. @@ -3442,21 +3431,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 ] @@ -3468,7 +3450,7 @@ SimpleDruidTestRTLCompiler >> gen_primitiveDeadBranchWithError [ | currentBlock | self MoveCq: 17 R: ReceiverResultReg. self genPrimReturn. - ^ 0 + ^ CompletePrimitive ] { #category : #generated } @@ -3618,17 +3600,15 @@ 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 ] @@ -3679,17 +3659,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 ] @@ -3990,7 +3968,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. @@ -4083,23 +4061,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 ] @@ -4291,7 +4272,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. @@ -4384,23 +4365,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 ] @@ -4592,7 +4576,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 | @@ -4620,46 +4604,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. @@ -4687,10 +4677,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 ] @@ -4735,17 +4728,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 ] @@ -4775,17 +4766,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 ] @@ -4794,17 +4783,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 ] @@ -4831,18 +4818,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 ] @@ -4872,17 +4857,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 ] @@ -4949,17 +4932,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 ] @@ -4968,17 +4949,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 ] @@ -4987,17 +4966,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 ] @@ -5006,17 +4983,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 ] @@ -5025,23 +5000,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. @@ -5049,43 +5028,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. @@ -5093,22 +5074,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. @@ -5123,7 +5100,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. @@ -5131,7 +5108,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. @@ -5140,8 +5117,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 ] @@ -5270,19 +5245,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 ] @@ -5339,17 +5312,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 ] @@ -5379,17 +5350,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 ] @@ -5398,17 +5367,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 ] @@ -5456,17 +5423,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 ] @@ -5610,9 +5575,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 ] @@ -5671,7 +5636,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. @@ -5679,13 +5644,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 ] @@ -6147,26 +6110,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 ] @@ -6175,17 +6136,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 ] @@ -6215,17 +6174,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 ] @@ -6234,21 +6191,21 @@ 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 ] @@ -6387,29 +6344,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 ] @@ -6704,19 +6653,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 ] @@ -6725,19 +6672,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 ] @@ -6885,17 +6830,15 @@ SimpleDruidTestRTLCompiler >> gen_primitiveWithConditionalCompilation [ 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 ] @@ -6923,17 +6866,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 ] @@ -6942,17 +6883,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 ] @@ -6961,17 +6900,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 ] @@ -6980,17 +6917,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 ] @@ -7041,19 +6976,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/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/DRAbstractCompilerCompiler.class.st b/Druid/DRAbstractCompilerCompiler.class.st index e25e1c3f..f658469e 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/DRAbstractInstruction.class.st b/Druid/DRAbstractInstruction.class.st index b1912fef..1bc52026 100644 --- a/Druid/DRAbstractInstruction.class.st +++ b/Druid/DRAbstractInstruction.class.st @@ -150,6 +150,18 @@ DRAbstractInstruction >> isNegate [ ^ false ] +{ #category : #testing } +DRAbstractInstruction >> isPrimitiveFail [ + + ^ false +] + +{ #category : #testing } +DRAbstractInstruction >> isStackEffect [ + + ^ false +] + { #category : #accessing } DRAbstractInstruction >> nextInstruction [ @@ -161,7 +173,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..8bf4671e 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 stackDependencies do: [ :dependency | "... with a dependecy in the other path ..." (dependency basicBlock isDominatedBy: aDRBasicBlock) ifTrue: [ "... then the other path must be linearized before" ^ false ] ] ] ]. @@ -401,6 +401,18 @@ DRBasicBlock >> floatFromBits: aValue [ ^ self addInstruction: (self instructionFactory floatFromBits: aValue) ] +{ #category : #building } +DRBasicBlock >> flushStack [ + + ^ self addInstruction: self instructionFactory flushStack +] + +{ #category : #building } +DRBasicBlock >> flushStackExceptTop: n [ + + ^ self addInstruction: (self instructionFactory flushStackExceptTop: n) +] + { #category : #accessing } DRBasicBlock >> forwardPredecessors [ @@ -465,6 +477,12 @@ DRBasicBlock >> hasPredecessors [ ^ predecessors notEmpty ] +{ #category : #accessing } +DRBasicBlock >> hasSuccessors [ + + ^ self successors notEmpty +] + { #category : #accessing } DRBasicBlock >> hyperblock [ @@ -770,7 +788,7 @@ DRBasicBlock >> isEmptyBasicBlock [ { #category : #accessing } DRBasicBlock >> isExitBlock [ - ^ isExitBlock + ^ false ] { #category : #accessing } @@ -1055,6 +1073,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. @@ -1372,15 +1408,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/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/DRBytecodeCompilerCompiler.class.st b/Druid/DRBytecodeCompilerCompiler.class.st index d6cfe338..edf9d8ed 100644 --- a/Druid/DRBytecodeCompilerCompiler.class.st +++ b/Druid/DRBytecodeCompilerCompiler.class.st @@ -75,7 +75,7 @@ DRBytecodeCompilerCompiler >> generateDruidIR [ { #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 2becb407..ea3eedf0 100644 --- a/Druid/DRBytecodeIRGenerator.class.st +++ b/Druid/DRBytecodeIRGenerator.class.st @@ -1,6 +1,6 @@ Class { #name : #DRBytecodeIRGenerator, - #superclass : #DRPrimitiveIRGenerator, + #superclass : #DRMetaCompilerIRGenerator, #instVars : [ 'jumpOffset' ], @@ -11,28 +11,25 @@ Class { DRBytecodeIRGenerator >> addAnnotateBytecode: aRBMethodNode [ self - addInstructionWithNoResultFrom: aRBMethodNode - instructionKind: DRAnnotateBytecode - operands: #( ). + addInstructionWithNoResultFrom: aRBMethodNode + instructionKind: DRAnnotateBytecode + operands: #( ). ^ self popOperand "Let the stack empty" ] { #category : #visiting } DRBytecodeIRGenerator >> finishCodeInterpretation: lastFrame [ - "Nothing" + "If this is the base frame, it should continue with the next bytecode at the end" + currentBasicBlock endInstruction: + (self instantiateNoResultInstruction: DRContinueNextBytecode) ] -{ #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 } @@ -216,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 } ] @@ -334,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. @@ -355,13 +352,27 @@ 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). + + "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: [ + marshall addBefore: (controlFlowGraph instructionFactory flushStackExceptTop: argumentCount simpleConstantFold + 1). + argumentCount simpleConstantFold + 1 timesRepeat: [ "Receiver" + self + pop: 1 + unspilled: argumentCount simpleConstantFold <= self numRegArgs ] ] + ifFalse: [ + marshall addBefore: controlFlowGraph instructionFactory flushStack. + marshall doPop: true ]. + ^ self push: DRPhysicalGeneralPurposeRegister receiverResultReg ] { #category : #'special cases' } @@ -390,7 +401,7 @@ DRBytecodeIRGenerator >> interpretStackPointerWith: aRBVariableNode [ { #category : #'special cases - stack' } DRBytecodeIRGenerator >> interpretStackTopWith: aRBMessageNode [ - + ^ self addInstructionFrom: aRBMessageNode instructionKind: DRLoadStackValue @@ -436,10 +447,10 @@ DRBytecodeIRGenerator >> newBasicBlockWithState: executionState [ ^ newBasicBlock ] -{ #category : #accessing } +{ #category : #initialization } DRBytecodeIRGenerator >> newCFG [ - ^ DRPrimitiveControlFlowGraph new + ^ DRControlFlowGraph new ] { #category : #accessing } @@ -451,13 +462,22 @@ DRBytecodeIRGenerator >> numberOfArguments: aValue [ self push: (self argRegisterNumber: i) ]" ] -{ #category : #accessing } +{ #category : #'pharo-stack' } DRBytecodeIRGenerator >> pop [ self - addInstructionFrom: nil + addInstructionWithNoResultFrom: nil instructionKind: DRPop - operands: #(). + operands: #( 1 false ). + ^ self popOperand +] + +{ #category : #accessing } +DRBytecodeIRGenerator >> pop: n unspilled: aBoolean [ + + self addInstructionWithNoResultFrom: nil instructionKind: DRPop operands: { + n. + aBoolean }. ^ self popOperand ] @@ -471,20 +491,6 @@ DRBytecodeIRGenerator >> push: aValue [ ^ self popOperand ] -{ #category : #'stack management' } -DRBytecodeIRGenerator >> pushFrameForCode: aDRCode receiver: aReceiver [ - - | frame | - frame := super pushFrameForCode: aDRCode receiver: aReceiver. - - "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/DRBytecodeObject.class.st b/Druid/DRBytecodeObject.class.st index ffb87578..7714c4d2 100644 --- a/Druid/DRBytecodeObject.class.st +++ b/Druid/DRBytecodeObject.class.st @@ -93,13 +93,27 @@ DRBytecodeObject >> compileUnitUsing: aCompiler [ self bytecodeNumberStart to: self bytecodeNumberEnd do: [ :e | interpreter currentBytecode: e. DRBytecodeCompilerCompiler new - bytecodes: { e -> self sourceSelector }; + bytecodes: { (e -> self sourceSelector) }; targetName: self genSelector; 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/DRCPSEdge.class.st b/Druid/DRCPSEdge.class.st index fd26dbf7..a00757a8 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 [ @@ -625,12 +631,6 @@ DRCPSEdge >> visitPop: aDRPop [ ^ nil ] -{ #category : #visiting } -DRCPSEdge >> visitPopMany: aDRPopMany [ - - ^ nil -] - { #category : #visiting } DRCPSEdge >> visitPush: aDRPush [ @@ -710,3 +710,9 @@ DRCPSEdge >> visitUnsignedRightShift: aDRRightShift [ ^ nil ] + +{ #category : #visiting } +DRCPSEdge >> visitUnspillStackSlot: aDRUnspillStackSlot [ + + ^ nil +] diff --git a/Druid/DRCleanStackInstructions.class.st b/Druid/DRCleanStackInstructions.class.st index bb3dd705..68051417 100644 --- a/Druid/DRCleanStackInstructions.class.st +++ b/Druid/DRCleanStackInstructions.class.st @@ -45,5 +45,5 @@ DRCleanStackInstructions >> interpretAndOptimise: aDRInstruction on: aStack [ "Replace by the pushed value" aDRInstruction replaceBy: pushInstruction operand1 ] ]. - aDRInstruction isFlushStack ifTrue: [ 1 halt ] + "aDRInstruction isFlushStack ifTrue: [ 1 halt ]" ] 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/DRCogitBytecodeCodeGenerator.class.st b/Druid/DRCogitBytecodeCodeGenerator.class.st index e8e83b8f..45f3ef9a 100644 --- a/Druid/DRCogitBytecodeCodeGenerator.class.st +++ b/Druid/DRCogitBytecodeCodeGenerator.class.st @@ -17,5 +17,6 @@ DRCogitBytecodeCodeGenerator >> visitFlushStack: aDRFlushStack [ generatorMethodBuilder addStatement: (RBMessageNode receiver: RBVariableNode selfNode - selector: #ssFlushStack) + selector: #ssFlushStackExceptTop: + arguments: { (RBLiteralValueNode value: aDRFlushStack operand1 value) }) ] diff --git a/Druid/DRCogitCanonicaliser.class.st b/Druid/DRCogitCanonicaliser.class.st index b03b0081..defbd605 100644 --- a/Druid/DRCogitCanonicaliser.class.st +++ b/Druid/DRCogitCanonicaliser.class.st @@ -359,25 +359,20 @@ 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: (DRPopMany - operands: - { (previous numberOfPoppedElements - + aDRPop numberOfPoppedElements) asDRValue } - result: DRNoRegister new) ] -] - -{ #category : #visiting } -DRCogitCanonicaliser >> visitPopMany: aDRPopMany [ - - ^ self visitPop: aDRPopMany + canBeMerged := aDRPop hasUsers not and: [ + 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 } @@ -411,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 02c6c571..20c2172d 100644 --- a/Druid/DRCogitCodeGenerator.class.st +++ b/Druid/DRCogitCodeGenerator.class.st @@ -254,15 +254,10 @@ 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. + blocks do: [ :b | + b instructionsDo: [ :i | + i isStaged ifFalse: [ self allocateVariable: i result ] ] ]. self generateCodeFromBlocks. "Generate the postamble in the fallthrough case" @@ -452,6 +447,12 @@ DRCogitCodeGenerator >> generatorMethodBuilder: aDRGeneratorMethodBuilder [ generatorMethodBuilder := aDRGeneratorMethodBuilder ] +{ #category : #'jump-management' } +DRCogitCodeGenerator >> hasDeferredBranchesTo: aDRBasicBlock [ + + ^ deferredBranches includesKey: aDRBasicBlock +] + { #category : #testing } DRCogitCodeGenerator >> hasIncomingBackjumps: aDRBasicBlock [ @@ -563,6 +564,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 [ @@ -697,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/DRCogitLinearScanRegisterAllocator.class.st b/Druid/DRCogitLinearScanRegisterAllocator.class.st index 66f17211..830d3f1b 100644 --- a/Druid/DRCogitLinearScanRegisterAllocator.class.st +++ b/Druid/DRCogitLinearScanRegisterAllocator.class.st @@ -86,17 +86,32 @@ DRCogitLinearScanRegisterAllocator >> coalesceIntervalsForTwoAddressCode [ { #category : #'live-analysis' } DRCogitLinearScanRegisterAllocator >> computeLivenessOfInstruction: anInstruction inBlock: b withLiveSet: live [ + "Instructions pushing registers to the stack extend the life of the register up to its pop or last use. + Thus, for each stack instruction (pop, stack access) we need to find the defining instruction (the push) if any. + If there is one, it means that we need to extend the life of that register up to this using instruction. + If there is none, it means that this is a bytecode parameter pushed by another bytecode, there is nothing to do" + (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 regiter the live interval for the new synthetic operand" - - ((anInstruction isDivision or: [ anInstruction isModulo ]) and: [ - anInstruction type isFloatType not ]) ifTrue: [ + "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: [ + ifTrue: [ newOperand := anInstruction basicBlock controlFlowGraph allocateTemporaryRegister. anInstruction addOperand: newOperand ] diff --git a/Druid/DRCogitOperandSorter.class.st b/Druid/DRCogitOperandSorter.class.st index a4299525..73bba31f 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 [ @@ -396,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/DRCogitPrimitiveCodeGenerator.class.st b/Druid/DRCogitPrimitiveCodeGenerator.class.st index 24d5fcfb..1076ab81 100644 --- a/Druid/DRCogitPrimitiveCodeGenerator.class.st +++ b/Druid/DRCogitPrimitiveCodeGenerator.class.st @@ -15,13 +15,28 @@ 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 removeAll: aControlFlowGraph failureExitBlocks. + linearizedBlocks addAllLast: aControlFlowGraph failureExitBlocks. + + ^ linearizedBlocks +] + { #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/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/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/DRCogitSimpleStackGenerator.class.st b/Druid/DRCogitSimpleStackGenerator.class.st index 7e87fc2d..7ac62635 100644 --- a/Druid/DRCogitSimpleStackGenerator.class.st +++ b/Druid/DRCogitSimpleStackGenerator.class.st @@ -16,6 +16,7 @@ DRCogitSimpleStackGenerator >> allocateVariable: aDRResult [ parent ifNotNil: [ ^ parent allocateVariable: aDRResult ]. aDRResult isNoResult ifTrue: [ ^ self ]. + variables at: aDRResult ifPresent: [ :var | ^ var ]. variableIndex := nextVariableIndex. @@ -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/DRCogitStackCanonicaliser.class.st b/Druid/DRCogitStackCanonicaliser.class.st index 10a5aa0f..ae6cddc8 100644 --- a/Druid/DRCogitStackCanonicaliser.class.st +++ b/Druid/DRCogitStackCanonicaliser.class.st @@ -8,10 +8,16 @@ 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. "?" ^ 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 new file mode 100644 index 00000000..83036593 --- /dev/null +++ b/Druid/DRCogitStackCoalescing.class.st @@ -0,0 +1,96 @@ +Class { + #name : #DRCogitStackCoalescing, + #superclass : #DROptimisation, + #category : #'Druid-Cogit' +} + +{ #category : #accessing } +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)" + + | commonPostDominator basicBlock stackEffects currentStackEffects stackEffectsInReverseOrder previous | + cfg rebuildStackDependencies. + stackEffects := cfg instructions select: [ :e | e isStackEffect ]. + 1 haltIf: [ stackEffects anySatisfy: [ :p | p hasUsers ] ]. + + stackEffectsInReverseOrder := Stack new. + currentStackEffects := #( ). + currentStackEffects := stackEffects select: [ :e | + (stackEffects intersection: + e stackEffectDependencies) isEmpty ]. + + previous := nil. + [ stackEffects notEmpty and: [ stackEffects ~= previous ] ] whileTrue: [ + previous := stackEffects copy. + 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 } +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 + 1) negated) ] ]. + + + postDominator addInstructionFirst: (postDominator instructionFactory + pop: 1 + unspilled: (pops anySatisfy: [ :e | e isUnspilled ])). + pops do: [ :p | p removeFromCFG ] +] + +{ #category : #accessing } +DRCogitStackCoalescing >> coalescePushes: 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/DRCogitStackToRegisterFlushHoisting.class.st b/Druid/DRCogitStackToRegisterFlushHoisting.class.st index 4434a47e..6fcaa470 100644 --- a/Druid/DRCogitStackToRegisterFlushHoisting.class.st +++ b/Druid/DRCogitStackToRegisterFlushHoisting.class.st @@ -1,7 +1,7 @@ Class { #name : #DRCogitStackToRegisterFlushHoisting, #superclass : #DROptimisation, - #category : #'Druid-BytecodeToJITCompilation' + #category : #'Druid-Cogit' } { #category : #accessing } @@ -9,38 +9,42 @@ DRCogitStackToRegisterFlushHoisting >> applyTo: cfg [ "Insert a flush stack instruction in the common dominator of all those instructions that require stack flushing. Explain why we need to hoist it." - | dominator instructionsNeedingStackFlush instructionDominatorPath targetBlock | - instructionsNeedingStackFlush := OrderedCollection new. + | dominator flushStackInstructions targetBlock | + flushStackInstructions := OrderedCollection new. cfg instructionsDo: [ :e | - e needsStackFlush ifTrue: [ instructionsNeedingStackFlush add: e ] ]. + e isFlushStack ifTrue: [ flushStackInstructions add: e ] ]. "If no instructions require flushing, do nothing" - instructionsNeedingStackFlush ifEmpty: [ ^ self ]. + flushStackInstructions ifEmpty: [ ^ self ]. "Find the blocks that will be executed always" cfg invalidateDominatorTree. - instructionDominatorPath := cfg dominatorTree dominatorPathToRoot: cfg lastBasicBlock. - "We have to find the dominator of all instructions..." - dominator := (cfg dominatorTree dominatorOfAll: - instructionsNeedingStackFlush) block. + dominator := cfg dominatorTree dominatorOfAllBlocks: + (flushStackInstructions collect: [ :e | + e basicBlock ]) , cfg exitBasicBlocks. + "... and add the flush to the closest dominator in the path to the end" - targetBlock := instructionDominatorPath reversed detect: [ :block | - dominator isDominatedBy: block ]. + targetBlock := dominator block. "BUT! If the target block has a conditional staged, we must follow the linearization at runtime" - [ targetBlock ~= dominator and: [ targetBlock endInstruction isStaged ] ] - whileTrue: [ - targetBlock := targetBlock successors detect: [ :succ | - dominator isDominatedBy: succ ] ]. + [ + targetBlock ~= dominator block and: [ + targetBlock endInstruction isStaged ] ] whileTrue: [ + targetBlock := targetBlock successors detect: [ :succ | + dominator block isDominatedBy: succ ] ]. + + flushStackInstructions do: [ :e | e removeFromCFG ]. "If only one instruction requires to flush and it is in the target block, the add it just before the instruction" - (instructionsNeedingStackFlush size = 1 and: [ - instructionsNeedingStackFlush first basicBlock = targetBlock ]) ifTrue: [ - instructionsNeedingStackFlush first addBefore: cfg instructionFactory flushStack. + (flushStackInstructions size = 1 and: [ + flushStackInstructions first basicBlock = targetBlock ]) + ifTrue: [ + flushStackInstructions first basicBlock addInstructionFirst: + flushStackInstructions first. ^ self ]. "Add the flush at the end of the target block" - targetBlock addInstruction: dominator instructionFactory flushStack + targetBlock addInstruction: flushStackInstructions first ] diff --git a/Druid/DRCogitStackToRegisterMappingGenerator.class.st b/Druid/DRCogitStackToRegisterMappingGenerator.class.st index 110efc54..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 [ @@ -62,11 +75,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 ] @@ -124,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 } @@ -133,7 +152,10 @@ DRCogitStackToRegisterMappingGenerator >> visitCogitSendMarshall: aDRCogitSendMa generatorMethodBuilder addStatement: (RBMessageNode receiver: RBVariableNode selfNode - selector: #marshallSendArguments: + selector: + #marshallSendArguments , (aDRCogitSendMarshall shouldPop + ifTrue: [ #'' ] + ifFalse: [ 'NoPush' ]) , ':' arguments: (aDRCogitSendMarshall numberOfArguments rtlPushArgumentExpressions: self)) @@ -152,7 +174,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. @@ -166,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 } @@ -192,14 +213,10 @@ DRCogitStackToRegisterMappingGenerator >> visitPop: aDRPop [ generatorMethodBuilder addStatement: (RBMessageNode receiver: RBVariableNode selfNode - selector: #ssPop: - arguments: { (RBLiteralValueNode value: aDRPop numberOfPoppedElements) }) -] - -{ #category : #visiting } -DRCogitStackToRegisterMappingGenerator >> visitPopMany: aDRPopMany [ - - ^ self visitPop: aDRPopMany + selector: #ssPop:popSpilled: + arguments: { + (RBLiteralValueNode value: aDRPop numberOfPoppedElements). + (RBLiteralValueNode value: aDRPop isUnspilled not) }) ] { #category : #visiting } @@ -224,6 +241,7 @@ DRCogitStackToRegisterMappingGenerator >> visitStoreTempVar: aDRStoreTemporaryVa arguments: (aDRStoreTemporaryVariable operand1 rtlPushArgumentExpressions: self)). + super visitStoreTempVar: aDRStoreTemporaryVariable ] @@ -241,3 +259,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/DRControlFlowGraph.class.st b/Druid/DRControlFlowGraph.class.st index 58b18a53..74445db7 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,7 +208,7 @@ DRControlFlowGraph >> blockById: anInteger [ { #category : #iterating } DRControlFlowGraph >> blocks [ - ^ basicBlocks + ^ basicBlocks copyWithAll: { initialBasicBlock } ] { #category : #accessing } @@ -223,7 +222,7 @@ DRControlFlowGraph >> blocksBetween: sourceBlock and: destinationBlock [ { #category : #iterating } DRControlFlowGraph >> blocksDo: aFullBlockClosure [ - basicBlocks do: aFullBlockClosure + self blocks do: aFullBlockClosure ] { #category : #iterating } @@ -279,7 +278,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 +291,8 @@ DRControlFlowGraph >> configureVisualization: view [ self showInfoIn: view. controller := RSCanvasController new - noLegend; - yourself. + noLegend; + yourself. view @ controller ] @@ -413,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 } @@ -516,8 +518,7 @@ DRControlFlowGraph >> initialize [ "How many spill slots we need in memory to execute the compiled method" numberOfSpillSlots := 0. - nextBasicBlockId := -1. - exitBasicBlock := self privateNewBasicBlock. + nextBasicBlockId := 0. initialBasicBlock := self privateNewBasicBlock ] @@ -718,6 +719,40 @@ DRControlFlowGraph >> privateNewBasicBlock [ ^ newBlock ] +{ #category : #building } +DRControlFlowGraph >> rebuildStackDependencies [ + + | lastStackInstructionPerBlock incomingStackInstructions blocks | + lastStackInstructionPerBlock := Dictionary new. + + blocks := self reversePostOrderBlocks. + + [ blocks isEmpty ] whileFalse: [ | e previousDependencies | + e := blocks removeFirst. + incomingStackInstructions := e predecessors + flatCollect: [ :p | + lastStackInstructionPerBlock + at: p + ifAbsent: [ #( ) ] ] + as: Set. + e instructions do: [ :i | + i isStackInstruction ifTrue: [ | thisIncomingStackInstructions | + i clearStackDependencies. + thisIncomingStackInstructions := incomingStackInstructions select: [ :d | (d stackEffectDependencies includes: i) not ]. + i stackDependencies: thisIncomingStackInstructions. + thisIncomingStackInstructions do: [ :s | s addStackDependent: i ]. + incomingStackInstructions := { i } ] ]. + + 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 } DRControlFlowGraph >> removeBasicBlock: aDRBasicBlock [ 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/DRDominatorTree.class.st b/Druid/DRDominatorTree.class.st index 7ea5fb55..83f822ab 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 @@ -175,15 +170,22 @@ DRDominatorTree >> dominanceFrontierOf: aBlock [ { #category : #querying } DRDominatorTree >> dominatorOfAll: instructions [ + ^ self dominatorOfAllBlocks: + (instructions collect: [ :i | i basicBlock ]) +] + +{ #category : #querying } +DRDominatorTree >> dominatorOfAllBlocks: blocks [ + | firstNode | - firstNode := self blockDictionary at: instructions first basicBlock. + firstNode := self blockDictionary at: blocks first. - ^ instructions allButFirst + ^ blocks allButFirst inject: firstNode - into: [ :dominator :instruction | + into: [ :dominator :basicBlock | self nearestCommonAncestorOf: dominator - and: (self blockDictionary at: instruction basicBlock) ] + and: (self blockDictionary at: basicBlock) ] ] { #category : #querying } diff --git a/Druid/DRFailureCodeBasedTailDuplication.class.st b/Druid/DRFailureCodeBasedTailDuplication.class.st index 5b39d7c1..7aaa8e6f 100644 --- a/Druid/DRFailureCodeBasedTailDuplication.class.st +++ b/Druid/DRFailureCodeBasedTailDuplication.class.st @@ -4,15 +4,18 @@ 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 and: [ + bb instructions noneSatisfy: [ :e | e isStackEffect ] ]) 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/DRIRGenerator.class.st b/Druid/DRIRGenerator.class.st index 3c2a1201..6223029b 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' } @@ -32,6 +33,13 @@ DRIRGenerator >> addDeferredReturnState: anExecutionState [ addDeferredReturnState: anExecutionState ] +{ #category : #visiting } +DRIRGenerator >> addEndInstruction: instruction [ + + self currentBasicBlock endInstruction: instruction. + instruction originAST: currentASTNode +] + { #category : #'execution state' } DRIRGenerator >> addFrameReturn: aDRStackFrame [ @@ -46,6 +54,8 @@ DRIRGenerator >> addFrameReturn: aDRStackFrame [ DRIRGenerator >> addInstruction: instruction from: aNode [ instruction origin: thisContext sender stack. + instruction needsStackFlush ifTrue: [ + self currentBasicBlock flushStack ]. self currentBasicBlock addInstruction: instruction. instruction originAST: aNode. self pushOperand: instruction. @@ -63,6 +73,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 [ @@ -158,6 +177,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 [ @@ -326,6 +390,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:. @@ -905,7 +970,7 @@ DRIRGenerator >> interpretFreeStartAssignmentWith: aRBAssignmentNode [ | byteSize valueToStore | aRBAssignmentNode value acceptVisitor: self. valueToStore := self popOperand. -1halt. + byteSize := 8. self addInstructionWithNoResultFrom: aRBAssignmentNode @@ -955,52 +1020,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' } @@ -1799,6 +1823,7 @@ DRIRGenerator >> popFrame [ | poppedFrame | "Here we are in callee" + poppedFrame := self popFrameMergingDeferredReturns. "Last frame!" @@ -2118,10 +2143,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/DRInstruction.class.st b/Druid/DRInstruction.class.st index ba1786cf..b2c3b8a5 100644 --- a/Druid/DRInstruction.class.st +++ b/Druid/DRInstruction.class.st @@ -138,6 +138,12 @@ DRInstruction >> copyToVariableIn: aDRPrimitiveIRGenerator inNode: aRBReturnNode ^ self ] +{ #category : #validation } +DRInstruction >> dataDependencies [ + + ^ self dependencies +] + { #category : #testing } DRInstruction >> hasDependency: anInstruction [ @@ -453,7 +459,7 @@ DRInstruction >> operands [ DRInstruction >> operands: aCollection [ operands asSet do: [ :each | each removeUser: self ]. - operands := aCollection asOrderedCollection. + operands := aCollection collect: [:e | e asDRValue ] as: OrderedCollection. self dependencies asSet do: [ :each | each addUser: self ] ] @@ -504,14 +510,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/DRInstructionFactory.class.st b/Druid/DRInstructionFactory.class.st index 336404ab..8f74f963 100644 --- a/Druid/DRInstructionFactory.class.st +++ b/Druid/DRInstructionFactory.class.st @@ -99,7 +99,13 @@ DRInstructionFactory >> floatFromBits: operand1 [ { #category : #factory } DRInstructionFactory >> flushStack [ - ^ DRFlushStack operands: #( ) result: DRNoRegister new + ^ self flushStackExceptTop: 0 +] + +{ #category : #factory } +DRInstructionFactory >> flushStackExceptTop: n [ + + ^ DRFlushStack operands: { n } result: DRNoRegister new ] { #category : #factory } @@ -268,12 +274,28 @@ DRInstructionFactory >> phiWithVariables: variables [ yourself ] +{ #category : #factory } +DRInstructionFactory >> pop [ + + ^ self pop: 1 unspilled: false +] + +{ #category : #building } +DRInstructionFactory >> pop: anInteger unspilled: aBoolean [ + + ^ DRPop + operands: { + anInteger. + aBoolean } + result: DRNoRegister new +] + { #category : #factory } DRInstructionFactory >> push: operand [ ^ DRPush operands: { operand asDRValue } - result: self allocateTemporaryRegister + result: DRNoRegister new ] { #category : #factory } @@ -284,7 +306,7 @@ DRInstructionFactory >> pushBase: base offset: offset [ base: base; offset: offset; yourself) } - result: self allocateTemporaryRegister + result: DRNoRegister new ] { #category : #building } @@ -339,3 +361,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/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 7ee85c81..e0b8dd2b 100644 --- a/Druid/DRInterpreterToCompiler.class.st +++ b/Druid/DRInterpreterToCompiler.class.st @@ -58,29 +58,43 @@ 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 - - primitiveAsFloat primitiveAsCharacter #primitiveImmediateAsInteger - "primitiveStringReplace (More than 2 args)" + ^ self generateDruidJITModelOn: targetClass superclass: aSuperclass compilerOptions: #() +] - primitiveClass #primitiveSize #primitiveAt #primitiveStringAt #primitiveAtPut #primitiveStringAtPut "#primitiveBehaviorHash" #primitiveIdentityHash +{ #category : #'instance creation' } +DRInterpreterToCompiler class >> generateDruidJITModelOn: targetClass superclass: aSuperclass compilerOptions: options [ - primitiveNew #primitiveNewWithArg - primitiveFullClosureValue - primitiveFullClosureValueNoContextSwitch - ). - -bytecodes := #( + | 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 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 := #( "pushReceiverVariableBytecode" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 "pushLiteralVariable16CasesBytecode" @@ -150,13 +164,28 @@ bytecodes := #( (self fromInterpreterClass: CogVMSimulatorLSB) doFailOnFirst; - selectPrimitives: [ :e | primitives includes: e selector ]; - selectBytecodes: [ :e | bytecodes includes: e bytecodeNumberStart ]; + selectPrimitives: [ :e | + ((primitives indexOf: e selector) between: 0 and: 54) and: [ + primitives includes: e selector ] ]; + selectBytecodes: [ :e | + (e bytecodeNumberStart between: 0 and: 255) and: [ + bytecodes includes: e bytecodeNumberStart ] ]; targetClass: targetClass; targetSuperclass: aSuperclass; + compilerOptions: options; build ] +{ #category : #'instance creation' } +DRInterpreterToCompiler class >> generateDruidStaticTypePredictionJITModel [ + +