From 02381105d663804224b2d19b9e50f5993eb74b27 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sat, 22 Jan 2000 16:10:06 +0000 Subject: [PATCH] + all code generator generated "mov reg1,reg2" instructions are now attempted to be removed using the replacereg code (-dnewoptimizations) * small fixes to -dreplacereg code --- compiler/csopt386.pas | 114 +++++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 45 deletions(-) diff --git a/compiler/csopt386.pas b/compiler/csopt386.pas index ab14c863a8..53f58742ef 100644 --- a/compiler/csopt386.pas +++ b/compiler/csopt386.pas @@ -189,12 +189,11 @@ Begin {CheckSequence} { hp2 now containts the last instruction of the sequence } { get the writestate at this point of the register in TmpState } TmpState := PPaiProp(hp2^.OptInfo)^.Regs[RegCounter].WState; -{ hp3 := first instruction after the sequence } - GetNextInstruction(hp2, hp2); { now, even though reg is in RegsLoadedForRef, sometimes it's still used } { afterwards. It is not if either it is not in usedregs anymore after the } { sequence, or if it is loaded with a new value right after the sequence } - If (TmpState = PPaiProp(hp2^.OptInfo)^.Regs[RegCounter].WState) And + If GetNextInstruction(hp2, hp2) and + (TmpState = PPaiProp(hp2^.OptInfo)^.Regs[RegCounter].WState) And (RegCounter in PPaiProp(hp2^.OptInfo)^.UsedRegs) Then { it is still used, so remove it from RegsLoadedForRef } Begin @@ -430,24 +429,6 @@ begin end end; -function regLoadedWithNewValue(reg: tregister; hp: pai): boolean; -{ assumes reg is a 32bit register } -var p: paicpu; -begin - p := paicpu(hp); - regLoadedWithNewValue := - assigned(hp) and - ((hp^.typ = ait_instruction) and - (((p^.opcode = A_MOV) or - (p^.opcode = A_MOVZX) or - (p^.opcode = A_MOVSX) or - (p^.opcode = A_LEA)) and - (p^.oper[1].typ = top_reg) and - (Reg32(p^.oper[1].reg) = reg)) or - ((p^.opcode = A_POP) and - (Reg32(p^.oper[0].reg) = reg))); -end; - Procedure RestoreRegContentsTo(reg: TRegister; const c: TContent; p, endP: pai); var {$ifdef replaceregdebug} @@ -526,19 +507,20 @@ end; function NoHardCodedRegs(p: paicpu): boolean; var chCount: byte; begin - if (p^.opcode = A_IMUL) then - noHardCodedRegs := p^.ops <> 1 - else - begin - NoHardCodedRegs := true; - with InsProp[p^.opcode] do - for chCount := 1 to MaxCh do - if Ch[chCount] in ([Ch_REAX..Ch_MEDI,Ch_WMemEDI,Ch_All]-[Ch_RESP,Ch_WESP,Ch_RWESP]) then - begin - NoHardCodedRegs := false; - break - end; - end; + case p^.opcode of + A_IMUL: noHardCodedRegs := p^.ops <> 1; + else + begin + NoHardCodedRegs := true; + with InsProp[p^.opcode] do + for chCount := 1 to MaxCh do + if Ch[chCount] in ([Ch_REAX..Ch_MEDI,Ch_WMemEDI,Ch_All]-[Ch_RESP,Ch_WESP,Ch_RWESP]) then + begin + NoHardCodedRegs := false; + break + end; + end; + end; end; Procedure ChangeReg(var Reg: TRegister; orgReg, newReg: TRegister); @@ -575,7 +557,8 @@ function RegSizesOK(oldReg,newReg: TRegister; p: paicpu): boolean; var opCount: byte; begin RegSizesOK := true; - if not(IsGP32reg(oldReg) and IsGP32Reg(newReg)) then + { if only one of them is a general purpose register ... } + if (IsGP32reg(oldReg) xor IsGP32Reg(newReg)) then begin for opCount := 0 to 2 do if (p^.oper[opCount].typ = top_reg) and @@ -690,7 +673,7 @@ begin end; function ReplaceReg(orgReg, newReg: TRegister; p: pai; - const c: TContent): Boolean; + const c: TContent; orgRegCanBeModified: Boolean): Boolean; { Tries to replace orgreg with newreg in all instructions coming after p } { until orgreg gets loaded with a new value. Returns true if successful, } { false otherwise. If successful, the contents of newReg are set to c, } @@ -709,23 +692,42 @@ begin begin tmpResult := getNextInstruction(endP,endP); + if tmpresult and not assigned(endP^.optInfo) then + begin + hp := new(pai_asm_comment,init(strpnew('next no optinfo'))); + hp^.next := endp; + hp^.previous := endp^.previous; + endp^.previous := hp; + if assigned(hp^.previous) then + hp^.previous^.next := hp; + exit; + end; If tmpResult and { don't take into account instructions that will be removed } Not (PPaiProp(endP^.optInfo)^.canBeRemoved) then begin sequenceEnd := noHardCodedRegs(paicpu(endP)) and - (RegLoadedWithNewValue(newReg,paicpu(endP)) or - (GetNextInstruction(endp,hp) and - FindRegDealloc(newReg,hp))); + RegLoadedWithNewValue(newReg,true,paicpu(endP)) or + (GetNextInstruction(endp,hp) and + FindRegDealloc(newReg,hp)); newRegModified := newRegModified or (not(sequenceEnd) and RegModifiedByInstruction(newReg,endP)); orgRegRead := newRegModified and RegReadByInstruction(orgReg,endP); - sequenceEnd := SequenceEnd and not(newRegModified and orgRegRead); + sequenceEnd := SequenceEnd and + { since newReg will be replaced by orgReg, we can't allow that newReg } + { gets modified if orgReg is still read afterwards (since after } + { replacing, this would mean that orgReg first gets modified and then } + { gets read in the assumption it still contains the unmodified value) } + not(newRegModified and orgRegRead) and + { since newReg will be replaced by orgReg, we can't allow that newReg } + { gets modified if orgRegCanBeModified = false } + (orgRegCanBeModified or not(newRegModified)); tmpResult := not(newRegModified and orgRegRead) and + (orgRegCanBeModified or not(newRegModified)) and (endP^.typ = ait_instruction) and not(paicpu(endP)^.is_jmp) and NoHardCodedRegs(paicpu(endP)) and @@ -734,9 +736,10 @@ begin end; end; sequenceEnd := sequenceEnd and + RegSizesOk(orgReg,newReg,paicpu(endP)) and not(newRegModified and (orgReg in PPaiProp(endP^.optInfo)^.usedRegs) and - not(RegLoadedWithNewValue(orgReg,paicpu(endP)))); + not(RegLoadedWithNewValue(orgReg,true,paicpu(endP)))); if SequenceEnd then begin @@ -777,11 +780,11 @@ begin { isn't used anymore } { In case b, the newreg was completely replaced by oldreg, so it's contents } { are unchanged compared the start of this sequence, so restore them } - If RegLoadedWithNewValue(newReg,endP) then + If RegLoadedWithNewValue(newReg,true,endP) then GetLastInstruction(endP,hp) else hp := endP; if (p <> endp) or - not RegLoadedWithNewValue(newReg,endP) then + not RegLoadedWithNewValue(newReg,true,endP) then RestoreRegContentsTo(newReg, c ,p, hp); { In both case a and b, it is possible that the new register was modified } { (e.g. an add/sub), so if it was replaced by oldreg in that instruction, } @@ -956,7 +959,7 @@ Begin getLastInstruction(p,hp3); If not ReplaceReg(RegInfo.New2OldReg[RegCounter], regCounter,hp3, - PPaiProp(hp4^.optInfo)^.Regs[regCounter]) then + PPaiProp(hp4^.optInfo)^.Regs[regCounter],true) then begin {$endif replacereg} hp3 := New(Paicpu,Op_Reg_Reg(A_MOV, S_L, @@ -1064,6 +1067,21 @@ Begin End; End; End; +{$ifdef replacereg} + top_Reg: + { try to replace the new reg with the old reg } + if (paicpu(p)^.opcode = A_MOV) and + getLastInstruction(p,hp4) then + begin + Case paicpu(p)^.oper[1].typ of + top_Reg: + if ReplaceReg(paicpu(p)^.oper[0].reg, + paicpu(p)^.oper[1].reg,p, + PPaiProp(hp4^.optInfo)^.Regs[regCounter],false) then + PPaiProp(p^.optInfo)^.canBeRemoved := true; + end + end; +{$endif replacereg} Top_Const: Begin Case Paicpu(p)^.oper[1].typ Of @@ -1149,7 +1167,13 @@ End. { $Log$ - Revision 1.39 2000-01-13 13:07:05 jonas + Revision 1.40 2000-01-22 16:10:06 jonas + + all code generator generated "mov reg1,reg2" instructions are now + attempted to be removed using the replacereg code + (-dnewoptimizations) + * small fixes to -dreplacereg code + + Revision 1.39 2000/01/13 13:07:05 jonas * released -dalignreg * some small fixes to -dnewOptimizations helper procedures