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

commits at source.squeak.org commits at source.squeak.org
Sat Feb 21 03:31:48 UTC 2015


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

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

Name: VMMaker.oscog-eem.1072
Author: eem
Time: 20 February 2015, 7:30:18.738 pm
UUID: bd9d8dd5-dea0-49da-8be7-cb246f49f554
Ancestors: VMMaker.oscog-eem.1071

Fix typing multiple assignments to a variable
- promote the type to the largest integral type of
  all assignments
	(primitiveDecompressFromByteArray)
- do /not/ promote a variable typed with an integral
  type to a floating point type (transformColor:)

Provide size of short int.

Fix weird regression for Objectmemory>>baseHeaderSize

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

Item was changed:
  ----- Method: CCodeGenerator>>isActualType:compatibleWithFormalType: (in category 'inlining') -----
  isActualType: actualTypeOrNil compatibleWithFormalType: formalTypeOrNil 
  	| actualType formalType |
  	actualType := actualTypeOrNil ifNil: [#sqInt].
  	formalType := formalTypeOrNil ifNil: [#sqInt].
  	((self isIntegralCType: actualType)
  	 and: [self isIntegralCType: formalType]) ifFalse:
  		[^actualType = formalType
+ 		 or: [formalType = #double and: [actualType = #float]]].
+ 	"For now, insist that the signedness agrees.  If the actual's type is unknown allow inlining.
+ 	 A formal defaults to #sqInt. Allowing inlining an unsigned type within a sqInt formal is wrong;
+ 	 snd for testing, it breaks e.g. the BitBltPlugin."
- 		 or: [formalType = 'double' and: [actualType = 'float']]].
- 	"For now, insist that the signedness agrees."
  	^(actualType first = $u) = (formalType first = $u)
+ 	  or: [actualTypeOrNil isNil] !
- 	  or: [actualTypeOrNil isNil] "a nil formal defaults to #sqInt"!

Item was added:
+ ----- Method: CCodeGenerator>>mergeTypeOf:in:with: (in category 'type inference') -----
+ mergeTypeOf: var in: aDictionary with: newType
+ 	"var is a variable that has been assigned an expression of type  newType.
+ 	 Either assign its type, if it is as yet untyped, or merge newType with its existing type.
+ 	 N.B. We refuse to promote a variable that already has integral type to a floating point
+ 	 type.  The existing plugins depend on this; one can always use an explicit type in future."
+ 	| existingType mergedType |
+ 	existingType := self
+ 						extractTypeFor: var
+ 						fromDeclaration: (aDictionary at: var ifAbsentPut: [newType, ' ', var]).
+ 	existingType ~= newType ifTrue:
+ 		[((self isIntegralCType: existingType)
+ 		  and: [self isFloatingPointCType: newType]) ifFalse:
+ 			[mergedType := self promoteArithmeticTypes: existingType and: newType.
+ 			 aDictionary at: var put: mergedType, ' ', var]]!

Item was added:
+ ----- Method: CCodeGenerator>>promoteArithmeticTypes:and: (in category 'type inference') -----
+ promoteArithmeticTypes: firstType and: secondType
+ 	"Answer the return type for an arithmetic sendThis is so that the inliner can still
+ 	 inline simple expressions.  Deal with pointer arithmetic, floating point arithmetic
+ 	 and promotion."
+ 	((#(#double float) includes: firstType)
+ 	 or: [#(#double float) includes: secondType]) ifTrue:
+ 		[^(firstType = #float and: [secondType = #float])
+ 			ifTrue: [#float]
+ 			ifFalse: [#double]].
+ 	"deal with unknowns, answering nil."
+ 	(firstType isNil or: [secondType isNil]) ifTrue:
+ 		[^nil].
+ 	"deal with promotion; answer the longest type, defaulting to the recever if they're the same"
+ 	^(self sizeOfIntegralCType: firstType) >= (self sizeOfIntegralCType: secondType)
+ 		ifTrue: [firstType]
+ 		ifFalse: [secondType]!

Item was changed:
  ----- Method: CCodeGenerator>>sizeOfIntegralCType: (in category 'inlining') -----
  sizeOfIntegralCType: anIntegralCType "<String>"
  	"N.B. Only works for values for which isIntegralCType: answers true."
  	| prunedCType index |
  	(anIntegralCType beginsWith: 'register ') ifTrue:
  		[^self sizeOfIntegralCType: (anIntegralCType allButFirst: 9)].
  	prunedCType := (anIntegralCType beginsWith: 'unsigned ')
  						ifTrue: [(anIntegralCType allButFirst: 9) withBlanksTrimmed]
  						ifFalse: [(anIntegralCType beginsWith: 'signed ')
  									ifTrue: [(anIntegralCType allButFirst: 7) withBlanksTrimmed]
  									ifFalse: [anIntegralCType]].
  	^prunedCType asString caseOf: {
  		['sqLong']	->	[8].
  		['usqLong']	->	[8].
  		['sqInt']		->	[BytesPerWord].
  		['usqInt']	->	[BytesPerWord].
  		['int']		->	[4].
  		['short']		->	[2].
+ 		['short int']	->	[2].
  		['char']		->	[1].
  		['long']		->	[BytesPerWord].
  		['size_t']		->	[BytesPerWord].
  		['pid_t']		->	[BytesPerWord].
  	}
  	otherwise:
  		[((anIntegralCType beginsWith: 'unsigned') "e.g. 'unsigned  : 8'"
  		  and: [(anIntegralCType includesAnyOf: '[*]') not
  		  and: [(index := anIntegralCType indexOf: $:) > 0]])
  			ifTrue: [(Integer readFrom: (anIntegralCType copyFrom: index + 1 to: anIntegralCType size) withBlanksTrimmed readStream) + 7 // 8]
  			ifFalse: [self error: 'unrecognized integral type']]!

Item was changed:
  ----- Method: CCodeGenerator>>typeForArithmetic:in: (in category 'type inference') -----
  typeForArithmetic: sendNode in: aTMethod
  	"Answer the return type for an arithmetic sendThis is so that the inliner can still
  	 inline simple expressions.  Deal with pointer arithmetic, floating point arithmetic
  	 and promotion."
  	| rcvrType argType |
- 	argType := self typeFor: sendNode args first in: aTMethod.
- 	argType = #double ifTrue:
- 		[^#double].
  	rcvrType := self typeFor: sendNode receiver in: aTMethod.
+ 	argType := self typeFor: sendNode args first in: aTMethod.
- 	"deal with unknowns, answering nil."
- 	(rcvrType isNil or: [argType isNil]) ifTrue:
- 		[^nil].
  	"deal with pointer arithmetic"
+ 	((rcvrType notNil and: [rcvrType last = $*]) or: [argType notNil and: [argType last = $*]]) ifTrue:
+ 		[(rcvrType isNil or: [argType isNil]) ifTrue:
+ 			[^nil].
+ 		 (rcvrType last = $* and: [argType last = $*]) ifTrue:
+ 			[sendNode selector == #- ifTrue:
+ 				[^#int].
+ 			 self error: 'invalid pointer arithmetic'].
+ 		 ^rcvrType last = $*
- 	(rcvrType last = $* or: [argType last = $*]) ifTrue:
- 		[(sendNode selector == #-
- 		  and: [rcvrType last = $* and: [argType last = $*]]) ifTrue:
- 			[^#int].
- 		 ^rcvrType last = $
  			ifTrue: [rcvrType]
  			ifFalse: [argType]].
+ 	^self promoteArithmeticTypes: rcvrType and: argType!
- 	"deal with promotion; answer the longest type, defaulting to the recever if they're the same"
- 	^(self sizeOfIntegralCType: rcvrType) >= (self sizeOfIntegralCType: argType)
- 		ifTrue: [rcvrType]
- 		ifFalse: [argType]!

Item was changed:
  ----- Method: ObjectMemory>>baseHeaderSize (in category 'interpreter access') -----
  baseHeaderSize
+ 	"N.B. This would appear to hard-code the header size for 32-bit images.  But if generating
+ 	 a 64-bit image, this method could be removed and the relevant one substituted.  We can't
+ 	 mark this method as <doNotGenerate> as we need an actual method to guide code gen."
+ 	^4!
- "To support SmartSyntaxPluginCodeGenerator"
- 	^self baseHeaderSize!

Item was changed:
  ----- Method: TMethod>>inferTypesForImplicitlyTypedVariablesIn: (in category 'type inference') -----
  inferTypesForImplicitlyTypedVariablesIn: aCodeGen
  	"infer types for untyped variables from assignments and arithmetic uses.
  	 For debugging answer a Dictionary from var to the nodes that determined types
  	 This for debugging:
  		(self copy inferTypesForImplicitlyTypedVariablesIn: aCodeGen)"
  	| alreadyExplicitlyTyped effectiveNodes |
+ 	"selector = #transformColor: ifTrue:
- 	"selector = #blockDispatchTargetsFor:perform:arg: ifTrue:
  		[self halt]."
  	alreadyExplicitlyTyped := declarations keys asSet.
  	effectiveNodes := Dictionary new. "this for debugging"
  	parseTree nodesDo:
  		[:node| | type var |
  		"If there is something of the form i >= 0, then i should be signed, not unsigned."
  		(node isSend
  		 and: [(locals includes: (var := node receiver variableNameOrNil))
  		 and: [(alreadyExplicitlyTyped includes: var) not "don't be fooled by inferred unsigned types"
  		 and: [(#(<= < >= >) includes: node selector)
  		 and: [node args first isConstant
  		 and: [node args first value = 0
  		 and: [(type := self typeFor: var in: aCodeGen) notNil
  		 and: [type first == $u]]]]]]]) ifTrue:
  			[declarations at: var put: (aCodeGen signedTypeForIntegralType: type), ' ', var.
  			 effectiveNodes at: var put: { declarations at: var. node }].
  		"if an assignment to an untyped local of a known type, set the local's type to that type.
  		 Only observe known sends (methods in the current set) and typed local variables."
  		(node isAssignment
  		 and: [(locals includes: (var := node variable name))
+ 		 and: [(alreadyExplicitlyTyped includes: var) not "don't be fooled by previously inferred types"
- 		 and: [(declarations includesKey: var) not
  		 and: [(type := node expression isSend
  						ifTrue: [aCodeGen returnTypeForSend: node expression in: self]
  						ifFalse: [self typeFor: node expression in: aCodeGen]) notNil
  		 and: [type ~= #void]]]]) ifTrue:
+ 			[aCodeGen mergeTypeOf: var in: declarations with: type.
+ 			 effectiveNodes at: var put: { declarations at: var. node }, (effectiveNodes at: var ifAbsent: [#()])]].
- 			[declarations at: var put: type, ' ', var.
- 			 effectiveNodes at: var put: { declarations at: var. node }]].
  	^effectiveNodes!



More information about the Vm-dev mailing list