Browse Source

* better support for regvars (still needs a move of the call to the optimize
procedure to a place where resetusableregisters is not yet called to work)
* small regallocation fixes for -dnewoptimizations

Jonas Maebe 25 years ago
parent
commit
4e361ef71f
2 changed files with 65 additions and 28 deletions
  1. 42 18
      compiler/csopt386.pas
  2. 23 10
      compiler/daopt386.pas

+ 42 - 18
compiler/csopt386.pas

@@ -39,7 +39,7 @@ Procedure CSE(AsmL: PAasmOutput; First, Last: Pai);
 Implementation
 Implementation
 
 
 Uses
 Uses
-  CObjects, verbose, hcodegen, globals,cpubase,cpuasm,DAOpt386;
+  CObjects, verbose, hcodegen, globals,cpubase,cpuasm,DAOpt386, tgeni386;
 
 
 {
 {
 Function PaiInSequence(P: Pai; Const Seq: TContent): Boolean;
 Function PaiInSequence(P: Pai; Const Seq: TContent): Boolean;
@@ -220,7 +220,8 @@ Procedure AllocRegBetween(AsmL: PAasmOutput; Reg: TRegister; p1, p2: Pai);
 { the type of p1 and p2 must not be in SkipInstr                        }
 { the type of p1 and p2 must not be in SkipInstr                        }
 var hp: pai;
 var hp: pai;
 Begin
 Begin
-  If not(assigned(p1)) Then
+  If not(reg in usableregs) or
+     not(assigned(p1)) Then
     { this happens with registers which are loaded implicitely, outside the }
     { this happens with registers which are loaded implicitely, outside the }
     { current block (e.g. esi with self)                                    }
     { current block (e.g. esi with self)                                    }
     exit;
     exit;
@@ -229,10 +230,12 @@ Begin
       Include(PPaiProp(p1^.OptInfo)^.UsedRegs,Reg);
       Include(PPaiProp(p1^.OptInfo)^.UsedRegs,Reg);
     p1 := Pai(p1^.next);
     p1 := Pai(p1^.next);
     Repeat
     Repeat
-      While (p1^.typ in (SkipInstr-[ait_regalloc])) Do
+      While assigned(p1) and
+            (p1^.typ in (SkipInstr-[ait_regalloc])) Do
         p1 := Pai(p1^.next);
         p1 := Pai(p1^.next);
 { remove all allocation/deallocation info about the register in between }
 { remove all allocation/deallocation info about the register in between }
-      If (p1^.typ = ait_regalloc) Then
+      If assigned(p1) and
+         (p1^.typ = ait_regalloc) Then
         If (PaiRegAlloc(p1)^.Reg = Reg) Then
         If (PaiRegAlloc(p1)^.Reg = Reg) Then
           Begin
           Begin
             hp := Pai(p1^.Next);
             hp := Pai(p1^.Next);
@@ -241,8 +244,10 @@ Begin
             p1 := hp;
             p1 := hp;
           End
           End
         Else p1 := Pai(p1^.next);
         Else p1 := Pai(p1^.next);
-    Until Not(p1^.typ in SkipInstr);
-  Until p1 = p2;
+    Until not(assigned(p1)) or
+          Not(p1^.typ in SkipInstr);
+  Until not(assigned(p1)) or
+        (p1 = p2);
 End;
 End;
 
 
 Procedure SetAlignReg(p: Pai);
 Procedure SetAlignReg(p: Pai);
@@ -673,12 +678,15 @@ begin
 end;
 end;
 
 
 function ReplaceReg(orgReg, newReg: TRegister; p: pai;
 function ReplaceReg(orgReg, newReg: TRegister; p: pai;
-           const c: TContent; orgRegCanBeModified: Boolean): Boolean;
+           const c: TContent; orgRegCanBeModified: Boolean;
+           var returnEndP: pai): Boolean;
 { Tries to replace orgreg with newreg in all instructions coming after p }
 { Tries to replace orgreg with newreg in all instructions coming after p }
 { until orgreg gets loaded with a new value. Returns true if successful, }
 { until orgreg gets loaded with a new value. Returns true if successful, }
 { false otherwise. If successful, the contents of newReg are set to c,   }
 { false otherwise. If successful, the contents of newReg are set to c,   }
 { which should hold the contents of newReg before the current sequence   }
 { which should hold the contents of newReg before the current sequence   }
 { started                                                                }
 { started                                                                }
+{ if the functino returns true, returnEndP holds the lat instruction     }
+{ where newReg was replaced by orgReg                                    }
 var endP, hp: Pai;
 var endP, hp: Pai;
     sequenceEnd, tmpResult, newRegModified, orgRegRead: Boolean;
     sequenceEnd, tmpResult, newRegModified, orgRegRead: Boolean;
 begin
 begin
@@ -767,6 +775,7 @@ begin
         hp^.next^.previous := hp;
         hp^.next^.previous := hp;
 {$endif replaceregdebug}
 {$endif replaceregdebug}
       ReplaceReg := true;
       ReplaceReg := true;
+      returnEndP := endP;
       hp := p;
       hp := p;
       while hp <> endP do
       while hp <> endP do
         begin
         begin
@@ -861,10 +870,7 @@ Procedure DoCSE(AsmL: PAasmOutput; First, Last: Pai);
  two different sequences}
  two different sequences}
 Var Cnt, Cnt2: Longint;
 Var Cnt, Cnt2: Longint;
     p, hp1, hp2: Pai;
     p, hp1, hp2: Pai;
-    hp3, hp4: Pai;
-{$ifdef csdebug}
-    hp5: pai;
-{$endif csdebug}
+    hp3, hp4, hp5: pai;
     RegInfo: TRegInfo;
     RegInfo: TRegInfo;
     RegCounter: TRegister;
     RegCounter: TRegister;
     TmpState: Byte;
     TmpState: Byte;
@@ -963,7 +969,7 @@ Begin
                                              getLastInstruction(p,hp3);
                                              getLastInstruction(p,hp3);
                                              If not ReplaceReg(RegInfo.New2OldReg[RegCounter],
                                              If not ReplaceReg(RegInfo.New2OldReg[RegCounter],
                                                       regCounter,hp3,
                                                       regCounter,hp3,
-                                                      PPaiProp(hp4^.optInfo)^.Regs[regCounter],true) then
+                                                      PPaiProp(hp4^.optInfo)^.Regs[regCounter],true,hp5) then
                                                begin
                                                begin
 {$endif replacereg}
 {$endif replacereg}
                                                  hp3 := New(Paicpu,Op_Reg_Reg(A_MOV, S_L,
                                                  hp3 := New(Paicpu,Op_Reg_Reg(A_MOV, S_L,
@@ -1081,8 +1087,13 @@ Begin
                             top_Reg:
                             top_Reg:
                               if ReplaceReg(paicpu(p)^.oper[0].reg,
                               if ReplaceReg(paicpu(p)^.oper[0].reg,
                                    paicpu(p)^.oper[1].reg,p,
                                    paicpu(p)^.oper[1].reg,p,
-                                   PPaiProp(hp4^.optInfo)^.Regs[regCounter],false) then
-                                PPaiProp(p^.optInfo)^.canBeRemoved := true;
+                                   PPaiProp(hp4^.optInfo)^.Regs[regCounter],false,hp1) then
+                                begin
+                                  PPaiProp(p^.optInfo)^.canBeRemoved := true;
+                                  allocRegBetween(asmL,paicpu(p)^.oper[0].reg,
+                                    PPaiProp(p^.optInfo)^.regs[paicpu(p)^.oper[0].reg].startMod,
+                                    hp1);
+                                end;
                           end
                           end
                         end;
                         end;
 {$endif replacereg}
 {$endif replacereg}
@@ -1091,18 +1102,26 @@ Begin
                         Case Paicpu(p)^.oper[1].typ Of
                         Case Paicpu(p)^.oper[1].typ Of
                           Top_Reg:
                           Top_Reg:
                             Begin
                             Begin
+                              regCounter := Reg32(Paicpu(p)^.oper[1].reg);
                               If GetLastInstruction(p, hp1) Then
                               If GetLastInstruction(p, hp1) Then
-                                With PPaiProp(hp1^.OptInfo)^.Regs[Reg32(Paicpu(p)^.oper[1].reg)] Do
+                                With PPaiProp(hp1^.OptInfo)^.Regs[regCounter] Do
                                   If (Typ = Con_Const) And
                                   If (Typ = Con_Const) And
                                      (paicpu(startMod)^.opsize >= paicpu(p)^.opsize) and
                                      (paicpu(startMod)^.opsize >= paicpu(p)^.opsize) and
                                      (paicpu(StartMod)^.oper[0].val = paicpu(p)^.oper[0].val) Then
                                      (paicpu(StartMod)^.oper[0].val = paicpu(p)^.oper[0].val) Then
-                                    PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
+                                    begin
+                                      PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
+                                      allocRegBetween(asmL,regCounter,startMod,p);
+                                    end;
                             End;
                             End;
 {$ifdef arithopt}
 {$ifdef arithopt}
                           Top_Ref:
                           Top_Ref:
                             if getLastInstruction(p,hp1) and
                             if getLastInstruction(p,hp1) and
                                findRegWithConst(hp1,paicpu(p)^.opsize,paicpu(p)^.oper[0].val,regCounter) then
                                findRegWithConst(hp1,paicpu(p)^.opsize,paicpu(p)^.oper[0].val,regCounter) then
-                              paicpu(p)^.loadreg(0,regCounter);
+                              begin
+                                paicpu(p)^.loadreg(0,regCounter);
+                                allocRegBetween(AsmL,reg32(regCounter),
+                                  PPaiProp(hp1^.optinfo)^.regs[regCounter].startMod,p);
+                              end;
 {$endif arithopt}
 {$endif arithopt}
                         End;
                         End;
                       End;
                       End;
@@ -1171,7 +1190,12 @@ End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.42  2000-01-28 15:15:31  jonas
+ Revision 1.43  2000-02-04 13:52:17  jonas
+   * better support for regvars (still needs a move of the call to the optimize
+   procedure to a place where resetusableregisters is not yet called to work)
+   * small regallocation fixes for -dnewoptimizations
+
+ Revision 1.42  2000/01/28 15:15:31  jonas
     * moved skipinstr from daopt386 to aasm
     * moved skipinstr from daopt386 to aasm
     * fixed crashing bug with -dreplacereg in csopt386.pas
     * fixed crashing bug with -dreplacereg in csopt386.pas
 
 

+ 23 - 10
compiler/daopt386.pas

@@ -212,7 +212,7 @@ Var
 Implementation
 Implementation
 
 
 Uses
 Uses
-  globals, systems, strings, verbose, hcodegen, symconst;
+  globals, systems, strings, verbose, hcodegen, symconst, tgeni386;
 
 
 Type
 Type
   TRefCompare = function(const r1, r2: TReference): Boolean;
   TRefCompare = function(const r1, r2: TReference): Boolean;
@@ -396,7 +396,8 @@ begin
     end;
     end;
 end;
 end;
 
 
-procedure getFuncResRegs(var regs: TRegSet);
+procedure getNoDeallocRegs(var regs: TRegSet);
+var regCounter: TRegister;
 begin
 begin
   regs := [];
   regs := [];
   if assigned(procinfo^.returntype.def) then
   if assigned(procinfo^.returntype.def) then
@@ -414,7 +415,10 @@ begin
             if procinfo^.returntype.def^.size = 8 then
             if procinfo^.returntype.def^.size = 8 then
               regs := regs + [R_EDX];
               regs := regs + [R_EDX];
           end;
           end;
-    end
+    end;
+  for regCounter := R_EAX to R_EBX do
+    if not(regCounter in usableregs) then
+      regs := regs + [regCounter];
 end;
 end;
 
 
 Procedure AddRegDeallocFor(asmL: paasmOutput; reg: TRegister; p: pai);
 Procedure AddRegDeallocFor(asmL: paasmOutput; reg: TRegister; p: pai);
@@ -422,7 +426,10 @@ var hp1: pai;
     funcResRegs: TRegset;
     funcResRegs: TRegset;
     funcResReg: boolean;
     funcResReg: boolean;
 begin
 begin
-  getFuncResRegs(funcResRegs);
+  if not(reg in usableregs) then
+    exit;
+  getNoDeallocRegs(funcResRegs);
+  funcResRegs := funcResRegs - usableregs;
   funcResReg := reg in funcResRegs;
   funcResReg := reg in funcResRegs;
   hp1 := p;
   hp1 := p;
   while not(funcResReg and
   while not(funcResReg and
@@ -434,7 +441,8 @@ begin
     hp1 := p;
     hp1 := p;
   { don't insert a dealloc for registers which contain the function result }
   { don't insert a dealloc for registers which contain the function result }
   { if they are followed by a jump to the exit label (for exit(...))       }
   { if they are followed by a jump to the exit label (for exit(...))       }
-  if not((hp1^.typ = ait_instruction) and
+  if not(funcResReg) or
+     not((hp1^.typ = ait_instruction) and
          (paicpu(hp1)^.opcode = A_JMP) and
          (paicpu(hp1)^.opcode = A_JMP) and
          (pasmlabel(paicpu(hp1)^.oper[0].sym) = aktexit2label)) then
          (pasmlabel(paicpu(hp1)^.oper[0].sym) = aktexit2label)) then
     begin
     begin
@@ -449,7 +457,7 @@ Procedure BuildLabelTableAndFixRegAlloc(asmL: PAasmOutput; Var LabelTable: PLabe
  Also fixes some RegDeallocs like "# %eax released; push (%eax)"}
  Also fixes some RegDeallocs like "# %eax released; push (%eax)"}
 Var p, hp1, hp2, lastP: Pai;
 Var p, hp1, hp2, lastP: Pai;
     regCounter: TRegister;
     regCounter: TRegister;
-    UsedRegs, funcResRegs: TRegSet;
+    UsedRegs, noDeallocRegs: TRegSet;
 Begin
 Begin
   UsedRegs := [];
   UsedRegs := [];
   If (LabelDif <> 0) Then
   If (LabelDif <> 0) Then
@@ -510,9 +518,9 @@ Begin
       until not(Assigned(p)) or
       until not(Assigned(p)) or
             not(p^.typ in (SkipInstr - [ait_regalloc]));
             not(p^.typ in (SkipInstr - [ait_regalloc]));
     End;
     End;
-  { don't add deallocation for function result variable }
-  getFuncResRegs(funcResRegs);
-  usedRegs := usedRegs - funcResRegs;
+  { don't add deallocation for function result variable or for regvars}
+  getNoDeallocRegs(noDeallocRegs);
+  usedRegs := usedRegs - noDeallocRegs;
   for regCounter := R_EAX to R_EDI do
   for regCounter := R_EAX to R_EDI do
     if regCounter in usedRegs then
     if regCounter in usedRegs then
       addRegDeallocFor(asmL,regCounter,lastP);
       addRegDeallocFor(asmL,regCounter,lastP);
@@ -2121,7 +2129,12 @@ End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.80  2000-01-28 15:15:31  jonas
+ Revision 1.81  2000-02-04 13:52:17  jonas
+   * better support for regvars (still needs a move of the call to the optimize
+   procedure to a place where resetusableregisters is not yet called to work)
+   * small regallocation fixes for -dnewoptimizations
+
+ Revision 1.80  2000/01/28 15:15:31  jonas
     * moved skipinstr from daopt386 to aasm
     * moved skipinstr from daopt386 to aasm
     * fixed crashing bug with -dreplacereg in csopt386.pas
     * fixed crashing bug with -dreplacereg in csopt386.pas