GCC Middle and Back End API Reference
tree-cfgcleanup.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "cfganal.h"
#include "cfgcleanup.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-ssa-loop-manip.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "gimple-match.h"
#include "gimple-fold.h"
#include "tree-ssa-loop-niter.h"
#include "cgraph.h"
#include "tree-into-ssa.h"
#include "tree-cfgcleanup.h"
Include dependency graph for tree-cfgcleanup.cc:


static bool remove_fallthru_edge (vec< edge, va_gc > *ev)
static bool convert_single_case_switch (gswitch *swtch, gimple_stmt_iterator &gsi)
static bool cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
static void cleanup_call_ctrl_altering_flag (basic_block bb, gimple *bb_end)
static bool cleanup_control_flow_bb (basic_block bb)
static bool tree_forwarder_block_p (basic_block bb, bool phi_wanted)
bool phi_alternatives_equal (basic_block dest, edge e1, edge e2)
static void move_debug_stmts_from_forwarder (basic_block src, basic_block dest, bool dest_single_pred_p, basic_block pred, bool pred_single_succ_p)
static bool remove_forwarder_block (basic_block bb)
bool fixup_noreturn_call (gimple *stmt)
static bool want_merge_blocks_p (basic_block bb1, basic_block bb2)
static bool cleanup_tree_cfg_bb (basic_block bb)
static bool maybe_dead_abnormal_edge_p (edge e)
static edge builtin_setjmp_setup_bb (basic_block bb)
static bool cleanup_control_flow_pre ()
static bool mfb_keep_latches (edge e)
static bool cleanup_tree_cfg_noloop (unsigned ssa_update_flags)
static void repair_loop_structures (void)
bool cleanup_tree_cfg (unsigned ssa_update_flags)
static bool remove_forwarder_block_with_phi (basic_block bb)
gimple_opt_passmake_pass_merge_phi (gcc::context *ctxt)
static unsigned int execute_cleanup_cfg_post_optimizing (void)
gimple_opt_passmake_pass_cleanup_cfg_post_optimizing (gcc::context *ctxt)
bool delete_unreachable_blocks_update_callgraph (cgraph_node *dst_node, bool update_clones)


bitmap cfgcleanup_altered_bbs

Function Documentation

◆ builtin_setjmp_setup_bb()

static edge builtin_setjmp_setup_bb ( basic_block bb)
If BB is a basic block ending with __builtin_setjmp_setup, return edge
from .ABNORMAL_DISPATCHER basic block to corresponding
__builtin_setjmp_receiver basic block, otherwise return NULL.   

References cfun, EDGE_COUNT, EDGE_PRED, EDGE_SUCC, gimple_call_arg(), gimple_call_builtin_p(), gsi_end_p(), gsi_last_nondebug_bb(), gsi_stmt(), label_to_block(), NULL, basic_block_def::preds, basic_block_def::succs, TREE_CODE, and TREE_OPERAND.

Referenced by cleanup_control_flow_pre().

◆ cleanup_call_ctrl_altering_flag()

static void cleanup_call_ctrl_altering_flag ( basic_block bb,
gimple * bb_end )

◆ cleanup_control_expr_graph()

◆ cleanup_control_flow_bb()

◆ cleanup_control_flow_pre()

◆ cleanup_tree_cfg()

◆ cleanup_tree_cfg_bb()

static bool cleanup_tree_cfg_bb ( basic_block bb)
Tries to cleanup cfg in basic block BB by merging blocks.  Returns
true if anything changes.   

References bitmap_set_bit, cfgcleanup_altered_bbs, merge_blocks(), remove_forwarder_block(), single_pred(), single_pred_p(), single_succ(), single_succ_p(), tree_forwarder_block_p(), and want_merge_blocks_p().

Referenced by cleanup_tree_cfg_noloop().

◆ cleanup_tree_cfg_noloop()

◆ convert_single_case_switch()

◆ delete_unreachable_blocks_update_callgraph()

bool delete_unreachable_blocks_update_callgraph ( cgraph_node * dst_node,
bool update_clones )

◆ execute_cleanup_cfg_post_optimizing()

static unsigned int execute_cleanup_cfg_post_optimizing ( void )
Pass: cleanup the CFG just before expanding trees to RTL.
This is just a round of label cleanups and case node grouping
because after the tree optimizers have run such cleanups may
be necessary.   

References cleanup_dead_labels(), cleanup_tree_cfg(), dump_enumerated_decls(), dump_flags, error(), execute_fixup_cfg(), fopen, group_case_labels(), maybe_remove_unreachable_handlers(), NULL, TDF_NOUID, TDF_SLIM, todo, TODO_cleanup_cfg, and TODO_update_ssa.

◆ fixup_noreturn_call()

◆ make_pass_cleanup_cfg_post_optimizing()

gimple_opt_pass * make_pass_cleanup_cfg_post_optimizing ( gcc::context * ctxt)

◆ make_pass_merge_phi()

gimple_opt_pass * make_pass_merge_phi ( gcc::context * ctxt)

◆ maybe_dead_abnormal_edge_p()

static bool maybe_dead_abnormal_edge_p ( edge e)
Return true if E is an EDGE_ABNORMAL edge for returns_twice calls,
i.e. one going from .ABNORMAL_DISPATCHER to basic block which doesn't
start with a forced or nonlocal label.  Calls which return twice can return
the second time only if they are called normally the first time, so basic
blocks which can be only entered through these abnormal edges but not
normally are effectively unreachable as well.  Additionally ignore
__builtin_setjmp_receiver starting blocks, which have one FORCED_LABEL
and which are always only reachable through EDGE_ABNORMAL edge.  They are
handled in cleanup_control_flow_pre.   

References DECL_NONLOCAL, dyn_cast(), FORCED_LABEL, g, gimple_call_arg(), gimple_call_builtin_p(), gimple_call_internal_p(), gimple_label_label(), gsi_end_p(), gsi_next(), gsi_next_nondebug(), gsi_start_bb(), gsi_start_nondebug_after_labels_bb(), gsi_stmt(), is_gimple_debug(), NULL_TREE, TREE_CODE, and TREE_OPERAND.

Referenced by cleanup_control_flow_pre().

◆ mfb_keep_latches()

static bool mfb_keep_latches ( edge e)

◆ move_debug_stmts_from_forwarder()

static void move_debug_stmts_from_forwarder ( basic_block src,
basic_block dest,
bool dest_single_pred_p,
basic_block pred,
bool pred_single_succ_p )

◆ phi_alternatives_equal()

bool phi_alternatives_equal ( basic_block dest,
edge e1,
edge e2 )
If all the PHI nodes in DEST have alternatives for E1 and E2 and
those alternatives are equal in each of the PHI nodes, then return
true, else return false.   

References gcc_assert, gimple_phi_arg_def(), gsi_end_p(), gsi_next(), gsi_start_phis(), NULL_TREE, operand_equal_for_phi_arg_p(), and gphi_iterator::phi().

Referenced by tree_switch_conversion::switch_conversion::collect(), remove_forwarder_block(), and remove_forwarder_block_with_phi().

◆ remove_fallthru_edge()

static bool remove_fallthru_edge ( vec< edge, va_gc > * ev)
Remove any fallthru edge from EV.  Return true if an edge was removed.   

References EDGE_COMPLEX, FOR_EACH_EDGE, and remove_edge_and_dominated_blocks().

Referenced by cleanup_control_flow_bb().

◆ remove_forwarder_block()

◆ remove_forwarder_block_with_phi()

◆ repair_loop_structures()

◆ tree_forwarder_block_p()

static bool tree_forwarder_block_p ( basic_block bb,
bool phi_wanted )

◆ want_merge_blocks_p()

static bool want_merge_blocks_p ( basic_block bb1,
basic_block bb2 )
Return true if we want to merge BB1 and BB2 into a single block.   

References can_merge_blocks_p(), basic_block_def::count, gsi_end_p(), gsi_last_nondebug_bb(), gsi_stmt(), profile_count::ok_for_merging(), and stmt_can_terminate_bb_p().

Referenced by cleanup_tree_cfg_bb().

Variable Documentation

◆ cfgcleanup_altered_bbs

bitmap cfgcleanup_altered_bbs
CFG cleanup for trees.
   Copyright (C) 2001-2024 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
The set of blocks in that at least one of the following changes happened:
-- the statement at the end of the block was changed
-- the block was newly created
-- the set of the predecessors of the block changed
-- the set of the successors of the block changed
??? Maybe we could track these changes separately, since they determine
    what cleanups it makes sense to try on the block.   

Referenced by cleanup_control_expr_graph(), cleanup_control_flow_bb(), cleanup_tree_cfg_bb(), cleanup_tree_cfg_noloop(), gimple_merge_blocks(), remove_edge_and_dominated_blocks(), remove_forwarder_block(), and replace_uses_by().