GCC Middle and Back End API Reference
gimple-harden-control-flow.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "memmodel.h"
#include "tm_p.h"
#include "tree.h"
#include "fold-const.h"
#include "gimple.h"
#include "gimplify.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-iterator.h"
#include "gimple-pretty-print.h"
#include "tree-cfg.h"
#include "tree-cfgcleanup.h"
#include "tree-eh.h"
#include "except.h"
#include "sbitmap.h"
#include "basic-block.h"
#include "cfghooks.h"
#include "cfgloop.h"
#include "cgraph.h"
#include "alias.h"
#include "varasm.h"
#include "output.h"
#include "langhooks.h"
#include "diagnostic.h"
#include "intl.h"
Include dependency graph for gimple-harden-control-flow.cc:

Data Structures

class  rt_bb_visited
 

Macros

#define INCLUDE_ALGORITHM   /* find @endverbatim */
 

Typedefs

typedef auto_vec< edge, 10 > chk_edges_t
 

Functions

static bool check_returning_calls_p ()
 
static gimplehardcfr_scan_block (basic_block bb, tree **retptr)
 
static bool returning_call_p (gcall *call)
 
static bool hardcfr_sibcall_search_preds (basic_block bb, chk_edges_t &chk_edges, int &count_chkcall, auto_sbitmap &chkcall_blocks, int &count_postchk, auto_sbitmap &postchk_blocks, tree *retptr)
 
static bool hardcfr_sibcall_search_block (basic_block bb, chk_edges_t &chk_edges, int &count_chkcall, auto_sbitmap &chkcall_blocks, int &count_postchk, auto_sbitmap &postchk_blocks, tree *retptr)
 
static bool always_throwing_noreturn_call_p (gimple *stmt)
 
gimple_opt_passmake_pass_harden_control_flow_redundancy (gcc::context *ctxt)
 

Macro Definition Documentation

◆ INCLUDE_ALGORITHM

#define INCLUDE_ALGORITHM   /* find @endverbatim */
Control flow redundancy hardening.
   Copyright (C) 2022-2024 Free Software Foundation, Inc.
   Contributed by Alexandre Oliva <oliva@adacore.com>.

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 MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the 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
<http://www.gnu.org/licenses/>.   

Typedef Documentation

◆ chk_edges_t

Function Documentation

◆ always_throwing_noreturn_call_p()

static bool always_throwing_noreturn_call_p ( gimple * stmt)
static
Avoid checking before noreturn calls that are known (expected,
really) to finish by throwing an exception, rather than by ending
the program or looping forever.  Such functions have to be
annotated, with an attribute (expected_throw) or flag (ECF_XTHROW),
so that exception-raising functions, such as C++'s __cxa_throw,
__cxa_rethrow, and Ada's gnat_rcheck_*, gnat_reraise*,
ada.exception.raise_exception*, and the language-independent
unwinders could be detected here and handled differently from other
noreturn functions.   

References ggc_alloc(), gimple_call_expected_throw_p(), and gimple_call_noreturn_p().

◆ check_returning_calls_p()

static bool check_returning_calls_p ( )
static
Return TRUE iff CFR checks should be inserted before returning
calls.   

References ggc_alloc().

Referenced by hardcfr_sibcall_search_block(), and returning_call_p().

◆ hardcfr_scan_block()

static gimple * hardcfr_scan_block ( basic_block bb,
tree ** retptr )
static
Scan BB from the end, updating *RETPTR if given as return stmts and
copies are found.  Return a call or a stmt that cannot appear after
a tail call, or NULL if the top of the block is reached without
finding any.   

References gcc_checking_assert, ggc_alloc(), gimple_assign_lhs(), gimple_assign_rhs1_ptr(), gimple_assign_single_p(), gimple_clobber_p(), gimple_return_retval_ptr(), gsi_end_p(), gsi_last_bb(), gsi_prev(), gsi_stmt(), is_gimple_call(), is_gimple_debug(), and NULL.

Referenced by hardcfr_sibcall_search_block(), and returning_call_p().

◆ hardcfr_sibcall_search_block()

static bool hardcfr_sibcall_search_block ( basic_block bb,
chk_edges_t & chk_edges,
int & count_chkcall,
auto_sbitmap & chkcall_blocks,
int & count_postchk,
auto_sbitmap & postchk_blocks,
tree * retptr )
static
Search backwards from the end of BB for a mandatory or potential
sibcall.  Schedule the block to be handled sort-of like noreturn if
so.  Recurse to preds, with updated RETPTR, if the block only
contains stmts that may follow such a call, scheduling checking at
edges and marking blocks as post-check as needed.  Return true iff,
at the end of the block, a check will have already been
performed.   

References bitmap_set_bit, check_returning_calls_p(), gcc_checking_assert, gcc_unreachable, ggc_alloc(), gimple_call_lhs(), gimple_call_must_tail_p(), gimple_call_noreturn_p(), gimple_call_tail_p(), hardcfr_scan_block(), hardcfr_sibcall_search_preds(), basic_block_def::index, NULL, returning_call_p(), single_succ_edge(), and single_succ_p().

Referenced by hardcfr_sibcall_search_preds().

◆ hardcfr_sibcall_search_preds()

static bool hardcfr_sibcall_search_preds ( basic_block bb,
chk_edges_t & chk_edges,
int & count_chkcall,
auto_sbitmap & chkcall_blocks,
int & count_postchk,
auto_sbitmap & postchk_blocks,
tree * retptr )
static
Declare for mutual recursion.   
Search preds of BB for a mandatory or potential sibcall or
returning call, and arrange for the blocks containing them to have
a check inserted before the call, like noreturn calls.  If any
preds are found to perform checking, schedule checks at the edges
of those that don't, and mark BB as postcheck..   

References bitmap_set_bit, EDGE_COUNT, EDGE_PRED, gcc_checking_assert, gcc_unreachable, ggc_alloc(), gimple_bb(), gimple_phi_arg_def_ptr(), gimple_phi_result(), hardcfr_sibcall_search_block(), i, basic_block_def::index, NULL, NUM_FIXED_BLOCKS, basic_block_def::preds, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, and TREE_CODE.

Referenced by hardcfr_sibcall_search_block().

◆ make_pass_harden_control_flow_redundancy()

gimple_opt_pass * make_pass_harden_control_flow_redundancy ( gcc::context * ctxt)
Instantiate a hardcfr pass.   

References ggc_alloc().

◆ returning_call_p()

static bool returning_call_p ( gcall * call)
static
Return TRUE iff CALL is to be preceded by a CFR checkpoint, i.e.,
if it's a returning call (one whose result is ultimately returned
without intervening non-copy statements) and we're checking
returning calls, a __builtin_return call (noreturn with a path to
the exit block), a must-tail call, or a tail call.   

References cfun, check_returning_calls_p(), EDGE_COUNT, EDGE_PRED, EXIT_BLOCK_PTR_FOR_FN, gcc_checking_assert, ggc_alloc(), gimple_bb(), gimple_call_lhs(), gimple_call_must_tail_p(), gimple_call_noreturn_p(), gimple_call_tail_p(), gimple_phi_arg_def_ptr(), gimple_phi_result(), hardcfr_scan_block(), i, n_basic_blocks_for_fn, NULL, NUM_FIXED_BLOCKS, path, basic_block_def::preds, single_succ(), single_succ_edge(), single_succ_p(), SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, and TREE_CODE.

Referenced by hardcfr_sibcall_search_block().