+ all code generator generated "mov reg1,reg2" instructions are now

attempted to be removed using the replacereg code
    (-dnewoptimizations)
  * small fixes to -dreplacereg code
This commit is contained in:
Jonas Maebe 2000-01-22 16:10:06 +00:00
parent b15a98cfa4
commit 02381105d6

View File

@ -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