This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Delete expand_tree_builtin from c-common.c
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 23 Jun 2004 22:58:57 -0600 (MDT)
- Subject: [PATCH] Delete expand_tree_builtin from c-common.c
It took a few more patches than I initially anticipated, but the
middle-end's fold_builtin (with some help from the rest of fold)
is now able to perform all of the lowering of builtin functions
to GCC tree nodes that currently gets done by expand_tree_builtin.
This allows us to delete all of the special-case handling of this
functionality from the C family front-ends, simplifying them greatly.
As expand_unordered_cmp in c-common.c is only ever called from
expand_tree_builtin, it can also be deleted. Once deleted, we can
simplify "build_function_call" in the C front-end, and both
"build_function_call" and "build_cxx_call" in the C++ front-end.
Things then cascade even further, as this latter change results in
an unused argument to build_cxx_call that can then be removed, and
all of the callers of build_cxx_call updated.
To use the official gcc-patches expression for this, "Whee!" :>
The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages, and regression tested with a
top-level "make -k check" with no new failures.
Ok for mainline?
2004-06-23 Roger Sayle <roger@eyesopen.com>
* c-common.c (expand_unordered_cmp): Delete.
(expand_tree_builtin): Delete.
* c-common.h (expand_tree_builtin): Delete function prototype.
* c-typeck.c (build_function_call): Don't call expand_tree_builtin.
cp/
* call.c (build_cxx_call): Don't call expand_tree_builtin. No
longer take both "args" and "convert_args" as arguments.
(build_op_delete_call): Update call to build_cxx_call.
(build_over_call): Likewise, update call to build_cxx_call.
* cp-tree.h (build_cxx_call): Update funtion prototype.
* typeck.c (build_function_call): Don't call expand_tree_builtin.
* rtti.c (throw_bad_cast): Update call to build_cxx_call.
(throw_bad_typeid): Likewise.
(build_dynamic_cast_1): Likewise.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.519
diff -c -3 -p -r1.519 c-common.c
*** c-common.c 22 Jun 2004 06:51:49 -0000 1.519
--- c-common.c 23 Jun 2004 23:55:44 -0000
*************** strip_pointer_operator (tree t)
*** 3500,3654 ****
return t;
}
- static tree expand_unordered_cmp (tree, tree, enum tree_code, enum tree_code);
-
- /* Expand a call to an unordered comparison function such as
- __builtin_isgreater(). FUNCTION is the function's declaration and
- PARAMS a list of the values passed. For __builtin_isunordered(),
- UNORDERED_CODE is UNORDERED_EXPR and ORDERED_CODE is NOP_EXPR. In
- other cases, UNORDERED_CODE and ORDERED_CODE are comparison codes
- that give the opposite of the desired result. UNORDERED_CODE is
- used for modes that can hold NaNs and ORDERED_CODE is used for the
- rest. */
-
- static tree
- expand_unordered_cmp (tree function, tree params,
- enum tree_code unordered_code,
- enum tree_code ordered_code)
- {
- tree arg0, arg1, type;
- enum tree_code code0, code1;
-
- /* Check that we have exactly two arguments. */
- if (params == 0 || TREE_CHAIN (params) == 0)
- {
- error ("too few arguments to function `%s'",
- IDENTIFIER_POINTER (DECL_NAME (function)));
- return error_mark_node;
- }
- else if (TREE_CHAIN (TREE_CHAIN (params)) != 0)
- {
- error ("too many arguments to function `%s'",
- IDENTIFIER_POINTER (DECL_NAME (function)));
- return error_mark_node;
- }
-
- arg0 = TREE_VALUE (params);
- arg1 = TREE_VALUE (TREE_CHAIN (params));
-
- code0 = TREE_CODE (TREE_TYPE (arg0));
- code1 = TREE_CODE (TREE_TYPE (arg1));
-
- /* Make sure that the arguments have a common type of REAL. */
- type = 0;
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
- && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
- type = common_type (TREE_TYPE (arg0), TREE_TYPE (arg1));
-
- if (type == 0 || TREE_CODE (type) != REAL_TYPE)
- {
- error ("non-floating-point argument to function `%s'",
- IDENTIFIER_POINTER (DECL_NAME (function)));
- return error_mark_node;
- }
-
- if (unordered_code == UNORDERED_EXPR)
- {
- if (MODE_HAS_NANS (TYPE_MODE (type)))
- return build_binary_op (unordered_code,
- convert (type, arg0),
- convert (type, arg1),
- 0);
- else
- return integer_zero_node;
- }
-
- return build_unary_op (TRUTH_NOT_EXPR,
- build_binary_op (MODE_HAS_NANS (TYPE_MODE (type))
- ? unordered_code
- : ordered_code,
- convert (type, arg0),
- convert (type, arg1),
- 0),
- 0);
- }
-
-
- /* Recognize certain built-in functions so we can make tree-codes
- other than CALL_EXPR. We do this when it enables fold-const.c
- to do something useful. */
- /* ??? By rights this should go in builtins.c, but only C and C++
- implement build_{binary,unary}_op. Not exactly sure what bits
- of functionality are actually needed from those functions, or
- where the similar functionality exists in the other front ends. */
-
- tree
- expand_tree_builtin (tree function, tree params, tree coerced_params)
- {
- if (DECL_BUILT_IN_CLASS (function) != BUILT_IN_NORMAL)
- return NULL_TREE;
-
- switch (DECL_FUNCTION_CODE (function))
- {
- case BUILT_IN_ABS:
- case BUILT_IN_LABS:
- case BUILT_IN_LLABS:
- case BUILT_IN_IMAXABS:
- case BUILT_IN_FABS:
- case BUILT_IN_FABSL:
- case BUILT_IN_FABSF:
- if (coerced_params == 0)
- return integer_zero_node;
- return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0);
-
- case BUILT_IN_CONJ:
- case BUILT_IN_CONJF:
- case BUILT_IN_CONJL:
- if (coerced_params == 0)
- return integer_zero_node;
- return build_unary_op (CONJ_EXPR, TREE_VALUE (coerced_params), 0);
-
- case BUILT_IN_CREAL:
- case BUILT_IN_CREALF:
- case BUILT_IN_CREALL:
- if (coerced_params == 0)
- return integer_zero_node;
- return non_lvalue (build_unary_op (REALPART_EXPR,
- TREE_VALUE (coerced_params), 0));
-
- case BUILT_IN_CIMAG:
- case BUILT_IN_CIMAGF:
- case BUILT_IN_CIMAGL:
- if (coerced_params == 0)
- return integer_zero_node;
- return non_lvalue (build_unary_op (IMAGPART_EXPR,
- TREE_VALUE (coerced_params), 0));
-
- case BUILT_IN_ISGREATER:
- return expand_unordered_cmp (function, params, UNLE_EXPR, LE_EXPR);
-
- case BUILT_IN_ISGREATEREQUAL:
- return expand_unordered_cmp (function, params, UNLT_EXPR, LT_EXPR);
-
- case BUILT_IN_ISLESS:
- return expand_unordered_cmp (function, params, UNGE_EXPR, GE_EXPR);
-
- case BUILT_IN_ISLESSEQUAL:
- return expand_unordered_cmp (function, params, UNGT_EXPR, GT_EXPR);
-
- case BUILT_IN_ISLESSGREATER:
- return expand_unordered_cmp (function, params, UNEQ_EXPR, EQ_EXPR);
-
- case BUILT_IN_ISUNORDERED:
- return expand_unordered_cmp (function, params, UNORDERED_EXPR, NOP_EXPR);
-
- default:
- break;
- }
-
- return NULL_TREE;
- }
-
/* Walk the statement tree, rooted at *tp. Apply FUNC to all the
sub-trees of *TP in a pre-order traversal. FUNC is called with the
DATA and the address of each sub-tree. If FUNC returns a non-NULL
--- 3500,3505 ----
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.244
diff -c -3 -p -r1.244 c-common.h
*** c-common.h 22 Jun 2004 06:51:50 -0000 1.244
--- c-common.h 23 Jun 2004 23:55:44 -0000
*************** extern tree default_conversion (tree);
*** 1032,1039 ****
extern tree common_type (tree, tree);
- extern tree expand_tree_builtin (tree, tree, tree);
-
extern tree decl_constant_value (tree);
/* Handle increment and decrement of boolean types. */
--- 1032,1037 ----
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.328
diff -c -3 -p -r1.328 c-typeck.c
*** c-typeck.c 23 Jun 2004 17:05:42 -0000 1.328
--- c-typeck.c 23 Jun 2004 23:55:46 -0000
*************** build_function_call (tree function, tree
*** 1876,1895 ****
check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params);
- /* Recognize certain built-in functions so we can make tree-codes
- other than CALL_EXPR. We do this when it enables fold-const.c
- to do something useful. */
-
- if (TREE_CODE (function) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
- && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
- {
- result = expand_tree_builtin (TREE_OPERAND (function, 0),
- params, coerced_params);
- if (result)
- return result;
- }
-
result = build (CALL_EXPR, TREE_TYPE (fntype),
function, coerced_params, NULL_TREE);
TREE_SIDE_EFFECTS (result) = 1;
--- 1876,1881 ----
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.483
diff -c -3 -p -r1.483 call.c
*** cp/call.c 23 Jun 2004 00:25:58 -0000 1.483
--- cp/call.c 23 Jun 2004 23:55:47 -0000
*************** build_op_delete_call (enum tree_code cod
*** 4023,4029 ****
/* The placement args might not be suitable for overload
resolution at this point, so build the call directly. */
mark_used (fn);
! return build_cxx_call (fn, args, args);
}
else
return build_function_call (fn, args);
--- 4023,4029 ----
/* The placement args might not be suitable for overload
resolution at this point, so build the call directly. */
mark_used (fn);
! return build_cxx_call (fn, args);
}
else
return build_function_call (fn, args);
*************** build_over_call (struct z_candidate *can
*** 4843,4875 ****
else
fn = build_addr_func (fn);
! return build_cxx_call (fn, args, converted_args);
}
! /* Build and return a call to FN, using the the CONVERTED_ARGS. ARGS
! gives the original form of the arguments. This function performs
no overload resolution, conversion, or other high-level
operations. */
tree
! build_cxx_call(tree fn, tree args, tree converted_args)
{
tree fndecl;
! /* Recognize certain built-in functions so we can make tree-codes
! other than CALL_EXPR. We do this when it enables fold-const.c
! to do something useful. */
! if (TREE_CODE (fn) == ADDR_EXPR
! && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
! && DECL_BUILT_IN (TREE_OPERAND (fn, 0)))
! {
! tree exp;
! exp = expand_tree_builtin (TREE_OPERAND (fn, 0), args, converted_args);
! if (exp)
! return exp;
! }
!
! fn = build_call (fn, converted_args);
/* If this call might throw an exception, note that fact. */
fndecl = get_callee_fndecl (fn);
--- 4843,4861 ----
else
fn = build_addr_func (fn);
! return build_cxx_call (fn, converted_args);
}
! /* Build and return a call to FN, using ARGS. This function performs
no overload resolution, conversion, or other high-level
operations. */
tree
! build_cxx_call (tree fn, tree args)
{
tree fndecl;
! fn = build_call (fn, args);
/* If this call might throw an exception, note that fact. */
fndecl = get_callee_fndecl (fn);
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.985
diff -c -3 -p -r1.985 cp-tree.h
*** cp/cp-tree.h 23 Jun 2004 00:26:00 -0000 1.985
--- cp/cp-tree.h 23 Jun 2004 23:55:48 -0000
*************** extern tree strip_top_quals (tree);
*** 3626,3632 ****
extern tree perform_implicit_conversion (tree, tree);
extern tree perform_direct_initialization_if_possible (tree, tree);
extern tree in_charge_arg_for_name (tree);
! extern tree build_cxx_call (tree, tree, tree);
#ifdef ENABLE_CHECKING
extern void validate_conversion_obstack (void);
#endif /* ENABLE_CHECKING */
--- 3626,3632 ----
extern tree perform_implicit_conversion (tree, tree);
extern tree perform_direct_initialization_if_possible (tree, tree);
extern tree in_charge_arg_for_name (tree);
! extern tree build_cxx_call (tree, tree);
#ifdef ENABLE_CHECKING
extern void validate_conversion_obstack (void);
#endif /* ENABLE_CHECKING */
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.552
diff -c -3 -p -r1.552 typeck.c
*** cp/typeck.c 22 Jun 2004 03:07:00 -0000 1.552
--- cp/typeck.c 23 Jun 2004 23:55:49 -0000
*************** build_function_call (tree function, tree
*** 2411,2417 ****
{
tree fntype, fndecl;
tree coerced_params;
- tree result;
tree name = NULL_TREE;
int is_method;
tree original = function;
--- 2411,2416 ----
*************** build_function_call (tree function, tree
*** 2489,2509 ****
if (warn_format)
check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params);
! /* Recognize certain built-in functions so we can make tree-codes
! other than CALL_EXPR. We do this when it enables fold-const.c
! to do something useful. */
!
! if (TREE_CODE (function) == ADDR_EXPR
! && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
! && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
! {
! result = expand_tree_builtin (TREE_OPERAND (function, 0),
! params, coerced_params);
! if (result)
! return result;
! }
!
! return build_cxx_call (function, params, coerced_params);
}
/* Convert the actual parameter expressions in the list VALUES
--- 2488,2494 ----
if (warn_format)
check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params);
! return build_cxx_call (function, coerced_params);
}
/* Convert the actual parameter expressions in the list VALUES
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/rtti.c,v
retrieving revision 1.182
diff -c -3 -p -r1.182 rtti.c
*** cp/rtti.c 13 May 2004 06:40:21 -0000 1.182
--- cp/rtti.c 23 Jun 2004 23:55:49 -0000
*************** throw_bad_cast (void)
*** 176,182 ****
fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
void_list_node));
! return build_cxx_call (fn, NULL_TREE, NULL_TREE);
}
/* Return an expression for "__cxa_bad_typeid()". The expression
--- 176,182 ----
fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
void_list_node));
! return build_cxx_call (fn, NULL_TREE);
}
/* Return an expression for "__cxa_bad_typeid()". The expression
*************** throw_bad_typeid (void)
*** 193,199 ****
fn = push_throw_library_fn (fn, t);
}
! return convert_from_reference (build_cxx_call (fn, NULL_TREE, NULL_TREE));
}
/* Return an lvalue expression whose type is "const std::type_info"
--- 193,199 ----
fn = push_throw_library_fn (fn, t);
}
! return convert_from_reference (build_cxx_call (fn, NULL_TREE));
}
/* Return an lvalue expression whose type is "const std::type_info"
*************** build_dynamic_cast_1 (tree type, tree ex
*** 652,658 ****
pop_nested_namespace (ns);
dynamic_cast_node = dcast_fn;
}
! result = build_cxx_call (dcast_fn, elems, elems);
if (tc == REFERENCE_TYPE)
{
--- 652,658 ----
pop_nested_namespace (ns);
dynamic_cast_node = dcast_fn;
}
! result = build_cxx_call (dcast_fn, elems);
if (tc == REFERENCE_TYPE)
{
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833