Eliot Miranda uploaded a new version of Cog to project VM Maker: http://source.squeak.org/VMMaker/Cog-eem.349.mcz ==================== Summary ==================== Name: Cog-eem.349 Author: eem Time: 3 January 2019, 3:53:57.607524 pm UUID: 09f2487e-d4ab-4a38-8b48-811e9d5d8564 Ancestors: Cog-eem.348 Eliminate the targets set in DominatorFinder (just use cameFroms) and simplify to use selectors not messages. =============== Diff against Cog-eem.348 =============== Item was changed: InstructionStream subclass: #DominatorFinder + instanceVariableNames: 'cameFroms dominators encoderClass thisInstruction previousInstruction jumpTarget thisPC' - instanceVariableNames: 'cameFroms dominators encoderClass thisInstruction previousInstruction jumpTarget thisPC targets' classVariableNames: 'ReturnSelectors' poolDictionaries: '' category: 'Cog-Explorations'! !DominatorFinder commentStamp: 'eem 1/2/2019 20:26' prior: 0! A DominatorFinder is an InstructionStream that finds the dominators of bytecodes. Specifically it aims to find the dominating conditional branches for join points. This is part of the register allocation problem, to know the common height of the stack at a join point. Only items above the common height need to be merged. I believe finding dominators in bytecode can be done with a simple scan using an FSM, e.g. in scanMethod. This class is part of an experiment to find out if I'm right. I observe that - the first conditional branch that branches to a target that is preceded by an unconditional branch dominates the target of the unconditional branch - if no conditional branch that branches to a target, branches to a target preceded by an unconditional branch (i.e. all are preceded by returns) then the first conditional branch dominates the target - a conditional branch that branches to a target preceded by a backward branch dominates its target (loops) Instance Variables cameFroms: <Array> dominators: <Dictionary> encoderClass: <BytecodeEncoder> previousInstruction: <Symbol> thisInstruction: <Symbol> thisPC: <Integer> cameFroms - the pcs of dominating conditional branches dominators - dictionary of dominating pc to dominated pc encoderClass - the encoderClass for the current method previousInstruction - the selector of the Message for the previous bytecode during the scan thisInstruction - the selector of the Message for the current bytecode during the scan thisPC - the pc for the current bytecode during the scan ! Item was changed: ----- Method: DominatorFinder>>doesNotUnderstand: (in category 'message handling') ----- doesNotUnderstand: aMessage + self recordThisInstruction: aMessage selector! - self recordThisInstruction: aMessage! Item was changed: ----- Method: DominatorFinder>>interpretNextInstructionFor: (in category 'decoding') ----- interpretNextInstructionFor: client | result | (cameFroms at: pc) ifNotNil: [:cameFromPC| "the first conditional branch that branches to a target that is preceded by an unconditional branch dominates the target of the unconditional branch" previousInstruction == #jump: ifTrue: [(jumpTarget >= pc + and: [(cameFroms at: jumpTarget) isNil]) ifTrue: + [self assert: (dominators includesKey: cameFromPC) not. + dominators at: cameFromPC put: jumpTarget]] - and: [(targets includes: jumpTarget) not]) ifTrue: - [dominators at: cameFromPC put: jumpTarget. - targets add: jumpTarget]] ifFalse: + "the first conditional branch that branches to a target not preceded by an unconditional branch dominates the target of the conditional branch" + [(dominators at: cameFromPC ifAbsent: nil) ifNil: + [dominators at: cameFromPC put: pc]]]. - [(targets includes: pc) ifFalse: - [dominators at: cameFromPC put: pc. - targets add: pc]]]. thisPC := pc. result := encoderClass interpretNextInstructionFor: client in: self. previousInstruction := thisInstruction! Item was changed: ----- Method: DominatorFinder>>jump: (in category 'instruction decoding') ----- jump: distance jumpTarget := pc + distance. + self recordThisInstruction: #jump:! - self recordThisInstruction: (Message selector: #jump: argument: distance)! Item was changed: ----- Method: DominatorFinder>>jump:if: (in category 'instruction decoding') ----- jump: distance if: condition | target | target := pc + distance. (cameFroms at: target) ifNil: [cameFroms at: target put: thisPC] ifNotNil: [:cameFromPC| self assert: cameFromPC < thisPC]. + self recordThisInstruction: #jump:if:! - self recordThisInstruction: (Message selector: #jump: argument: distance)! Item was changed: ----- Method: DominatorFinder>>method:pc: (in category 'private') ----- method: method pc: startpc super method: method pc: startpc. cameFroms := Array new: method endPC. encoderClass := method encoderClass. + dominators := Dictionary new! - dominators := Dictionary new. - targets := Set new! Item was changed: ----- Method: DominatorFinder>>recordThisInstruction: (in category 'private') ----- + recordThisInstruction: aSelector + thisInstruction := aSelector! - recordThisInstruction: aMessage - thisInstruction := aMessage selector! Item was added: + ----- Method: MessageNode>>isSingleReturningIf (in category '*Cog-Explorations-testing') ----- + isSingleReturningIf + + ^((special between: 1 and: 2) "ifTrue:/ifFalse:" + or: [special between: 15 and: 16]) "ifNil:/ifNotNil:" + and: [arguments first returns]! |
Free forum by Nabble | Edit this page |