+ change always floating point divisions into multiplications if they are a power of two,

this is an exact operation so it is always allowed
* change only divisions by normal numbers into multiplications

git-svn-id: trunk@29085 -
This commit is contained in:
florian 2014-11-16 20:47:38 +00:00
parent 7180d184c5
commit 5c67fcc43f
19 changed files with 99 additions and 24 deletions

View File

@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type extended;

View File

@ -41,6 +41,9 @@ Type
TConstPtrUInt = qword;
bestreal = extended;
{$if FPC_FULLVERSION>20700}
bestrealrec = TExtended80Rec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type extended;

View File

@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type extended;

View File

@ -22,6 +22,13 @@ Interface
Type
bestreal = extended;
{$if FPC_FULLVERSION>20700}
{$ifdef FPC_HAS_TYPE_EXTENDED}
bestrealrec = TExtended80Rec;
{$else}
bestrealrec = TDoubleRec;
{$endif}
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type extended;

View File

@ -84,23 +84,23 @@ interface
treelogfilename = 'tree.log';
{$if defined(CPUARM) and defined(FPUFPA)}
MathQNaN : tdoublerec = (bytes : (0,0,252,255,0,0,0,0));
MathInf : tdoublerec = (bytes : (0,0,240,127,0,0,0,0));
MathNegInf : tdoublerec = (bytes : (0,0,240,255,0,0,0,0));
MathPi : tdoublerec = (bytes : (251,33,9,64,24,45,68,84));
MathQNaN : tcompdoublerec = (bytes : (0,0,252,255,0,0,0,0));
MathInf : tcompdoublerec = (bytes : (0,0,240,127,0,0,0,0));
MathNegInf : tcompdoublerec = (bytes : (0,0,240,255,0,0,0,0));
MathPi : tcompdoublerec = (bytes : (251,33,9,64,24,45,68,84));
{$else}
{$ifdef FPC_LITTLE_ENDIAN}
MathQNaN : tdoublerec = (bytes : (0,0,0,0,0,0,252,255));
MathInf : tdoublerec = (bytes : (0,0,0,0,0,0,240,127));
MathNegInf : tdoublerec = (bytes : (0,0,0,0,0,0,240,255));
MathPi : tdoublerec = (bytes : (24,45,68,84,251,33,9,64));
MathPiExtended : textendedrec = (bytes : (53,194,104,33,162,218,15,201,0,64));
MathQNaN : tcompdoublerec = (bytes : (0,0,0,0,0,0,252,255));
MathInf : tcompdoublerec = (bytes : (0,0,0,0,0,0,240,127));
MathNegInf : tcompdoublerec = (bytes : (0,0,0,0,0,0,240,255));
MathPi : tcompdoublerec = (bytes : (24,45,68,84,251,33,9,64));
MathPiExtended : tcompextendedrec = (bytes : (53,194,104,33,162,218,15,201,0,64));
{$else FPC_LITTLE_ENDIAN}
MathQNaN : tdoublerec = (bytes : (255,252,0,0,0,0,0,0));
MathInf : tdoublerec = (bytes : (127,240,0,0,0,0,0,0));
MathNegInf : tdoublerec = (bytes : (255,240,0,0,0,0,0,0));
MathPi : tdoublerec = (bytes : (64,9,33,251,84,68,45,24));
MathPiExtended : textendedrec = (bytes : (64,0,201,15,218,162,33,104,194,53));
MathQNaN : tcompdoublerec = (bytes : (255,252,0,0,0,0,0,0));
MathInf : tcompdoublerec = (bytes : (127,240,0,0,0,0,0,0));
MathNegInf : tcompdoublerec = (bytes : (255,240,0,0,0,0,0,0));
MathPi : tcompdoublerec = (bytes : (64,9,33,251,84,68,45,24));
MathPiExtended : tcompextendedrec = (bytes : (64,0,201,15,218,162,33,104,194,53));
{$endif FPC_LITTLE_ENDIAN}
{$endif}
@ -963,7 +963,7 @@ implementation
result := -1;
end;
function convertdoublerec(d : tdoublerec) : tdoublerec;{$ifdef USEINLINE}inline;{$endif}
function convertdoublerec(d : tcompdoublerec) : tcompdoublerec;{$ifdef USEINLINE}inline;{$endif}
{$ifdef CPUARM}
var
i : longint;

View File

@ -110,12 +110,12 @@ interface
{$endif i8086}
{ Use a variant record to be sure that the array if aligned correctly }
tdoublerec=record
tcompdoublerec=record
case byte of
0 : (bytes:array[0..7] of byte);
1 : (value:double);
end;
textendedrec=record
tcompextendedrec=record
case byte of
0 : (bytes:array[0..9] of byte);
1 : (value:extended);

View File

@ -30,6 +30,9 @@ Interface
Type
bestreal = extended;
{$if FPC_FULLVERSION>20700}
bestrealrec = TExtended80Rec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -30,6 +30,9 @@ Interface
Type
bestreal = extended;
{$if FPC_FULLVERSION>20700}
bestrealrec = TExtended80Rec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -30,6 +30,9 @@ uses
Type
bestreal = extended;
{$if FPC_FULLVERSION>20700}
bestrealrec = TExtended80Rec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = type double;

View File

@ -684,23 +684,41 @@ implementation
result:=t;
exit;
end;
{$if FPC_FULLVERSION>20700}
{ bestrealrec is 2.7.1+ only }
{ replace .../const by a multiplication, but only if fastmath is enabled or
the division is done by a power of 2, do not mess with special floating point values like Inf etc.
{ replace .../const by a multiplication, but only if fastmath is enabled,
do this after constant folding to avoid unnecessary precision loss if
an slash expresion would be first converted into a multiplication and later
folded }
if (nodetype=slashn) and
{ do not mess with currency types }
(not(is_currency(right.resultdef))) and
(cs_opt_fastmath in current_settings.optimizerswitches) then
(((cs_opt_fastmath in current_settings.optimizerswitches) and (rt=ordconstn)) or
((cs_opt_fastmath in current_settings.optimizerswitches) and (rt=realconstn) and
(bestrealrec(trealconstnode(right).value_real).SpecialType in [fsPositive,fsNegative])
) or
((rt=realconstn) and
(bestrealrec(trealconstnode(right).value_real).SpecialType in [fsPositive,fsNegative]) and
{ mantissa returns the mantissa/fraction without the hidden 1, so power of two means only the hidden
bit is set => mantissa must be 0 }
(bestrealrec(trealconstnode(right).value_real).Mantissa=0)
)
) then
case rt of
ordconstn:
begin
nodetype:=muln;
t:=crealconstnode.create(1/tordconstnode(right).value,resultdef);
right.free;
right:=t;
exit;
{ the normal code handles div/0 }
if (tordconstnode(right).value<>0) then
begin
nodetype:=muln;
t:=crealconstnode.create(1/tordconstnode(right).value,resultdef);
right.free;
right:=t;
exit;
end;
end;
realconstn:
begin
@ -709,6 +727,7 @@ implementation
exit;
end;
end;
{$endif FPC_FULLVERSION>20700}
{ first, we handle widestrings, so we can check later for }
{ stringconstn only }

View File

@ -21,6 +21,9 @@ Interface
Type
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -21,6 +21,9 @@ uses
type
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -30,6 +30,9 @@ uses
type
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -34,6 +34,9 @@ Type
TConstPtrUInt = Longword;
bestreal = double;
{$if FPC_FULLVERSION>20700}
bestrealrec = TDoubleRec;
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;

View File

@ -30,6 +30,13 @@ Interface
Type
bestreal = extended;
{$if FPC_FULLVERSION>20700}
{$ifdef FPC_HAS_TYPE_EXTENDED}
bestrealrec = TExtended80Rec;
{$else}
bestrealrec = TDoubleRec;
{$endif}
{$endif FPC_FULLVERSION>20700}
ts32real = single;
ts64real = double;
ts80real = extended;