+ based on a patch by Laksen, optimize (v>=x) and (v<=y) into (v-x)<(y-x)

git-svn-id: trunk@39759 -
This commit is contained in:
florian 2018-09-16 13:09:36 +00:00
parent 8307e46e4b
commit a21397e356

View File

@ -376,9 +376,76 @@ implementation
function taddnode.simplify(forinline : boolean) : tnode; function taddnode.simplify(forinline : boolean) : tnode;
function is_range_test(nodel, noder: taddnode; var value: tnode; var cl,cr: qword): boolean;
const
is_upper_test: array[ltn..gten] of boolean = (true,true,false,false);
inclusive_adjust: array[boolean,ltn..gten] of integer = ((1,0,-1,0),
(-1,0,1,0));
var var
t : tnode; swapl, swapr: Boolean;
valuer: tnode;
t: QWord;
begin
result:=false;
swapl:=false;
swapr:=false;
if nodel.left.nodetype=ordconstn then
begin
swapl:=true;
cl:=tordconstnode(nodel.left).value.uvalue;
value:=nodel.right;
end
else if nodel.right.nodetype=ordconstn then
begin
cl:=tordconstnode(nodel.right).value.uvalue;
value:=nodel.left;
end
else
exit;
if is_signed(value.resultdef) then
exit;
if noder.left.nodetype=ordconstn then
begin
swapl:=true;
cr:=tordconstnode(noder.left).value.uvalue;
valuer:=noder.right;
end
else if noder.right.nodetype=ordconstn then
begin
cr:=tordconstnode(noder.right).value.uvalue;
valuer:=noder.left;
end
else
exit;
if not value.isequal(valuer) then
exit;
{ this could be simplified too, but probably never happens }
if (is_upper_test[nodel.nodetype] xor swapl)=(is_upper_test[noder.nodetype] xor swapr) then
exit;
cl:=cl+inclusive_adjust[swapl,nodel.nodetype];
cr:=cr+inclusive_adjust[swapr,noder.nodetype];
if is_upper_test[nodel.nodetype] xor swapl then
begin
t:=cl;
cl:=cr;
cr:=t;
end;
result:=true;
end;
var
t , vl: tnode;
lt,rt : tnodetype; lt,rt : tnodetype;
hdef,
rd,ld : tdef; rd,ld : tdef;
rv,lv,v : tconstexprint; rv,lv,v : tconstexprint;
rvd,lvd : bestreal; rvd,lvd : bestreal;
@ -390,6 +457,7 @@ implementation
resultset : Tconstset; resultset : Tconstset;
res, res,
b : boolean; b : boolean;
cr, cl : qword;
begin begin
result:=nil; result:=nil;
l1:=0; l1:=0;
@ -984,6 +1052,25 @@ implementation
} }
if is_boolean(left.resultdef) and is_boolean(right.resultdef) then if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
begin begin
{ transform unsigned comparisons of (v>=x) and (v<=y)
into (v-x)<(y-x)
}
if (nodetype=andn) and
(left.nodetype in [ltn,lten,gtn,gten]) and
(right.nodetype in [ltn,lten,gtn,gten]) and
(not might_have_sideeffects(left)) and
(not might_have_sideeffects(right)) and
is_range_test(taddnode(left),taddnode(right),vl,cl,cr) then
begin
hdef:=get_unsigned_inttype(vl.resultdef);
vl:=ctypeconvnode.create_internal(vl.getcopy,hdef);
result:=caddnode.create_internal(lten,
ctypeconvnode.create_internal(caddnode.create_internal(subn,vl,cordconstnode.create(cl,hdef,false)),hdef),
cordconstnode.create(cr-cl,hdef,false));
exit;
end;
{ even when short circuit boolean evaluation is active, this { even when short circuit boolean evaluation is active, this
optimization cannot be performed in case the node has optimization cannot be performed in case the node has
side effects, because this can change the result (e.g., in an side effects, because this can change the result (e.g., in an