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

commits at source.squeak.org commits at source.squeak.org
Tue May 19 00:46:26 UTC 2015


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

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

Name: VMMaker.oscog-eem.1315
Author: eem
Time: 18 May 2015, 5:44:23.955 pm
UUID: a8172799-131a-401c-861e-55a1d2c21710
Ancestors: VMMaker.oscog-eem.1314

Slang:
Do a more thorough job of transforming complex
to:[by:]do: loops so that the limit expression is only
evaluated once, not on each iteration of the loop.

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

Item was added:
+ ----- Method: TMethod>>ensureToByDoLoopLimitIsSafeAndEfficient:in: (in category 'transformations') -----
+ ensureToByDoLoopLimitIsSafeAndEfficient: node in: aCodeGen
+ 	"For both safety and efficiency, make sure that to:[by:]do: loops
+ 	 with complex limits have a variable to hold the limit expression.
+ 	 In C the limit expression is evaluated each time round the loop
+ 	 so if the loop has side-effects (which it usually will), the C compiler
+ 	 may not be able to optimize the limit expression itself."
+ 	| limitExpr hasSideEffects |
+ 	 limitExpr := node args first.
+ 	 hasSideEffects := limitExpr anySatisfy:
+ 						[:subNode|
+ 						subNode isSend
+ 						and: [(aCodeGen isBuiltinSelector: subNode selector) not
+ 						and: [(subNode isStructSendIn: aCodeGen) not]]].
+ 	 node args size = 4
+ 		ifTrue:
+ 			[hasSideEffects
+ 				ifTrue: [locals add: node args last name]
+ 				ifFalse: [node arguments: node args allButLast]]
+ 		ifFalse: "If the expression is complex but as yet there is no limit variable, add it"
+ 			[hasSideEffects ifTrue:
+ 				[| var |
+ 				 var := self unusedNamePrefixedBy: 'toDoLimit' avoiding: locals. "N.B. adds it to locals!!!!"
+ 				 node arguments: node args, {TVariableNode new setName: var; yourself}.
+ 				 declarations
+ 					at: node args third args first
+ 					ifPresent: [:decl| self declarationAt: var put: (self typeFor: node args third args first in: aCodeGen), ' ', var]]]!

Item was changed:
  ----- Method: TMethod>>prepareMethodIn: (in category 'transformations') -----
  prepareMethodIn: aCodeGen
  	"Record sends of builtin operators, map sends of the special selector dispatchOn:in:
  	 with case statement nodes, and map sends of caseOf:[otherwise:] to switch statements.
+ 	 Declare limit variables for to:[by:]do: loops with limits that potentially have side-effects.
  	 As a hack also update the types of variables introduced to implement cascades correctly.
  	 This has to be done at the same time as this is done, so why not piggy back here?"
  	extraVariableNumber ifNotNil:
  		[declarations keysAndValuesDo:
  			[:varName :decl|
  			decl isBlock ifTrue:
  				[self assert: ((varName beginsWith: 'cascade') and: [varName last isDigit]).
  				 locals add: varName.
  				 self declarationAt: varName
  					put: (decl value: self value: aCodeGen), ' ', varName]]].
  	aCodeGen
  		pushScope: declarations
  		while:"N.B.  nodesWithParentsDo: is bottom-up, hence replacement is destructive and conserved."
  			[parseTree nodesWithParentsDo:
  				[:node :parent|
  				 node isSend ifTrue:
  					[(aCodeGen isBuiltinSelector: node selector)
  						ifTrue:
  							[node isBuiltinOperator: true.
  							"If a to:by:do:'s limit has side-effects, declare the limit variable, otherwise delete it from the args"
+ 							 node selector = #to:by:do: ifTrue:
+ 								[self ensureToByDoLoopLimitIsSafeAndEfficient: node in: aCodeGen]]
- 							 (node selector = #to:by:do:
- 							  and: [node args size = 4]) ifTrue:
- 								[| limitExpr |
- 								 limitExpr := node args first.
- 								 (limitExpr anySatisfy:
- 										[:subNode|
- 										subNode isSend
- 										and: [(aCodeGen isBuiltinSelector: subNode selector) not
- 										and: [(subNode isStructSendIn: aCodeGen) not]]])
- 									ifTrue: [locals add: node args last name]
- 									ifFalse:
- 										[node arguments: node args allButLast]]]
  						ifFalse:
  							[(CaseStatements includes: node selector) ifTrue:
  								[parent replaceNodesIn: (Dictionary newFromPairs: { node. self buildCaseStmt: node in: aCodeGen})].
  							 (#(caseOf: #caseOf:otherwise:) includes: node selector) ifTrue:
  								[parent replaceNodesIn: (Dictionary newFromPairs: { node. self buildSwitchStmt: node parent: parent })]]]]]!



More information about the Vm-dev mailing list