By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,341 Members | 1,430 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,341 IT Pros & Developers. It's quick & easy.

Constant expression optimization

P: n/a
Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.

Details:
-------

The compiler does all calculation in the highest precision
available (long double), and then transforms the result into
the (maybe) lower precision as required.

For instance:
float f = sqrtf(2.0f);

The compiler transforms the input constant in a long double
precision constant, then transforms the result into a float
constant.

This code:
long double ld = sqrt(2.0f);

will provoke a call to sqrt(2.0f) with the 2.0 transformed
into a long double from a float constant, then the
result cast again down into a float from a double, then
cast up again to do the assignment of a float into a long
double. The actual value passed will be
1.414213538169861
and not
1.41421356237309504
as it should be in long double precision.
I hope I did not forget some obscure rule in this. Please
if you think about some problems with this optimization
just answer.

The functions supported are most of the functions in math.h
(sqrt acos sin/cos) etc.

Later I will add strlen of constant strings. (strlen("hello"))

What other functions would you add?

Thanks in advance for your attention.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Oct 20 '08 #1
Share this Question
Share on Google+
34 Replies


P: n/a
On Oct 20, 8:19 pm, jacob navia <ja...@nospam.comwrote:
Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.
<snip>
What other functions would you add?
I'd add memset(&obj, 0, sizeof obj); as T obj = {0}; if memset is the
first operation on obj.

Oct 20 '08 #2

P: n/a
jacob navia wrote:
Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.

Details:
-------

The compiler does all calculation in the highest precision
available (long double), and then transforms the result into
the (maybe) lower precision as required.

For instance:
float f = sqrtf(2.0f);

The compiler transforms the input constant in a long double
precision constant, then transforms the result into a float
constant.

This code:
long double ld = sqrt(2.0f);

will provoke a call to sqrt(2.0f) with the 2.0 transformed
into a long double from a float constant, then the
result cast again down into a float from a double, then
cast up again to do the assignment of a float into a long
double. The actual value passed will be
1.414213538169861
and not
1.41421356237309504
as it should be in long double precision.
I hope I did not forget some obscure rule in this. Please
if you think about some problems with this optimization
just answer.
I think you've identified the main issue, which is that two
roundings don't always give the same result as one. But there
are so few guarantees about the accuracy of floating-point results
in C that you can probably get away with the slight sloppiness.
If there's a compiler option to disable the fudging, that might
help keep the numericists happy.

Are you doing anything with pow(any, integer)? Changing
pow(x, 2.0) into x*x, that sort of thing?
The functions supported are most of the functions in math.h
(sqrt acos sin/cos) etc.

Later I will add strlen of constant strings. (strlen("hello"))

What other functions would you add?
If you can get hold of a "representative" collection of programs
and profile them, you may be able to get better guidance on what's
worth optimizing than just by asking around. For example, do you
have reason to believe that some programs evaluate sqrt(2.0) often
enough that replacing it with 1.414... would be a big help?

--
Er*********@sun.com

Oct 20 '08 #3

P: n/a


jacob navia wrote:
I hope I did not forget some obscure rule in this. Please
if you think about some problems with this optimization
just answer.
There are two potential problems with this.
1) How do you make sure the internal calculation will be the
same as what would have happened from an actual library
call.

2) What happens if someone uses their own library and it
produces a different result from your internal calculation
or redefines the function completely
w..
Oct 20 '08 #4

P: n/a
jacob navia <ja***@nospam.comwrites:
Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.
What will sqrt(-1.0) do?

Oct 20 '08 #5

P: n/a
Nate Eldredge wrote:
jacob navia <ja***@nospam.comwrites:
Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.

What will sqrt(-1.0) do?
What would you imagine?


Brian
Oct 20 '08 #6

P: n/a
On Oct 20, 9:00 pm, Walter Banks <wal...@bytecraft.comwrote:
jacob navia wrote:
I hope I did not forget some obscure rule in this. Please
if you think about some problems with this optimization
just answer.

There are two potential problems with this.
<snip>
2) What happens if someone uses their own library and it
produces a different result from your internal calculation
or redefines the function completely
If the library is conforming, it should be the same result as I
understand it.
Also, if he redefines the function, he's invoking undefined behavior
and anything can happend. ;-)
Oct 20 '08 #7

P: n/a
Walter Banks wrote:
>
jacob navia wrote:
>I hope I did not forget some obscure rule in this. Please
if you think about some problems with this optimization
just answer.

There are two potential problems with this.
1) How do you make sure the internal calculation will be the
same as what would have happened from an actual library
call.

2) What happens if someone uses their own library and it
produces a different result from your internal calculation
or redefines the function completely
These optimisations are already common.

--
Ian Collins
Oct 20 '08 #8

P: n/a
In any sane implementation, the sqrt functions will produce correctly
rounded results for any input value. An implementation not doing this
is not IEEE 754 conforming and will be considered broken by most
people. The double precision variant is broken. I think the first
number that demonstrates the brokenness is x = (1 + 3 * 2^-52), where
the correct result is 1 + 1 * 2^-52; your code would get the incorrect
result 1 + 2 * 2^-52.

And in any remotely sane implementation, the result of a function call
would not depend on whether the compiler realized that it can
determine the value of an argument or not. For example, if I write

inline double f (double x) { return sqrt (2.0 * x); }

the result of f (1.0) should never depend on how clever the compiler
is, and whether it figures out that the argument is 2.0 or not.
Oct 20 '08 #9

P: n/a
"Default User" <de***********@yahoo.comwrites:
Nate Eldredge wrote:
>jacob navia <ja***@nospam.comwrites:
Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.

What will sqrt(-1.0) do?

What would you imagine?
Well, by my reading of 7.12 (9) and 7.12.7.5 (2), it should either set
errno to EDOM or raise a floating-point exception, or both, depending on
the value of math_errhandling.

Incidentally, where in the standard is "floating-point exception"
defined, and is it stated exactly what happens when a floating-point
exception is raised? A natural assumption would be that it raises the
signal SIGFPE but I can't find that explicitly stated.
Oct 20 '08 #10

P: n/a
On Oct 20, 7:00*pm, Walter Banks <wal...@bytecraft.comwrote:
2) What happens if someone uses their own library and it
* * *produces a different result from your internal calculation
* * or redefines the function completely
If the right standard header file <math.his included, then I think
the compiler can assume that sqrt () is the actual standard library
function, and if the programmer replaces it with something else, it's
their own fault. If the programmer just adds a declaration himself
like

#include <stdio.h>
int main (void)
{
extern double sqrt (double x);
printf ("7.3f\n", sqrt (2.0));
}

without including <math.h>, then the compiler cannot do this
optimisation.
Oct 20 '08 #11

P: n/a
Nate Eldredge wrote:
"Default User" <de***********@yahoo.comwrites:
Nate Eldredge wrote:
What will sqrt(-1.0) do?
What would you imagine?

Well, by my reading of 7.12 (9) and 7.12.7.5 (2)
You aren't much fun.


Brian
Oct 20 '08 #12

P: n/a
Eric Sosman wrote:
Are you doing anything with pow(any, integer)? Changing
pow(x, 2.0) into x*x, that sort of thing?
When the second argument is an integer I call ipow.
I did not think about that specific optimization. Thanks.
>The functions supported are most of the functions in math.h
(sqrt acos sin/cos) etc.

Later I will add strlen of constant strings. (strlen("hello"))

What other functions would you add?

If you can get hold of a "representative" collection of programs
and profile them, you may be able to get better guidance on what's
worth optimizing than just by asking around. For example, do you
have reason to believe that some programs evaluate sqrt(2.0) often
enough that replacing it with 1.414... would be a big help?

Well it can be more complicated than that...

When I extend constant folding into doubles (I do now
only integers constant folding) I will be able
to use this too, enhancing constant folding across
function calls.
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Oct 20 '08 #13

P: n/a
christian.bau wrote:
On Oct 20, 7:00�pm, Walter Banks <wal...@bytecraft.comwrote:
2) What happens if someone uses their own library and it
� � �produces a different result from your internal calculation
� � or redefines the function completely

If the right standard header file <math.his included, then I think
the compiler can assume that sqrt () is the actual standard library
function, and if the programmer replaces it with something else, it's
their own fault. If the programmer just adds a declaration himself
like

#include <stdio.h>
int main (void)
{
extern double sqrt (double x);
printf ("7.3f\n", sqrt (2.0));
}

without including <math.h>, then the compiler cannot do this
optimisation.
I don't follow that - what difference does it make how the identifier
'sqrt' is declared? sqrt is an identifier with external linkage
declared in a standard header. According to 7.3.1p1, "All identifiers
with external linkage in any of the following subclauses (including
the future library directions) are always reserved for use as
identifiers with external linkage), so no such declaration can refer
to a user-defined alternative function, whether it's declared in
<math.hor in the user code.
Oct 20 '08 #14

P: n/a
Walter Banks wrote:
>
jacob navia wrote:
>I hope I did not forget some obscure rule in this. Please
if you think about some problems with this optimization
just answer.

There are two potential problems with this.
1) How do you make sure the internal calculation will be the
same as what would have happened from an actual library
call.
I call the library routine within the compiler, albeit
with more precision than necessary.

2) What happens if someone uses their own library and it
produces a different result from your internal calculation
or redefines the function completely
In that case I screw it... I just did not think about that
possibility.

I will test if math.h is included. Thanks.
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Oct 20 '08 #15

P: n/a
Nate Eldredge wrote:
jacob navia <ja***@nospam.comwrites:
>Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.

What will sqrt(-1.0) do?
Store a NAN.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Oct 20 '08 #16

P: n/a
jacob navia <ja***@nospam.comwrites:
Nate Eldredge wrote:
>jacob navia <ja***@nospam.comwrites:
>>Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.

What will sqrt(-1.0) do?

Store a NAN.
I'm not sure that's conforming. See my post <86************@vulcan.lan>.

Oct 20 '08 #17

P: n/a
christian.bau wrote:
In any sane implementation, the sqrt functions will produce correctly
rounded results for any input value. An implementation not doing this
is not IEEE 754 conforming and will be considered broken by most
people. The double precision variant is broken. I think the first
number that demonstrates the brokenness is x = (1 + 3 * 2^-52), where
the correct result is 1 + 1 * 2^-52; your code would get the incorrect
result 1 + 2 * 2^-52.
I obtain 1.0 as the result at compile time.

The following code
#include <math.h>
int main(void)
{
double ld = sqrt(1+3*0.00000000000000022204460492503130808);
double ld1 = 1;

ld1 += 3*0.00000000000000022204460492503130808;
ld1 = sqrt(ld1);

if (ld == ld1)
printf("OK\n");
else
printf("%30.16f\n",ld-ld1);
}

prints

OK.

And in any remotely sane implementation, the result of a function call
would not depend on whether the compiler realized that it can
determine the value of an argument or not. For example, if I write

inline double f (double x) { return sqrt (2.0 * x); }

the result of f (1.0) should never depend on how clever the compiler
is, and whether it figures out that the argument is 2.0 or not.
Well, I do not see any differences...

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Oct 20 '08 #18

P: n/a
ja*********@verizon.net wrote:
christian.bau wrote:
>On Oct 20, 7:00�pm, Walter Banks <wal...@bytecraft.comwrote:
>>2) What happens if someone uses their own library and it
� � �produces a different result from your internal calculation
� � or redefines the function completely
If the right standard header file <math.his included, then I think
the compiler can assume that sqrt () is the actual standard library
function, and if the programmer replaces it with something else, it's
their own fault. If the programmer just adds a declaration himself
like

#include <stdio.h>
int main (void)
{
extern double sqrt (double x);
printf ("7.3f\n", sqrt (2.0));
}

without including <math.h>, then the compiler cannot do this
optimisation.

I don't follow that - what difference does it make how the identifier
'sqrt' is declared? sqrt is an identifier with external linkage
declared in a standard header. According to 7.3.1p1, "All identifiers
with external linkage in any of the following subclauses (including
the future library directions) are always reserved for use as
identifiers with external linkage), so no such declaration can refer
to a user-defined alternative function, whether it's declared in
<math.hor in the user code.
WOW!!!

THANKS A LOT!

That will simplify things a lot!

:-)
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Oct 20 '08 #19

P: n/a
Walter Banks wrote, On 20/10/08 19:00:
>
jacob navia wrote:
>I hope I did not forget some obscure rule in this. Please
if you think about some problems with this optimization
just answer.

There are two potential problems with this.

1) How do you make sure the internal calculation will be the
same as what would have happened from an actual library
call.
I don't think there is any requirement for the functions to be stable.
2) What happens if someone uses their own library and it
produces a different result from your internal calculation
or redefines the function completely
This is only relevant if they do not include math.h either directly or
indirectly *and* their function is declared static. Otherwise they have
invoked undefined behaviour and it is not Jacob's problem and his
compiler can do whatever is most convenient for Jacob.

Jacob, can I suggest that one possibly simple way to deal with this
issue would be to implement a pragma to enable this optimisation and
then set the pragma in your math.h? Maybe with a switch that causes the
pragma to be ignored. Just ensure that the following program works (I
have no reason to suppose it won't) and you have probably avoided the
traps...

#include <stdio.h>

static void sqrt(void)
{
puts("sqrt overridden");
}
static float sqrtf(float f)
{
puts("sqrtf overridden");
return 0;
}
int main(void)
{
float f=sqrtf(2);
sqrt();
printf("f=%f\n",f);
return 0;
}

Please note this is *not* a complaint and I have absolutely no reason to
suspect you currently get this wrong. It is simply a suggestion of a
test for you new optimisation.

I have seen code (written in Pascal rather than C) which would have
benefited by this type of optimisation, so it could certainly be useful
for some people. Especially useful if the it interacts in all possible
ways with constant propagation so something like...
double d1 = complex_but_constant_expression;
double d2 = sqrt(d1/2);
double d3 = 3*d2;
gives d3 getting assigned a constant value.

Of course, what I've just suggested for the optimisation could make it
far harder for you, so by all means feel free to ignore this suggestion.
It is your product and your time, not mine, and I am not part of your
target audience for the compiler.
--
Flash Gordon
If spamming me sent it to sm**@spam.causeway.com
If emailing me use my reply-to address
See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/
Oct 20 '08 #20

P: n/a
jacob navia wrote, On 20/10/08 19:58:
Walter Banks wrote:
<snip>
>2) What happens if someone uses their own library and it
produces a different result from your internal calculation
or redefines the function completely

In that case I screw it... I just did not think about that
possibility.

I will test if math.h is included. Thanks.
See other messages in this thread. Walter's example invokes undefined
behaviour so *anything* your compiler does with it is valid. However,
testing if math.h is included might be the easiest way to deal with the
obscure and deliberately nit-picking example I posted.
--
Flash Gordon
If spamming me sent it to sm**@spam.causeway.com
If emailing me use my reply-to address
See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/
Oct 20 '08 #21

P: n/a
jacob navia wrote:
ja*********@verizon.net wrote:
>christian.bau wrote:
>>On Oct 20, 7:00�pm, Walter Banks <wal...@bytecraft.comwrote:

2) What happens if someone uses their own library and it
� � �produces a different result from your internal calculation
� � or redefines the function completely
If the right standard header file <math.his included, then I think
the compiler can assume that sqrt () is the actual standard library
function, and if the programmer replaces it with something else, it's
their own fault. If the programmer just adds a declaration himself
like

#include <stdio.h>
int main (void)
{
extern double sqrt (double x);
printf ("7.3f\n", sqrt (2.0));
}

without including <math.h>, then the compiler cannot do this
optimisation.

I don't follow that - what difference does it make how the identifier
'sqrt' is declared? sqrt is an identifier with external linkage
declared in a standard header. According to 7.3.1p1, "All identifiers
with external linkage in any of the following subclauses (including
the future library directions) are always reserved for use as
identifiers with external linkage), so no such declaration can refer
to a user-defined alternative function, whether it's declared in
<math.hor in the user code.

WOW!!!

THANKS A LOT!

That will simplify things a lot!
If that's sarcasm, never mind. But just in case:

James Kuyper is correct in saying that the Standard does not
define what happens when the program tries to co-opt a reserved
identifier. However, some implementations do in fact permit some
or all of their components to be replaced by program code, within
limits, and many programmers have found it useful to do so. Look
at the dozens of malloc() variants floating around, for example.

So: lcc is not *obliged* to allow the programmer to supply his
own sqrt(). But if lcc has done so in the past, it may well be that
someone has taken advantage of the opportunity. Those who have will
be unlikely to approve of changes that take away what they perceive
as their freedom.

(Personal note: Yes, I've overridden an implementation's sqrt()
function. The vendor's sqrt() had a teeny-tiny bug: It crashed as
soon as it was called ... The fact that I could replace sqrt() made
the difference between a C implementation I could use and one that I
couldn't, a fairly big swing in the all-important QoI index.)

--
Er*********@sun.com
Oct 20 '08 #22

P: n/a
jacob navia <ja***@nospam.comwrites:
WOW!!!

THANKS A LOT!

That will simplify things a lot!

:-)
You still have to pay attention to static.

Yours,

--
Jean-Marc
Oct 20 '08 #23

P: n/a
On Mon, 20 Oct 2008 11:42:13 -0700, Nate Eldredge wrote:
Incidentally, where in the standard is "floating-point exception"
defined, and is it stated exactly what happens when a floating-point
exception is raised? A natural assumption would be that it raises the
signal SIGFPE but I can't find that explicitly stated.
7.6p1:
"A /floating-point status flag/ is a system variable whose value is set
(but never cleared) when a /floating-point exception/ is raised, which
occurs as a side effect of exceptional floating-point arithmetic to
provide auxiliary information."

Floating-point exception is in italics, meaning this is the definition of
the term, from which you can conclude that when a fp exception is raised,
the only thing that happens is a status flag is set.

Raising SIGFPE cannot be done by a conforming implementation (ignoring
calls to raise) unless the behaviour is already outside the scope of the
standard, in which case there is no requirement to raise SIGFPE.

("Warning: The posting profile's server doesn't carry newsgroup
"comp.compilers.lcc"." I've simply dropped it.)
Oct 20 '08 #24

P: n/a
jacob navia wrote, On 20/10/08 20:13:
ja*********@verizon.net wrote:
>christian.bau wrote:
>>On Oct 20, 7:00�pm, Walter Banks <wal...@bytecraft.comwrote:

2) What happens if someone uses their own library and it
� � �produces a different result from your internal calculation
� � or redefines the function completely
If the right standard header file <math.his included, then I think
the compiler can assume that sqrt () is the actual standard library
function, and if the programmer replaces it with something else, it's
their own fault. If the programmer just adds a declaration himself
like

#include <stdio.h>
int main (void)
{
extern double sqrt (double x);
printf ("7.3f\n", sqrt (2.0));
}

without including <math.h>, then the compiler cannot do this
optimisation.

I don't follow that - what difference does it make how the identifier
'sqrt' is declared? sqrt is an identifier with external linkage
declared in a standard header. According to 7.3.1p1, "All identifiers
with external linkage in any of the following subclauses (including
the future library directions) are always reserved for use as
identifiers with external linkage), so no such declaration can refer
to a user-defined alternative function, whether it's declared in
<math.hor in the user code.

WOW!!!

THANKS A LOT!

That will simplify things a lot!

:-)
That is *precisely* what rules like that were put in the standard for!
However, beware static functions when math.h is not included.
--
Flash Gordon
If spamming me sent it to sm**@spam.causeway.com
If emailing me use my reply-to address
See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/
Oct 20 '08 #25

P: n/a

"Eric Sosman" <Er*********@sun.comwrote in message
For example, do you
have reason to believe that some programs evaluate sqrt(2.0) often
enough that replacing it with 1.414... would be a big help?
root 5 is used in Fibonacci numbers. It's convenient to be able to type it
as sqrt(5).

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 20 '08 #26

P: n/a

"Eric Sosman" <Er*********@sun.comwrote in message
(Personal note: Yes, I've overridden an implementation's sqrt()
function. The vendor's sqrt() had a teeny-tiny bug: It crashed as
soon as it was called ... The fact that I could replace sqrt() made
the difference between a C implementation I could use and one that I
couldn't, a fairly big swing in the all-important QoI index.)
#define sqrt(x) pow(x, 0.5)

should do the trick.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 20 '08 #27

P: n/a
In article <86************@vulcan.lan>, Nate Eldredge <na**@vulcan.lanwrote:
"Default User" <de***********@yahoo.comwrites:
Nate Eldredge wrote:
jacob navia <ja***@nospam.comwrites:

Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.

What will sqrt(-1.0) do?
What would you imagine?

Well, by my reading of 7.12 (9) and 7.12.7.5 (2), it should either set
errno to EDOM or raise a floating-point exception, or both, depending on
the value of math_errhandling.

Incidentally, where in the standard is "floating-point exception"
defined, and is it stated exactly what happens when a floating-point
exception is raised? A natural assumption would be that it raises the
signal SIGFPE but I can't find that explicitly stated.
Whoosh!
Oct 20 '08 #28

P: n/a
bl********@gishpuppy.com (blargg) writes:
In article <86************@vulcan.lan>, Nate Eldredge <na**@vulcan.lanwrote:
>"Default User" <de***********@yahoo.comwrites:
Nate Eldredge wrote:

jacob navia <ja***@nospam.comwrites:

Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.

What will sqrt(-1.0) do?

What would you imagine?

Well, by my reading of 7.12 (9) and 7.12.7.5 (2), it should either set
errno to EDOM or raise a floating-point exception, or both, depending on
the value of math_errhandling.

Incidentally, where in the standard is "floating-point exception"
defined, and is it stated exactly what happens when a floating-point
exception is raised? A natural assumption would be that it raises the
signal SIGFPE but I can't find that explicitly stated.

Whoosh!
Ah, indeed.

Well done, sir. Treat yourself to a richly-deserved defenestration. ;-)
Oct 20 '08 #29

P: n/a
Nate Eldredge wrote:
bl********@gishpuppy.com (blargg) writes:
In article <86************@vulcan.lan>, Nate Eldredge
<na**@vulcan.lanwrote:
"Default User" <de***********@yahoo.comwrites:
What will sqrt(-1.0) do?

What would you imagine?

Well, by my reading of 7.12 (9) and 7.12.7.5 (2)
Whoosh!

Ah, indeed.

Well done, sir. Treat yourself to a richly-deserved defenestration.
;-)
Heyyyy. That was my joke. I deserve the . . . er, never mind.


Brian

Oct 20 '08 #30

P: n/a
"christian.bau" wrote:
Walter Banks <wal...@bytecraft.comwrote:
>2) What happens if someone uses their own library and it
produces a different result from your internal calculation
or redefines the function completely

If the right standard header file <math.his included, then I
think the compiler can assume that sqrt () is the actual
standard library function, and if the programmer replaces it
with something else, it's their own fault. If the programmer
just adds a declaration himself like
Whether or not <math.his included, strictly speaking the function
sqrt() may not be replaced. In practice, most systems will allow
it.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Oct 20 '08 #31

P: n/a
In your first post you claim you do the following steps when you see a
constant argument:

1. Take the constant argument.
2. Convert it to long double (I am assuming you mean 80 bit extended)
3. Calculate the square root (I am assuming you mean an 80 bit
extended square root)
4. Convert the result to double (64 bit)

And with a variable double argument you do this:

1. Take the 64 bit double argument
2. Calculate a 64 bit square root.

In 64 bit double precision, the last bit of a number in the range 1 <=
x < 2 has a value of 2^-52. The square root of (1 + 3 * 2^-52) in the
reals is a tiny bit smaller than 1 + 1.5 * 2^-52. In double precision
arithmetic according to the IEEE 754 Standard, this will be rounded
down to 1 + 1 * 2^-52. If you do the square root calculation in
extended precision, the result will be rounded to 1 + 1.5 * 2^-52, and
when that result is rounded again to double precision, you get 1 +
2^-52. There is no way the result should ever be 1.0.

Possibilities are: Your compiler is clever enough to find that ld1 has
a known value and performs exactly the same optimisation, or it
doesn't figure out that 1 + 3 * ..... is a constant and doesn't
perform the optimisation at all, or you do all calculations in long
double, or you use 64 bit long double, or your description of what the
compiler does is wrong.

Oct 21 '08 #32

P: n/a
Flash Gordon <sm**@spam.causeway.comwrites:
something like...
double d1 = complex_but_constant_expression;
To help avoid misunderstandings it might be best to use the phrase
"non-trivial" in place of "complex" when that is the meaning you
intend (as I believe it is here) as "complex" has another meaning
which is also relevant in this specific context.

mlp
Oct 21 '08 #33

P: n/a
On Oct 20, 12:19*pm, jacob navia <ja...@nospam.comwrote:
Hi

I am adding an optimization to lcc-win:

sqrt(2.0) will provoke now that the constant 1.4142... etc will be
generated instead of generating an actual call.

Details:
-------

The compiler does all calculation in the highest precision
available (long double), and then transforms the result into
the (maybe) lower precision as required.

For instance:
* * * * float f = sqrtf(2.0f);

The compiler transforms the input constant in a long double
precision constant, then transforms the result into a float
constant.

This code:
* * * * long double ld = sqrt(2.0f);

will provoke a call to sqrt(2.0f) with the 2.0 transformed
into a long double from a float constant, then the
result cast again down into a float from a double, then
cast up again to do the assignment of a float into a long
double. The actual value passed will be
1.414213538169861
and not
1.41421356237309504
as it should be in long double precision.

I hope I did not forget some obscure rule in this. Please
if you think about some problems with this optimization
just answer.

The functions supported are most of the functions in math.h
(sqrt acos sin/cos) etc.

Later I will add strlen of constant strings. (strlen("hello"))

What other functions would you add?

Thanks in advance for your attention.

That sort of optimization can be pretty straight-forward if you do
link time code generation. If the functions are in C, constant
propagation/evaluation will naturally reduce sqrt(2) to a constant.
Even if you have the functions implemented in assembler, if you can
tag their object in a recognizable way (perhaps a switch in
the .drectve section*) they can be evaluated during the code
generation step.
*youre using PE, right?
Oct 21 '08 #34

P: n/a
On Oct 20, 3:39*pm, Eric Sosman <Eric.Sos...@sun.comwrote:
...
* * *(Personal note: Yes, I've overridden an implementation's sqrt()
For the record I've had to do it with vendor qsort() as well (crashing
bug - crash on entry iirc).

--T
Oct 23 '08 #35

This discussion thread is closed

Replies have been disabled for this discussion.