diff --git a/compiler/aoptobj.pas b/compiler/aoptobj.pas index 7520280831..a393c88ccc 100644 --- a/compiler/aoptobj.pas +++ b/compiler/aoptobj.pas @@ -367,7 +367,8 @@ Unit AoptObj; cutils, globals, verbose, - procinfo; + procinfo, + aoptutils; function JumpTargetOp(ai: taicpu): poper; inline; @@ -1147,25 +1148,6 @@ Unit AoptObj; end; - function SkipLabels(hp: tai; var hp2: tai): boolean; - {skips all labels and returns the next "real" instruction} - begin - while assigned(hp.next) and - (tai(hp.next).typ in SkipInstr + [ait_label,ait_align]) Do - hp := tai(hp.next); - if assigned(hp.next) then - begin - SkipLabels := True; - hp2 := tai(hp.next) - end - else - begin - hp2 := hp; - SkipLabels := False - end; - end; - - function FindAnyLabel(hp: tai; var l: tasmlabel): Boolean; begin FindAnyLabel := false; diff --git a/compiler/aoptutils.pas b/compiler/aoptutils.pas index 68043028e5..3d85618794 100644 --- a/compiler/aoptutils.pas +++ b/compiler/aoptutils.pas @@ -32,6 +32,9 @@ unit aoptutils; function MatchOpType(const p : taicpu;type0: toptype) : Boolean; function MatchOpType(const p : taicpu;type0,type1 : toptype) : Boolean; + { skips all labels and returns the next "real" instruction } + function SkipLabels(hp: tai; var hp2: tai): boolean; + implementation function MatchOpType(const p : taicpu; type0: toptype) : Boolean; @@ -45,5 +48,25 @@ unit aoptutils; Result:=(p.oper[0]^.typ=type0) and (p.oper[0]^.typ=type1); end; + + { skips all labels and returns the next "real" instruction } + function SkipLabels(hp: tai; var hp2: tai): boolean; + begin + while assigned(hp.next) and + (tai(hp.next).typ in SkipInstr + [ait_label,ait_align]) Do + hp := tai(hp.next); + if assigned(hp.next) then + begin + SkipLabels := True; + hp2 := tai(hp.next) + end + else + begin + hp2 := hp; + SkipLabels := False + end; + end; + + end. diff --git a/compiler/i386/aoptcpu.pas b/compiler/i386/aoptcpu.pas index 6b2994eccb..379fa91b76 100644 --- a/compiler/i386/aoptcpu.pas +++ b/compiler/i386/aoptcpu.pas @@ -56,6 +56,7 @@ unit aoptcpu; aoptbase, cpuinfo, aasmcpu, + aoptutils, procinfo, cgutils,cgx86, { units we should get rid off: } @@ -684,24 +685,6 @@ begin end; end; -{ skips all labels and returns the next "real" instruction } -function SkipLabels(hp: tai; var hp2: tai): boolean; - begin - while assigned(hp.next) and - (tai(hp.next).typ in SkipInstr + [ait_label,ait_align]) Do - hp := tai(hp.next); - if assigned(hp.next) then - begin - SkipLabels := True; - hp2 := tai(hp.next) - end - else - begin - hp2 := hp; - SkipLabels := False - end; - end; - { First pass of peephole optimizations } procedure TCPUAsmOPtimizer.PeepHoleOptPass1; @@ -1992,35 +1975,8 @@ begin if OptPass2Imul(p) then continue; A_JMP: - { - change - jmp .L1 - ... - .L1: - ret - into - ret - } - if (taicpu(p).oper[0]^.typ=top_ref) and (taicpu(p).oper[0]^.ref^.refaddr=addr_full) then - begin - hp1:=getlabelwithsym(tasmlabel(taicpu(p).oper[0]^.ref^.symbol)); - if assigned(hp1) and SkipLabels(hp1,hp1) and (hp1.typ=ait_instruction) and (taicpu(hp1).opcode=A_RET) and (taicpu(p).condition=C_None) then - begin - tasmlabel(taicpu(p).oper[0]^.ref^.symbol).decrefs; - taicpu(p).opcode:=A_RET; - taicpu(p).is_jmp:=false; - taicpu(p).ops:=taicpu(hp1).ops; - case taicpu(hp1).ops of - 0: - taicpu(p).clearop(0); - 1: - taicpu(p).loadconst(0,taicpu(hp1).oper[0]^.val); - else - internalerror(2016041301); - end; - continue; - end; - end; + if OptPass2Jmp(p) then + continue; A_MOV: if OptPass2MOV(p) then continue; diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas index a70b6d932b..2aab96d4a7 100644 --- a/compiler/x86/aoptx86.pas +++ b/compiler/x86/aoptx86.pas @@ -55,6 +55,7 @@ unit aoptx86; function OptPass2MOV(var p : tai) : boolean; function OptPass2Imul(var p : tai) : boolean; + function OptPass2Jmp(var p : tai) : boolean; procedure DebugMsg(const s : string; p : tai);inline; @@ -89,6 +90,8 @@ unit aoptx86; cutils, verbose, procinfo, + aasmbase, + aoptutils, symconst,symsym, itcpugas; @@ -1369,6 +1372,45 @@ unit aoptx86; end; + function TX86AsmOptimizer.OptPass2Jmp(var p : tai) : boolean; + var + hp1 : tai; + begin + { + change + jmp .L1 + ... + .L1: + ret + into + ret + } + result:=false; + if (taicpu(p).oper[0]^.typ=top_ref) and (taicpu(p).oper[0]^.ref^.refaddr=addr_full) and (taicpu(p).oper[0]^.ref^.base=NR_NO) and + (taicpu(p).oper[0]^.ref^.index=NR_NO) then + begin + hp1:=getlabelwithsym(tasmlabel(taicpu(p).oper[0]^.ref^.symbol)); + if (taicpu(p).condition=C_None) and assigned(hp1) and SkipLabels(hp1,hp1) and + MatchInstruction(hp1,A_RET,[S_NO]) then + begin + tasmlabel(taicpu(p).oper[0]^.ref^.symbol).decrefs; + taicpu(p).opcode:=A_RET; + taicpu(p).is_jmp:=false; + taicpu(p).ops:=taicpu(hp1).ops; + case taicpu(hp1).ops of + 0: + taicpu(p).clearop(0); + 1: + taicpu(p).loadconst(0,taicpu(hp1).oper[0]^.val); + else + internalerror(2016041301); + end; + result:=true; + end; + end; + end; + + function TX86AsmOptimizer.OptPass1AND(var p : tai) : boolean; var hp1 : tai; diff --git a/compiler/x86_64/aoptcpu.pas b/compiler/x86_64/aoptcpu.pas index 1bd495f52f..6c503b0285 100644 --- a/compiler/x86_64/aoptcpu.pas +++ b/compiler/x86_64/aoptcpu.pas @@ -357,6 +357,8 @@ end; Result:=OptPass2MOV(p); A_IMUL: Result:=OptPass2Imul(p); + A_JMP: + Result:=OptPass2Jmp(p); end; end; end;