Forráskód Böngészése

+ Next portion of MIPS peephole optimizations. Get more aggressive and do more than a single pass if needed, enabling optimization of instructions that logically turn into MOVE due to register renaming.

git-svn-id: trunk@33095 -
sergei 9 éve
szülő
commit
41751bc5b4
1 módosított fájl, 87 hozzáadás és 24 törlés
  1. 87 24
      compiler/mips/aoptcpu.pas

+ 87 - 24
compiler/mips/aoptcpu.pas

@@ -202,11 +202,6 @@ unit aoptcpu;
         Result:=GetNextInstruction(Next,Next);
       until {not(cs_opt_level3 in current_settings.optimizerswitches) or} not(Result) or (Next.typ<>ait_instruction) or (RegInInstruction(reg,Next)) or
         (is_calljmp(taicpu(Next).opcode));
-      if Result and (next.typ=ait_instruction) and is_calljmp(taicpu(next).opcode) then
-        begin
-          result:=false;
-          next:=nil;
-        end;
     end;
 
 
@@ -338,6 +333,35 @@ unit aoptcpu;
         ait_instruction:
           begin
             case taicpu(p).opcode of
+              A_BC:
+                begin
+                  { BEQ/BNE with same register are bogus, but can be generated for code like
+                   "if lo(qwordvar)=cardinal(qwordvar) ...",
+                    optimizations below can also yield them, e.g. if one register was initially R0. }
+                  if (taicpu(p).condition in [C_EQ,C_NE]) and
+                    (taicpu(p).oper[0]^.reg=taicpu(p).oper[1]^.reg) then
+                    begin
+                      if (taicpu(p).condition=C_NE) then
+                        begin
+                          if (taicpu(p).oper[2]^.typ = top_ref) and
+                            (taicpu(p).oper[2]^.ref^.symbol is TAsmLabel) then
+                            TAsmLabel(taicpu(p).oper[2]^.ref^.symbol).decrefs;
+                          RemoveDelaySlot(p);
+                          GetNextInstruction(p,next);
+                        end
+                      else
+                        begin
+                          next:=taicpu.op_sym(A_BA,taicpu(p).oper[2]^.ref^.symbol);
+                          taicpu(next).fileinfo:=taicpu(p).fileinfo;
+                          asml.insertbefore(next,p);
+                        end;
+                      asml.remove(p);
+                      p.Free;
+                      p:=next;
+                      result:=true;
+                    end;
+                end;
+
               A_SEH:
                 begin
                   if GetNextInstructionUsingReg(p,next,taicpu(p).oper[0]^.reg) and
@@ -350,13 +374,14 @@ unit aoptcpu;
                       asml.remove(p);
                       p.free;
                       p:=next;
+                      result:=true;
                     end
                   else
-                    TryRemoveMov(p,A_MOVE);
+                    result:=TryRemoveMov(p,A_MOVE);
                 end;
               A_SEB:
                 { TODO: can be handled similar to A_SEH, but it's almost never encountered }
-                TryRemoveMov(p,A_MOVE);
+                result:=TryRemoveMov(p,A_MOVE);
 
               A_SLL:
                 begin
@@ -384,10 +409,11 @@ unit aoptcpu;
                           p.free;
                           next.free;
                           p:=next2;
+                          result:=true;
                         end;
                     end
                   else
-                    TryRemoveMov(p,A_MOVE);
+                    result:=TryRemoveMov(p,A_MOVE);
                 end;
 
               A_SRL:
@@ -415,9 +441,10 @@ unit aoptcpu;
                     begin
                       asml.remove(next);
                       next.free;
+                      result:=true;
                     end
                   else
-                    TryRemoveMov(p,A_MOVE);
+                    result:=TryRemoveMov(p,A_MOVE);
                 end;
 
               A_ANDI:
@@ -445,6 +472,7 @@ unit aoptcpu;
                       asml.remove(next2);
                       next.free;
                       next2.free;
+                      result:=true;
                     end
                   { Remove zero extension if register is used only for byte/word memory store }
                   else if (taicpu(p).oper[2]^.typ=top_const) and
@@ -459,9 +487,10 @@ unit aoptcpu;
                       asml.remove(p);
                       p.free;
                       p:=next;
+                      result:=true;
                     end
                   else
-                    TryRemoveMov(p,A_MOVE);
+                    result:=TryRemoveMov(p,A_MOVE);
                 end;
 
               A_MOV_S:
@@ -470,7 +499,7 @@ unit aoptcpu;
                      (next.typ=ait_instruction) then
                     begin
                       if TryRemoveMovBeforeStore(p,taicpu(next),[A_SWC1]) then
-                        { optimization successful };
+                        result:=true;
                     end;
                 end;
 
@@ -480,7 +509,7 @@ unit aoptcpu;
                      (next.typ=ait_instruction) then
                     begin
                       if TryRemoveMovBeforeStore(p,taicpu(next),[A_SDC1]) then
-                        { optimization successful };
+                        result:=true;
                     end;
                 end;
 
@@ -492,12 +521,12 @@ unit aoptcpu;
                     begin
                       { MOVE  Rx,Ry; store Rx,(ref); dealloc Rx   ==> store Ry,(ref) }
                       if TryRemoveMovBeforeStore(p,taicpu(next),[A_SB,A_SH,A_SW]) then
-                        { optimization successful }
+                        result:=true
                       else if TryRemoveMovToRefIndex(p,taicpu(next)) then
-                        { successful as well }
+                        result:=true
                       { MOVE  Rx,Ry; opcode  Rx,Rx,any              ==> opcode Rx,Ry,any
                         MOVE  Rx,Ry; opcode  Rx,Rz,Rx               ==> opcode Rx,Rz,Ry   }
-                      else if (taicpu(next).opcode in [A_ADD,A_ADDU,A_ADDI,A_ADDIU,A_SUB,A_SUBU]) and
+                      else if (taicpu(next).opcode in [A_ADD,A_ADDU,A_ADDI,A_ADDIU,A_SUB,A_SUBU,A_AND,A_ANDI,A_SLLV,A_SRLV,A_SRAV]) and
                          MatchOperand(taicpu(next).oper[0]^,taicpu(p).oper[0]^.reg) then
                         begin
                           if MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) then
@@ -506,6 +535,7 @@ unit aoptcpu;
                               asml.remove(p);
                               p.free;
                               p:=next;
+                              result:=true;
                             end
                           { TODO: if Ry=NR_R0, this effectively changes instruction into MOVE,
                             providing further optimization possibilities }
@@ -515,10 +545,12 @@ unit aoptcpu;
                               asml.remove(p);
                               p.free;
                               p:=next;
+                              result:=true;
                             end;
                         end
                       { MOVE  Rx,Ry; opcode Rz,Rx,any; dealloc Rx  ==> opcode Rz,Ry,any }
-                      else if (taicpu(next).opcode in [A_ADD,A_ADDU,A_ADDI,A_ADDIU,A_SUB,A_SUBU,A_SLT,A_SLTU,A_DIV,A_DIVU]) and
+                      else if (taicpu(next).opcode in [A_ADD,A_ADDU,A_ADDI,A_ADDIU,A_SUB,A_SUBU,A_SLT,A_SLTU,A_DIV,A_DIVU,
+                                                       A_SLL,A_SRL,A_SRA,A_SLLV,A_SRLV,A_SRAV,A_AND,A_ANDI,A_OR,A_ORI,A_XOR,A_XORI]) and
                          Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) then
                         begin
                           if MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) then
@@ -527,6 +559,7 @@ unit aoptcpu;
                               asml.remove(p);
                               p.free;
                               p:=next;
+                              result:=true;
                             end
                           else if MatchOperand(taicpu(next).oper[2]^,taicpu(p).oper[0]^.reg) then
                             begin
@@ -534,25 +567,32 @@ unit aoptcpu;
                               asml.remove(p);
                               p.free;
                               p:=next;
+                              result:=true;
                             end;
                         end
-                      { MULT[U] must be handled separately due to different operand numbers }
-                      else if (taicpu(next).opcode in [A_MULT,A_MULTU]) and
+                      { MULT[U] and cond.branches must be handled separately due to different operand numbers }
+                      else if (taicpu(next).opcode in [A_MULT,A_MULTU,A_BC]) and
                          Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) then
                         begin
                           if MatchOperand(taicpu(next).oper[0]^,taicpu(p).oper[0]^.reg) then
                             begin
                               taicpu(next).loadreg(0,taicpu(p).oper[1]^.reg);
+                              if MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) then
+                                taicpu(next).loadreg(1,taicpu(p).oper[1]^.reg);
                               asml.remove(p);
                               p.free;
                               p:=next;
+                              result:=true;
                             end
                           else if MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) then
                             begin
                               taicpu(next).loadreg(1,taicpu(p).oper[1]^.reg);
+                              if MatchOperand(taicpu(next).oper[0]^,taicpu(p).oper[0]^.reg) then
+                                taicpu(next).loadreg(0,taicpu(p).oper[1]^.reg);
                               asml.remove(p);
                               p.free;
                               p:=next;
+                              result:=true;
                             end;
                         end
                       else if TryRemoveMov(p,A_MOVE) then
@@ -564,9 +604,9 @@ unit aoptcpu;
                               asml.remove(p);
                               p.free;
                               p:=next;
+                              result:=true;
                             end;
                         end;
-                      { TODO: MOVE  Rx,Ry; Bcc Rx,Rz,label; dealloc Rx   ==> Bcc Ry,Rz,label  }
                     end;
                 end;
 
@@ -610,28 +650,51 @@ unit aoptcpu;
                     result:=TryRemoveMov(p,A_MOVE);
                 end;
 
+              A_ADD,A_ADDU,A_OR:
+                begin
+                  if MatchOperand(taicpu(p).oper[1]^,NR_R0) then
+                    begin
+                      taicpu(p).freeop(1);
+                      taicpu(p).oper[1]:=taicpu(p).oper[2];
+                      taicpu(p).oper[2]:=nil;
+                      taicpu(p).ops:=2;
+                      taicpu(p).opercnt:=2;
+                      taicpu(p).opcode:=A_MOVE;
+                      result:=true;
+                    end
+                  else if MatchOperand(taicpu(p).oper[2]^,NR_R0) then
+                    begin
+                      taicpu(p).freeop(2);
+                      taicpu(p).ops:=2;
+                      taicpu(p).opercnt:=2;
+                      taicpu(p).opcode:=A_MOVE;
+                      result:=true;
+                    end
+                  else
+                    result:=TryRemoveMov(p,A_MOVE);
+                end;
+
               A_LB,A_LBU,A_LH,A_LHU,A_LW,
-              A_ADD,A_ADDU,
               A_ADDI,
               A_SUB,A_SUBU,
               A_SRA,A_SRAV,
               A_SRLV,
               A_SLLV,
               A_MFLO,A_MFHI,
-              A_AND,A_OR,A_XOR,A_ORI,A_XORI:
-                TryRemoveMov(p,A_MOVE);
+              A_AND,A_XOR,A_ORI,A_XORI:
+                result:=TryRemoveMov(p,A_MOVE);
 
               A_LWC1,
               A_ADD_s, A_SUB_s, A_MUL_s, A_DIV_s,
               A_ABS_s, A_NEG_s, A_SQRT_s,
               A_CVT_s_w, A_CVT_s_l, A_CVT_s_d:
-                TryRemoveMov(p,A_MOV_s);
+                result:=TryRemoveMov(p,A_MOV_s);
 
               A_LDC1,
               A_ADD_d, A_SUB_d, A_MUL_d, A_DIV_d,
               A_ABS_d, A_NEG_d, A_SQRT_d,
               A_CVT_d_w, A_CVT_d_l, A_CVT_d_s:
-                TryRemoveMov(p,A_MOV_d);
+                result:=TryRemoveMov(p,A_MOV_d);
             end;
           end;
       end;