Hi!
This is the implementation of __builtin_early_constant_p builtin which
is at all optimization levels quite similar to __builtin_constant_p
at -O0, except that the FE folding might be slightly different between -O0
and -O1+. In any case, the builtin is folded to 0 already during the FEs
if the argument can't be proven constant or non-constant, like with
__builtin_constant_p at -O0.
The users can use it for stuff where __builtin_constant_p doesn't really
work (e.g. the kernel ilog2 case), for e.g. C macro constexpr-like
programming.
Is this ok for stage1, or do you find it not useful at all?
In any case, bootstrapped/regtested on x86_64-linux and i686-linux.
2018-03-07 Jakub Jelinek
PR c++/78420
* builtins.def (BUILT_IN_EARLY_CONSTANT_P): New built-in.
* builtins.h (force_folding_builtin_constant_p): Change from bool to
int.
* builtins.c (force_folding_builtin_constant_p): Likewise.
(expand_builtin): Handle BUILT_IN_EARLY_CONSTANT_P like
BUILT_IN_CONSTANT_P.
(fold_builtin_constant_p): Check force_folding_builtin_constant_p > 0
instead of force_folding_builtin_constant_p.
(fold_builtin_1) : Don't return
integer_zero_node if force_folding_builtin_constant_p < 0.
: New case.
(is_simple_builtin): Handle BUILT_IN_EARLY_CONSTANT_P like
BUILT_IN_CONSTANT_P.
* doc/extend.texi (__builtin_early_constant_p): Document.
c-family/
* c-common.c (check_builtin_function_arguments): Handle
BUILT_IN_EARLY_CONSTANT_P like BUILT_IN_CONSTANT_P.
c/
* c-parser.c (c_parser_get_builtin_args): Adjust for
force_folding_builtin_constant_p now being int rather than bool.
cp/
* cp-tree.h (DECL_IS_BUILTIN_CONSTANT_P): Handle
BUILT_IN_EARLY_CONSTANT_P like BUILT_IN_CONSTANT_P.
* call.c (magic_varargs_p): Likewise.
* tree.c (builtin_valid_in_constant_expr_p): Likewise.
* constexpr.c (cxx_eval_builtin_function_call): Likewise.
Adjust for force_folding_builtin_constant_p now being int rather than
bool.
* cp-gimplify.c: Include builtins.h.
(cp_fold): For __builtin*_constant_p adjust temporarily
force_folding_builtin_constant_p rather than optimize.
testsuite/
* g++.dg/delayedfold/builtin-constant4.C: New test.
* g++.dg/delayedfold/builtin-constant3.C: New test.
* g++.dg/ext/builtin14.C: New test.
* g++.dg/ext/builtin12.C: New test.
* g++.dg/ext/builtin13.C: New test.
* g++.dg/cpp1y/constexpr-78420.C: New test.
* g++.dg/cpp0x/constexpr-builtin5.C: New test.
* g++.dg/cpp0x/constexpr-builtin4.C: New test.
* gcc.dg/torture/pr78420.c: New test.
--- gcc/builtins.def.jj 2018-01-03 10:19:55.103533949 +0100
+++ gcc/builtins.def2018-03-07 15:55:20.756617250 +0100
@@ -857,6 +857,7 @@ DEF_EXT_LIB_BUILTIN(BUILT_IN_DCGETTE
DEF_EXT_LIB_BUILTIN(BUILT_IN_DGETTEXT, "dgettext",
BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_FORMAT_ARG_2)
DEF_GCC_BUILTIN(BUILT_IN_DWARF_CFA, "dwarf_cfa", BT_FN_PTR, ATTR_NULL)
DEF_GCC_BUILTIN(BUILT_IN_DWARF_SP_COLUMN, "dwarf_sp_column",
BT_FN_UINT, ATTR_NULL)
+DEF_GCC_BUILTIN(BUILT_IN_EARLY_CONSTANT_P, "early_constant_p",
BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN(BUILT_IN_EH_RETURN, "eh_return",
BT_FN_VOID_PTRMODE_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN(BUILT_IN_EH_RETURN_DATA_REGNO, "eh_return_data_regno",
BT_FN_INT_INT, ATTR_LEAF_LIST)
DEF_EXT_LIB_BUILTIN(BUILT_IN_EXECL, "execl",
BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
--- gcc/builtins.h.jj 2018-01-04 00:43:16.103702766 +0100
+++ gcc/builtins.h 2018-03-07 16:31:54.898348803 +0100
@@ -46,8 +46,10 @@ extern struct target_builtins *this_targ
#define this_target_builtins (_target_builtins)
#endif
-/* Non-zero if __builtin_constant_p should be folded right away. */
-extern bool force_folding_builtin_constant_p;
+/* 1 if __builtin_{,early_}constant_p should be folded right away,
+ -1 if __builtin_{,early_}constant_p should not be folded to 0 when
+ fold_builtin_constant_p returned NULL. */
+extern int force_folding_builtin_constant_p;
extern bool is_builtin_fn (tree);
extern bool called_as_built_in (tree);
--- gcc/builtins.c.jj 2018-02-19 20:35:54.418015330 +0100
+++ gcc/builtins.c 2018-03-07 16:32:12.326353626 +0100
@@ -91,8 +91,10 @@ const char * built_in_names[(int) END_BU
initialized to NULL_TREE. */
builtin_info_type builtin_info[(int)END_BUILTINS];
-/* Non-zero if __builtin_constant_p should be folded right away. */
-bool force_folding_builtin_constant_p;
+/* 1 if __builtin_{,early_}constant_p should be folded right away,
+ -1 if __builtin_{,early_}constant_p should not be folded to 0 when
+ fold_builtin_constant_p returned NULL. */
+int force_folding_builtin_constant_p;