Browse Source

+ generic TAOptObj.AllocRegBetween
- removed x86 specific AllocRegBetween

git-svn-id: trunk@38445 -

florian 7 years ago
parent
commit
78878f59b1
2 changed files with 120 additions and 112 deletions
  1. 120 1
      compiler/aoptobj.pas
  2. 0 111
      compiler/x86/aoptx86.pas

+ 120 - 1
compiler/aoptobj.pas

@@ -315,6 +315,10 @@ Unit AoptObj;
           nil                                                                        }
         Function FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
 
+        { allocates register reg between (and including) instructions p1 and p2
+          the type of p1 and p2 must not be in SkipInstr }
+        procedure AllocRegBetween(reg : tregister; p1,p2 : tai; var initialusedregs : TAllUsedRegs);
+
         { reg used after p? }
         function RegUsedAfterInstruction(reg: Tregister; p: tai; var AllUsedRegs: TAllUsedRegs): Boolean;
 
@@ -370,7 +374,8 @@ Unit AoptObj;
       cutils,
       globals,
       verbose,
-      aoptutils;
+      aoptutils,
+      procinfo;
 
 
     function JumpTargetOp(ai: taicpu): poper; inline;
@@ -1146,6 +1151,120 @@ Unit AoptObj;
        End;
 
 
+    { allocates register reg between (and including) instructions p1 and p2
+      the type of p1 and p2 must not be in SkipInstr }
+    procedure TAOptObj.AllocRegBetween(reg: tregister; p1, p2: tai; var initialusedregs: TAllUsedRegs);
+      var
+        hp, start: tai;
+        removedsomething,
+        firstRemovedWasAlloc,
+        lastRemovedWasDealloc: boolean;
+      begin
+{$ifdef EXTDEBUG}
+{        if assigned(p1.optinfo) and
+           (ptaiprop(p1.optinfo)^.usedregs <> initialusedregs) then
+         internalerror(2004101010); }
+{$endif EXTDEBUG}
+        start := p1;
+       if (reg = NR_STACK_POINTER_REG) or
+          (reg = current_procinfo.framepointer) or
+           not(assigned(p1)) then
+          { this happens with registers which are loaded implicitely, outside the }
+          { current block (e.g. esi with self)                                    }
+          exit;
+        { make sure we allocate it for this instruction }
+        getnextinstruction(p2,p2);
+        lastRemovedWasDealloc := false;
+        removedSomething := false;
+        firstRemovedWasAlloc := false;
+{$ifdef allocregdebug}
+        hp := tai_comment.Create(strpnew('allocating '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+
+          ' from here...'));
+        insertllitem(asml,p1.previous,p1,hp);
+        hp := tai_comment.Create(strpnew('allocated '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+
+          ' till here...'));
+        insertllitem(asml,p2,p2.next,hp);
+{$endif allocregdebug}
+        { do it the safe way: always allocate the full super register,
+          as we do no register re-allocation in the peephole optimizer,
+          this does not hurt
+        }
+        case getregtype(reg) of
+          R_MMREGISTER:
+            reg:=newreg(R_MMREGISTER,getsupreg(reg),R_SUBMMWHOLE);
+          R_INTREGISTER:
+            reg:=newreg(R_INTREGISTER,getsupreg(reg),R_SUBWHOLE);
+          R_FPUREGISTER:
+            reg:=newreg(R_FPUREGISTER,getsupreg(reg),R_SUBWHOLE);
+          R_ADDRESSREGISTER:
+            reg:=newreg(R_ADDRESSREGISTER,getsupreg(reg),R_SUBWHOLE);
+          else
+            Internalerror(2018030701);
+        end;
+        if not(RegInUsedRegs(reg,initialusedregs)) then
+          begin
+            hp := tai_regalloc.alloc(reg,nil);
+            insertllItem(p1.previous,p1,hp);
+            IncludeRegInUsedRegs(reg,initialusedregs);
+          end;
+        while assigned(p1) and
+              (p1 <> p2) do
+          begin
+            if assigned(p1.optinfo) then
+              internalerror(2014022301); // IncludeRegInUsedRegs(reg,ptaiprop(p1.optinfo)^.usedregs);
+            p1 := tai(p1.next);
+            repeat
+              while assigned(p1) and
+                    (p1.typ in (SkipInstr-[ait_regalloc])) Do
+                p1 := tai(p1.next);
+
+              { remove all allocation/deallocation info about the register in between }
+              if assigned(p1) and
+                 (p1.typ = ait_regalloc) then
+                begin
+                  { same super register, different sub register? }
+                  if SuperRegistersEqual(reg,tai_regalloc(p1).reg) and (tai_regalloc(p1).reg<>reg) then
+                    begin
+                      if (getsubreg(tai_regalloc(p1).reg)>getsubreg(reg)) or (getsubreg(reg)=R_SUBH) then
+                        internalerror(2016101501);
+                      tai_regalloc(p1).reg:=reg;
+                    end;
+
+                  if tai_regalloc(p1).reg=reg then
+                    begin
+                      if not removedSomething then
+                        begin
+                          firstRemovedWasAlloc := tai_regalloc(p1).ratype=ra_alloc;
+                          removedSomething := true;
+                        end;
+                      lastRemovedWasDealloc := (tai_regalloc(p1).ratype=ra_dealloc);
+                      hp := tai(p1.Next);
+                      asml.Remove(p1);
+                      p1.free;
+                      p1 := hp;
+                    end
+                  else
+                    p1 := tai(p1.next);
+                end;
+            until not(assigned(p1)) or
+                  not(p1.typ in SkipInstr);
+          end;
+        if assigned(p1) then
+          begin
+            if firstRemovedWasAlloc then
+              begin
+                hp := tai_regalloc.Alloc(reg,nil);
+                insertLLItem(start.previous,start,hp);
+              end;
+            if lastRemovedWasDealloc then
+              begin
+                hp := tai_regalloc.DeAlloc(reg,nil);
+                insertLLItem(p1.previous,p1,hp);
+              end;
+          end;
+      end;
+
+
     function TAOptObj.RegUsedAfterInstruction(reg: Tregister; p: tai;var AllUsedRegs: TAllUsedRegs): Boolean;
       begin
         AllUsedRegs[getregtype(reg)].Update(tai(p.Next),true);

+ 0 - 111
compiler/x86/aoptx86.pas

@@ -50,7 +50,6 @@ unit aoptx86;
 
         procedure DebugMsg(const s : string; p : tai);inline;
 
-        procedure AllocRegBetween(reg : tregister; p1,p2 : tai;var initialusedregs : TAllUsedRegs);
         class function IsExitCode(p : tai) : boolean;
         class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
         procedure RemoveLastDeallocForFuncRes(p : tai);
@@ -609,116 +608,6 @@ unit aoptx86;
       end;
 
 
-    { allocates register reg between (and including) instructions p1 and p2
-      the type of p1 and p2 must not be in SkipInstr
-      note that this routine is both called from the peephole optimizer
-      where optinfo is not yet initialised) and from the cse (where it is)  }
-    procedure TX86AsmOptimizer.AllocRegBetween(reg: tregister; p1, p2: tai; var initialusedregs: TAllUsedRegs);
-      var
-        hp, start: tai;
-        removedsomething,
-        firstRemovedWasAlloc,
-        lastRemovedWasDealloc: boolean;
-      begin
-{$ifdef EXTDEBUG}
-{        if assigned(p1.optinfo) and
-           (ptaiprop(p1.optinfo)^.usedregs <> initialusedregs) then
-         internalerror(2004101010); }
-{$endif EXTDEBUG}
-        start := p1;
-       if (reg = NR_ESP) or
-          (reg = current_procinfo.framepointer) or
-           not(assigned(p1)) then
-          { this happens with registers which are loaded implicitely, outside the }
-          { current block (e.g. esi with self)                                    }
-          exit;
-        { make sure we allocate it for this instruction }
-        getnextinstruction(p2,p2);
-        lastRemovedWasDealloc := false;
-        removedSomething := false;
-        firstRemovedWasAlloc := false;
-{$ifdef allocregdebug}
-        hp := tai_comment.Create(strpnew('allocating '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+
-          ' from here...'));
-        insertllitem(asml,p1.previous,p1,hp);
-        hp := tai_comment.Create(strpnew('allocated '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+
-          ' till here...'));
-        insertllitem(asml,p2,p2.next,hp);
-{$endif allocregdebug}
-        { do it the safe way: always allocate the full super register,
-          as we do no register re-allocation in the peephole optimizer,
-          this does not hurt
-        }
-        case getregtype(reg) of
-          R_MMREGISTER:
-            reg:=newreg(R_MMREGISTER,getsupreg(reg),R_SUBMMWHOLE);
-          R_INTREGISTER:
-            reg:=newreg(R_INTREGISTER,getsupreg(reg),R_SUBWHOLE);
-        end;
-        if not(RegInUsedRegs(reg,initialusedregs)) then
-          begin
-            hp := tai_regalloc.alloc(reg,nil);
-            insertllItem(p1.previous,p1,hp);
-            IncludeRegInUsedRegs(reg,initialusedregs);
-          end;
-        while assigned(p1) and
-              (p1 <> p2) do
-          begin
-            if assigned(p1.optinfo) then
-              internalerror(2014022301); // IncludeRegInUsedRegs(reg,ptaiprop(p1.optinfo)^.usedregs);
-            p1 := tai(p1.next);
-            repeat
-              while assigned(p1) and
-                    (p1.typ in (SkipInstr-[ait_regalloc])) Do
-                p1 := tai(p1.next);
-
-              { remove all allocation/deallocation info about the register in between }
-              if assigned(p1) and
-                 (p1.typ = ait_regalloc) then
-                begin
-                  { same super register, different sub register? }
-                  if SuperRegistersEqual(reg,tai_regalloc(p1).reg) and (tai_regalloc(p1).reg<>reg) then
-                    begin
-                      if (getsubreg(tai_regalloc(p1).reg)>getsubreg(reg)) or (getsubreg(reg)=R_SUBH) then
-                        internalerror(2016101501);
-                      tai_regalloc(p1).reg:=reg;
-                    end;
-
-                  if tai_regalloc(p1).reg=reg then
-                    begin
-                      if not removedSomething then
-                        begin
-                          firstRemovedWasAlloc := tai_regalloc(p1).ratype=ra_alloc;
-                          removedSomething := true;
-                        end;
-                      lastRemovedWasDealloc := (tai_regalloc(p1).ratype=ra_dealloc);
-                      hp := tai(p1.Next);
-                      asml.Remove(p1);
-                      p1.free;
-                      p1 := hp;
-                    end
-                  else
-                    p1 := tai(p1.next);
-                end;
-            until not(assigned(p1)) or
-                  not(p1.typ in SkipInstr);
-          end;
-        if assigned(p1) then
-          begin
-            if firstRemovedWasAlloc then
-              begin
-                hp := tai_regalloc.Alloc(reg,nil);
-                insertLLItem(start.previous,start,hp);
-              end;
-            if lastRemovedWasDealloc then
-              begin
-                hp := tai_regalloc.DeAlloc(reg,nil);
-                insertLLItem(p1.previous,p1,hp);
-              end;
-          end;
-      end;
-
-
     function TX86AsmOptimizer.RegLoadedWithNewValue(reg: tregister; hp: tai): boolean;
       var
         p: taicpu;