From cc7725b3c4521e7a5116d73b095e0b3bcd5a2215 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Tue, 6 Nov 2007 00:34:56 +0000 Subject: [PATCH] more libc mapper functions added [r16457] --- include/libfirm/lowering.h | 62 ++++++++++++++--- ir/be/test/rtsopt.c | 43 +++++++++++- ir/lower/lower_intrinsics.c | 130 +++++++++++++++++++++++++++++++++--- 3 files changed, 214 insertions(+), 21 deletions(-) diff --git a/include/libfirm/lowering.h b/include/libfirm/lowering.h index 1e0070580..f6f5a3c1d 100644 --- a/include/libfirm/lowering.h +++ b/include/libfirm/lowering.h @@ -278,61 +278,103 @@ typedef union _i_record { unsigned lower_intrinsics(i_record *list, int length, int part_block_used); /** - * A mapper for the integer absolute value: inttype abs(inttype v). + * A mapper for the integer/float absolute value: type abs(type v). * Replaces the call by a Abs node. * * @return always 1 */ -int i_mapper_Abs(ir_node *call, void *ctx); +int i_mapper_abs(ir_node *call, void *ctx); /** * A mapper for the floating point sqrt(v): floattype sqrt(floattype v); * * @return 0 if the sqrt call was removed, 0 else. */ -int i_mapper_Sqrt(ir_node *call, void *ctx); +int i_mapper_sqrt(ir_node *call, void *ctx); /** * A mapper for the floating point pow(a, b): floattype pow(floattype a, floattype b); * * @return 0 if the pow call was removed, 0 else. */ -int i_mapper_Pow(ir_node *call, void *ctx); +int i_mapper_pow(ir_node *call, void *ctx); /** * A mapper for the floating point exp(a): floattype exp(floattype a); * * @return 0 if the exp call was removed, 0 else. */ -int i_mapper_Exp(ir_node *call, void *ctx); +int i_mapper_exp(ir_node *call, void *ctx); + +/** + * A mapper for the floating point sin(a): floattype sin(floattype a); + * + * @return 0 if the sin call was removed, 0 else. + */ +int i_mapper_sin(ir_node *call, void *ctx); + +/** + * A mapper for the floating point sin(a): floattype cos(floattype a); + * + * @return 0 if the cos call was removed, 0 else. + */ +int i_mapper_cos(ir_node *call, void *ctx); + +/** + * A mapper for the floating point tan(a): floattype tan(floattype a); + * + * @return 0 if the tan call was removed, 0 else. + */ +int i_mapper_tan(ir_node *call, void *ctx); + +/** + * A mapper for the floating point asin(a): floattype asin(floattype a); + * + * @return 0 if the asin call was removed, 0 else. + */ +int i_mapper_asin(ir_node *call, void *ctx); + +/** + * A mapper for the floating point acos(a): floattype acos(floattype a); + * + * @return 0 if the tan call was removed, 0 else. + */ +int i_mapper_acos(ir_node *call, void *ctx); + +/** + * A mapper for the floating point atan(a): floattype atan(floattype a); + * + * @return 0 if the atan call was removed, 0 else. + */ +int i_mapper_atan(ir_node *call, void *ctx); /** * A mapper for the strcmp-Function: inttype strcmp(char pointer a, char pointer b); * * @return 0 if the strcmp call was removed, 0 else. */ -int i_mapper_Strcmp(ir_node *call, void *ctx); +int i_mapper_strcmp(ir_node *call, void *ctx); /** * A mapper for the strcmp-Function: inttype strncmp(char pointer a, char pointer b, inttype len); * * @return 0 if the strncmp call was removed, 0 else. */ -int i_mapper_Strncmp(ir_node *call, void *ctx); +int i_mapper_strncmp(ir_node *call, void *ctx); /** * A mapper for the memcpy-Function: void pointer memcpy(void pointer d, void pointer s, inttype c); * * @return 0 if the memcpy call was removed, 0 else. */ -int i_mapper_Memcpy(ir_node *call, void *ctx); +int i_mapper_memcpy(ir_node *call, void *ctx); /** * A mapper for the memset-Function: void pointer memset(void pointer d, inttype C, inttype len); * * @return 0 if the memset call was removed, 0 else. */ -int i_mapper_Memset(ir_node *call, void *ctx); +int i_mapper_memset(ir_node *call, void *ctx); /** * A mapper for the alloca() function: pointer alloca(inttype size) @@ -340,7 +382,7 @@ int i_mapper_Memset(ir_node *call, void *ctx); * * @return always 1 */ -int i_mapper_Alloca(ir_node *call, void *ctx); +int i_mapper_alloca(ir_node *call, void *ctx); /** * A runtime routine description. diff --git a/ir/be/test/rtsopt.c b/ir/be/test/rtsopt.c index 5ee945ad9..22dac297e 100644 --- a/ir/be/test/rtsopt.c +++ b/ir/be/test/rtsopt.c @@ -8,6 +8,11 @@ int test_abs(int a) { return abs(a); } +/* transform into Abs node */ +double test_fabs(double a) { + return fabs(a); +} + /* transform info memcpy(test + strlen(test), "ab", 2), gcc(+), icc(-) */ char *test_strcat(void) { static char test[10] = "ab"; @@ -229,20 +234,52 @@ int test_fwrite3(FILE *f, char *s, int l) { return fwrite(s,1,1,f); } +/* evaluate, gcc(+) */ +double test_sin1(void) { + return sin(0.0); +} + /* transform into cos(x), gcc(+), icc(-) */ -double test_cos(double x) { +double test_cos1(double x) { return cos(-x); } +/* evaluate, gcc(+) */ +double test_cos2(void) { + return cos(0.0); +} + /* transform into cosf(x), gcc(+), icc(-) */ -float test_cosf(float x) { +float test_cosf1(float x) { return cosf(-x); } +#if 0 /* transform into cosl(x), gcc(+), icc(-) */ long double test_cosl(long double x) { return cosl(-x); } +#endif + +/* evaluate, gcc(+) */ +double test_tan1(void) { + return tan(0); +} + +/* evaluate, gcc(-) */ +double test_asin1(void) { + return asin(0.0); +} + +/* evaluate, gcc(-) */ +double test_acos1(void) { + return acos(1.0); +} + +/* evaluate, gcc(+) */ +double test_atans1(void) { + return atan(0.0); +} /* evaluate into 0.0, gcc(+), icc(+) */ double test_sqrt1() { @@ -261,6 +298,8 @@ double test_sqrt3() { /* transform exit(3) into a return 3, gcc(-), icc(-) */ int main() { + printf("%f\n", test_asin1()); + printf("%f\n", test_acos1()); exit(0); return 42; } diff --git a/ir/lower/lower_intrinsics.c b/ir/lower/lower_intrinsics.c index 3dbb13e09..da9ac0484 100644 --- a/ir/lower/lower_intrinsics.c +++ b/ir/lower/lower_intrinsics.c @@ -182,7 +182,7 @@ static void replace_call(ir_node *irn, ir_node *call, ir_node *mem, ir_node *reg } /* A mapper for the integer abs. */ -int i_mapper_Abs(ir_node *call, void *ctx) { +int i_mapper_abs(ir_node *call, void *ctx) { ir_node *mem = get_Call_mem(call); ir_node *block = get_nodes_block(call); ir_node *op = get_Call_param(call, 0); @@ -196,7 +196,7 @@ int i_mapper_Abs(ir_node *call, void *ctx) { } /* A mapper for the alloca() function. */ -int i_mapper_Alloca(ir_node *call, void *ctx) { +int i_mapper_alloca(ir_node *call, void *ctx) { ir_node *mem = get_Call_mem(call); ir_node *block = get_nodes_block(call); ir_node *op = get_Call_param(call, 0); @@ -215,7 +215,7 @@ int i_mapper_Alloca(ir_node *call, void *ctx) { } /* A mapper for the floating point sqrt. */ -int i_mapper_Sqrt(ir_node *call, void *ctx) { +int i_mapper_sqrt(ir_node *call, void *ctx) { ir_node *mem; tarval *tv; ir_node *op = get_Call_param(call, 0); @@ -236,7 +236,7 @@ int i_mapper_Sqrt(ir_node *call, void *ctx) { } /* A mapper for the floating point pow. */ -int i_mapper_Pow(ir_node *call, void *ctx) { +int i_mapper_pow(ir_node *call, void *ctx) { dbg_info *dbg; ir_node *mem; ir_node *left = get_Call_param(call, 0); @@ -285,7 +285,7 @@ int i_mapper_Pow(ir_node *call, void *ctx) { } /* A mapper for the floating point exp. */ -int i_mapper_Exp(ir_node *call, void *ctx) { +int i_mapper_exp(ir_node *call, void *ctx) { ir_node *val = get_Call_param(call, 0); (void) ctx; @@ -301,8 +301,120 @@ int i_mapper_Exp(ir_node *call, void *ctx) { return 0; } +/* A mapper for the floating point sin. */ +int i_mapper_sin(ir_node *call, void *ctx) { + ir_node *val = get_Call_param(call, 0); + (void) ctx; + + if (is_Const(val) && is_Const_null(val)) { + /* sin(0.0) = 0.0 */ + ir_node *mem = get_Call_mem(call); + replace_call(val, call, mem, NULL, NULL); + return 1; + } + return 0; +} + +/* A mapper for the floating point cos. */ +int i_mapper_cos(ir_node *call, void *ctx) { + ir_node *val = get_Call_param(call, 0); + (void) ctx; + + if (is_strictConv(val)) { + ir_node *op = get_Conv_op(val); + if (is_Minus(op)) { + /* cos(-x) = cos(x) with strictConv */ + ir_node *block = get_nodes_block(call); + ir_mode *mode = get_irn_mode(val); + dbg_info *dbg = get_irn_dbg_info(val); + + op = get_Minus_op(op); + val = new_rd_Conv(dbg, current_ir_graph, block, op, mode); + if (is_Conv(val)) { + /* still a Conv ? */ + set_Conv_strict(val, 1); + } + set_Call_param(call, 0, val); + } + } else if (is_Minus(val)) { + /* cos(-x) = cos(x) */ + val = get_Minus_op(val); + set_Call_param(call, 0, val); + } + + if (is_Const(val) && is_Const_null(val)) { + /* cos(0.0) = 1.0 */ + ir_node *block = get_nodes_block(call); + ir_mode *mode = get_irn_mode(val); + ir_node *irn = new_r_Const(current_ir_graph, block, mode, get_mode_one(mode)); + ir_node *mem = get_Call_mem(call); + replace_call(irn, call, mem, NULL, NULL); + return 1; + } + return 0; +} + +/* A mapper for the floating point tan. */ +int i_mapper_tan(ir_node *call, void *ctx) { + ir_node *val = get_Call_param(call, 0); + (void) ctx; + + if (is_Const(val) && is_Const_null(val)) { + /* tan(0.0) = 0.0 */ + ir_node *mem = get_Call_mem(call); + replace_call(val, call, mem, NULL, NULL); + return 1; + } + return 0; +} + +/* A mapper for the floating point asin. */ +int i_mapper_asin(ir_node *call, void *ctx) { + ir_node *val = get_Call_param(call, 0); + (void) ctx; + + if (is_Const(val) && is_Const_null(val)) { + /* asin(0.0) = 0.0 */ + ir_node *mem = get_Call_mem(call); + replace_call(val, call, mem, NULL, NULL); + return 1; + } + return 0; +} + +/* A mapper for the floating point acos. */ +int i_mapper_acos(ir_node *call, void *ctx) { + ir_node *val = get_Call_param(call, 0); + (void) ctx; + + if (is_Const(val) && is_Const_one(val)) { + /* acos(1.0) = 0.0 */ + ir_node *block = get_nodes_block(call); + ir_mode *mode = get_irn_mode(val); + ir_node *irn = new_r_Const(current_ir_graph, block, mode, get_mode_null(mode)); + ir_node *mem = get_Call_mem(call); + replace_call(irn, call, mem, NULL, NULL); + return 1; + } + return 0; +} + +/* A mapper for the floating point atan. */ +int i_mapper_atan(ir_node *call, void *ctx) { + ir_node *val = get_Call_param(call, 0); + (void) ctx; + + if (is_Const(val) && is_Const_null(val)) { + /* atan(0.0) = 0.0 */ + ir_node *mem = get_Call_mem(call); + replace_call(val, call, mem, NULL, NULL); + return 1; + } + return 0; +} + /* A mapper for strcmp */ -int i_mapper_Strcmp(ir_node *call, void *ctx) { +int i_mapper_strcmp(ir_node *call, void *ctx) { ir_node *left = get_Call_param(call, 0); ir_node *right = get_Call_param(call, 1); ir_node *irn; @@ -326,7 +438,7 @@ int i_mapper_Strcmp(ir_node *call, void *ctx) { } /* A mapper for strncmp */ -int i_mapper_Strncmp(ir_node *call, void *ctx) { +int i_mapper_strncmp(ir_node *call, void *ctx) { ir_node *left = get_Call_param(call, 0); ir_node *right = get_Call_param(call, 1); ir_node *len = get_Call_param(call, 2); @@ -352,7 +464,7 @@ int i_mapper_Strncmp(ir_node *call, void *ctx) { } /* A mapper for memcpy */ -int i_mapper_Memcpy(ir_node *call, void *ctx) { +int i_mapper_memcpy(ir_node *call, void *ctx) { ir_node *len = get_Call_param(call, 2); (void) ctx; @@ -368,7 +480,7 @@ int i_mapper_Memcpy(ir_node *call, void *ctx) { } /* A mapper for memset */ -int i_mapper_Memset(ir_node *call, void *ctx) { +int i_mapper_memset(ir_node *call, void *ctx) { ir_node *len = get_Call_param(call, 2); (void) ctx; -- 2.20.1