[Vm-dev] VM Maker: VMMaker.oscog-eem.2207.mcz

commits at source.squeak.org commits at source.squeak.org
Thu May 4 20:07:22 UTC 2017

Eliot Miranda uploaded a new version of VMMaker to project VM Maker:

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

Name: VMMaker.oscog-eem.2207
Author: eem
Time: 4 May 2017, 1:06:35.361278 pm
UUID: 8da5de9b-33d7-478b-9081-58591f7da69a
Ancestors: VMMaker.oscog-eem.2206

Fix regression in or about VMMaker.oscog-eem.2144 that made simStackPtr char in a BytecodeFixup.  This must be signed char to swork; on ARM char is by default unsigned.

Slang: Don't iinline unused self_in_foo variables when inlining struct methods.

=============== Diff against VMMaker.oscog-eem.2206 ===============

Item was changed:
  ----- Method: CogAbstractInstruction>>genAlignCStackSavingRegisters:numArgs:wordAlignment: (in category 'abi') -----
+ genAlignCStackSavingRegisters: regMask numArgs: numArgs wordAlignment: alignment
- genAlignCStackSavingRegisters: registerMask numArgs: numArgs wordAlignment: alignment
  	<inline: true>
  	| regMaskCopy numRegsPushed wordsPushedModAlignment delta |
  	<var: 'regMaskCopy' type: #usqInt>
+ 	regMaskCopy := regMask asUnsignedInteger.
- 	regMaskCopy := registerMask asUnsignedInteger.
  	numRegsPushed := 0.
  	[regMaskCopy ~= 0] whileTrue:
  		[numRegsPushed := numRegsPushed + (regMaskCopy bitAnd: 1).
  		 regMaskCopy := regMaskCopy bitShift: -1].
  	(numRegsPushed = 0
  	 and: [self numIntRegArgs >= numArgs]) ifTrue:
  	wordsPushedModAlignment := numRegsPushed + numArgs \\ alignment.
  	wordsPushedModAlignment ~= 0 ifTrue:
  		[delta := alignment - wordsPushedModAlignment.
  		 cogit SubCq: delta * objectMemory wordSize R: SPReg].

Item was changed:
  ----- Method: CogBytecodeFixup class>>instVarNamesAndTypesForTranslationDo: (in category 'translation') -----
  instVarNamesAndTypesForTranslationDo: aBinaryBlock
  	"Enumerate aBinaryBlock with the names and C type strings for the inst vars to include in a BytecodeFixup struct."
  	"self withAllSubclasses collect: [:ea| ea typedef]"
  	self filteredInstVarNames do:
  			value: ivn
  			value: (ivn first ~= $# ifTrue:
  						[ivn caseOf: {
  							['targetInstruction']			-> [#'AbstractInstruction *'].
  							['mergeSimStack']			-> [#'SimStackEntry *'].
  							['instructionIndex']			-> [#'unsigned short'].
+ 							['simStackPtr']				-> [#'signed char'].
- 							['simStackPtr']				-> [#char].
  							['simNativeStackPtr']		-> [#'short'].
  							['simNativeStackSize']		-> [#'unsigned short'].
  							['isReceiverResultRegSelf']	-> [#char] }])]!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>printRegisterMask:on: (in category 'debug printing') -----
  printRegisterMask: registerMask on: aStream
+ 	<doNotGenerate>
  	| first |
  	aStream nextPut: ${.
  	registerMask = 0
  			[aStream nextPutAll: 'NoReg']
  			[first := true.
  			 0 to: 31 do:
  				(registerMask anyMask: 1 << reg) ifTrue:
  					[first ifFalse: [aStream space].
  					 first := false.
  					 aStream nextPutAll: (backEnd nameForRegister: reg)]]].
  	aStream nextPut: $}; flush!

Item was changed:
  ----- Method: TMethod>>argAssignmentsFor:send:in: (in category 'inlining') -----
  argAssignmentsFor: meth send: aSendNode in: aCodeGen
  	"Return a collection of assignment nodes that assign the given argument expressions to the formal parameter variables of the given method."
  	"Optimization: If the actual parameters are either constants or local variables in the target method (the receiver), substitute them directly into the body of meth. Note that global variables cannot be subsituted because the inlined method might depend on the exact ordering of side effects to the globals."
  	| stmtList substitutionDict argList |
  	meth args size > (argList := aSendNode args) size ifTrue:
  		[self assert: (meth args first beginsWith: 'self_in_').
  		 argList := {aSendNode receiver}, aSendNode args].
  	stmtList := OrderedCollection new: argList size.
  	substitutionDict := Dictionary new: argList size.
  	meth args with: argList do:
+ 		[:argName :exprNode | | varNode |
- 		[:argName :exprNode |
  		(self isNode: exprNode substitutableFor: argName inMethod: meth in: aCodeGen)
  					at: argName
  					put: (aCodeGen
  							node: exprNode
  							typeCompatibleWith: argName
  							inliningInto: meth
  							in: self).
+ 				 locals remove: argName ifAbsent: [self assert: (argName beginsWith: 'self_in_')].
+ 				 declarations removeKey: argName ifAbsent: nil]
+ 			ifFalse: "Add an assignment for anything except an unused self_in_foo argument"
+ 				[varNode := TVariableNode new setName: argName.
+ 				 ((argName beginsWith: 'self_in_')
+ 				  and: [meth parseTree noneSatisfy: [:node| varNode isSameAs: node]]) ifFalse:
+ 					[stmtList addLast:
+ 						(TAssignmentNode new
+ 							setVariable: varNode
+ 							expression: (aCodeGen
+ 											node: exprNode copy
+ 											typeCompatibleWith: argName
+ 											inliningInto: meth
+ 											in: self))]]].
- 				 locals remove: argName.
- 				declarations removeKey: argName ifAbsent: nil]
- 			ifFalse:
- 				[stmtList addLast:
- 					(TAssignmentNode new
- 						setVariable: (TVariableNode new setName: argName)
- 						expression: (aCodeGen
- 										node: exprNode copy
- 										typeCompatibleWith: argName
- 										inliningInto: meth
- 										in: self))]].
  	meth parseTree: (meth parseTree bindVariablesIn: substitutionDict).

Item was changed:
  ----- Method: TMethod>>inlineSend:directReturn:exitVar:in: (in category 'inlining') -----
  inlineSend: aSendNode directReturn: directReturn exitVar: exitVar in: aCodeGen
  	"Answer a collection of statements to replace the given send.  directReturn indicates
  	 that the send is the expression in a return statement, so returns can be left in the
  	 body of the inlined method. If exitVar is nil, the value returned by the send is not
  	 used; thus, returns need not assign to the output variable.
  	 Types are propagated to as-yet-untyped variables when inlining a send that is assigned,
  	 otherwise the assignee variable type must match the return type of the inlinee.  Return
  	 types are not propagated."
+ 	| sel meth methArgs exitLabel inlineStmts label exitType notToBeRenamed |
- 	| sel meth methArgs exitLabel inlineStmts label exitType |
  	sel := aSendNode selector.
  	meth := aCodeGen methodNamed: sel.
  	methArgs := meth args.
  	"convenient for debugging..."
  	aCodeGen maybeBreakForInlineOf: aSendNode in: self.
+ 	(methArgs notEmpty and: [methArgs first beginsWith: 'self_in_'])
+ 		ifTrue:
+ 			[notToBeRenamed := {methArgs first}.
+ 			 methArgs := methArgs allButFirst]
+ 		ifFalse:
+ 			[notToBeRenamed := #()].
- 	(methArgs notEmpty and: [methArgs first beginsWith: 'self_in_']) ifTrue:
- 		[methArgs := methArgs allButFirst].
  	methArgs size = aSendNode args size ifFalse:
  	meth := meth copy.
  	(meth statements size > 1
  	 and: [meth statements first isSend
  	 and: [meth statements first selector == #flag:]]) ifTrue:
  		[meth statements removeFirst].
  	"Propagate the return type of an inlined method"
  	(directReturn or: [exitVar notNil]) ifTrue:
  		[exitType := directReturn 
  						ifTrue: [returnType] 
  						ifFalse: [(self typeFor: exitVar in: aCodeGen) ifNil: [#sqInt]].
  		(exitType = #void or: [exitType = meth returnType]) ifFalse:
  			[meth propagateReturnIn: aCodeGen]].
  	"Propagate any unusual argument types to untyped argument variables"
  		with: aSendNode args
  		do: [:formal :actual|
  			(meth declarationAt: formal ifAbsent: nil) ifNil:
  				[(self typeFor: actual in: aCodeGen) ifNotNil:
  					type ~= #sqInt ifTrue:
  						[meth declarationAt: formal put: (type last = $* ifTrue: [type, formal] ifFalse: [type, ' ', formal])]]]].
+ 	meth renameVarsForInliningInto: self except: notToBeRenamed in: aCodeGen.
- 	meth renameVarsForInliningInto: self except: #() in: aCodeGen.
  	meth renameLabelsForInliningInto: self.
+ 	self addVarsDeclarationsAndLabelsOf: meth except: notToBeRenamed.
- 	self addVarsDeclarationsAndLabelsOf: meth except: #().
  	meth hasReturn ifTrue:
  		[directReturn ifFalse:
  			[exitLabel := self unusedLabelForInliningInto: self.
  			 (meth exitVar: exitVar label: exitLabel) "is label used?"
  				ifTrue: [ labels add: exitLabel ]
  				ifFalse: [ exitLabel := nil ]]].
  	(inlineStmts := OrderedCollection new: meth statements size + meth args size + 2)
  		add: (label := TLabeledCommentNode new setComment: 'begin ', sel);
  		addAll: (self argAssignmentsFor: meth send: aSendNode in: aCodeGen);
  		addAll: meth statements.  "method body"
  	directReturn ifTrue:
  		[meth endsWithReturn
  				[exitVar ifNotNil: "don't remove the returns if being invoked in the context of a return"
  					[inlineStmts at: inlineStmts size put: inlineStmts last copyWithoutReturn]]
  				[inlineStmts add:
  					(TReturnNode new setExpression: (TVariableNode new setName: 'nil'))]].
  	exitLabel ifNotNil:
  		[inlineStmts add:
  			(TLabeledCommentNode new setLabel:
  				exitLabel comment: 'end ', meth selector)].
  	inlineStmts size = 1 ifTrue: "Nuke empty methods; e.g. override of flushAtCache"
  		[self assert: inlineStmts first isComment.
  		 inlineStmts removeFirst].

Item was changed:
+ ----- Method: TVariableNode>>hasSideEffect (in category 'testing') -----
- ----- Method: TVariableNode>>hasSideEffect (in category 'as yet unclassified') -----
  	"Answer if the parse tree rooted at this node has a side-effect or not."

More information about the Vm-dev mailing list