From 3bb63aebd8060e2baf8baf687c1a320e81ebba91 Mon Sep 17 00:00:00 2001 From: jakub Date: Thu, 24 Sep 2009 09:21:39 +0000 Subject: [PATCH] * cgraphunit.c (cgraph_lower_function): Revert last change. * targhooks.c (default_static_chain): Use !DECL_STATIC_CHAIN instead of DECL_NO_STATIC_CHAIN. * tree-cfg.c (verify_gimple_call): Likewise. * tree-nested.c (get_chain_decl, get_chain_field, convert_tramp_reference_op, convert_gimple_call): Likewise. (convert_all_function_calls): Likewise. Always set or clear DECL_STATIC_CHAIN initially, for !n->outer clear it. (lower_nested_functions): Remove DECL_NO_STATIC_CHAIN checking code. * c-parser.c (c_parser_declaration_or_fndef): Set DECL_STATIC_CHAIN if nested. * print-tree.c (print_node): Handle DECL_STATIC_CHAIN instead of DECL_NO_STATIC_CHAIN. * config/i386/i386.c (ix86_static_chain): Use !DECL_STATIC_CHAIN instead of DECL_NO_STATIC_CHAIN. (ix86_function_regparm, find_drap_reg): Likewise. Don't test decl_function_context. * varasm.c (initializer_constant_valid_p): Likewise. * tree.h (DECL_NO_STATIC_CHAIN): Renamed to ... (DECL_STATIC_CHAIN): ... this. * config/moxie/moxie.c (moxie_static_chain): Use !DECL_STATIC_CHAIN instead of DECL_NO_STATIC_CHAIN. * method.c (make_thunk, make_alias_for): Don't set DECL_NO_STATIC_CHAIN. * decl.c (builtin_function_1, grokfndecl): Likewise. * lex.c (build_lang_decl): Likewise. * gcc-interface/utils.c (gnat_pushdecl): Don't set DECL_NO_STATIC_CHAIN, set DECL_STATIC_CHAIN for nested functions. * testsuite/gcc.target/i386/pr12329.c: Adjust. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152114 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 25 ++++++++++++++++ gcc/ada/ChangeLog | 6 ++++ gcc/ada/gcc-interface/utils.c | 9 ++++-- gcc/c-parser.c | 5 ++++ gcc/cgraphunit.c | 5 ---- gcc/config/i386/i386.c | 14 +++------ gcc/config/moxie/moxie.c | 2 +- gcc/cp/ChangeLog | 7 +++++ gcc/cp/decl.c | 7 ----- gcc/cp/lex.c | 5 ---- gcc/cp/method.c | 4 --- gcc/print-tree.c | 4 +-- gcc/targhooks.c | 2 +- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.target/i386/pr12329.c | 2 +- gcc/tree-cfg.c | 4 +-- gcc/tree-nested.c | 52 ++++++++++----------------------- gcc/tree.h | 5 ++-- gcc/varasm.c | 3 +- 19 files changed, 83 insertions(+), 82 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4c210979f5c..3c20a418625 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2009-09-24 Jakub Jelinek + + * cgraphunit.c (cgraph_lower_function): Revert last change. + * targhooks.c (default_static_chain): Use !DECL_STATIC_CHAIN + instead of DECL_NO_STATIC_CHAIN. + * tree-cfg.c (verify_gimple_call): Likewise. + * tree-nested.c (get_chain_decl, get_chain_field, + convert_tramp_reference_op, convert_gimple_call): Likewise. + (convert_all_function_calls): Likewise. Always set or clear + DECL_STATIC_CHAIN initially, for !n->outer clear it. + (lower_nested_functions): Remove DECL_NO_STATIC_CHAIN checking code. + * c-parser.c (c_parser_declaration_or_fndef): Set DECL_STATIC_CHAIN + if nested. + * print-tree.c (print_node): Handle DECL_STATIC_CHAIN instead of + DECL_NO_STATIC_CHAIN. + * config/i386/i386.c (ix86_static_chain): Use !DECL_STATIC_CHAIN + instead of DECL_NO_STATIC_CHAIN. + (ix86_function_regparm, find_drap_reg): Likewise. Don't test + decl_function_context. + * varasm.c (initializer_constant_valid_p): Likewise. + * tree.h (DECL_NO_STATIC_CHAIN): Renamed to ... + (DECL_STATIC_CHAIN): ... this. + * config/moxie/moxie.c (moxie_static_chain): Use !DECL_STATIC_CHAIN + instead of DECL_NO_STATIC_CHAIN. + 2009-09-23 Basile Starynkevitch Rafael Avila de Espindola diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index dddef52d6f4..0cbd4db4bf2 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2009-09-24 Jakub Jelinek + + * gcc-interface/utils.c (gnat_pushdecl): Don't set + DECL_NO_STATIC_CHAIN, set DECL_STATIC_CHAIN for + nested functions. + 2009-09-21 Joel Sherrill * s-osinte-rtems.ad[bs]: Get_Page_Size cannot return 0. diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 31f24ce0340..1559cf14490 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -439,9 +439,12 @@ gnat_pushdecl (tree decl, Node_Id gnat_node) { DECL_CONTEXT (decl) = current_function_decl; - /* Functions imported in another function are not really nested. */ - if (TREE_CODE (decl) == FUNCTION_DECL && TREE_PUBLIC (decl)) - DECL_NO_STATIC_CHAIN (decl) = 1; + /* Functions imported in another function are not really nested. + For really nested functions mark them initially as needing + a static chain for uses of that flag before unnesting; + lower_nested_functions will then recompute it. */ + if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl)) + DECL_STATIC_CHAIN (decl) = 1; } TREE_NO_WARNING (decl) = (gnat_node == Empty || Warnings_Off (gnat_node)); diff --git a/gcc/c-parser.c b/gcc/c-parser.c index d9ea159c4e5..3f6e949fe8e 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -1323,6 +1323,11 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, if (nested) { tree decl = current_function_decl; + /* Mark nested functions as needing static-chain initially. + lower_nested_functions will recompute it but the + DECL_STATIC_CHAIN flag is also used before that happens, + by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */ + DECL_STATIC_CHAIN (decl) = 1; add_stmt (fnbody); finish_function (); c_pop_function_context (); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 890737aeb96..2ad07187e04 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -498,11 +498,6 @@ cgraph_lower_function (struct cgraph_node *node) lower_nested_functions (node->decl); gcc_assert (!node->nested); - /* Non-nested functions never need a static chain. */ - if (!DECL_NO_STATIC_CHAIN (node->decl) - && decl_function_context (node->decl) == NULL) - DECL_NO_STATIC_CHAIN (node->decl) = 1; - tree_lowering_passes (node->decl); node->lowered = true; } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7c215420666..3b11b915194 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4508,9 +4508,7 @@ ix86_function_regparm (const_tree type, const_tree decl) /* We don't want to use regparm(3) for nested functions as these use a static chain pointer in the third argument. */ - if (local_regparm == 3 - && decl_function_context (decl) - && !DECL_NO_STATIC_CHAIN (decl)) + if (local_regparm == 3 && DECL_STATIC_CHAIN (decl)) local_regparm = 2; /* Each fixed register usage increases register pressure, @@ -8128,9 +8126,7 @@ find_drap_reg (void) Since function with tail call may use any caller-saved registers in epilogue, DRAP must not use caller-saved register in such case. */ - if ((decl_function_context (decl) - && !DECL_NO_STATIC_CHAIN (decl)) - || crtl->tail_call_emit) + if (DECL_STATIC_CHAIN (decl) || crtl->tail_call_emit) return R13_REG; return R10_REG; @@ -8141,9 +8137,7 @@ find_drap_reg (void) Since function with tail call may use any caller-saved registers in epilogue, DRAP must not use caller-saved register in such case. */ - if ((decl_function_context (decl) - && !DECL_NO_STATIC_CHAIN (decl)) - || crtl->tail_call_emit) + if (DECL_STATIC_CHAIN (decl) || crtl->tail_call_emit) return DI_REG; /* Reuse static chain register if it isn't used for parameter @@ -19811,7 +19805,7 @@ ix86_static_chain (const_tree fndecl, bool incoming_p) { unsigned regno; - if (DECL_NO_STATIC_CHAIN (fndecl)) + if (!DECL_STATIC_CHAIN (fndecl)) return NULL; if (TARGET_64BIT) diff --git a/gcc/config/moxie/moxie.c b/gcc/config/moxie/moxie.c index 215bbdf75a3..7515fa26a47 100644 --- a/gcc/config/moxie/moxie.c +++ b/gcc/config/moxie/moxie.c @@ -460,7 +460,7 @@ moxie_static_chain (const_tree fndecl, bool incoming_p) { rtx addr, mem; - if (DECL_NO_STATIC_CHAIN (fndecl)) + if (!DECL_STATIC_CHAIN (fndecl)) return NULL; if (incoming_p) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 338e725ca66..4c6e0c796c0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2009-09-24 Jakub Jelinek + + * method.c (make_thunk, make_alias_for): Don't set + DECL_NO_STATIC_CHAIN. + * decl.c (builtin_function_1, grokfndecl): Likewise. + * lex.c (build_lang_decl): Likewise. + 2009-09-23 Dodji Seketeli PR debug/41065 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 407f734bc45..c720f6c33a3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3580,10 +3580,6 @@ builtin_function_1 (tree decl, tree context, bool is_global) retrofit_lang_decl (decl); - /* All nesting of C++ functions is lexical; there is never a "static - chain" in the sense of GNU C nested functions. */ - DECL_NO_STATIC_CHAIN (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; SET_OVERLOADED_OPERATOR_CODE (decl, ERROR_MARK); SET_DECL_LANGUAGE (decl, lang_c); @@ -6779,9 +6775,6 @@ grokfndecl (tree ctype, && !grok_op_properties (decl, /*complain=*/true)) return NULL_TREE; - if (ctype && decl_function_context (decl)) - DECL_NO_STATIC_CHAIN (decl) = 1; - if (funcdef_flag) /* Make the init_value nonzero so pushdecl knows this is not tentative. error_mark_node is replaced later with the BLOCK. */ diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 5eb182d3caf..041e391f543 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -516,11 +516,6 @@ build_lang_decl (enum tree_code code, tree name, tree type) code, name, type); retrofit_lang_decl (t); - /* All nesting of C++ functions is lexical; there is never a "static - chain" in the sense of GNU C nested functions. */ - if (code == FUNCTION_DECL) - DECL_NO_STATIC_CHAIN (t) = 1; - return t; } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 6acf1bb4b71..b0df48938a8 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -151,9 +151,6 @@ make_thunk (tree function, bool this_adjusting, DECL_CONSTRUCTOR_P (thunk) = 0; DECL_EXTERNAL (thunk) = 1; DECL_ARTIFICIAL (thunk) = 1; - /* Even if this thunk is a member of a local class, we don't - need a static chain. */ - DECL_NO_STATIC_CHAIN (thunk) = 1; /* The THUNK is not a pending inline, even if the FUNCTION is. */ DECL_PENDING_INLINE_P (thunk) = 0; DECL_DECLARED_INLINE_P (thunk) = 0; @@ -281,7 +278,6 @@ make_alias_for (tree function, tree newid) DECL_CONSTRUCTOR_P (alias) = 0; DECL_EXTERNAL (alias) = 0; DECL_ARTIFICIAL (alias) = 1; - DECL_NO_STATIC_CHAIN (alias) = 1; DECL_PENDING_INLINE_P (alias) = 0; DECL_DECLARED_INLINE_P (alias) = 0; DECL_USE_TEMPLATE (alias) = 0; diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 1d66769a1f7..f4b74d95ffc 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -381,8 +381,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent) fputs (" autoinline", file); if (code == FUNCTION_DECL && DECL_BUILT_IN (node)) fputs (" built-in", file); - if (code == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (node)) - fputs (" no-static-chain", file); + if (code == FUNCTION_DECL && DECL_STATIC_CHAIN (node)) + fputs (" static-chain", file); if (code == FIELD_DECL && DECL_PACKED (node)) fputs (" packed", file); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 8a2e56bab16..dd52da98638 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -631,7 +631,7 @@ default_internal_arg_pointer (void) rtx default_static_chain (const_tree fndecl, bool incoming_p) { - if (DECL_NO_STATIC_CHAIN (fndecl)) + if (!DECL_STATIC_CHAIN (fndecl)) return NULL; if (incoming_p) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4c8e14e3332..0e92d054469 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-09-24 Jakub Jelinek + + * testsuite/gcc.target/i386/pr12329.c: Adjust. + 2009-09-23 Alexandre Oliva PR debug/41248 diff --git a/gcc/testsuite/gcc.target/i386/pr12329.c b/gcc/testsuite/gcc.target/i386/pr12329.c index 21d2c6580e2..c3d8a6128dd 100644 --- a/gcc/testsuite/gcc.target/i386/pr12329.c +++ b/gcc/testsuite/gcc.target/i386/pr12329.c @@ -6,7 +6,7 @@ extern void abort (void); int test_nested (int i) { - int __attribute__ ((__noinline__, __regparm__(3))) foo(int j, int k, int l) /* { dg-error "nested functions are limited to 2 register parameters" } */ + int __attribute__ ((__noinline__, __regparm__(3))) foo(int j, int k, int l) { return i + j + k + l; } diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index cfde858927f..df1f6caa857 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3575,7 +3575,7 @@ verify_gimple_call (gimple stmt) } /* If there is a static chain argument, this should not be an indirect - call, and the decl should not have DECL_NO_STATIC_CHAIN set. */ + call, and the decl should have DECL_STATIC_CHAIN set. */ if (gimple_call_chain (stmt)) { if (TREE_CODE (fn) != ADDR_EXPR @@ -3586,7 +3586,7 @@ verify_gimple_call (gimple stmt) } fn = TREE_OPERAND (fn, 0); - if (DECL_NO_STATIC_CHAIN (fn)) + if (!DECL_STATIC_CHAIN (fn)) { error ("static chain with function that doesn't use one"); return true; diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index fe938d913e1..706571c59ec 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -353,11 +353,11 @@ get_chain_decl (struct nesting_info *info) if (dump_file && (dump_flags & TDF_DETAILS) - && DECL_NO_STATIC_CHAIN (info->context)) - fprintf (dump_file, "Resetting no-static-chain for %s\n", + && !DECL_STATIC_CHAIN (info->context)) + fprintf (dump_file, "Setting static-chain for %s\n", lang_hooks.decl_printable_name (info->context, 2)); - DECL_NO_STATIC_CHAIN (info->context) = 0; + DECL_STATIC_CHAIN (info->context) = 1; } return decl; } @@ -387,11 +387,11 @@ get_chain_field (struct nesting_info *info) if (dump_file && (dump_flags & TDF_DETAILS) - && DECL_NO_STATIC_CHAIN (info->context)) - fprintf (dump_file, "Resetting no-static-chain for %s\n", + && !DECL_STATIC_CHAIN (info->context)) + fprintf (dump_file, "Setting static-chain for %s\n", lang_hooks.decl_printable_name (info->context, 2)); - DECL_NO_STATIC_CHAIN (info->context) = 0; + DECL_STATIC_CHAIN (info->context) = 1; } return field; } @@ -1872,7 +1872,7 @@ convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data) /* If the nested function doesn't use a static chain, then it doesn't need a trampoline. */ - if (DECL_NO_STATIC_CHAIN (decl)) + if (!DECL_STATIC_CHAIN (decl)) break; /* If we don't want a trampoline, then don't build one. */ @@ -1972,7 +1972,7 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p, if (!decl) break; target_context = decl_function_context (decl); - if (target_context && !DECL_NO_STATIC_CHAIN (decl)) + if (target_context && DECL_STATIC_CHAIN (decl)) { gimple_call_set_chain (stmt, get_static_chain (info, target_context, &wi->gsi)); @@ -2046,20 +2046,20 @@ convert_all_function_calls (struct nesting_info *root) int iter_count; bool any_changed; - /* First, optimistically set no_static_chain for all decls that haven't + /* First, optimistically clear static_chain for all decls that haven't used the static chain already for variable access. */ FOR_EACH_NEST_INFO (n, root) { tree decl = n->context; - if (n->outer && !n->chain_decl && !n->chain_field) + if (!n->outer || (!n->chain_decl && !n->chain_field)) { - DECL_NO_STATIC_CHAIN (decl) = 1; + DECL_STATIC_CHAIN (decl) = 0; if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Guessing no-static-chain for %s\n", + fprintf (dump_file, "Guessing no static-chain for %s\n", lang_hooks.decl_printable_name (decl, 2)); } else - gcc_assert (!DECL_NO_STATIC_CHAIN (decl)); + DECL_STATIC_CHAIN (decl) = 1; } /* Walk the functions and perform transformations. Note that these @@ -2081,7 +2081,7 @@ convert_all_function_calls (struct nesting_info *root) FOR_EACH_NEST_INFO (n, root) { tree decl = n->context; - bool old_no_static_chain = DECL_NO_STATIC_CHAIN (decl); + bool old_static_chain = DECL_STATIC_CHAIN (decl); walk_function (convert_tramp_reference_stmt, convert_tramp_reference_op, n); @@ -2089,7 +2089,7 @@ convert_all_function_calls (struct nesting_info *root) /* If a call to another function created the use of a chain within this function, we'll have to continue iteration. */ - if (old_no_static_chain && !DECL_NO_STATIC_CHAIN (decl)) + if (!old_static_chain && DECL_STATIC_CHAIN (decl)) any_changed = true; } } @@ -2337,7 +2337,7 @@ finalize_nesting_tree_1 (struct nesting_info *root) if (!field) continue; - gcc_assert (!DECL_NO_STATIC_CHAIN (i->context)); + gcc_assert (DECL_STATIC_CHAIN (i->context)); arg3 = build_addr (root->frame_decl, context); arg2 = build_addr (i->context, context); @@ -2528,10 +2528,6 @@ lower_nested_functions (tree fndecl) { struct cgraph_node *cgn; struct nesting_info *root; -#ifdef ENABLE_CHECKING - struct nesting_info *n; - bitmap orig_decl_no_static_chain; -#endif /* If there are no nested functions, there's nothing to do. */ cgn = cgraph_node (fndecl); @@ -2548,15 +2544,6 @@ lower_nested_functions (tree fndecl) bitmap_obstack_initialize (&nesting_info_bitmap_obstack); root = create_nesting_tree (cgn); -#ifdef ENABLE_CHECKING - /* The C++ and Ada front ends set DECL_NO_STATIC_CHAIN in various - instances where they expect no static chain needed. */ - orig_decl_no_static_chain = BITMAP_ALLOC (&nesting_info_bitmap_obstack); - FOR_EACH_NEST_INFO (n, root) - if (DECL_NO_STATIC_CHAIN (n->context)) - bitmap_set_bit (orig_decl_no_static_chain, DECL_UID (n->context)); -#endif - walk_all_functions (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, root); @@ -2570,13 +2557,6 @@ lower_nested_functions (tree fndecl) finalize_nesting_tree (root); unnest_nesting_tree (root); -#ifdef ENABLE_CHECKING - /* Validate the original settings of DECL_NO_STATIC_CHAIN. */ - FOR_EACH_NEST_INFO (n, root) - if (bitmap_bit_p (orig_decl_no_static_chain, DECL_UID (n->context))) - gcc_assert (DECL_NO_STATIC_CHAIN (n->context)); -#endif - free_nesting_tree (root); bitmap_obstack_release (&nesting_info_bitmap_obstack); diff --git a/gcc/tree.h b/gcc/tree.h index afb1d4260a0..4f4fd309b6e 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3141,9 +3141,8 @@ struct GTY(()) #define DECL_NO_LIMIT_STACK(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.no_limit_stack) -/* In a FUNCTION_DECL with a nonzero DECL_CONTEXT, indicates that a - static chain is not needed. */ -#define DECL_NO_STATIC_CHAIN(NODE) \ +/* In a FUNCTION_DECL indicates that a static chain is needed. */ +#define DECL_STATIC_CHAIN(NODE) \ (FUNCTION_DECL_CHECK (NODE)->function_decl.regdecl_flag) /* Nonzero for a decl that cgraph has decided should be inlined into diff --git a/gcc/varasm.c b/gcc/varasm.c index f4532b8bb6c..91ec68aade0 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -4212,8 +4212,7 @@ initializer_constant_valid_p (tree value, tree endtype) /* Taking the address of a nested function involves a trampoline, unless we don't need or want one. */ if (TREE_CODE (op0) == FUNCTION_DECL - && decl_function_context (op0) - && !DECL_NO_STATIC_CHAIN (op0) + && DECL_STATIC_CHAIN (op0) && !TREE_NO_TRAMPOLINE (value)) return NULL_TREE; /* "&{...}" requires a temporary to hold the constructed -- 2.11.0