Browse Source

+ JccAdd2SetccAdd optimization
* take care of C_C/C_NC in JccAdd/Inc/Dec2(Cmc)Adc/Sbb

git-svn-id: trunk@44268 -

florian 5 years ago
parent
commit
8f0376c888
1 changed files with 76 additions and 2 deletions
  1. 76 2
      compiler/x86/aoptx86.pas

+ 76 - 2
compiler/x86/aoptx86.pas

@@ -180,6 +180,7 @@ unit aoptx86;
       globals,
       cpuinfo,
       procinfo,
+      paramgr,
       aasmbase,
       aoptbase,aoptutils,
       symconst,symsym,
@@ -4723,6 +4724,8 @@ unit aoptx86;
         l : Longint;
         condition : TAsmCond;
         symbol: TAsmSymbol;
+        reg: tsuperregister;
+        regavailable: Boolean;
       begin
         result:=false;
         symbol:=nil;
@@ -4748,7 +4751,7 @@ unit aoptx86;
                    @@1: }
               begin
                 carryadd_opcode:=A_NONE;
-                if Taicpu(p).condition in [C_NAE,C_B] then
+                if Taicpu(p).condition in [C_NAE,C_B,C_C] then
                   begin
                     if (Taicpu(hp1).opcode=A_INC) or
                       ((Taicpu(hp1).opcode=A_ADD) and
@@ -4781,7 +4784,7 @@ unit aoptx86;
                         exit;
                       end;
                   end
-                else if Taicpu(p).condition in [C_AE,C_NB] then
+                else if Taicpu(p).condition in [C_AE,C_NB,C_NC] then
                   begin
                     if (Taicpu(hp1).opcode=A_INC) or
                       ((Taicpu(hp1).opcode=A_ADD) and
@@ -4810,6 +4813,77 @@ unit aoptx86;
                         result:=true;
                         exit;
                       end;
+                  end
+                 {
+                   jcc @@1                            setcc tmpreg
+                   inc/dec/add/sub operand    ->      (movzx tmpreg)
+                   @@1:                               add/sub tmpreg,operand
+
+                   While this increases code size slightly, it makes the code much faster if the
+                   jump is unpredictable
+                 }
+                else if not(cs_opt_size in current_settings.optimizerswitches) and
+                  ((((Taicpu(hp1).opcode=A_ADD) or (Taicpu(hp1).opcode=A_SUB)) and
+                    (Taicpu(hp1).oper[0]^.typ=top_const) and
+                    (Taicpu(hp1).oper[1]^.typ=top_reg) and
+                    (Taicpu(hp1).oper[0]^.val=1)) or
+                   ((Taicpu(hp1).opcode=A_INC) or (Taicpu(hp1).opcode=A_DEC))
+                  ) then
+                  begin
+                    TransferUsedRegs(TmpUsedRegs);
+                    UpdateUsedRegs(TmpUsedRegs, tai(p.next));
+
+                    { search for an available register which is volatile }
+                    regavailable:=false;
+                    for reg in tcpuregisterset do
+                      begin
+                        if (reg in paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption)) and
+                          not(reg in TmpUsedRegs[R_INTREGISTER].GetUsedRegs) and
+                          not(RegInInstruction(newreg(R_INTREGISTER,reg,R_SUBL),hp1))
+{$ifdef i386}
+                          and (reg in [RS_EAX,RS_EBX,RS_ECX,RS_EDX])
+{$endif i386}
+                          then
+                          begin
+                            regavailable:=true;
+                            break;
+                          end;
+                      end;
+
+                    if regavailable then
+                      begin
+                        Taicpu(p).clearop(0);
+                        Taicpu(p).ops:=1;
+                        Taicpu(p).is_jmp:=false;
+                        Taicpu(p).opcode:=A_SETcc;
+                        DebugMsg(SPeepholeOptimization+'JccAdd2SetccAdd',p);
+                        Taicpu(p).condition:=inverse_cond(Taicpu(p).condition);
+                        Taicpu(p).loadreg(0,newreg(R_INTREGISTER,reg,R_SUBL));
+
+                        if getsubreg(Taicpu(hp1).oper[1]^.reg)<>R_SUBL then
+                          begin
+                            case getsubreg(Taicpu(hp1).oper[1]^.reg) of
+                              R_SUBW:
+                                hp2:=Taicpu.op_reg_reg(A_MOVZX,S_BW,newreg(R_INTREGISTER,reg,R_SUBL),
+                                  newreg(R_INTREGISTER,reg,R_SUBW));
+                              R_SUBD,
+                              R_SUBQ:
+                                hp2:=Taicpu.op_reg_reg(A_MOVZX,S_BL,newreg(R_INTREGISTER,reg,R_SUBL),
+                                  newreg(R_INTREGISTER,reg,R_SUBD));
+                              else
+                                Internalerror(2020030601);
+                            end;
+                            taicpu(hp2).fileinfo:=taicpu(hp1).fileinfo;
+                            asml.InsertAfter(hp2,p);
+                          end;
+                        if (Taicpu(hp1).opcode=A_INC) or (Taicpu(hp1).opcode=A_DEC) then
+                          begin
+                            Taicpu(hp1).ops:=2;
+                            Taicpu(hp1).loadoper(1,Taicpu(hp1).oper[0]^)
+                          end;
+                        Taicpu(hp1).loadreg(0,newreg(R_INTREGISTER,reg,getsubreg(Taicpu(hp1).oper[1]^.reg)));
+                        AllocRegBetween(newreg(R_INTREGISTER,reg,getsubreg(Taicpu(hp1).oper[1]^.reg)),p,hp1,UsedRegs);
+                      end;
                   end;
               end;