VM Maker: VMMaker.oscog-eem.2102.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-eem.2102.mcz

commits-2
 
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!