From d8406c4227e9a4274812b62b65fe0a7e78b2ef0d Mon Sep 17 00:00:00 2001 From: nickysn Date: Mon, 10 Apr 2017 14:06:19 +0000 Subject: [PATCH] + perform the "i:=-i" / "i:=not i" optimization even when there are typecasts inserted; this makes the optimization work for all integer types git-svn-id: trunk@35763 - --- compiler/nld.pas | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/compiler/nld.pas b/compiler/nld.pas index 04ea443265..cb31d2bb53 100644 --- a/compiler/nld.pas +++ b/compiler/nld.pas @@ -670,9 +670,8 @@ implementation end; { replace i:=not i by in_not_assign_x(i) i:=-i by in_neg_assign_x(i) - todo: for some integer types, there are extra implicit - typecasts inserted by the compiler; this code should be - updated to handle them as well } + + this handles the case, where there are no implicit type conversions } if (right.nodetype in [notn,unaryminusn]) and (tunarynode(right).left.isequal(left)) and is_integer(tunarynode(right).left.resultdef) and @@ -690,6 +689,38 @@ implementation left:=nil; exit; end; + { replace i:=not i by in_not_assign_x(i) + i:=-i by in_neg_assign_x(i) + + this handles the case with type conversions: + outer typeconv: right + neg/not: ttypeconvnode(right).left + inner typeconv: tunarynode(ttypeconvnode(right).left).left + right side 'i': ttypeconvnode(tunarynode(ttypeconvnode(right).left).left).left } + if (right.nodetype=typeconvn) and + (ttypeconvnode(right).convtype=tc_int_2_int) and + (ttypeconvnode(right).left.nodetype in [notn,unaryminusn]) and + is_integer(ttypeconvnode(right).left.resultdef) and + (right.resultdef.size<=ttypeconvnode(right).left.resultdef.size) and + (tunarynode(ttypeconvnode(right).left).left.nodetype=typeconvn) and + (ttypeconvnode(tunarynode(ttypeconvnode(right).left).left).convtype=tc_int_2_int) and + are_equal_ints(right.resultdef,ttypeconvnode(tunarynode(ttypeconvnode(right).left).left).left.resultdef) and + ttypeconvnode(tunarynode(ttypeconvnode(right).left).left).left.isequal(left) and + is_integer(ttypeconvnode(tunarynode(ttypeconvnode(right).left).left).left.resultdef) and + ((localswitches*[cs_check_overflow,cs_check_range])=[]) and + ((right.localswitches*[cs_check_overflow,cs_check_range])=[]) and + valid_for_var(ttypeconvnode(tunarynode(ttypeconvnode(right).left).left).left,false) and + not(might_have_sideeffects(ttypeconvnode(tunarynode(ttypeconvnode(right).left).left).left)) then + begin + if ttypeconvnode(right).left.nodetype=notn then + newinlinenodetype:=in_not_assign_x + else + newinlinenodetype:=in_neg_assign_x; + result:=cinlinenode.createintern( + newinlinenodetype,false,left); + left:=nil; + exit; + end; end; end; end;