[Vm-dev] VM Maker: VMMaker.oscog-cb.1207.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Apr 17 01:14:05 UTC 2015


Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-cb.1207.mcz

==================== Summary ====================

Name: VMMaker.oscog-cb.1207
Author: cb
Time: 16 April 2015, 6:12:21.174 pm
UUID: 67297437-fcdb-41f7-a9cd-949fff51f29b
Ancestors: VMMaker.oscog-cb.1206

Fixed the dead code elimination so that now it eliminates an unconditionnal branch over a nop in case of inlined branches such as #== then branch or inlined comparison then branch.

Added a method for in-image compilation.

=============== Diff against VMMaker.oscog-cb.1206 ===============

Item was added:
+ ----- Method: CurrentImageCoInterpreterFacade>>marryFrameCopiesTemps (in category 'frame access') -----
+ marryFrameCopiesTemps
+ 	^ false!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>compileAbstractInstructionsFrom:through: (in category 'compile abstract instructions') -----
  compileAbstractInstructionsFrom: start through: end
  	"Loop over bytecodes, dispatching to the generator for each bytecode, handling fixups in due course."
  	| nextOpcodeIndex descriptor nExts fixup result |
  	<var: #descriptor type: #'BytecodeDescriptor *'>
  	<var: #fixup type: #'BytecodeFixup *'>
  	self traceSimStack.
  	bytecodePC := start.
  	nExts := 0.
  	descriptor := nil.
  	deadCode := false.
  	[self cCode: '' inSmalltalk:
  		[(debugBytecodePointers includes: bytecodePC) ifTrue: [self halt]].
  	fixup := self fixupAt: bytecodePC - initialPC.
  	fixup targetInstruction asUnsignedInteger > 0
  		ifTrue:
+ 			[fixup targetInstruction asUnsignedInteger >= 2 ifTrue:
+ 				[self merge: fixup afterContinuation: deadCode not].
+ 			deadCode := false]
- 			[deadCode := false.
- 	 		 fixup targetInstruction asUnsignedInteger >= 2 ifTrue:
- 				[self merge: fixup
- 					afterContinuation: (descriptor notNil
- 										and: [descriptor isUnconditionalBranch
- 											or: [descriptor isReturn]]) not]]
  		ifFalse: "If there's no fixup following a return there's no jump to that code and it is dead."
  			[(descriptor notNil and: [descriptor isReturn]) ifTrue:
  				[deadCode := true]].
  	 self cCode: '' inSmalltalk:
  		[deadCode ifFalse:
  			[self assert: simStackPtr + (needsFrame ifTrue: [0] ifFalse: [1])
  						= (self debugStackPointerFor: bytecodePC)]].
  	 byte0 := (objectMemory fetchByte: bytecodePC ofObject: methodObj) + bytecodeSetOffset.
  	 descriptor := self generatorAt: byte0.
  	 self loadSubsequentBytesForDescriptor: descriptor at: bytecodePC.
  	 nextOpcodeIndex := opcodeIndex.
  	 result := deadCode
  				ifTrue: "insert nops for dead code that is mapped so that bc to mc mapping is not many to one"
  					[(descriptor isMapped
  					  or: [inBlock and: [descriptor isMappedInBlock]]) ifTrue:
  						[self annotateBytecode: self Nop].
  						0]
  				ifFalse:
  					[self perform: descriptor generator].
  	 descriptor isExtension ifFalse: "extended bytecodes must consume their extensions"
  		[self assert: (extA = 0 and: [extB = 0])].
  	 self traceDescriptor: descriptor; traceSimStack.
  	 (fixup targetInstruction asUnsignedInteger between: 1 and: 2) ifTrue:
  		["There is a fixup for this bytecode.  It must point to the first generated
  		   instruction for this bytecode.  If there isn't one we need to add a label."
  		 opcodeIndex = nextOpcodeIndex ifTrue:
  			[self Label].
  		 fixup targetInstruction: (self abstractInstructionAt: nextOpcodeIndex)].
  	 bytecodePC := self nextBytecodePCFor: descriptor at: bytecodePC exts: nExts in: methodObj.
  	 result = 0 and: [bytecodePC <= end]] whileTrue:
  		[nExts := descriptor isExtension ifTrue: [nExts + 1] ifFalse: [0]].
  	self checkEnoughOpcodes.
  	^result!

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) + (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 ]
- 					 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) ] ]
- 				operand: (self ensureNonMergeFixupAt: targetBytecodePC - initialPC) asUnsignedInteger.
- 			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 
  				annotate: (self MoveCw: objectMemory falseObject R: destReg) 
  				objRef: objectMemory falseObject.
  	 		jump := self Jump: 0.
  			condJump jmpTarget: (self 
  				annotate: (self MoveCw: objectMemory trueObject R: destReg) 
  				objRef: objectMemory trueObject).
  			jump jmpTarget: self Label].
  	^ 0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genSpecialSelectorEqualsEquals (in category 'bytecode generators') -----
  genSpecialSelectorEqualsEquals
  	| nextPC postBranchPC targetBytecodePC primDescriptor branchDescriptor nExts
  	  unforwardArg unforwardRcvr jumpEqual jumpNotEqual rcvrReg argReg result |
  	<var: #jumpEqual type: #'AbstractInstruction *'>
  	<var: #jumpNotEqual type: #'AbstractInstruction *'>
  	<var: #primDescriptor type: #'BytecodeDescriptor *'>
  	<var: #branchDescriptor type: #'BytecodeDescriptor *'>
  	primDescriptor := self generatorAt: byte0.
  	"forwarders have been followed in cog:selector:"
  	(self ssTop type = SSConstant
  	 and: [(self ssValue: 1) type = SSConstant]) ifTrue:
  		[self assert: primDescriptor isMapped not.
  		 result := self ssTop constant = (self ssValue: 1) constant
  									ifTrue: [objectMemory trueObject]
  									ifFalse: [objectMemory falseObject].
  		 self ssPop: 2.
  		 ^self ssPushConstant: result].
  
  	nextPC := bytecodePC + primDescriptor numBytes.
  	nExts := 0.
  	[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 := (self ssValue: 1) type ~= SSConstant
  						or: [objectRepresentation shouldAnnotateObjectReference: (self ssValue: 1) constant].
  	unforwardArg := self ssTop type ~= SSConstant
  						or: [objectRepresentation shouldAnnotateObjectReference: self ssTop constant].
  
  	"Don't use ReceiverResultReg for receiver to keep ReceiverResultReg live.
  	 Optimize e.g. rcvr == nil, the common case for ifNil: et al."
  	needsFrame
  		ifTrue: 
  			[unforwardArg ifTrue:
  				[self ssAllocateRequiredReg: (argReg := Arg0Reg) upThrough: simStackPtr - 1].
  			 self ssAllocateRequiredReg: (rcvrReg := Arg1Reg) upThrough: simStackPtr - 2]
  		ifFalse:
  			[unforwardArg ifTrue:
  				[argReg := self ssAllocatePreferredReg: ClassReg].
  			 rcvrReg := self ssAllocatePreferredReg: SendNumArgsReg].
  	unforwardArg
  		ifTrue:
  			[self ssTop popToReg: argReg.
  			 objectRepresentation genEnsureOopInRegNotForwarded: argReg scratchReg: TempReg.
  			 (self ssValue: 1) popToReg: rcvrReg.
  			 unforwardRcvr ifTrue:
  				[objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg].
  			 self CmpR: argReg R: rcvrReg]
  		ifFalse:
  			[(self ssValue: 1) popToReg: rcvrReg.
  			 unforwardRcvr ifTrue:
  				[objectRepresentation genEnsureOopInRegNotForwarded: rcvrReg scratchReg: TempReg].
  			 self CmpCq: self ssTop constant 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 annotate: (self MoveCw: objectMemory trueObject R: rcvrReg)
  			objRef: objectMemory trueObject.
  		 jumpEqual := self Jump: 0.
  		 jumpNotEqual jmpTarget: (self annotate: (self MoveCw: objectMemory falseObject R: rcvrReg)
  										objRef: objectMemory falseObject).
  		 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)].
- 	self Jump: (self ensureNonMergeFixupAt: postBranchPC - initialPC).
  	^0!



More information about the Vm-dev mailing list