[Vm-dev] VM Maker: VMMaker.oscog-cb.1211.mcz
commits at source.squeak.org
commits at source.squeak.org
Sat Apr 18 00:28:11 UTC 2015
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-cb.1211.mcz
==================== Summary ====================
Name: VMMaker.oscog-cb.1211
Author: cb
Time: 17 April 2015, 5:26:30.846 pm
UUID: 5bfea133-65e7-4b14-a105-9d71ebc8266a
Ancestors: VMMaker.oscog-eem.1210
Used register allocation in #== with V3 in order to limit register moves.
Use bytecodeSetOffset constant instead of some bitAnd: computation.
=============== Diff against VMMaker.oscog-eem.1210 ===============
Item was changed:
----- Method: StackToRegisterMappingCogit>>genBinaryInlineComparison:opFalse:destReg: (in category 'inline primitive generators') -----
genBinaryInlineComparison: opTrue opFalse: opFalse destReg: destReg
"Inlined comparison. opTrue = jump for true and opFalse = jump for false"
| nextPC branchDescriptor nExts |
nextPC := bytecodePC + 3.
nExts := 0.
+ [branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + bytecodeSetOffset.
- [branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + (byte0 bitAnd: 256).
branchDescriptor isExtension] whileTrue:
[nExts := nExts + 1.
nextPC := nextPC + branchDescriptor numBytes].
(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse])
ifTrue: "This is the path where the inlined comparison is followed immediately by a branch"
[| targetBytecodePC postBranchPC |
targetBytecodePC := nextPC
+ branchDescriptor numBytes
+ (self spanFor: branchDescriptor at: nextPC exts: nExts in: methodObj).
postBranchPC := nextPC + branchDescriptor numBytes.
(self fixupAt: nextPC - initialPC) targetInstruction = 0
ifTrue: "The next instruction is dead. we can skip it."
[deadCode := true.
self ensureFixupAt: targetBytecodePC - initialPC.
self ensureFixupAt: postBranchPC - initialPC ]
ifFalse:
[self ssPushConstant: objectMemory trueObject]. "dummy value"
self gen: (branchDescriptor isBranchTrue ifTrue: [opTrue] ifFalse: [opFalse])
operand: (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
deadCode ifFalse: [ self Jump: (self ensureNonMergeFixupAt: postBranchPC - initialPC) ] ]
ifFalse: "This is the path where the inlined comparison is *not* followed immediately by a branch"
[| condJump jump |
condJump := self gen: opTrue operand: 0.
self genMoveFalseR: destReg.
jump := self Jump: 0.
condJump jmpTarget: (self genMoveTrueR: destReg).
jump jmpTarget: self Label].
^ 0!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genSpecialSelectorEqualsEqualsWithForwarders (in category 'bytecode generators') -----
genSpecialSelectorEqualsEqualsWithForwarders
| primDescriptor nextPC nExts branchDescriptor unforwardRcvr argReg targetBytecodePC
unforwardArg rcvrReg jumpNotEqual jumpEqual postBranchPC label fixup |
<var: #jumpEqual type: #'AbstractInstruction *'>
<var: #jumpNotEqual type: #'AbstractInstruction *'>
<var: #primDescriptor type: #'BytecodeDescriptor *'>
<var: #branchDescriptor type: #'BytecodeDescriptor *'>
primDescriptor := self generatorAt: byte0.
nextPC := bytecodePC + primDescriptor numBytes.
nExts := 0.
+ [branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + bytecodeSetOffset.
- [branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + (byte0 bitAnd: 256).
branchDescriptor isExtension] whileTrue:
[nExts := nExts + 1.
nextPC := nextPC + branchDescriptor numBytes].
"If branching the stack must be flushed for the merge"
(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifTrue:
[self ssFlushTo: simStackPtr - 2].
unforwardRcvr := (objectRepresentation isUnannotatableConstant: (self ssValue: 1)) not.
unforwardArg := (objectRepresentation isUnannotatableConstant: self ssTop) not.
"if the rcvr or the arg is an annotable constant, we need to push it to a register
else the forwarder check can't jump back to the comparison after unforwarding the constant"
unforwardArg
ifTrue:
[unforwardRcvr
ifTrue:
[self allocateTwoRegistersInto: [:rTop :rNext| argReg := rTop. rcvrReg := rNext].
self ssTop popToReg: argReg.
(self ssValue:1) popToReg: rcvrReg]
ifFalse:
[argReg := self allocateOneRegister.
self ssTop popToReg: argReg]]
ifFalse:
[self assert: unforwardRcvr.
rcvrReg := self allocateOneRegister.
(self ssValue:1) popToReg: rcvrReg].
label := self Label.
"Here we can use Cq because the constant does not need to be annotated"
self assert: (unforwardArg not or: [argReg notNil]).
self assert: (unforwardRcvr not or: [rcvrReg notNil]).
unforwardArg
ifFalse: [ self CmpCq: self ssTop constant R: rcvrReg ]
ifTrue: [ unforwardRcvr
ifFalse: [ self CmpCq: (self ssValue: 1) constant R: argReg ]
ifTrue: [ self CmpR: argReg R: rcvrReg ] ].
self ssPop: 2.
"If not followed by a branch, resolve to true or false."
(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
[jumpEqual := self JumpZero: 0.
unforwardArg ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg jumpBackTo: label ].
unforwardRcvr ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg jumpBackTo: label ].
self genMoveFalseR: rcvrReg.
jumpNotEqual := self Jump: 0.
jumpEqual jmpTarget: (self genMoveTrueR: rcvrReg).
jumpNotEqual jmpTarget: self Label.
self ssPushRegister: rcvrReg.
^0].
"Further since there is a following conditional jump bytecode, define
non-merge fixups and leave the cond bytecode to set the mergeness."
targetBytecodePC := nextPC
+ branchDescriptor numBytes
+ (self spanFor: branchDescriptor at: nextPC exts: nExts in: methodObj).
postBranchPC := nextPC + branchDescriptor numBytes.
(self fixupAt: nextPC - initialPC) targetInstruction = 0
ifTrue: "The next instruction is dead. we can skip it."
[deadCode := true.
self ensureFixupAt: targetBytecodePC - initialPC.
self ensureFixupAt: postBranchPC - initialPC]
ifFalse:
[self ssPushConstant: objectMemory trueObject]. "dummy value"
self assert: (unforwardArg or: [ unforwardRcvr ]).
branchDescriptor isBranchTrue ifTrue:
[ deadCode ifFalse: [ fixup := self ensureNonMergeFixupAt: postBranchPC - initialPC ].
self JumpZero: (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
unforwardArg ifTrue: [ (deadCode or: [ unforwardRcvr ])
ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg jumpBackTo: label ]
ifFalse: [ objectRepresentation
genEnsureOopInRegNotForwarded: argReg
scratchReg: TempReg
ifForwarder: label
ifNotForwarder: fixup ] ].
unforwardRcvr ifTrue: [ deadCode
ifTrue: [objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg jumpBackTo: label ]
ifFalse: [objectRepresentation
genEnsureOopInRegNotForwarded: rcvrReg
scratchReg: TempReg
ifForwarder: label
ifNotForwarder: fixup ] ] ].
branchDescriptor isBranchFalse ifTrue:
[ fixup := (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
self JumpZero: (self ensureNonMergeFixupAt: postBranchPC - initialPC).
unforwardArg ifTrue: [ unforwardRcvr
ifFalse: [objectRepresentation
genEnsureOopInRegNotForwarded: argReg
scratchReg: TempReg
ifForwarder: label
ifNotForwarder: fixup ]
ifTrue: [ objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg jumpBackTo: label ] ].
unforwardRcvr ifTrue:
[ objectRepresentation
genEnsureOopInRegNotForwarded: rcvrReg
scratchReg: TempReg
ifForwarder: label
ifNotForwarder: fixup ].
"Not reached"].
^0!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genVanillaSpecialSelectorEqualsEquals (in category 'bytecode generators') -----
genVanillaSpecialSelectorEqualsEquals
| nextPC postBranchPC targetBytecodePC primDescriptor branchDescriptor nExts
jumpEqual jumpNotEqual rcvrReg argReg argIsConstant rcvrIsConstant |
<var: #jumpEqual type: #'AbstractInstruction *'>
<var: #jumpNotEqual type: #'AbstractInstruction *'>
<var: #primDescriptor type: #'BytecodeDescriptor *'>
<var: #branchDescriptor type: #'BytecodeDescriptor *'>
primDescriptor := self generatorAt: byte0.
nextPC := bytecodePC + primDescriptor numBytes.
nExts := 0.
[branchDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + bytecodeSetOffset.
branchDescriptor isExtension] whileTrue:
[nExts := nExts + 1.
nextPC := nextPC + branchDescriptor numBytes].
"If branching the stack must be flushed for the merge"
(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifTrue:
[self ssFlushTo: simStackPtr - 2].
"Don't use ReceiverResultReg for receiver to keep ReceiverResultReg live.
Optimize e.g. rcvr == nil, the common case for ifNil: et al."
argIsConstant := self ssTop type = SSConstant.
rcvrIsConstant := argIsConstant and: [ (self ssValue:1) type = SSConstant ].
+ argIsConstant
+ ifFalse:
+ [rcvrIsConstant
+ ifFalse:
+ [self allocateTwoRegistersInto: [:rTop :rNext| argReg := rTop. rcvrReg := rNext].
+ self ssTop popToReg: argReg.
+ (self ssValue:1) popToReg: rcvrReg]
+ ifTrue:
+ [argReg := self allocateOneRegister.
+ self ssTop popToReg: argReg]]
+ ifTrue:
+ [self assert: rcvrIsConstant not.
+ rcvrReg := self allocateOneRegister.
+ (self ssValue:1) popToReg: rcvrReg].
- needsFrame "If frameless, arg0 and arg1 may be live"
- ifTrue: [argReg := Arg0Reg. rcvrReg := Arg1Reg]
- ifFalse: [argReg := ClassReg. rcvrReg := SendNumArgsReg].
- argIsConstant ifFalse:
- [self ssAllocateRequiredReg: argReg upThrough: simStackPtr - 1.
- self ssTop popToReg: argReg].
- rcvrIsConstant ifFalse:
- [ self ssAllocateRequiredReg: rcvrReg upThrough: simStackPtr - 2.
- (self ssValue:1) popToReg: rcvrReg.].
argIsConstant
ifTrue: [ self genCompConstant: self ssTop constant R: rcvrReg ]
ifFalse: [ rcvrIsConstant
ifTrue: [ self genCompConstant: (self ssValue: 1) constant R: argReg ]
ifFalse: [ self CmpR: argReg R: rcvrReg ] ].
self ssPop: 2.
"If not followed by a branch, resolve to true or false."
(branchDescriptor isBranchTrue or: [branchDescriptor isBranchFalse]) ifFalse:
[jumpNotEqual := self JumpNonZero: 0.
self genMoveTrueR: rcvrReg.
jumpEqual := self Jump: 0.
jumpNotEqual jmpTarget: (self genMoveFalseR: rcvrReg).
jumpEqual jmpTarget: self Label.
self ssPushRegister: rcvrReg.
^0].
"Further since there is a following conditional jump bytecode, define
non-merge fixups and leave the cond bytecode to set the mergeness."
targetBytecodePC := nextPC
+ branchDescriptor numBytes
+ (self spanFor: branchDescriptor at: nextPC exts: nExts in: methodObj).
postBranchPC := nextPC + branchDescriptor numBytes.
(self fixupAt: nextPC - initialPC) targetInstruction = 0
ifTrue: "The next instruction is dead. we can skip it."
[deadCode := true.
self ensureFixupAt: targetBytecodePC - initialPC.
self ensureFixupAt: postBranchPC - initialPC]
ifFalse:
[self ssPushConstant: objectMemory trueObject]. "dummy value"
self gen: (branchDescriptor isBranchTrue ifTrue: [JumpZero] ifFalse: [JumpNonZero])
operand: (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
deadCode ifFalse: [self Jump: (self ensureNonMergeFixupAt: postBranchPC - initialPC)].
^0!
More information about the Vm-dev
mailing list