[CLN-list] Re: optimization and warnings [Was: CLN 1.2.0]
Bruno Haible
bruno at clisp.org
Mon Jan 21 10:46:24 CET 2008
Alexei Sheplyakov wrote:
> I'm not sure if CLN code is safe to compile with plain -O2.
>
> With CXXFLAGS="-m64 -O2 -Wall -march=k8 -finline-limit=2000" I get tons of
> warnings like
>
> ../../include/cln/number.h: In constructor 'cln::cl_number::cl_number(float)':
> ../../include/cln/number.h:238: warning: type-punning to incomplete type might break strict-aliasing rules
> ../../include/cln/number.h: In member function 'cln::cl_number& cln::cl_number::operator=(float)':
> ../../include/cln/number.h:238: warning: type-punning to incomplete type might break strict-aliasing rules
> ../../include/cln/number.h: In constructor 'cln::cl_number::cl_number(double)':
> ../../include/cln/number.h:239: warning: type-punning to incomplete type might break strict-aliasing rules
>
> Just for the record, I use
> g++-4.1 (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21).
Attached is a proposed patch that removes most of the warnings. They cause
two additional instructions to be added to the functions cl_float_to_FF_pointer
and cl_double_to_DF_pointer, but this is worth the gain of being able to
compile cln with -O2 with modern gcc. Richy, ok to apply?
Jörg Arndt wrote:
> (2) no warnings!, I suggest to use
> -W -Wall -Wconversion -Wsign-promo -Wsign-compare -Wunused \
> -Wshadow -Wundef
While I agree that -Wall is generally useful, and -W is sometimes useful,
the others spew too many warnings on perfectly valid code, IMO. Your mileage
might vary, of course.
Bruno
diff -c -3 -r1.202 ChangeLog
*** cln/ChangeLog 19 Jan 2008 20:50:30 -0000 1.202
--- cln/ChangeLog 21 Jan 2008 09:39:05 -0000
***************
*** 1,3 ****
--- 1,30 ----
+ 2007-01-20 Bruno Haible <bruno at clisp.org>
+
+ Avoid some gcc warnings.
+ * autoconf/floatparam.c (flipped_double): Use a union instead of a
+ type-punning cast.
+ * include/cln/number.h (union ffloatjanus, union dfloatjanus): Remove
+ declarations.
+ (cl_float_to_FF_pointer, cl_double_to_DF_pointer): Change argument
+ type.
+ (CL_DEFINE_FLOAT_CONSTRUCTOR, CL_DEFINE_DOUBLE_CONSTRUCTOR): Update.
+ * src/float/dfloat/cl_FF.h (cl_float_to_FF_pointer): Change argument
+ type.
+ (cl_float_to_FF): Remove function.
+ * src/float/ffloat/conv/cl_FF_from_float.cc (FAST_FLOAT): Define.
+ (cl_float_to_FF_pointer): Change argument type.
+ * src/float/dfloat/cl_DF.h (cl_double_to_DF_pointer): Change argument
+ type.
+ (cl_double_to_DF): Remove function.
+ * src/float/dfloat/conv/cl_DF_from_double.cc (FAST_DOUBLE): Define.
+ (cl_double_to_DF_pointer): Change argument type.
+ * src/float/lfloat/cl_LF_impl.h (LF_decode): Mark the mantlen_zuweisung
+ assignment as possibly unused.
+ * src/base/cl_low.h (mulu32): Mark the hi_zuweisung assignment as
+ possibly unused.
+ * src/float/transcendental/cl_LF_zeta_int.cc (compute_zeta_cvz2):
+ Remove unused local variable.
+
2007-01-19 Richard B. Kreckel <kreckel at ginac.de>
* Version 1.2.0 released.
diff -c -3 -r1.3 floatparam.c
*** cln/autoconf/floatparam.c 19 Dec 2006 14:50:43 -0000 1.3
--- cln/autoconf/floatparam.c 21 Jan 2008 09:39:05 -0000
***************
*** 92,99 ****
static void flipped_double (void)
{
typedef struct { unsigned lo, hi; } dfloat;
! double x = 2;
! dfloat test = *(dfloat*)&x;
if (test.lo==0 && test.hi!=0) {
printf("#define double_wordorder_bigendian_p 0\n");
} else if (test.lo!=0 && test.hi==0) {
--- 92,100 ----
static void flipped_double (void)
{
typedef struct { unsigned lo, hi; } dfloat;
! union { dfloat eksplicit; double machine_double; } x;
! x.machine_double = 2;
! dfloat test = x.eksplicit;
if (test.lo==0 && test.hi!=0) {
printf("#define double_wordorder_bigendian_p 0\n");
} else if (test.lo!=0 && test.hi==0) {
diff -c -3 -r1.6 number.h
*** cln/include/cln/number.h 11 Dec 2006 17:31:06 -0000 1.6
--- cln/include/cln/number.h 21 Jan 2008 09:39:06 -0000
***************
*** 146,179 ****
// Constructors and assignment operators from C numeric types.
// from `float':
! union ffloatjanus;
! extern cl_private_thing cl_float_to_FF_pointer (const union ffloatjanus& val);
#define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_) \
inline _class_ :: _class_ (const float x) \
{ \
! pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
} \
inline _class_& _class_::operator= (const float x) \
{ \
cl_dec_refcount(*this); \
! pointer = cl_float_to_FF_pointer(*(const union ffloatjanus *)&x); \
return *this; \
}
// from `double':
! union dfloatjanus;
! extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const union dfloatjanus& val);
#define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_) \
inline _class_::_class_ (const double x) \
{ \
! pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
} \
inline _class_& _class_::operator= (const double x) \
{ \
cl_dec_refcount(*this); \
! pointer = cl_double_to_DF_pointer(*(const union dfloatjanus *)&x); \
return *this; \
}
--- 146,177 ----
// Constructors and assignment operators from C numeric types.
// from `float':
! extern cl_private_thing cl_float_to_FF_pointer (const float val);
#define CL_DEFINE_FLOAT_CONSTRUCTOR(_class_) \
inline _class_ :: _class_ (const float x) \
{ \
! pointer = cl_float_to_FF_pointer(x); \
} \
inline _class_& _class_::operator= (const float x) \
{ \
cl_dec_refcount(*this); \
! pointer = cl_float_to_FF_pointer(x); \
return *this; \
}
// from `double':
! extern struct cl_heap_dfloat * cl_double_to_DF_pointer (const double val);
#define CL_DEFINE_DOUBLE_CONSTRUCTOR(_class_) \
inline _class_::_class_ (const double x) \
{ \
! pointer = cl_double_to_DF_pointer(x); \
} \
inline _class_& _class_::operator= (const double x) \
{ \
cl_dec_refcount(*this); \
! pointer = cl_double_to_DF_pointer(x); \
return *this; \
}
diff -c -3 -r1.14 cl_low.h
*** cln/src/base/cl_low.h 9 Oct 2007 22:26:28 -0000 1.14
--- cln/src/base/cl_low.h 21 Jan 2008 09:39:06 -0000
***************
*** 165,171 ****
var union { double f; uint32 i[2]; uint16 s[4]; } __fi; \
__fi.f = (double)(sint32)(_x)*(double)(sint32)(_y) \
+ (double)(4503599627370496.0L); /* + 2^52, zum Normalisieren */\
! hi_zuweisung __fi.s[1]; /* mittlere 16 Bit herausholen, (benutzt CL_CPU_BIG_ENDIAN_P !) */\
lo_zuweisung __fi.i[1]; /* untere 32 Bit herausholen (benutzt CL_CPU_BIG_ENDIAN_P !) */\
}
#else
--- 165,171 ----
var union { double f; uint32 i[2]; uint16 s[4]; } __fi; \
__fi.f = (double)(sint32)(_x)*(double)(sint32)(_y) \
+ (double)(4503599627370496.0L); /* + 2^52, zum Normalisieren */\
! unused (hi_zuweisung __fi.s[1]); /* mittlere 16 Bit herausholen, (benutzt CL_CPU_BIG_ENDIAN_P !) */\
lo_zuweisung __fi.i[1]; /* untere 32 Bit herausholen (benutzt CL_CPU_BIG_ENDIAN_P !) */\
}
#else
***************
*** 205,217 ****
extern "C" uint32 mulu32_high; // -> High-Teil
#if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
! ({ var uint32 _x = (x); \
! var uint32 _y = (y); \
! var uint32 _hi; \
! var uint32 _lo; \
__asm__("mulul %3,%0:%1" : "=d" (_hi), "=d"(_lo) : "1" (_x), "dm" (_y) ); \
! hi_zuweisung _hi; \
! lo_zuweisung _lo; \
})
#elif defined(__GNUC__) && defined(__m68k__)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
--- 205,217 ----
extern "C" uint32 mulu32_high; // -> High-Teil
#if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
! ({ var uint32 _x = (x); \
! var uint32 _y = (y); \
! var uint32 _hi; \
! var uint32 _lo; \
__asm__("mulul %3,%0:%1" : "=d" (_hi), "=d"(_lo) : "1" (_x), "dm" (_y) ); \
! unused (hi_zuweisung _hi); \
! lo_zuweisung _lo; \
})
#elif defined(__GNUC__) && defined(__m68k__)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
***************
*** 231,237 ****
_hi += high16(_mid); _mid = highlow32_0(low16(_mid)); \
_lo += _mid; if (_lo < _mid) { _hi += 1; } /* 64-Bit-Addition */\
} \
! hi_zuweisung _hi; \
lo_zuweisung _lo; \
})
#elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
--- 231,237 ----
_hi += high16(_mid); _mid = highlow32_0(low16(_mid)); \
_lo += _mid; if (_lo < _mid) { _hi += 1; } /* 64-Bit-Addition */\
} \
! unused (hi_zuweisung _hi); \
lo_zuweisung _lo; \
})
#elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
***************
*** 241,260 ****
: "=r" (_prod) \
: "r" ((uint32)(x)), "r" ((uint32)(y)) \
); \
! hi_zuweisung (uint32)(_prod>>32); \
lo_zuweisung (uint32)(_prod); \
})
#elif defined(__GNUC__) && defined(__sparc__) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
({ lo_zuweisung mulu32_(x,y); /* extern in Assembler */ \
{var register uint32 _hi __asm__("%g1"); \
! hi_zuweisung _hi; \
}})
#elif defined(__GNUC__) && defined(__arm__) && 0 // see comment cl_asm_arm.cc
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
({ lo_zuweisung mulu32_(x,y); /* extern in Assembler */ \
{var register uint32 _hi __asm__("%r1"/*"%a2"*/); \
! hi_zuweisung _hi; \
}})
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
--- 241,260 ----
: "=r" (_prod) \
: "r" ((uint32)(x)), "r" ((uint32)(y)) \
); \
! unused (hi_zuweisung (uint32)(_prod>>32)); \
lo_zuweisung (uint32)(_prod); \
})
#elif defined(__GNUC__) && defined(__sparc__) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
({ lo_zuweisung mulu32_(x,y); /* extern in Assembler */ \
{var register uint32 _hi __asm__("%g1"); \
! unused (hi_zuweisung _hi); \
}})
#elif defined(__GNUC__) && defined(__arm__) && 0 // see comment cl_asm_arm.cc
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
({ lo_zuweisung mulu32_(x,y); /* extern in Assembler */ \
{var register uint32 _hi __asm__("%r1"/*"%a2"*/); \
! unused (hi_zuweisung _hi); \
}})
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
***************
*** 264,270 ****
: "=d" /* %edx */ (_hi), "=a" /* %eax */ (_lo) \
: "g" ((uint32)(x)), "1" /* %eax */ ((uint32)(y)) \
); \
! hi_zuweisung _hi; lo_zuweisung _lo; \
})
#elif defined(__GNUC__) && defined(__mips__) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
--- 264,270 ----
: "=d" /* %edx */ (_hi), "=a" /* %eax */ (_lo) \
: "g" ((uint32)(x)), "1" /* %eax */ ((uint32)(y)) \
); \
! unused (hi_zuweisung _hi); lo_zuweisung _lo; \
})
#elif defined(__GNUC__) && defined(__mips__) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
***************
*** 274,300 ****
: "=r" (_hi), "=r" (_lo) \
: "r" ((uint32)(x)), "r" ((uint32)(y)) \
); \
! hi_zuweisung _hi; lo_zuweisung _lo; \
})
#elif defined(__GNUC__) && defined(HAVE_LONGLONG) && !defined(__arm__)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
({ var register uint64 _prod = (uint64)(uint32)(x) * (uint64)(uint32)(y); \
! hi_zuweisung (uint32)(_prod>>32); \
lo_zuweisung (uint32)(_prod); \
})
#elif defined(WATCOM) && defined(__i386__) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
! { var register uint32 _hi; \
! var register uint32 _lo; \
! _lo = mulu32_(x,y), _hi = mulu32_high_(); \
! hi_zuweisung _hi; lo_zuweisung _lo; \
}
extern "C" uint32 mulu32_high_ (void);
#pragma aux mulu32_ = 0xF7 0xE2 /* mull %edx */ parm [eax] [edx] value [eax] modify [eax edx];
#pragma aux mulu32_high_ = /* */ value [edx] modify [];
#else
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
! { lo_zuweisung mulu32_(x,y); hi_zuweisung mulu32_high; }
#if (defined(__m68k__) || defined(__sparc__) || defined(__sparc64__) || defined(__arm__) || (defined(__i386__) && !defined(WATCOM) && !defined(MICROSOFT)) || defined(__x86_64__) || defined(__mips__) || defined(__hppa__)) && !defined(NO_ASM)
// mulu32_ extern in Assembler
#if defined(__sparc__) || defined(__sparc64__)
--- 274,300 ----
: "=r" (_hi), "=r" (_lo) \
: "r" ((uint32)(x)), "r" ((uint32)(y)) \
); \
! unused (hi_zuweisung _hi); lo_zuweisung _lo; \
})
#elif defined(__GNUC__) && defined(HAVE_LONGLONG) && !defined(__arm__)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
({ var register uint64 _prod = (uint64)(uint32)(x) * (uint64)(uint32)(y); \
! unused (hi_zuweisung (uint32)(_prod>>32)); \
lo_zuweisung (uint32)(_prod); \
})
#elif defined(WATCOM) && defined(__i386__) && !defined(NO_ASM)
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
! { var register uint32 _hi; \
! var register uint32 _lo; \
! _lo = mulu32_(x,y), _hi = mulu32_high_(); \
! unused (hi_zuweisung _hi); lo_zuweisung _lo; \
}
extern "C" uint32 mulu32_high_ (void);
#pragma aux mulu32_ = 0xF7 0xE2 /* mull %edx */ parm [eax] [edx] value [eax] modify [eax edx];
#pragma aux mulu32_high_ = /* */ value [edx] modify [];
#else
#define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
! { lo_zuweisung mulu32_(x,y); unused (hi_zuweisung mulu32_high); }
#if (defined(__m68k__) || defined(__sparc__) || defined(__sparc64__) || defined(__arm__) || (defined(__i386__) && !defined(WATCOM) && !defined(MICROSOFT)) || defined(__x86_64__) || defined(__mips__) || defined(__hppa__)) && !defined(NO_ASM)
// mulu32_ extern in Assembler
#if defined(__sparc__) || defined(__sparc64__)
diff -c -3 -r1.5 cl_DF.h
*** cln/src/float/dfloat/cl_DF.h 15 Sep 2007 21:34:16 -0000 1.5
--- cln/src/float/dfloat/cl_DF.h 21 Jan 2008 09:39:06 -0000
***************
*** 309,318 ****
// e=2047, m=0: vorzeichenbehaftete Infinity
// e=2047, m/=0: NaN
! // cl_double_to_DF(val) wandelt ein IEEE-Double-Float val in ein Double-Float um.
! extern cl_heap_dfloat* cl_double_to_DF_pointer (const dfloatjanus& val);
! inline const cl_DF cl_double_to_DF (const dfloatjanus& val)
! { return cl_double_to_DF_pointer(val); }
// cl_DF_to_double(obj,&val);
// wandelt ein Double-Float obj in ein IEEE-Double-Float val um.
--- 309,316 ----
// e=2047, m=0: vorzeichenbehaftete Infinity
// e=2047, m/=0: NaN
! // cl_double_to_DF_pointer(val) wandelt ein IEEE-Double-Float val in ein Double-Float um.
! extern cl_heap_dfloat* cl_double_to_DF_pointer (const double val);
// cl_DF_to_double(obj,&val);
// wandelt ein Double-Float obj in ein IEEE-Double-Float val um.
diff -c -3 -r1.4 cl_DF_from_double.cc
*** cln/src/float/dfloat/conv/cl_DF_from_double.cc 15 Sep 2007 21:34:16 -0000 1.4
--- cln/src/float/dfloat/conv/cl_DF_from_double.cc 21 Jan 2008 09:39:06 -0000
***************
*** 1,4 ****
! // cl_double_to_FF().
// General includes.
#include "cl_sysdep.h"
--- 1,7 ----
! // cl_double_to_DF_pointer().
!
! // Ensure that union dfloatjanus has a 'double' alternative.
! #define FAST_DOUBLE
// General includes.
#include "cl_sysdep.h"
***************
*** 11,18 ****
namespace cln {
! cl_heap_dfloat* cl_double_to_DF_pointer (const dfloatjanus& val_)
{
var dfloat val = val_.eksplicit;
#if (cl_word_size==64)
var uintL exp = (val >> DF_mant_len) & (bit(DF_exp_len)-1); // e
--- 14,23 ----
namespace cln {
! cl_heap_dfloat* cl_double_to_DF_pointer (const double x)
{
+ var union dfloatjanus val_;
+ val_.machine_double = x;
var dfloat val = val_.eksplicit;
#if (cl_word_size==64)
var uintL exp = (val >> DF_mant_len) & (bit(DF_exp_len)-1); // e
diff -c -3 -r1.4 cl_FF.h
*** cln/src/float/ffloat/cl_FF.h 15 Sep 2007 21:34:16 -0000 1.4
--- cln/src/float/ffloat/cl_FF.h 21 Jan 2008 09:39:06 -0000
***************
*** 237,246 ****
// e=255, m=0: vorzeichenbehaftete Infinity
// e=255, m/=0: NaN
! // cl_float_to_FF(val) wandelt ein IEEE-Single-Float val in ein Single-Float um.
! extern cl_private_thing cl_float_to_FF_pointer (const ffloatjanus& val);
! inline const cl_FF cl_float_to_FF (const ffloatjanus& val)
! { return cl_float_to_FF_pointer(val); }
// cl_FF_to_float(obj,&val);
// wandelt ein Single-Float obj in ein IEEE-Single-Float val um.
--- 237,244 ----
// e=255, m=0: vorzeichenbehaftete Infinity
// e=255, m/=0: NaN
! // cl_float_to_FF_pointer(val) wandelt ein IEEE-Single-Float val in ein Single-Float um.
! extern cl_private_thing cl_float_to_FF_pointer (const float val);
// cl_FF_to_float(obj,&val);
// wandelt ein Single-Float obj in ein IEEE-Single-Float val um.
diff -c -3 -r1.4 cl_FF_from_float.cc
*** cln/src/float/ffloat/conv/cl_FF_from_float.cc 15 Sep 2007 21:34:16 -0000 1.4
--- cln/src/float/ffloat/conv/cl_FF_from_float.cc 21 Jan 2008 09:39:06 -0000
***************
*** 1,4 ****
! // cl_float_to_FF().
// General includes.
#include "cl_sysdep.h"
--- 1,7 ----
! // cl_float_to_FF_pointer().
!
! // Ensure that union ffloatjanus has a 'float' alternative.
! #define FAST_FLOAT
// General includes.
#include "cl_sysdep.h"
***************
*** 10,17 ****
// Implementation.
! cl_private_thing cl_float_to_FF_pointer (const ffloatjanus& val_)
{
var ffloat val = val_.eksplicit;
var uintL exp = (val >> FF_mant_len) & (bit(FF_exp_len)-1); // e
if (exp == 0) // e=0 ?
--- 13,22 ----
// Implementation.
! cl_private_thing cl_float_to_FF_pointer (const float x)
{
+ var union ffloatjanus val_;
+ val_.machine_float = x;
var ffloat val = val_.eksplicit;
var uintL exp = (val >> FF_mant_len) & (bit(FF_exp_len)-1); // e
if (exp == 0) // e=0 ?
diff -c -3 -r1.4 cl_LF_impl.h
*** cln/src/float/lfloat/cl_LF_impl.h 15 Sep 2007 21:34:16 -0000 1.4
--- cln/src/float/lfloat/cl_LF_impl.h 21 Jan 2008 09:39:06 -0000
***************
*** 68,74 ****
{ var Lfloat _x = TheLfloat(obj); \
var uintE uexp = _x->expo; \
if (uexp==0) \
! { mantlen_zuweisung _x->len; zero_statement } /* e=0 -> Zahl 0.0 */\
else \
{ exp_zuweisung (sintE)(uexp - LF_exp_mid); /* Exponent */ \
sign_zuweisung _x->sign; /* Vorzeichen */\
--- 68,74 ----
{ var Lfloat _x = TheLfloat(obj); \
var uintE uexp = _x->expo; \
if (uexp==0) \
! { unused (mantlen_zuweisung _x->len); zero_statement } /* e=0 -> Zahl 0.0 */\
else \
{ exp_zuweisung (sintE)(uexp - LF_exp_mid); /* Exponent */ \
sign_zuweisung _x->sign; /* Vorzeichen */\
diff -c -3 -r1.8 cl_LF_zeta_int.cc
*** cln/src/float/transcendental/cl_LF_zeta_int.cc 11 Jan 2008 16:50:15 -0000 1.8
--- cln/src/float/transcendental/cl_LF_zeta_int.cc 21 Jan 2008 09:39:07 -0000
***************
*** 94,100 ****
// evaluated using the binary splitting algorithm with truncation.
var uintC actuallen = len+2; // 2 guard digits
var uintC N = (uintC)(0.39321985*intDsize*actuallen)+1;
- var uintC n;
struct rational_series_stream : cl_pqd_series_stream {
uintC n;
int s;
--- 94,99 ----
More information about the CLN-list
mailing list