mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 23:21:57 +02:00
+ 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:
parent
8307e46e4b
commit
a21397e356
@ -376,9 +376,76 @@ implementation
|
||||
|
||||
|
||||
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
|
||||
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 : tnode;
|
||||
t , vl: tnode;
|
||||
lt,rt : tnodetype;
|
||||
hdef,
|
||||
rd,ld : tdef;
|
||||
rv,lv,v : tconstexprint;
|
||||
rvd,lvd : bestreal;
|
||||
@ -390,6 +457,7 @@ implementation
|
||||
resultset : Tconstset;
|
||||
res,
|
||||
b : boolean;
|
||||
cr, cl : qword;
|
||||
begin
|
||||
result:=nil;
|
||||
l1:=0;
|
||||
@ -984,6 +1052,25 @@ implementation
|
||||
}
|
||||
if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
|
||||
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
|
||||
optimization cannot be performed in case the node has
|
||||
side effects, because this can change the result (e.g., in an
|
||||
|
Loading…
Reference in New Issue
Block a user