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

Rolandas Guobys rolandasguobys at gmail.com
Fri Jul 9 16:31:40 UTC 2021


please don't send me more letters !!!

> On 2020-06-24, at 04:41, commits at source.squeak.org wrote:
> 
> 
> Eliot Miranda uploaded a new version of VMMaker to project VM Maker Inbox:
> http://source.squeak.org/VMMakerInbox/VMMaker.oscog-eem.2765.mcz
> 
> ==================== Summary ====================
> 
> Name: VMMaker.oscog-eem.2765
> Author: eem
> Time: 23 June 2020, 6:41:19.556484 pm
> UUID: 91b9976e-60b9-4b5c-a2f8-b621dd454a07
> Ancestors: VMMaker.oscog-eem.2764
> 
> Spur: Rewrite the revised followForwardedObjectFields:toDepth: soi it can be correctly inlined.
> 
> Slang: Change the order of application of ensureConditionalAssignmentsAreTransformedIn: so it is always the last thing done in tryToInlineMethodsIn:.
> 
> Straight-forward optimization of bindVariablesIn: in the common case of methods being inlined swith unchanged parameters.
> 
> =============== Diff against VMMaker.oscog-eem.2764 ===============
> 
> Item was changed:
>  ----- Method: Spur32BitCoMemoryManager>>followForwardedObjectFields:toDepth: (in category 'as yet unclassified') -----
>  followForwardedObjectFields: objOop toDepth: depth
>      "Follow pointers in the object to depth.
>       Answer if any forwarders were found.
>       How to avoid cyclic structures?? A temporary mark bit? eem 6/22/2020 no need since depth is always finite."
>      <api>
>      <inline: false>
> +    | found fmt limit |
> -    | oop found fmt |
>      found := false.
>      self assert: ((self isPointers: objOop) or: [self isOopCompiledMethod: objOop]).
>      fmt := self formatOf: objOop.
> +    limit := (self numPointerSlotsOf: objOop format: fmt) - 1.
>      "It is essential to skip the first field of a method because it may be a
>       reference to a Cog method in the method zone, not a real object at all."
>      ((self isCompiledMethodFormat: fmt)
>              ifTrue: [1]
>              ifFalse: [0])
> +        to: limit
> +        do: [:i| | oop |
> -        to: (self numPointerSlotsOf: objOop format: fmt) - 1
> -        do: [:i|
>               oop := self fetchPointer: i ofObject: objOop.
>               (self isNonImmediate: oop) ifTrue:
>                  [(self isForwarded: oop) ifTrue:
>                      [found := true.
>                       oop := self followForwarded: oop.
>                       self storePointer: i ofObject: objOop withValue: oop].
>                  (depth > 0
>                   and: [(self hasPointerFields: oop)
>                   and: [self followForwardedObjectFields: oop toDepth: depth - 1]]) ifTrue:
>                      [found := true]]].
>      ^found!
> 
> Item was changed:
>  ----- Method: Spur64BitCoMemoryManager>>followForwardedObjectFields:toDepth: (in category 'forwarding') -----
>  followForwardedObjectFields: objOop toDepth: depth
>      "Follow pointers in the object to depth.
>       Answer if any forwarders were found.
>       How to avoid cyclic structures?? A temporary mark bit? eem 6/22/2020 no need since depth is always finite."
>      <api>
>      <inline: false>
> +    | found fmt limit |
> -    | oop found fmt |
>      found := false.
>      self assert: ((self isPointers: objOop) or: [self isOopCompiledMethod: objOop]).
>      fmt := self formatOf: objOop.
> +    limit := (self numPointerSlotsOf: objOop format: fmt) - 1.
>      "It is essential to skip the first field of a method because it may be a
>       reference to a Cog method in the method zone, not a real object at all."
>      ((self isCompiledMethodFormat: fmt)
>              ifTrue: [1]
>              ifFalse: [0])
> +        to: limit
> +        do: [:i| | oop |
> -        to: (self numPointerSlotsOf: objOop format: fmt) - 1
> -        do: [:i|
>               oop := self fetchPointer: i ofObject: objOop.
>               (self isNonImmediate: oop) ifTrue:
>                  [(self isForwarded: oop) ifTrue:
>                      [found := true.
>                       oop := self followForwarded: oop.
>                       self storePointer: i ofObject: objOop withValue: oop].
>                  (depth > 0
>                   and: [(self hasPointerFields: oop)
>                   and: [self followForwardedObjectFields: oop toDepth: depth - 1]]) ifTrue:
>                      [found := true]]].
>      ^found!
> 
> Item was changed:
>  ----- Method: TMethod>>exitVar:label:in: (in category 'inlining') -----
>  exitVar: exitVar label: exitLabel in: aCodeGen
>      "Replace each return statement in this method with an assignment to the
>       exit variable followed by either a return or a goto to the given label.
>       Answer if a goto was generated."
>      "Optimization: If exitVar is nil, the return value of the inlined method is not being used, so don't add the assignment statement."
> 
>      | labelUsed map elisions eliminateReturnSelfs |
>      labelUsed := false.
>      map := Dictionary new.
>      elisions := Set new.
>      "Conceivably one might ^self from a struct class and mean it.  In most cases though
>       ^self means `get me outta here, fast'.  So unless this method is from a VMStruct class,
>       elide any ^self's"
>      eliminateReturnSelfs := ((definingClass inheritsFrom: VMClass) and: [definingClass isStructClass]) not
>                                and: [returnType = #void or: [returnType = #sqInt]].
>      parseTree nodesDo:
>          [:node | | replacement |
>          node isReturn ifTrue:
>              [self transformReturnSubExpression: node
>                  toAssignmentOf: exitVar
>                  andGoto: exitLabel
>                  unless: eliminateReturnSelfs
>                  into: [:rep :labelWasUsed|
>                      replacement := rep.
>                      labelWasUsed ifTrue: [labelUsed := true]]
>                  in: aCodeGen.
>              "replaceNodesIn: is strictly top-down, so any replacement for ^expr ifTrue: [...^fu...] ifFalse: [...^bar...]
>               will prevent replacement of either ^fu or ^bar. The corollary is that ^expr ifTrue: [foo] ifFalse: [^bar]
>               must be transformed into expr ifTrue: [^foo] ifFalse: [^bar]"
>              (node expression isConditionalSend
>               and: [node expression hasExplicitReturn])
>                  ifTrue:
>                      [elisions add: node.
>                       (node expression args reject: [:arg| arg endsWithReturn]) do:
>                          [:nodeNeedingReturn|
>                           self transformReturnSubExpression: nodeNeedingReturn statements last
>                              toAssignmentOf: exitVar
>                              andGoto: exitLabel
>                              unless: eliminateReturnSelfs
>                              into: [:rep :labelWasUsed|
>                                  replacement := rep.
> +                                labelWasUsed ifTrue: [labelUsed := true]]
> +                            in: aCodeGen.
> -                                labelWasUsed ifTrue: [labelUsed := true]].
>                           map
>                              at: nodeNeedingReturn statements last
>                              put: replacement]]
>                  ifFalse:
>                      [map
>                          at: node
>                          put: (replacement ifNil:
>                                  [TLabeledCommentNode new setComment: 'return ', node expression printString])]]].
>      map isEmpty ifTrue:
>          [self deny: labelUsed.
>           ^false].
>      "Now do a top-down replacement for all returns that should be mapped to assignments and gotos"
>      parseTree replaceNodesIn: map.
>      "Now it is safe to eliminate the returning ifs..."
>      elisions isEmpty ifFalse:
>          [| elisionMap |
>           elisionMap := Dictionary new.
>           elisions do: [:returnNode| elisionMap at: returnNode put: returnNode expression].
>           parseTree replaceNodesIn: elisionMap].
>      "Now flatten any new statement lists..."
>      parseTree nodesDo:
>          [:node| | list |
>          (node isStmtList
>           and: [node statements notEmpty
>           and: [node statements last isStmtList]]) ifTrue:
>              [list := node statements last statements.
>               node statements removeLast; addAllLast: list]].
>      ^labelUsed!
> 
> Item was changed:
>  ----- Method: TMethod>>inlineFunctionCall:in: (in category 'inlining') -----
>  inlineFunctionCall: aSendNode in: aCodeGen
>      "Answer the body of the called function, substituting the actual
>       parameters for the formal argument variables in the method body.
>       Assume caller has established that:
>          1. the method arguments are all substitutable nodes, and
>          2. the method to be inlined contains no additional embedded returns."
> 
>      | sel meth doNotRename argsForInlining substitutionDict |
> +    aCodeGen maybeBreakForInlineOf: aSendNode in: self.
>      sel := aSendNode selector.
>      meth := (aCodeGen methodNamed: sel) copy.
>      meth ifNil:
>          [^self inlineBuiltin: aSendNode in: aCodeGen].
>      doNotRename := Set withAll: args.
>      argsForInlining := aSendNode argumentsForInliningCodeGenerator: aCodeGen.
>      meth args with: argsForInlining do:
>          [ :argName :exprNode |
>          exprNode isLeaf ifTrue:
>              [doNotRename add: argName]].
>      (meth statements size = 2
>      and: [meth statements first isSend
>      and: [meth statements first selector == #flag:]]) ifTrue:
>          [meth statements removeFirst].
>      meth renameVarsForInliningInto: self except: doNotRename in: aCodeGen.
>      meth renameLabelsForInliningInto: self.
>      self addVarsDeclarationsAndLabelsOf: meth except: doNotRename.
>      substitutionDict := Dictionary new: meth args size * 2.
>      meth args with: argsForInlining do:
>          [ :argName :exprNode |
> +        (exprNode isVariable and: [exprNode name = argName]) ifFalse:
> +            [substitutionDict at: argName put: exprNode].
> -        substitutionDict at: argName put: exprNode.
>          (doNotRename includes: argName) ifFalse:
>              [locals remove: argName]].
>      meth parseTree bindVariablesIn: substitutionDict.
>      ^meth parseTree endsWithReturn
>          ifTrue: [meth parseTree copyWithoutReturn]
>          ifFalse: [meth parseTree]!
> 
> Item was changed:
>  ----- Method: TMethod>>tryToInlineMethodsIn: (in category 'inlining') -----
>  tryToInlineMethodsIn: aCodeGen
>      "Expand any (complete) inline methods sent by this method.
>       Set the complete flag when all inlining has been done.
>       Answer if something was inlined."
> 
>      | didSomething statementLists |
>      "complete ifTrue:
>          [^false]."
> 
>      self definedAsMacro ifTrue:
>          [complete ifTrue:
>              [^false].
>           ^complete := true].
> 
> -    self ensureConditionalAssignmentsAreTransformedIn: aCodeGen.
>      didSomething := self tryToInlineMethodStatementsIn: aCodeGen statementListsInto: [:stmtLists| statementLists := stmtLists].
>      didSomething := (self tryToInlineMethodExpressionsIn: aCodeGen) or: [didSomething].
> +    self ensureConditionalAssignmentsAreTransformedIn: aCodeGen.
> 
>      didSomething ifTrue:
>          [writtenToGlobalVarsCache := nil].
> 
>      complete ifFalse:
>          [self checkForCompletenessIn: aCodeGen.
>           complete ifTrue: [didSomething := true]].  "marking a method complete is progress"
>      ^didSomething!
> 
> Item was changed:
>  ----- Method: TStmtListNode>>bindVariablesIn: (in category 'transformations') -----
>  bindVariablesIn: aDictionary
> 
> +    aDictionary notEmpty ifTrue:
> +        [statements := statements collect: [:s| s bindVariablesIn: aDictionary]]!
> -    statements := statements collect: [ :s | s bindVariablesIn: aDictionary ].!
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20210709/7825a6a9/attachment-0001.html>


More information about the Vm-dev mailing list