diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/Makefile.am | 2 | ||||
-rw-r--r-- | src/util/Makefile.sources | 2 | ||||
-rw-r--r-- | src/util/SConscript | 7 | ||||
-rw-r--r-- | src/util/macros.h | 26 | ||||
-rw-r--r-- | src/util/register_allocate.c | 56 | ||||
-rw-r--r-- | src/util/rounding.h | 54 | ||||
-rw-r--r-- | src/util/strtod.c (renamed from src/util/strtod.cpp) | 22 | ||||
-rw-r--r-- | src/util/strtod.h | 6 |
8 files changed, 141 insertions, 34 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 2e7542e4245..1e087b40d38 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -46,9 +46,9 @@ libmesautil_la_SOURCES = \ if ENABLE_SHADER_CACHE libmesautil_la_SOURCES += $(MESA_UTIL_SHADER_CACHE_FILES) -endif libmesautil_la_LIBADD = $(SHA1_LIBS) +endif roundeven_test_LDADD = -lm diff --git a/src/util/Makefile.sources b/src/util/Makefile.sources index dc559391823..82df3bcb00a 100644 --- a/src/util/Makefile.sources +++ b/src/util/Makefile.sources @@ -19,7 +19,7 @@ MESA_UTIL_FILES := \ set.c \ set.h \ simple_list.h \ - strtod.cpp \ + strtod.c \ strtod.h \ texcompress_rgtc_tmp.h \ u_atomic.h diff --git a/src/util/SConscript b/src/util/SConscript index 9e4d481f838..3dbe70a2e8a 100644 --- a/src/util/SConscript +++ b/src/util/SConscript @@ -54,3 +54,10 @@ u_atomic_test = env.Program( ) alias = env.Alias("u_atomic_test", u_atomic_test, u_atomic_test[0].abspath) AlwaysBuild(alias) + +roundeven_test = env.Program( + target = 'roundeven_test', + source = ['roundeven_test.c'], +) +alias = env.Alias("roundeven_test", roundeven_test, roundeven_test[0].abspath) +AlwaysBuild(alias) diff --git a/src/util/macros.h b/src/util/macros.h index 3b708ed6aa2..84e4f182bcf 100644 --- a/src/util/macros.h +++ b/src/util/macros.h @@ -103,6 +103,17 @@ do { \ #define assume(expr) assert(expr) #endif +/* Attribute const is used for functions that have no effects other than their + * return value, and only rely on the argument values to compute the return + * value. As a result, calls to it can be CSEed. Note that using memory + * pointed to by the arguments is not allowed for const functions. + */ +#ifdef HAVE_FUNC_ATTRIBUTE_CONST +#define ATTRIBUTE_CONST __attribute__((__const__)) +#else +#define ATTRIBUTE_CONST +#endif + #ifdef HAVE_FUNC_ATTRIBUTE_FLATTEN #define FLATTEN __attribute__((__flatten__)) #else @@ -130,6 +141,15 @@ do { \ #define PACKED #endif +/* Attribute pure is used for functions that have no effects other than their + * return value. As a result, calls to it can be dead code eliminated. + */ +#ifdef HAVE_FUNC_ATTRIBUTE_PURE +#define ATTRIBUTE_PURE __attribute__((__pure__)) +#else +#define ATTRIBUTE_PURE +#endif + #ifdef __cplusplus /** * Macro function that evaluates to true if T is a trivially @@ -182,6 +202,12 @@ do { \ #define UNUSED #endif +#ifdef HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT +#define MUST_CHECK __attribute__((warn_unused_result)) +#else +#define MUST_CHECK +#endif + /** Compute ceiling of integer quotient of A divided by B. */ #define DIV_ROUND_UP( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) diff --git a/src/util/register_allocate.c b/src/util/register_allocate.c index 2ad8c3ce11a..436e008b01a 100644 --- a/src/util/register_allocate.c +++ b/src/util/register_allocate.c @@ -321,33 +321,37 @@ ra_set_finalize(struct ra_regs *regs, unsigned int **q_values) regs->classes[b]->q[c] = q_values[b][c]; } } - return; + } else { + /* Compute, for each class B and C, how many regs of B an + * allocation to C could conflict with. + */ + for (b = 0; b < regs->class_count; b++) { + for (c = 0; c < regs->class_count; c++) { + unsigned int rc; + int max_conflicts = 0; + + for (rc = 0; rc < regs->count; rc++) { + int conflicts = 0; + unsigned int i; + + if (!reg_belongs_to_class(rc, regs->classes[c])) + continue; + + for (i = 0; i < regs->regs[rc].num_conflicts; i++) { + unsigned int rb = regs->regs[rc].conflict_list[i]; + if (reg_belongs_to_class(rb, regs->classes[b])) + conflicts++; + } + max_conflicts = MAX2(max_conflicts, conflicts); + } + regs->classes[b]->q[c] = max_conflicts; + } + } } - /* Compute, for each class B and C, how many regs of B an - * allocation to C could conflict with. - */ - for (b = 0; b < regs->class_count; b++) { - for (c = 0; c < regs->class_count; c++) { - unsigned int rc; - int max_conflicts = 0; - - for (rc = 0; rc < regs->count; rc++) { - int conflicts = 0; - unsigned int i; - - if (!reg_belongs_to_class(rc, regs->classes[c])) - continue; - - for (i = 0; i < regs->regs[rc].num_conflicts; i++) { - unsigned int rb = regs->regs[rc].conflict_list[i]; - if (reg_belongs_to_class(rb, regs->classes[b])) - conflicts++; - } - max_conflicts = MAX2(max_conflicts, conflicts); - } - regs->classes[b]->q[c] = max_conflicts; - } + for (b = 0; b < regs->count; b++) { + ralloc_free(regs->regs[b].conflict_list); + regs->regs[b].conflict_list = NULL; } } @@ -648,7 +652,7 @@ ra_get_best_spill_node(struct ra_graph *g) float cost = g->nodes[n].spill_cost; float benefit; - if (cost <= 0.0) + if (cost <= 0.0f) continue; if (g->nodes[n].in_stack) diff --git a/src/util/rounding.h b/src/util/rounding.h index 0cbe9269f7b..7b5608b8a78 100644 --- a/src/util/rounding.h +++ b/src/util/rounding.h @@ -21,7 +21,19 @@ * IN THE SOFTWARE. */ +#ifndef _ROUNDING_H +#define _ROUNDING_H + +#include "c99_compat.h" // inline + #include <math.h> +#include <limits.h> +#include <stdint.h> + +#ifdef __x86_64__ +#include <xmmintrin.h> +#include <emmintrin.h> +#endif #ifdef __SSE4_1__ #include <smmintrin.h> @@ -76,3 +88,45 @@ _mesa_roundeven(double x) return rint(x); #endif } + +/** + * \brief Rounds \c x to the nearest integer, with ties to the even integer, + * and returns the value as a long int. + */ +static inline long +_mesa_lroundevenf(float x) +{ +#ifdef __x86_64__ +#if LONG_MAX == INT64_MAX + return _mm_cvtss_si64(_mm_load_ss(&x)); +#elif LONG_MAX == INT32_MAX + return _mm_cvtss_si32(_mm_load_ss(&x)); +#else +#error "Unsupported long size" +#endif +#else + return lrintf(x); +#endif +} + +/** + * \brief Rounds \c x to the nearest integer, with ties to the even integer, + * and returns the value as a long int. + */ +static inline long +_mesa_lroundeven(double x) +{ +#ifdef __x86_64__ +#if LONG_MAX == INT64_MAX + return _mm_cvtsd_si64(_mm_load_sd(&x)); +#elif LONG_MAX == INT32_MAX + return _mm_cvtsd_si32(_mm_load_sd(&x)); +#else +#error "Unsupported long size" +#endif +#else + return lrint(x); +#endif +} + +#endif diff --git a/src/util/strtod.cpp b/src/util/strtod.c index 2b4dd982a80..ea7d395e2da 100644 --- a/src/util/strtod.cpp +++ b/src/util/strtod.c @@ -30,18 +30,28 @@ #include <locale.h> #ifdef HAVE_XLOCALE_H #include <xlocale.h> +static locale_t loc; #endif #endif #include "strtod.h" +void +_mesa_locale_init(void) +{ #if defined(_GNU_SOURCE) && defined(HAVE_XLOCALE_H) -static struct locale_initializer { - locale_initializer() { loc = newlocale(LC_CTYPE_MASK, "C", NULL); } - locale_t loc; -} loc_init; + loc = newlocale(LC_CTYPE_MASK, "C", NULL); #endif +} + +void +_mesa_locale_fini(void) +{ +#if defined(_GNU_SOURCE) && defined(HAVE_XLOCALE_H) + freelocale(loc); +#endif +} /** * Wrapper around strtod which uses the "C" locale so the decimal @@ -51,7 +61,7 @@ double _mesa_strtod(const char *s, char **end) { #if defined(_GNU_SOURCE) && defined(HAVE_XLOCALE_H) - return strtod_l(s, end, loc_init.loc); + return strtod_l(s, end, loc); #else return strtod(s, end); #endif @@ -66,7 +76,7 @@ float _mesa_strtof(const char *s, char **end) { #if defined(_GNU_SOURCE) && defined(HAVE_XLOCALE_H) - return strtof_l(s, end, loc_init.loc); + return strtof_l(s, end, loc); #elif defined(HAVE_STRTOF) return strtof(s, end); #else diff --git a/src/util/strtod.h b/src/util/strtod.h index 02c25ddb78f..60e15cfa0eb 100644 --- a/src/util/strtod.h +++ b/src/util/strtod.h @@ -31,6 +31,12 @@ extern "C" { #endif +extern void +_mesa_locale_init(void); + +extern void +_mesa_locale_fini(void); + extern double _mesa_strtod(const char *s, char **end); |