On Fri, 2013-08-30 at 10:04 +0200, Richard Biener wrote: > On Thu, Aug 29, 2013 at 6:20 PM, David Malcolm <dmalc...@redhat.com> wrote: > > * gimple.c (gt_ggc_mx (gimple)): New, as required by GTY((user)). > > (gt_pch_nx (gimple)): Likewise. > > (gt_pch_nx (gimple, gt_pointer_operator, void *)): Likewise. > > * gimple.h (gt_ggc_mx (gimple)): Declare. > > (gt_pch_nx (gimple)): Declare. > > (gt_pch_nx (gimple, gt_pointer_operator, void *)): Declare. > > No GIMPLE should reside in PCHs so you should be able to just put > gcc_unreachable () in them ... (if dropping them does not work)
Thanks. I'm attaching a revised version of the patch which does this, bringing the length of the hand-written GTY code for this down from 741 lines to 267 lines. Successfully bootstrapped on x86_64-unknown-linux-gnu (with plain "configure" and thus with checking enabled); all tests show same results as a unpatched control build (of r202029).
>From 4edea4c28c624d4d308d8be731f4415d22e10f14 Mon Sep 17 00:00:00 2001 From: David Malcolm <dmalc...@redhat.com> Date: Mon, 26 Aug 2013 20:41:04 -0400 Subject: [PATCH 6/6] Add manual GTY hooks * gimple.c (gt_ggc_mx (gimple)): New, as required by GTY((user)). (gt_pch_nx (gimple)): New, stub implementation. (gt_pch_nx (gimple, gt_pointer_operator, void *)): Likewise. * gimple.h (gt_ggc_mx (gimple)): Declare. (gt_pch_nx (gimple)): Declare. (gt_pch_nx (gimple, gt_pointer_operator, void *)): Declare. * tree-cfg.c (ggc_mx (gimple&)): Remove declaration, as this collides with the function that GTY((user)) expects. (gt_ggc_mx (edge_def *)): Replace call to gt_ggc_mx on the gimple with gt_ggc_mx_gimple_statement_base: in the pre-GTY((user)) world, "gt_ggc_mx" was the function to be called on a possibly NULL pointed to check if needed marking and if so to traverse its fields. In the GTY((user)) world, "gt_ggc_mx" is the function to be called on non-NULL objects immediately *after* they have been marked: it does not mark the object itself. (gt_pch_nx (gimple&)): Remove declaration. (gt_pch_nx (edge_def *)): Update as per the mx hook. --- gcc/gimple.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/gimple.h | 6 ++ gcc/tree-cfg.c | 6 +- 3 files changed, 277 insertions(+), 4 deletions(-) diff --git a/gcc/gimple.c b/gcc/gimple.c index 1ad36d1..a5b4799 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -4338,4 +4338,273 @@ build_type_cast (tree to_type, gimple op, enum ssa_mode mode) return build_type_cast (to_type, gimple_assign_lhs (op), mode); } +void +gt_ggc_mx (gimple gs) +{ + gimple x = gs; + /* Emulation of the "chain_next" GTY attribute. + + gs has already been marked. + Iterate the chain of next statements, marking until we reach one that + has already been marked, or NULL. */ + gimple xlimit = gs->next; + while (ggc_test_and_set_mark (xlimit)) + xlimit = xlimit->next; + + /* All of the statements within the half-open interval [x..xlimit) have + just been marked. Iterate through the list, visiting their fields. */ + while (x != xlimit) + { + gt_ggc_m_15basic_block_def (x->bb); + switch (gimple_statement_structure (&((*x)))) + { + case GSS_BASE: + break; + case GSS_WITH_OPS: + { + gimple_statement_with_ops *stmt + = static_cast <gimple_statement_with_ops *> (x); + size_t num = (size_t)(stmt->num_ops); + for (size_t i = 0; i != num; i++) + gt_ggc_m_9tree_node (stmt->op[i]); + } + break; + case GSS_WITH_MEM_OPS_BASE: + break; + case GSS_WITH_MEM_OPS: + { + gimple_statement_with_memory_ops *stmt + = static_cast <gimple_statement_with_memory_ops *> (x); + size_t num = (size_t)(stmt->num_ops); + for (size_t i = 0; i != num; i++) + gt_ggc_m_9tree_node (stmt->op[i]); + } + break; + case GSS_CALL: + { + gimple_statement_call *stmt + = static_cast <gimple_statement_call *> (x); + gt_ggc_m_15bitmap_head_def (stmt->call_used.vars); + gt_ggc_m_15bitmap_head_def (stmt->call_clobbered.vars); + switch (stmt->subcode & GF_CALL_INTERNAL) + { + case 0: + gt_ggc_m_9tree_node (stmt->u.fntype); + break; + case GF_CALL_INTERNAL: + break; + default: + break; + } + size_t num = (size_t)(stmt->num_ops); + for (size_t i = 0; i != num; i++) + gt_ggc_m_9tree_node (stmt->op[i]); + } + break; + case GSS_OMP: + { + gimple_statement_omp *stmt + = static_cast <gimple_statement_omp *> (x); + gt_ggc_mx_gimple_statement_base (stmt->body); + } + break; + case GSS_BIND: + { + gimple_statement_bind *stmt + = static_cast <gimple_statement_bind *> (x); + gt_ggc_m_9tree_node (stmt->vars); + gt_ggc_m_9tree_node (stmt->block); + gt_ggc_mx_gimple_statement_base (stmt->body); + } + break; + case GSS_CATCH: + { + gimple_statement_catch *stmt + = static_cast <gimple_statement_catch *> (x); + gt_ggc_m_9tree_node (stmt->types); + gt_ggc_mx_gimple_statement_base (stmt->handler); + } + break; + case GSS_EH_FILTER: + { + gimple_statement_eh_filter *stmt + = static_cast <gimple_statement_eh_filter *> (x); + gt_ggc_m_9tree_node (stmt->types); + gt_ggc_mx_gimple_statement_base (stmt->failure); + } + break; + case GSS_EH_MNT: + { + gimple_statement_eh_mnt *stmt + = static_cast <gimple_statement_eh_mnt *> (x); + gt_ggc_m_9tree_node (stmt->fndecl); + } + break; + case GSS_EH_ELSE: + { + gimple_statement_eh_else*stmt + = static_cast <gimple_statement_eh_else *> (x); + gt_ggc_mx_gimple_statement_base (stmt->n_body); + gt_ggc_mx_gimple_statement_base (stmt->e_body); + } + break; + case GSS_PHI: + { + gimple_statement_phi *stmt + = static_cast <gimple_statement_phi *> (x); + size_t num = (size_t)(stmt->nargs); + gt_ggc_m_9tree_node (stmt->result); + for (size_t i = 0; i != num; i++) + gt_ggc_m_9tree_node (stmt->args[i].def); + } + break; + case GSS_EH_CTRL: + break; + case GSS_TRY: + { + gimple_statement_try *stmt + = static_cast <gimple_statement_try *> (x); + gt_ggc_mx_gimple_statement_base (stmt->eval); + gt_ggc_mx_gimple_statement_base (stmt->cleanup); + } + break; + case GSS_WCE: + { + gimple_statement_wce *stmt + = static_cast <gimple_statement_wce *> (x); + gt_ggc_mx_gimple_statement_base (stmt->cleanup); + } + break; + case GSS_ASM: + { + gimple_statement_asm *stmt + = static_cast <gimple_statement_asm *> (x); + size_t num = (size_t)(stmt->num_ops); + gt_ggc_m_S (stmt->string); + for (size_t i = 0; i != num; i++) + gt_ggc_m_9tree_node (stmt->op[i]); + } + break; + case GSS_OMP_CRITICAL: + { + gimple_statement_omp_critical *stmt + = static_cast <gimple_statement_omp_critical *> (x); + gt_ggc_mx_gimple_statement_base (stmt->body); + gt_ggc_m_9tree_node (stmt->name); + } + break; + case GSS_OMP_FOR: + { + gimple_statement_omp_for *stmt + = static_cast <gimple_statement_omp_for *> (x); + size_t num = (size_t)(stmt->collapse); + gt_ggc_mx_gimple_statement_base (stmt->body); + gt_ggc_m_9tree_node (stmt->clauses); + if (stmt->iter != NULL) { + for (size_t i = 0; i != num; i++) { + gt_ggc_m_9tree_node (stmt->iter[i].index); + gt_ggc_m_9tree_node (stmt->iter[i].initial); + gt_ggc_m_9tree_node (stmt->iter[i].final); + gt_ggc_m_9tree_node (stmt->iter[i].incr); + } + ggc_mark (stmt->iter); + } + gt_ggc_mx_gimple_statement_base (stmt->pre_body); + } + break; + case GSS_OMP_PARALLEL: + { + gimple_statement_omp_parallel *stmt + = static_cast <gimple_statement_omp_parallel *> (x); + gt_ggc_mx_gimple_statement_base (stmt->body); + gt_ggc_m_9tree_node (stmt->clauses); + gt_ggc_m_9tree_node (stmt->child_fn); + gt_ggc_m_9tree_node (stmt->data_arg); + } + break; + case GSS_OMP_TASK: + { + gimple_statement_omp_task *stmt + = static_cast <gimple_statement_omp_task *> (x); + gt_ggc_mx_gimple_statement_base (stmt->body); + gt_ggc_m_9tree_node (stmt->clauses); + gt_ggc_m_9tree_node (stmt->child_fn); + gt_ggc_m_9tree_node (stmt->data_arg); + gt_ggc_m_9tree_node (stmt->copy_fn); + gt_ggc_m_9tree_node (stmt->arg_size); + gt_ggc_m_9tree_node (stmt->arg_align); + } + break; + case GSS_OMP_SECTIONS: + { + gimple_statement_omp_sections *stmt + = static_cast <gimple_statement_omp_sections *> (x); + gt_ggc_mx_gimple_statement_base (stmt->body); + gt_ggc_m_9tree_node (stmt->clauses); + gt_ggc_m_9tree_node (stmt->control); + } + break; + case GSS_OMP_SINGLE: + { + gimple_statement_omp_single *stmt + = static_cast <gimple_statement_omp_single *> (x); + gt_ggc_mx_gimple_statement_base (stmt->body); + gt_ggc_m_9tree_node (stmt->clauses); + } + break; + case GSS_OMP_CONTINUE: + { + gimple_statement_omp_continue *stmt + = static_cast <gimple_statement_omp_continue *> (x); + gt_ggc_m_9tree_node (stmt->control_def); + gt_ggc_m_9tree_node (stmt->control_use); + } + break; + case GSS_OMP_ATOMIC_LOAD: + { + gimple_statement_omp_atomic_load *stmt + = static_cast <gimple_statement_omp_atomic_load *> (x); + gt_ggc_m_9tree_node (stmt->rhs); + gt_ggc_m_9tree_node (stmt->lhs); + } + break; + case GSS_OMP_ATOMIC_STORE: + { + gimple_statement_omp_atomic_store *stmt + = static_cast <gimple_statement_omp_atomic_store *> (x); + gt_ggc_m_9tree_node (stmt->val); + } + break; + case GSS_TRANSACTION: + { + gimple_statement_transaction *stmt + = static_cast <gimple_statement_transaction *> (x); + gt_ggc_mx_gimple_statement_base (stmt->body); + gt_ggc_m_9tree_node (stmt->label); + } + break; + default: + break; + } + x = x->next; + } +} + +void +gt_pch_nx (gimple gs ATTRIBUTE_UNUSED) +{ + /* gimple should not be present in PCH files. */ + gcc_unreachable (); +} + +void +gt_pch_nx (gimple gs ATTRIBUTE_UNUSED, + gt_pointer_operator op ATTRIBUTE_UNUSED, + void *cookie ATTRIBUTE_UNUSED) +{ + /* gimple should not be present in PCH files. */ + gcc_unreachable (); +} + + #include "gt-gimple.h" diff --git a/gcc/gimple.h b/gcc/gimple.h index 0f6eb77..2e865e9 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -222,6 +222,12 @@ struct GTY((user)) gimple_statement_base { gimple GTY((skip)) prev; }; +/* GTY((user)) hooks for gimple, called once per-traversal. */ +void gt_ggc_mx (gimple gs); +void gt_pch_nx (gimple gs); +void gt_pch_nx (gimple gs, gt_pointer_operator op, void *cookie); + + /* Base structure for tuples with operands. */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index af8685c..185c072 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -8291,7 +8291,6 @@ make_pass_warn_unused_result (gcc::context *ctxt) /* Garbage collection support for edge_def. */ extern void gt_ggc_mx (tree&); -extern void gt_ggc_mx (gimple&); extern void gt_ggc_mx (rtx&); extern void gt_ggc_mx (basic_block&); @@ -8302,7 +8301,7 @@ gt_ggc_mx (edge_def *e) gt_ggc_mx (e->src); gt_ggc_mx (e->dest); if (current_ir_type () == IR_GIMPLE) - gt_ggc_mx (e->insns.g); + gt_ggc_mx_gimple_statement_base (e->insns.g); else gt_ggc_mx (e->insns.r); gt_ggc_mx (block); @@ -8311,7 +8310,6 @@ gt_ggc_mx (edge_def *e) /* PCH support for edge_def. */ extern void gt_pch_nx (tree&); -extern void gt_pch_nx (gimple&); extern void gt_pch_nx (rtx&); extern void gt_pch_nx (basic_block&); @@ -8322,7 +8320,7 @@ gt_pch_nx (edge_def *e) gt_pch_nx (e->src); gt_pch_nx (e->dest); if (current_ir_type () == IR_GIMPLE) - gt_pch_nx (e->insns.g); + gt_pch_nx_gimple_statement_base (e->insns.g); else gt_pch_nx (e->insns.r); gt_pch_nx (block); -- 1.7.11.7