瀏覽代碼

* i386: more clean up of TCPUAsmOPtimizer.PeepHoleOptPass1Cpu

git-svn-id: trunk@43465 -
florian 5 年之前
父節點
當前提交
87b3b089d6
共有 1 個文件被更改,包括 221 次插入301 次删除
  1. 221 301
      compiler/i386/aoptcpu.pas

+ 221 - 301
compiler/i386/aoptcpu.pas

@@ -245,324 +245,244 @@ unit aoptcpu;
                   Result:=true;
                   exit;
                 end;
-              { Handle Jmp Optimizations }
-              if taicpu(p).is_jmp then
-                begin
-                  { the following if-block removes all code between a jmp and the next label,
-                    because it can never be executed }
-                  if (taicpu(p).opcode = A_JMP) then
-                    begin
-                      hp2:=p;
-                      while GetNextInstruction(hp2, hp1) and
-                            (hp1.typ <> ait_label) do
-                        if not(hp1.typ in ([ait_label]+skipinstr)) then
-                          begin
-                            { don't kill start/end of assembler block,
-                              no-line-info-start/end, cfi end, etc }
-                            if not(hp1.typ in [ait_align,ait_marker]) and
-                               ((hp1.typ<>ait_cfi) or
-                                (tai_cfi_base(hp1).cfityp<>cfi_endproc)) then
-                              begin
-                                asml.remove(hp1);
-                                hp1.free;
-                              end
-                            else
-                              hp2:=hp1;
-                          end
-                        else break;
-                      end;
-                  { remove jumps to a label coming right after them }
-                  if GetNextInstruction(p, hp1) then
-                    begin
-                      if FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol), hp1) and
-    { TODO: FIXME removing the first instruction fails}
-                          (p<>blockstart) then
-                        begin
-                          hp2:=tai(hp1.next);
-                          asml.remove(p);
-                          p.free;
-                          p:=hp2;
-                          Result:=true;
-                          exit;
-                        end
+              case taicpu(p).opcode Of
+                A_AND:
+                  Result:=OptPass1And(p);
+                A_CMP:
+                  begin
+                    { cmp register,$8000                neg register
+                      je target                 -->     jo target
+
+                      .... only if register is deallocated before jump.}
+                    case Taicpu(p).opsize of
+                      S_B: v:=$80;
+                      S_W: v:=$8000;
+                      S_L: v:=aint($80000000);
                       else
-                        begin
-                          if hp1.typ = ait_label then
-                            SkipLabels(hp1,hp1);
-                          if (tai(hp1).typ=ait_instruction) and
-                              (taicpu(hp1).opcode=A_JMP) and
-                              GetNextInstruction(hp1, hp2) and
-                              FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol), hp2) then
-                            begin
-                              if taicpu(p).opcode=A_Jcc then
-                                begin
-                                  taicpu(p).condition:=inverse_cond(taicpu(p).condition);
-                                  tai_label(hp2).labsym.decrefs;
-                                  taicpu(p).oper[0]^.ref^.symbol:=taicpu(hp1).oper[0]^.ref^.symbol;
-                                  { when free'ing hp1, the ref. isn't decresed, so we don't
-                                    increase it (FK)
-
-                                    taicpu(p).oper[0]^.ref^.symbol.increfs;
-                                  }
-                                  asml.remove(hp1);
-                                  hp1.free;
-                                  GetFinalDestination(asml, taicpu(p),0);
-                                end
-                              else
-                                begin
-                                  GetFinalDestination(asml, taicpu(p),0);
-                                  p:=tai(p.next);
-                                  Result:=true;
-                                  exit;
-                                end;
-                            end
-                          else
-                            GetFinalDestination(asml, taicpu(p),0);
-                        end;
+                        internalerror(2013112905);
                     end;
-                end
-              else
-              { All other optimizes }
-                begin
-                  case taicpu(p).opcode Of
-                    A_AND:
-                      Result:=OptPass1And(p);
-                    A_CMP:
+                    if (taicpu(p).oper[0]^.typ=Top_const) and
+                       (taicpu(p).oper[0]^.val=v) and
+                       (Taicpu(p).oper[1]^.typ=top_reg) and
+                       GetNextInstruction(p, hp1) and
+                       (hp1.typ=ait_instruction) and
+                       (taicpu(hp1).opcode=A_Jcc) and
+                       (Taicpu(hp1).condition in [C_E,C_NE]) and
+                       not(RegInUsedRegs(Taicpu(p).oper[1]^.reg, UsedRegs)) then
                       begin
-                        { cmp register,$8000                neg register
-                          je target                 -->     jo target
-
-                          .... only if register is deallocated before jump.}
-                        case Taicpu(p).opsize of
-                          S_B: v:=$80;
-                          S_W: v:=$8000;
-                          S_L: v:=aint($80000000);
-                          else
-                            internalerror(2013112905);
-                        end;
-                        if (taicpu(p).oper[0]^.typ=Top_const) and
-                           (taicpu(p).oper[0]^.val=v) and
-                           (Taicpu(p).oper[1]^.typ=top_reg) and
-                           GetNextInstruction(p, hp1) and
-                           (hp1.typ=ait_instruction) and
-                           (taicpu(hp1).opcode=A_Jcc) and
-                           (Taicpu(hp1).condition in [C_E,C_NE]) and
-                           not(RegInUsedRegs(Taicpu(p).oper[1]^.reg, UsedRegs)) then
-                          begin
-                            Taicpu(p).opcode:=A_NEG;
-                            Taicpu(p).loadoper(0,Taicpu(p).oper[1]^);
-                            Taicpu(p).clearop(1);
-                            Taicpu(p).ops:=1;
-                            if Taicpu(hp1).condition=C_E then
-                              Taicpu(hp1).condition:=C_O
-                            else
-                              Taicpu(hp1).condition:=C_NO;
-                            Result:=true;
-                          end;
-                        {
-                        @@2:                              @@2:
-                          ....                              ....
-                          cmp operand1,0
-                          jle/jbe @@1
-                          dec operand1             -->      sub operand1,1
-                          jmp @@2                           jge/jae @@2
-                        @@1:                              @@1:
-                          ...                               ....}
-                        if (taicpu(p).oper[0]^.typ = top_const) and
-                           (taicpu(p).oper[1]^.typ in [top_reg,top_ref]) and
-                           (taicpu(p).oper[0]^.val = 0) and
-                           GetNextInstruction(p, hp1) and
-                           (hp1.typ = ait_instruction) and
-                           (taicpu(hp1).is_jmp) and
-                           (taicpu(hp1).opcode=A_Jcc) and
-                           (taicpu(hp1).condition in [C_LE,C_BE]) and
-                           GetNextInstruction(hp1,hp2) and
-                           (hp2.typ = ait_instruction) and
-                           (taicpu(hp2).opcode = A_DEC) and
-                           OpsEqual(taicpu(hp2).oper[0]^,taicpu(p).oper[1]^) and
-                           GetNextInstruction(hp2, hp3) and
-                           (hp3.typ = ait_instruction) and
-                           (taicpu(hp3).is_jmp) and
-                           (taicpu(hp3).opcode = A_JMP) and
-                           GetNextInstruction(hp3, hp4) and
-                           FindLabel(tasmlabel(taicpu(hp1).oper[0]^.ref^.symbol),hp4) then
-                          begin
-                            taicpu(hp2).Opcode := A_SUB;
-                            taicpu(hp2).loadoper(1,taicpu(hp2).oper[0]^);
-                            taicpu(hp2).loadConst(0,1);
-                            taicpu(hp2).ops:=2;
-                            taicpu(hp3).Opcode := A_Jcc;
-                            case taicpu(hp1).condition of
-                              C_LE: taicpu(hp3).condition := C_GE;
-                              C_BE: taicpu(hp3).condition := C_AE;
-                              else
-                                internalerror(2019050903);
-                            end;
-                            asml.remove(p);
-                            asml.remove(hp1);
-                            p.free;
-                            hp1.free;
-                            p := hp2;
-                            Result:=true;
-                          end
+                        Taicpu(p).opcode:=A_NEG;
+                        Taicpu(p).loadoper(0,Taicpu(p).oper[1]^);
+                        Taicpu(p).clearop(1);
+                        Taicpu(p).ops:=1;
+                        if Taicpu(hp1).condition=C_E then
+                          Taicpu(hp1).condition:=C_O
+                        else
+                          Taicpu(hp1).condition:=C_NO;
+                        Result:=true;
                       end;
-                    A_FLD:
-                      Result:=OptPass1FLD(p);
-                    A_FSTP,A_FISTP:
-                      Result:=OptPass1FSTP(p);
-                    A_LEA:
-                      Result:=OptPass1LEA(p);
-                    A_MOV:
-                      Result:=OptPass1MOV(p);
-                    A_MOVSX,
-                    A_MOVZX :
-                      Result:=OptPass1Movx(p);
-  (* should not be generated anymore by the current code generator
-                    A_POP:
+                    {
+                    @@2:                              @@2:
+                      ....                              ....
+                      cmp operand1,0
+                      jle/jbe @@1
+                      dec operand1             -->      sub operand1,1
+                      jmp @@2                           jge/jae @@2
+                    @@1:                              @@1:
+                      ...                               ....}
+                    if (taicpu(p).oper[0]^.typ = top_const) and
+                       (taicpu(p).oper[1]^.typ in [top_reg,top_ref]) and
+                       (taicpu(p).oper[0]^.val = 0) and
+                       GetNextInstruction(p, hp1) and
+                       (hp1.typ = ait_instruction) and
+                       (taicpu(hp1).is_jmp) and
+                       (taicpu(hp1).opcode=A_Jcc) and
+                       (taicpu(hp1).condition in [C_LE,C_BE]) and
+                       GetNextInstruction(hp1,hp2) and
+                       (hp2.typ = ait_instruction) and
+                       (taicpu(hp2).opcode = A_DEC) and
+                       OpsEqual(taicpu(hp2).oper[0]^,taicpu(p).oper[1]^) and
+                       GetNextInstruction(hp2, hp3) and
+                       (hp3.typ = ait_instruction) and
+                       (taicpu(hp3).is_jmp) and
+                       (taicpu(hp3).opcode = A_JMP) and
+                       GetNextInstruction(hp3, hp4) and
+                       FindLabel(tasmlabel(taicpu(hp1).oper[0]^.ref^.symbol),hp4) then
                       begin
-                        if target_info.system=system_i386_go32v2 then
+                        taicpu(hp2).Opcode := A_SUB;
+                        taicpu(hp2).loadoper(1,taicpu(hp2).oper[0]^);
+                        taicpu(hp2).loadConst(0,1);
+                        taicpu(hp2).ops:=2;
+                        taicpu(hp3).Opcode := A_Jcc;
+                        case taicpu(hp1).condition of
+                          C_LE: taicpu(hp3).condition := C_GE;
+                          C_BE: taicpu(hp3).condition := C_AE;
+                          else
+                            internalerror(2019050903);
+                        end;
+                        asml.remove(p);
+                        asml.remove(hp1);
+                        p.free;
+                        hp1.free;
+                        p := hp2;
+                        Result:=true;
+                      end
+                  end;
+                A_FLD:
+                  Result:=OptPass1FLD(p);
+                A_FSTP,A_FISTP:
+                  Result:=OptPass1FSTP(p);
+                A_LEA:
+                  Result:=OptPass1LEA(p);
+                A_MOV:
+                  Result:=OptPass1MOV(p);
+                A_MOVSX,
+                A_MOVZX :
+                  Result:=OptPass1Movx(p);
+(* should not be generated anymore by the current code generator
+                A_POP:
+                  begin
+                    if target_info.system=system_i386_go32v2 then
+                    begin
+                      { Transform a series of pop/pop/pop/push/push/push to }
+                      { 'movl x(%esp),%reg' for go32v2 (not for the rest,   }
+                      { because I'm not sure whether they can cope with     }
+                      { 'movl x(%esp),%reg' with x > 0, I believe we had    }
+                      { such a problem when using esp as frame pointer (JM) }
+                      if (taicpu(p).oper[0]^.typ = top_reg) then
                         begin
-                          { Transform a series of pop/pop/pop/push/push/push to }
-                          { 'movl x(%esp),%reg' for go32v2 (not for the rest,   }
-                          { because I'm not sure whether they can cope with     }
-                          { 'movl x(%esp),%reg' with x > 0, I believe we had    }
-                          { such a problem when using esp as frame pointer (JM) }
-                          if (taicpu(p).oper[0]^.typ = top_reg) then
+                          hp1 := p;
+                          hp2 := p;
+                          l := 0;
+                          while getNextInstruction(hp1,hp1) and
+                                (hp1.typ = ait_instruction) and
+                                (taicpu(hp1).opcode = A_POP) and
+                                (taicpu(hp1).oper[0]^.typ = top_reg) do
                             begin
-                              hp1 := p;
-                              hp2 := p;
-                              l := 0;
-                              while getNextInstruction(hp1,hp1) and
-                                    (hp1.typ = ait_instruction) and
-                                    (taicpu(hp1).opcode = A_POP) and
-                                    (taicpu(hp1).oper[0]^.typ = top_reg) do
-                                begin
-                                  hp2 := hp1;
-                                  inc(l,4);
-                                end;
-                              getLastInstruction(p,hp3);
-                              l1 := 0;
-                              while (hp2 <> hp3) and
-                                    assigned(hp1) and
-                                    (hp1.typ = ait_instruction) and
-                                    (taicpu(hp1).opcode = A_PUSH) and
-                                    (taicpu(hp1).oper[0]^.typ = top_reg) and
-                                    (taicpu(hp1).oper[0]^.reg.enum = taicpu(hp2).oper[0]^.reg.enum) do
-                                begin
-                                  { change it to a two op operation }
-                                  taicpu(hp2).oper[1]^.typ:=top_none;
-                                  taicpu(hp2).ops:=2;
-                                  taicpu(hp2).opcode := A_MOV;
-                                  taicpu(hp2).loadoper(1,taicpu(hp1).oper[0]^);
-                                  reference_reset(tmpref);
-                                  tmpRef.base.enum:=R_INTREGISTER;
-                                  tmpRef.base.number:=NR_STACK_POINTER_REG;
-                                  convert_register_to_enum(tmpref.base);
-                                  tmpRef.offset := l;
-                                  taicpu(hp2).loadRef(0,tmpRef);
-                                  hp4 := hp1;
-                                  getNextInstruction(hp1,hp1);
-                                  asml.remove(hp4);
-                                  hp4.free;
-                                  getLastInstruction(hp2,hp2);
-                                  dec(l,4);
-                                  inc(l1);
-                                end;
-                              if l <> -4 then
+                              hp2 := hp1;
+                              inc(l,4);
+                            end;
+                          getLastInstruction(p,hp3);
+                          l1 := 0;
+                          while (hp2 <> hp3) and
+                                assigned(hp1) and
+                                (hp1.typ = ait_instruction) and
+                                (taicpu(hp1).opcode = A_PUSH) and
+                                (taicpu(hp1).oper[0]^.typ = top_reg) and
+                                (taicpu(hp1).oper[0]^.reg.enum = taicpu(hp2).oper[0]^.reg.enum) do
+                            begin
+                              { change it to a two op operation }
+                              taicpu(hp2).oper[1]^.typ:=top_none;
+                              taicpu(hp2).ops:=2;
+                              taicpu(hp2).opcode := A_MOV;
+                              taicpu(hp2).loadoper(1,taicpu(hp1).oper[0]^);
+                              reference_reset(tmpref);
+                              tmpRef.base.enum:=R_INTREGISTER;
+                              tmpRef.base.number:=NR_STACK_POINTER_REG;
+                              convert_register_to_enum(tmpref.base);
+                              tmpRef.offset := l;
+                              taicpu(hp2).loadRef(0,tmpRef);
+                              hp4 := hp1;
+                              getNextInstruction(hp1,hp1);
+                              asml.remove(hp4);
+                              hp4.free;
+                              getLastInstruction(hp2,hp2);
+                              dec(l,4);
+                              inc(l1);
+                            end;
+                          if l <> -4 then
+                            begin
+                              inc(l,4);
+                              for l1 := l1 downto 1 do
                                 begin
-                                  inc(l,4);
-                                  for l1 := l1 downto 1 do
-                                    begin
-                                      getNextInstruction(hp2,hp2);
-                                      dec(taicpu(hp2).oper[0]^.ref^.offset,l);
-                                    end
+                                  getNextInstruction(hp2,hp2);
+                                  dec(taicpu(hp2).oper[0]^.ref^.offset,l);
                                 end
                             end
-                          end
-                        else
-                          begin
-                            if (taicpu(p).oper[0]^.typ = top_reg) and
-                              GetNextInstruction(p, hp1) and
-                              (tai(hp1).typ=ait_instruction) and
-                              (taicpu(hp1).opcode=A_PUSH) and
-                              (taicpu(hp1).oper[0]^.typ = top_reg) and
-                              (taicpu(hp1).oper[0]^.reg.enum=taicpu(p).oper[0]^.reg.enum) then
-                              begin
-                                { change it to a two op operation }
-                                taicpu(p).oper[1]^.typ:=top_none;
-                                taicpu(p).ops:=2;
-                                taicpu(p).opcode := A_MOV;
-                                taicpu(p).loadoper(1,taicpu(p).oper[0]^);
-                                reference_reset(tmpref);
-                                TmpRef.base.enum := R_ESP;
-                                taicpu(p).loadRef(0,TmpRef);
-                                asml.remove(hp1);
-                                hp1.free;
-                              end;
-                          end;
-                      end;
-  *)
-                    A_PUSH:
+                        end
+                      end
+                    else
                       begin
-                        if (taicpu(p).opsize = S_W) and
-                           (taicpu(p).oper[0]^.typ = Top_Const) and
-                           GetNextInstruction(p, hp1) and
-                           (tai(hp1).typ = ait_instruction) and
-                           (taicpu(hp1).opcode = A_PUSH) and
-                           (taicpu(hp1).oper[0]^.typ = Top_Const) and
-                           (taicpu(hp1).opsize = S_W) then
+                        if (taicpu(p).oper[0]^.typ = top_reg) and
+                          GetNextInstruction(p, hp1) and
+                          (tai(hp1).typ=ait_instruction) and
+                          (taicpu(hp1).opcode=A_PUSH) and
+                          (taicpu(hp1).oper[0]^.typ = top_reg) and
+                          (taicpu(hp1).oper[0]^.reg.enum=taicpu(p).oper[0]^.reg.enum) then
                           begin
-                            taicpu(p).changeopsize(S_L);
-                            taicpu(p).loadConst(0,taicpu(p).oper[0]^.val shl 16 + word(taicpu(hp1).oper[0]^.val));
+                            { change it to a two op operation }
+                            taicpu(p).oper[1]^.typ:=top_none;
+                            taicpu(p).ops:=2;
+                            taicpu(p).opcode := A_MOV;
+                            taicpu(p).loadoper(1,taicpu(p).oper[0]^);
+                            reference_reset(tmpref);
+                            TmpRef.base.enum := R_ESP;
+                            taicpu(p).loadRef(0,TmpRef);
                             asml.remove(hp1);
                             hp1.free;
-                            Result:=true;
                           end;
                       end;
-                    A_SHL, A_SAL:
-                      Result:=OptPass1SHLSAL(p);
-                    A_SUB:
-                      Result:=OptPass1Sub(p);
-                    A_MOVAPD,
-                    A_MOVAPS,
-                    A_MOVUPD,
-                    A_MOVUPS,
-                    A_VMOVAPS,
-                    A_VMOVAPD,
-                    A_VMOVUPS,
-                    A_VMOVUPD:
-                      Result:=OptPass1_V_MOVAP(p);
-                    A_VDIVSD,
-                    A_VDIVSS,
-                    A_VSUBSD,
-                    A_VSUBSS,
-                    A_VMULSD,
-                    A_VMULSS,
-                    A_VADDSD,
-                    A_VADDSS,
-                    A_VANDPD,
-                    A_VANDPS,
-                    A_VORPD,
-                    A_VORPS,
-                    A_VXORPD,
-                    A_VXORPS:
-                      Result:=OptPass1VOP(p);
-                    A_MULSD,
-                    A_MULSS,
-                    A_ADDSD,
-                    A_ADDSS:
-                      Result:=OptPass1OP(p);
-                    A_VMOVSD,
-                    A_VMOVSS,
-                    A_MOVSD,
-                    A_MOVSS:
-                      Result:=OptPass1MOVXX(p);
-                    A_SETcc:
-                      Result:=OptPass1SETcc(p);
-                    else
-                      ;
                   end;
-              end; { if is_jmp }
+*)
+                A_PUSH:
+                  begin
+                    if (taicpu(p).opsize = S_W) and
+                       (taicpu(p).oper[0]^.typ = Top_Const) and
+                       GetNextInstruction(p, hp1) and
+                       (tai(hp1).typ = ait_instruction) and
+                       (taicpu(hp1).opcode = A_PUSH) and
+                       (taicpu(hp1).oper[0]^.typ = Top_Const) and
+                       (taicpu(hp1).opsize = S_W) then
+                      begin
+                        taicpu(p).changeopsize(S_L);
+                        taicpu(p).loadConst(0,taicpu(p).oper[0]^.val shl 16 + word(taicpu(hp1).oper[0]^.val));
+                        asml.remove(hp1);
+                        hp1.free;
+                        Result:=true;
+                      end;
+                  end;
+                A_SHL, A_SAL:
+                  Result:=OptPass1SHLSAL(p);
+                A_SUB:
+                  Result:=OptPass1Sub(p);
+                A_MOVAPD,
+                A_MOVAPS,
+                A_MOVUPD,
+                A_MOVUPS,
+                A_VMOVAPS,
+                A_VMOVAPD,
+                A_VMOVUPS,
+                A_VMOVUPD:
+                  Result:=OptPass1_V_MOVAP(p);
+                A_VDIVSD,
+                A_VDIVSS,
+                A_VSUBSD,
+                A_VSUBSS,
+                A_VMULSD,
+                A_VMULSS,
+                A_VADDSD,
+                A_VADDSS,
+                A_VANDPD,
+                A_VANDPS,
+                A_VORPD,
+                A_VORPS,
+                A_VXORPD,
+                A_VXORPS:
+                  Result:=OptPass1VOP(p);
+                A_MULSD,
+                A_MULSS,
+                A_ADDSD,
+                A_ADDSS:
+                  Result:=OptPass1OP(p);
+                A_VMOVSD,
+                A_VMOVSS,
+                A_MOVSD,
+                A_MOVSS:
+                  Result:=OptPass1MOVXX(p);
+                A_SETcc:
+                  Result:=OptPass1SETcc(p);
+                else
+                  ;
+              end;
             end;
           else
             ;