From 2be48eba1472ed3db15f7cf1775093a9447d4fa4 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Mon, 5 Nov 2007 10:29:12 +0000 Subject: [PATCH] more libc mapper functions added [r16427] --- include/libfirm/lowering.h | 23 ++++++++++++- ir/be/test/rtsopt.c | 10 ++++++ ir/lower/lower_intrinsics.c | 64 +++++++++++++++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 3 deletions(-) diff --git a/include/libfirm/lowering.h b/include/libfirm/lowering.h index 802316089..1e0070580 100644 --- a/include/libfirm/lowering.h +++ b/include/libfirm/lowering.h @@ -299,6 +299,13 @@ int i_mapper_Sqrt(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); + /** * A mapper for the strcmp-Function: inttype strcmp(char pointer a, char pointer b); * @@ -307,12 +314,26 @@ int i_mapper_Pow(ir_node *call, void *ctx); int i_mapper_Strcmp(ir_node *call, void *ctx); /** - * A mapper for the memcpy-Function: void pointer strcmp(void pointer d, void pointer s, inttype c); + * 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); + +/** + * 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); +/** + * 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); + /** * A mapper for the alloca() function: pointer alloca(inttype size) * Replaces the call by a Alloca(stack_alloc) node. diff --git a/ir/be/test/rtsopt.c b/ir/be/test/rtsopt.c index 73d14877a..5ee945ad9 100644 --- a/ir/be/test/rtsopt.c +++ b/ir/be/test/rtsopt.c @@ -64,6 +64,11 @@ int test_strncmp4(void) { return strncmp("ab", "cd", 2); } +/* evaluate, gcc(+) */ +int test_strncmp5(char *a, char *b) { + return strncmp(a, b, 0); +} + /* transform into *s = '\0', s, gcc(+), icc(-) */ char *test_strcpy1(char *s) { return strcpy(s, ""); @@ -154,6 +159,11 @@ double test_pow5(double a) { return pow(a, -1.0); } +/* evaluate */ +double test_exp1(void) { + return exp(0); +} + /* transform into putchar, gcc(+), icc(-) */ void test_printf1() { printf("\n"); diff --git a/ir/lower/lower_intrinsics.c b/ir/lower/lower_intrinsics.c index 5d7aa6125..5da53a53d 100644 --- a/ir/lower/lower_intrinsics.c +++ b/ir/lower/lower_intrinsics.c @@ -284,6 +284,24 @@ int i_mapper_Pow(ir_node *call, void *ctx) { return 1; } +/* A mapper for the floating point exp. */ +int i_mapper_Exp(ir_node *call, void *ctx) { + dbg_info *dbg; + ir_node *val = get_Call_param(call, 0); + (void) ctx; + + if (is_Const(val) && is_Const_null(val)) { + /* exp(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 strcmp */ int i_mapper_Strcmp(ir_node *call, void *ctx) { ir_node *left = get_Call_param(call, 0); @@ -308,12 +326,38 @@ int i_mapper_Strcmp(ir_node *call, void *ctx) { return 0; } +/* A mapper for strncmp */ +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); + ir_node *irn; + (void) ctx; + + if (left == right || (is_Const(len) && is_Const_null(len))) { + /* a strncmp(s, s, len) ==> 0 OR + a strncmp(a, b, 0) ==> 0 */ + ir_node *mem = get_Call_mem(call); + ir_node *adr = get_Call_ptr(call); + ir_entity *ent = get_SymConst_entity(adr); + ir_type *call_tp = get_entity_type(ent); + ir_type *res_tp = get_method_res_type(call_tp, 0); + ir_mode *mode = get_type_mode(res_tp); + ir_node *block = get_nodes_block(call); + + irn = new_r_Const(current_ir_graph, block, mode, get_mode_null(mode)); + replace_call(irn, call, mem, NULL, NULL); + return 1; + } + return 0; +} + /* A mapper for memcpy */ int i_mapper_Memcpy(ir_node *call, void *ctx) { - ir_node *count = get_Call_param(call, 2); + ir_node *len = get_Call_param(call, 2); (void) ctx; - if (is_Const(count) && is_Const_null(count)) { + if (is_Const(len) && is_Const_null(len)) { /* a memcpy(d, s, 0) ==> d */ ir_node *mem = get_Call_mem(call); ir_node *dst = get_Call_param(call, 0); @@ -324,6 +368,22 @@ int i_mapper_Memcpy(ir_node *call, void *ctx) { return 0; } +/* A mapper for memset */ +int i_mapper_Memset(ir_node *call, void *ctx) { + ir_node *len = get_Call_param(call, 2); + (void) ctx; + + if (is_Const(len) && is_Const_null(len)) { + /* a memset(d, C, 0) ==> d */ + ir_node *mem = get_Call_mem(call); + ir_node *dst = get_Call_param(call, 0); + + replace_call(dst, call, mem, NULL, NULL); + return 1; + } + return 0; +} + /** * Returns the result mode of a node. */ -- 2.20.1