Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2102.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2102 Author: eem Time: 18 January 2017, 2:41:35.36236 pm UUID: f25b8519-a6a1-4c9b-9733-d5904f9d5894 Ancestors: VMMaker.oscog-eem.2101 Slang fixes for RegisterAllocatingCogit. Eliminate the unused inst temp from popToReg: and storeToReg: =============== Diff against VMMaker.oscog-eem.2101 =============== Item was changed: ----- Method: CogRASSBytecodeFixup>>mergeSimStack (in category 'accessing') ----- mergeSimStack + <returnTypeC: #'CogSimStackEntry *'> + ^mergeSimStack! - - ^ mergeSimStack! Item was changed: ----- Method: CogRegisterAllocatingSimStackEntry>>isSameEntryAs: (in category 'comparing') ----- isSameEntryAs: ssEntry + <var: 'ssEntry' type: #'CogSimStackEntry *'> ^type = ssEntry type and: [((type = SSBaseOffset or: [type == SSSpill]) and: [offset = ssEntry offset and: [register = ssEntry register]]) or: [(type = SSRegister and: [register = ssEntry register]) or: [(type = SSConstant and: [constant = ssEntry constant])]]]! Item was changed: ----- Method: CogRegisterAllocatingSimStackEntry>>popToReg: (in category 'compile abstract instructions') ----- popToReg: reg - <var: #inst type: #'AbstractInstruction *'> liveRegister ~= NoReg ifTrue: [self deny: (type = SSRegister and: [register ~= liveRegister and: [cogit needsFrame]]). spilled ifTrue: "This is rare, and in some cases it isn't even needed (e.g. frameful return) but we can't tell as yet." [cogit AddCq: objectRepresentation wordSize R: SPReg]. reg ~= liveRegister ifTrue: [cogit MoveR: liveRegister R: reg] ifFalse: [cogit Label]] ifFalse: [spilled ifTrue: [cogit PopR: reg] ifFalse: [type caseOf: { [SSBaseOffset] -> [cogit MoveMw: offset r: register R: reg]. [SSConstant] -> [cogit genMoveConstant: constant R: reg]. [SSRegister] -> [reg ~= register ifTrue: [cogit MoveR: register R: reg] ifFalse: [cogit Label]] }]]. (reg ~= TempReg and: [reg ~= liveRegister and: [type ~= SSRegister]]) ifTrue: [liveRegister := reg. cogit copyLiveRegisterToCopiesOf: self]! Item was changed: ----- Method: CogRegisterAllocatingSimStackEntry>>reconcileBackwardsWith: (in category 'compile abstract instructions') ----- reconcileBackwardsWith: targetEntry "Make the state of the receiver, a stack entry at a backward jump, the same as the corresponding simStackEntry at the target of the jump" + <var: #targetEntry type: #'SimStackEntry *'> - <var: #targetEntry type: #'targetEntry *'> | targetReg | (targetReg := targetEntry registerOrNone) = NoReg ifTrue: [^self]. targetEntry type = SSConstant ifTrue: [self assert: (type = SSConstant and: [constant = targetEntry constant]). ^self]. liveRegister ~= NoReg ifTrue: [liveRegister ~= targetReg ifTrue: [cogit MoveR: liveRegister R: targetReg]. ^self]. type caseOf: { [SSBaseOffset] -> [cogit MoveMw: offset r: register R: targetReg]. [SSSpill] -> [cogit MoveMw: offset r: register R: targetReg]. [SSConstant] -> [cogit genMoveConstant: constant R: targetReg]. [SSRegister] -> [register ~= targetReg ifTrue: [cogit MoveR: register R: targetReg]] }! Item was changed: ----- Method: CogRegisterAllocatingSimStackEntry>>reconcileForwardsWith: (in category 'compile abstract instructions') ----- reconcileForwardsWith: targetEntry "Make the state of the receiver, a stack entry at the end of a basic block, the same as the corresponding simStackEntry at the target of a preceding jump to the beginning of the next basic block. Make sure targetEntry reflects the state of the merged simStack; it will be installed as the current entry by restoreSimStackAtMergePoint: in mergeWithFixupIfRequired:. Answer if the liveRegister for the targetEntry (if any) should be deassigned; this is because if merging a non-temp with a temp that has a live register we can assign to the register, but must unassign the register from the temp, otherwise the temp will acquire the merged value without an assignment." + <var: #targetEntry type: #'SimStackEntry *'> - <var: #targetEntry type: #'targetEntry *'> | targetReg | (targetReg := targetEntry registerOrNone) = NoReg ifTrue: [| reg | self assert: targetEntry spilled. (self isSameEntryAs: targetEntry) ifTrue: [self assert: spilled. ^false]. (reg := self registerOrNone) = NoReg ifTrue: [reg := TempReg]. self storeToReg: reg. spilled ifTrue: [cogit MoveR: reg Mw: targetEntry offset r: targetEntry register] ifFalse: [cogit PushR: reg]. ^false]. liveRegister ~= NoReg ifTrue: [liveRegister ~= targetReg ifTrue: [cogit MoveR: liveRegister R: targetReg]. (spilled and: [targetEntry spilled not]) ifTrue: [cogit AddCq: objectRepresentation wordSize R: SPReg]. ^false]. spilled ifTrue: [targetEntry spilled ifFalse: [cogit PopR: targetReg. "KISS; generate the least number of instructions..." ^false]] ifFalse: [targetEntry spilled ifTrue: [cogit SubCq: objectRepresentation wordSize R: SPReg]]. type caseOf: { [SSBaseOffset] -> [cogit MoveMw: offset r: register R: targetReg]. [SSSpill] -> [cogit MoveMw: offset r: register R: targetReg]. [SSConstant] -> [cogit genMoveConstant: constant R: targetReg]. [SSRegister] -> [register ~= targetReg ifTrue: [cogit MoveR: register R: targetReg]] }. (targetEntry type = SSConstant and: [type ~= SSConstant or: [constant ~= targetEntry constant]]) ifTrue: [targetEntry register: targetReg; type: SSRegister]. "If merging a non-temp with a temp that has a live register we can assign to the register, but must unassign the register from the temp, otherwise the temp will acquire the merged value without an assignment." ^targetEntry type = SSBaseOffset and: [targetEntry register = FPReg and: [(self isSameEntryAs: targetEntry) not]]! Item was changed: ----- Method: CogRegisterAllocatingSimStackEntry>>reconcilePoppingWith: (in category 'compile abstract instructions') ----- reconcilePoppingWith: targetEntry "Make the state of a targetEntry, a stack entry following a non-inlined special selector send, the same as the corresponding entry (the receiver) along the inlined path." + <var: #targetEntry type: #'SimStackEntry *'> - <var: #targetEntry type: #'targetEntry *'> | targetReg | targetEntry spilled ifTrue: [self assert: (self isSameEntryAs: targetEntry). (targetReg := targetEntry registerOrNone) = NoReg ifTrue: [^self]. type caseOf: { [SSBaseOffset] -> [cogit MoveMw: offset r: register R: targetReg]. [SSSpill] -> [cogit MoveMw: offset r: register R: targetReg]. [SSConstant] -> [cogit genMoveConstant: constant R: targetReg]. [SSRegister] -> [targetReg ~= register ifTrue: [cogit MoveR: register R: targetReg]] }. ^self]. (targetEntry type ~= SSConstant and: [(targetReg := targetEntry registerOrNone) ~= NoReg]) ifTrue: [cogit PopR: targetReg] ifFalse: [cogit AddCq: objectRepresentation wordSize R: SPReg]! Item was changed: ----- Method: CogSimStackEntry>>popToReg: (in category 'compile abstract instructions') ----- popToReg: reg - | inst | - <var: #inst type: #'AbstractInstruction *'> spilled ifTrue: + [cogit PopR: reg] - [inst := cogit PopR: reg] ifFalse: [type caseOf: { + [SSBaseOffset] -> [cogit MoveMw: offset r: register R: reg]. + [SSConstant] -> [cogit genMoveConstant: constant R: reg]. + [SSRegister] -> [reg ~= register + ifTrue: [cogit MoveR: register R: reg] + ifFalse: [cogit Label]] }]! - [SSBaseOffset] -> [inst := cogit MoveMw: offset r: register R: reg]. - [SSConstant] -> [inst := cogit genMoveConstant: constant R: reg]. - [SSRegister] -> [inst := reg ~= register - ifTrue: [cogit MoveR: register R: reg] - ifFalse: [cogit Label]] }].! Item was changed: ----- Method: CogSimStackEntry>>storeToReg: (in category 'compile abstract instructions') ----- storeToReg: reg - | inst | - <var: #inst type: #'AbstractInstruction *'> type caseOf: { + [SSBaseOffset] -> [cogit MoveMw: offset r: register R: reg]. + [SSSpill] -> [cogit MoveMw: offset r: register R: reg]. + [SSConstant] -> [cogit genMoveConstant: constant R: reg]. + [SSRegister] -> [reg ~= register + ifTrue: [cogit MoveR: register R: reg] + ifFalse: [cogit Label]] }! - [SSBaseOffset] -> [inst := cogit MoveMw: offset r: register R: reg]. - [SSSpill] -> [inst := cogit MoveMw: offset r: register R: reg]. - [SSConstant] -> [inst := cogit genMoveConstant: constant R: reg]. - [SSRegister] -> [inst := reg ~= register - ifTrue: [cogit MoveR: register R: reg] - ifFalse: [cogit Label]] }! Item was changed: ----- Method: RegisterAllocatingCogit>>deassignRegisterForTempVar:in: (in category 'bytecode generator support') ----- deassignRegisterForTempVar: targetEntry in: mergeSimStack "If merging a non-temp with a temp that has a live register we can assign to the register, but must unassign the register from the temp, otherwise the temp will acquire the merged value without an assignment. The targetEntry must also be transmogrified into an SSRegister entry." <var: #targetEntry type: #'SimStackEntry *'> + <var: #duplicateEntry type: #'SimStackEntry *'> <var: #mergeSimStack type: #'SimStackEntry *'> <inline: true> | reg | reg := targetEntry liveRegister. self assert: (targetEntry type = SSBaseOffset and: [targetEntry register = FPReg]). simStackPtr to: 0 by: -1 do: [:j| | duplicateEntry | duplicateEntry := self simStack: mergeSimStack at: j. (targetEntry isSameEntryAs: duplicateEntry) ifTrue: [duplicateEntry liveRegister: NoReg]]. targetEntry type: SSRegister; register: reg! Item was changed: ----- Method: RegisterAllocatingCogit>>ensureReceiverResultRegContainsSelf (in category 'bytecode generator support') ----- ensureReceiverResultRegContainsSelf super ensureReceiverResultRegContainsSelf. methodOrBlockNumTemps to: simStackPtr do: [:i| + ((self addressOf: simSelf) isSameEntryAs: (self simStackAt: i)) - (simSelf isSameEntryAs: (self simStackAt: i)) ifTrue: [(self simStackAt: i) liveRegister: ReceiverResultReg] ifFalse: [(self simStackAt: i) liveRegister = ReceiverResultReg ifTrue: [(self simStackAt: i) liveRegister: NoReg]]]. simSelf liveRegister: ReceiverResultReg! Item was changed: ----- Method: RegisterAllocatingCogit>>flushLiveRegistersForSend (in category 'bytecode generator support') ----- flushLiveRegistersForSend <inline: true> self assert: simSelf type = SSBaseOffset. simSelf liveRegister: NoReg. 0 to: simStackPtr do: [:i| self assert: ((self simStackAt: i) spilled and: [(self simStackAt: i) type = SSConstant or: [((self simStackAt: i) type = SSBaseOffset or: [i >= methodOrBlockNumTemps + and: [(self simStackAt: i) type = SSSpill]]) - and: (self simStackAt: i) type = SSSpill]) and: [(self simStackAt: i) register = FPReg and: [(self simStackAt: i) offset = (self frameOffsetOfTemporary: i)]]]]). (self simStackAt: i) liveRegister: NoReg]! Item was changed: ----- Method: RegisterAllocatingCogit>>mergeCurrentSimStackWith: (in category 'bytecode generator support') ----- mergeCurrentSimStackWith: fixup <var: #fixup type: #'BytecodeFixup *'> | mergeSimStack direction currentEntry targetEntry | <var: #mergeSimStack type: #'SimStackEntry *'> "At a merge point the cogit expects the stack to be in the same state as mergeSimStack. mergeSimStack is the state as of some jump forward to this point. So make simStack agree with mergeSimStack (it is, um, problematic to plant code at the jump). Values may have to be assigned to registers. Registers may have to be swapped. The state of optStatus must agree." <var: #targetEntry type: #'SimStackEntry *'> <var: #currentEntry type: #'SimStackEntry *'> - <var: #duplicateEntry type: #'SimStackEntry *'> (mergeSimStack := fixup mergeSimStack) ifNil: [^self]. "Assignments amongst the registers must be made in order to avoid overwriting. If necessary exchange registers amongst simStack's entries to resolve any conflicts." self resolveRegisterOrderConflictsBetweenCurrentSimStackAnd: mergeSimStack. self assert: (self conflcitsResolvedBetweenSimStackAnd: mergeSimStack). "Must determine if we will push or pop values. If pushing values must enumerate from bottom to top. If popping, must enumerate from top to bottom." direction := self directionForMergeWith: mergeSimStack. direction > 0 ifTrue: [0 to: simStackPtr do: [:i| currentEntry := self simStack: simStack at: i. targetEntry := self simStack: mergeSimStack at: i. (currentEntry reconcileForwardsWith: targetEntry) ifTrue: [self assert: i >= methodOrBlockNumArgs. self deassignRegisterForTempVar: targetEntry in: mergeSimStack]. "Note, we could update the simStack and spillBase here but that is done in restoreSimStackAtMergePoint: spilled ifFalse: [simSpillBase := i - 1]. simStack at: i put: (self cCode: [mergeSimStack at: i] inSmalltalk: [(mergeSimStack at: i) copy])"]] ifFalse: [simStackPtr to: 0 by: -1 do: [:i| currentEntry := self simStack: simStack at: i. targetEntry := self simStack: mergeSimStack at: i. (currentEntry reconcileForwardsWith: targetEntry) ifTrue: [self assert: i >= methodOrBlockNumArgs. self deassignRegisterForTempVar: targetEntry in: mergeSimStack]. "Note, we could update the simStack and spillBase here but that is done in restoreSimStackAtMergePoint: spilled ifFalse: [simSpillBase := i - 1]. simStack at: i put: (self cCode: [mergeSimStack at: i] inSmalltalk: [(mergeSimStack at: i) copy])"]]. "a.k.a. fixup isReceiverResultRegSelf: (fixup isReceiverResultRegSelf and: [optStatus isReceiverResultRegLive])" optStatus isReceiverResultRegLive ifFalse: [fixup isReceiverResultRegSelf: false]! Item was changed: ----- Method: RegisterAllocatingCogit>>reconcileRegisterStateForBackwardJoin: (in category 'bytecode generator support') ----- reconcileRegisterStateForBackwardJoin: fixup + <var: #fixup type: #'BytecodeFixup *'> - <var: #fixup type: #'SSBytecodeFixup *'> | fixupSimStack | <var: #fixupSimStack type: #'SimStackEntry *'> + self assert: (optStatus ssEntry isSameEntryAs: (self addressOf: simSelf)). - self assert: (optStatus ssEntry isSameEntryAs: simSelf). fixup isReceiverResultRegSelf ifTrue: [optStatus isReceiverResultRegLive ifFalse: [optStatus ssEntry storeToReg: ReceiverResultReg]]. fixupSimStack := fixup mergeSimStack. simStackPtr to: 0 by: -1 do: [:i| self assert: (self simStackAt: i) spilled. + (self simStackAt: i) reconcileBackwardsWith: (self addressOf: (fixupSimStack at: i))]! - (self simStackAt: i) reconcileBackwardsWith: (fixupSimStack at: i)]! Item was changed: ----- Method: RegisterAllocatingCogit>>setMergeSimStackOf: (in category 'bytecode generator support') ----- setMergeSimStackOf: fixup <var: #fixup type: #'BytecodeFixup *'> self moveVolatileSimStackEntriesToRegisters. fixup mergeSimStack ifNil: [self assert: nextFixup <= numFixups. self cCode: [fixup mergeSimStack: mergeSimStacksBase + (nextFixup * self simStackSlots * (self sizeof: CogSimStackEntry))]. nextFixup := nextFixup + 1] ifNotNil: [self assert: fixup simStackPtr = simStackPtr. 0 to: simStackPtr do: [:i| + self assert: ((self simStackAt: i) isSameEntryAs: (self addressOf: (fixup mergeSimStack at: i))). + (self simStackAt: i) liveRegister ~= (self addressOf: (fixup mergeSimStack at: i)) liveRegister ifTrue: - self assert: ((self simStackAt: i) isSameEntryAs: (fixup mergeSimStack at: i)). - (self simStackAt: i) liveRegister ~= (fixup mergeSimStack at: i) liveRegister ifTrue: [(self simStackAt: i) liveRegister: NoReg]]]. fixup simStackPtr: simStackPtr; isReceiverResultRegSelf: optStatus isReceiverResultRegLive. self cCode: [self mem: fixup mergeSimStack cp: simStack y: self simStackSlots * (self sizeof: CogSimStackEntry)] inSmalltalk: [fixup mergeSimStack: self copySimStack]! Item was changed: ----- Method: RegisterAllocatingCogit>>simSelfOnStackInReceiverResultReg (in category 'bytecode generator support') ----- simSelfOnStackInReceiverResultReg "For assert checking only." methodOrBlockNumArgs to: simStackPtr do: [:i| + (((self addressOf: simSelf) isSameEntryAs: (self simStackAt: i)) - ((simSelf isSameEntryAs: (self simStackAt: i)) and: [(self simStackAt: i) registerOrNone = ReceiverResultReg]) ifTrue: [^true]]. ^false! Item was changed: ----- Method: RegisterAllocatingCogit>>voidReceiverResultRegContainsSelf (in category 'bytecode generator support') ----- voidReceiverResultRegContainsSelf "Used when ReceiverResultReg is allocated for other than simSelf, and there may be references to ReceiverResultReg which need to be spilled." self assert: (simSelf liveRegister = ReceiverResultReg) = optStatus isReceiverResultRegLive. optStatus isReceiverResultRegLive ifFalse: [self deny: self simSelfOnStackInReceiverResultReg. ^self]. optStatus isReceiverResultRegLive: false. methodOrBlockNumTemps to: simStackPtr do: [:i| + ((self addressOf: simSelf) isSameEntryAs: (self simStackAt: i)) ifTrue: - (simSelf isSameEntryAs: (self simStackAt: i)) ifTrue: [(self simStackAt: i) liveRegister: NoReg]]. simSelf liveRegister: NoReg! |
Free forum by Nabble | Edit this page |