summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/Makefile.am2
-rw-r--r--src/util/Makefile.sources2
-rw-r--r--src/util/SConscript7
-rw-r--r--src/util/macros.h26
-rw-r--r--src/util/register_allocate.c56
-rw-r--r--src/util/rounding.h54
-rw-r--r--src/util/strtod.c (renamed from src/util/strtod.cpp)22
-rw-r--r--src/util/strtod.h6
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);