From 8d7e60ed79bad7635b85547c9299f80cc8bbde19 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 13 Apr 2017 14:34:59 -0400 Subject: [PATCH 05/10] FIXME: more test coverage --- gcc/testsuite/gcc.dg/heap-optimization.c | 180 +++++++++++++++++++++++++++++-- 1 file changed, 172 insertions(+), 8 deletions(-) diff --git a/gcc/testsuite/gcc.dg/heap-optimization.c b/gcc/testsuite/gcc.dg/heap-optimization.c index c9f8a03..9c4feea 100644 --- a/gcc/testsuite/gcc.dg/heap-optimization.c +++ b/gcc/testsuite/gcc.dg/heap-optimization.c @@ -3,7 +3,6 @@ #include -#if 1 typedef unsigned int edit_distance_t; #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) @@ -52,9 +51,7 @@ levenshtein_distance (const char *s, int len_s, free(v1); return result; } -#endif -#if 1 /* This already gets optimized well. fre1 turns: @@ -87,11 +84,50 @@ int unboxing (int x, int y) return result; } +/* As above, but for alloca, rather than malloc; optimized in same way. */ + +int unboxing_alloca (int x, int y) +{ + int *ptr_a, *ptr_b; + int result; + + ptr_a = alloca (sizeof(int)); + *ptr_a = x; + + ptr_b = alloca (sizeof(int)); + *ptr_b = y; + + result = *ptr_a + *ptr_b; + + return result; +} + +/* As above, but with a struct wrapper; optimized in the same way. */ + +struct boxed_int +{ + int value; +}; + +int unboxing_struct (int x, int y) +{ + struct boxed_int *ptr_a, *ptr_b; + int result; + + ptr_a = alloca (sizeof (struct boxed_int)); + ptr_a->value = x; + ptr_b = alloca (sizeof (struct boxed_int)); + ptr_b->value = y; + + result = ptr_a->value + ptr_b->value; + + return result; +} + /* PR tree-optimization/21046. */ extern void foo (char *p, int i); -#if 0 void hoist_alloc_1 (void) { char *p; @@ -117,7 +153,6 @@ void hoist_alloc_2 (void) free (p); } } -#endif /* PR middle-end/53082. */ @@ -144,9 +179,7 @@ void test_combined (void) free(s1); free(s2); free(s3); } } -#endif -#if 1 // objinst.c /* -*- mode: c -*- @@ -255,4 +288,135 @@ int main(int argc, char *argv[]) { } return 0; } -#endif + +enum kind { KIND_INT, KIND_FLOAT }; + +typedef struct value +{ + enum kind kind; + union { + int u_int; + float u_float; + } u; +} value; + +value *value_new_int (int i) +{ + value *v = malloc (sizeof (value)); + v->kind = KIND_INT; + v->u.u_int = i; + return v; +} + +value *value_new_float (float f) +{ + value *v = malloc (sizeof (value)); + v->kind = KIND_FLOAT; + v->u.u_float = f; + return v; +} + +void value_free (value *v) +{ + free (v); +} + +int value_as_int (value *v_in) +{ + switch (v_in->kind) + { + case KIND_INT: + return v_in->u.u_int; + case KIND_FLOAT: + return v_in->u.u_float; + } +} + +float value_as_float (value *v_in) +{ + switch (v_in->kind) + { + case KIND_INT: + return v_in->u.u_int; + case KIND_FLOAT: + return v_in->u.u_float; + } +} + +value *times_two (value *v_in) +{ + switch (v_in->kind) + { + case KIND_INT: + return value_new_int (v_in->u.u_int * 2); + case KIND_FLOAT: + return value_new_float (v_in->u.u_float * 2.); + } +} + +value *value_sub (value *v_x, value *v_y) +{ + switch (v_x->kind) + { + case KIND_INT: + return value_new_int (v_x->u.u_int - value_as_int (v_y)); + case KIND_FLOAT: + return value_new_float (v_x->u.u_float - value_as_float (v_y)); + } +} + +value *value_mult (value *v_x, value *v_y) +{ + switch (v_x->kind) + { + case KIND_INT: + return value_new_int (v_x->u.u_int * value_as_int (v_y)); + case KIND_FLOAT: + return value_new_float (v_x->u.u_float * value_as_float (v_y)); + } +} + +int dynamic_times_two (int i) +{ + value *v = value_new_int (i); + value *d = times_two (v); + int result = d->u.u_int; + free (d); + free (v); + return result; +} + +value *dynamic_discriminant (value *a, value *b, value *c) +{ + /* b^2 - 4 * a * c */ + value *b_squared = value_mult (b, b); + value *const_4 = value_new_float (4.); + value *four_a = value_mult (const_4, a); + value *four_a_c = value_mult (four_a, c); + value *diff = value_sub (b_squared, four_a_c); + + value_free (b_squared); + value_free (const_4); + value_free (four_a); + value_free (four_a_c); + + return diff; +} + +float discriminant (float a, float b, float c) +{ + value *v_a = value_new_float (a); + value *v_b = value_new_float (b); + value *v_c = value_new_float (c); + + value *v_result = dynamic_discriminant (v_a, v_b, v_c); + + float result = value_as_float (v_result); + + value_free (v_a); + value_free (v_b); + value_free (v_c); + value_free (v_result); + + return result; +} -- 1.8.5.3