GCC Middle and Back End API Reference
tree-ssa-loop-ch.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "gimple-ssa.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "tree-into-ssa.h"
#include "cfgloop.h"
#include "tree-inline.h"
#include "tree-ssa-threadedge.h"
#include "tree-ssa-sccvn.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
#include "value-range.h"
#include "gimple-range.h"
#include "gimple-range-path.h"
#include "gimple-pretty-print.h"
#include "cfganal.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop-niter.h"
#include "tree-scalar-evolution.h"
Include dependency graph for tree-ssa-loop-ch.cc:


enum  ch_decision {
  ch_impossible , ch_possible , ch_possible_zero_cost , ch_win ,


static path_range_queryget_range_query (class loop *loop, basic_block bb, gimple_ranger &ranger)
static edge static_loop_exit (class loop *l, basic_block bb, gimple_ranger &ranger, path_range_query *&query)
static bool loop_static_stmt_p (class loop *loop, gimple_ranger &ranger, path_range_query *&query, gimple *stmt)
static bool loop_invariant_op_p (class loop *loop, tree op)
static bool loop_static_op_p (class loop *loop, tree op)
static bool loop_combined_static_and_iv_p (class loop *loop, tree op)
static ch_decision should_duplicate_loop_header_p (basic_block header, class loop *loop, gimple_ranger *ranger, int *limit, hash_set< edge > *invariant_exits, hash_set< edge > *static_exits)
static bool do_while_loop_p (class loop *loop)
static void update_profile_after_ch (class loop *loop, basic_block *region, basic_block *region_copy, unsigned n_region, hash_set< edge > *invariant_exits, hash_set< edge > *static_exits, profile_count entry_count)
gimple_opt_passmake_pass_ch_vect (gcc::context *ctxt)
gimple_opt_passmake_pass_ch (gcc::context *ctxt)

Enumeration Type Documentation

◆ ch_decision

Decision about posibility of copying a given header.   

Function Documentation

◆ do_while_loop_p()

◆ get_range_query()

static path_range_query * get_range_query ( class loop * loop,
basic_block bb,
gimple_ranger & ranger )
Loop header copying on trees.
   Copyright (C) 2004-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 MERCHANTABILITY or
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
Return path query insteance for testing ranges of statements
in headers of LOOP contained in basic block BB.
Use RANGER instance.   

References loop::header, loop_preheader_edge(), path, ranger, and single_pred_edge().

Referenced by alloca_call_type(), check_bounds_or_overlap(), check_nul_terminated_array(), determine_value_range(), dr_step_indicator(), dump_strlen_info(), tree_switch_conversion::bit_test_cluster::emit(), execute_fast_vrp(), expr_not_equal_to(), expr_to_aff_combination(), find_var_cmp_const(), find_what_p_points_to(), fur_source::fur_source(), strlen_pass::get_len_or_size(), get_range(), get_ref_base_and_extent(), get_size_range(), gori_on_edge(), strlen_pass::handle_integral_assign(), infer_loop_bounds_from_signedness(), insert_into_preds_of_block(), ipa_compute_jump_functions_for_edge(), iv_can_overflow_p(), loop_static_stmt_p(), maybe_diag_stxncpy_trunc(), minmax_from_comparison(), optimize_range_tests_to_bit_test(), fold_using_range::range_of_ssa_name_with_loop_info(), record_nonwrapping_iv(), refine_value_range_using_guard(), scev_var_range_cant_overflow(), set_strlen_range(), set_switch_stmt_execution_predicate(), simplify_conversion_using_ranges(), simplify_rotate(), size_must_be_zero_p(), split_constant_offset(), ssa_name_has_boolean_range(), static_loop_exit(), vect_get_range_info(), and vect_recog_divmod_pattern().

◆ loop_combined_static_and_iv_p()

static bool loop_combined_static_and_iv_p ( class loop * loop,
tree op )
Return true if OP combines outcome of static and
loop invariant conditional.   

References flow_bb_inside_loop_p(), gcc_checking_assert, gimple_bb(), gimple_uid(), is_gimple_min_invariant(), SSA_NAME_DEF_STMT, and SSA_NAME_IS_DEFAULT_DEF.

Referenced by should_duplicate_loop_header_p().

◆ loop_invariant_op_p()

static bool loop_invariant_op_p ( class loop * loop,
tree op )

◆ loop_static_op_p()

static bool loop_static_op_p ( class loop * loop,
tree op )
Return true if OP combines outcome of static and
loop invariant conditional.   

References flow_bb_inside_loop_p(), gcc_checking_assert, gimple_bb(), gimple_uid(), is_gimple_min_invariant(), SSA_NAME_DEF_STMT, and SSA_NAME_IS_DEFAULT_DEF.

Referenced by should_duplicate_loop_header_p().

◆ loop_static_stmt_p()

static bool loop_static_stmt_p ( class loop * loop,
gimple_ranger & ranger,
path_range_query *& query,
gimple * stmt )
Return true if STMT is static in LOOP.  This means that its value
is constant in the first iteration.
Use RANGER and formulate query cached in QUERY.   

References get_range_query(), gimple_bb(), gimple_range_type(), r, path_range_query::range_of_stmt(), ranger, and value_range::supports_type_p().

Referenced by should_duplicate_loop_header_p().

◆ make_pass_ch()

gimple_opt_pass * make_pass_ch ( gcc::context * ctxt)

◆ make_pass_ch_vect()

gimple_opt_pass * make_pass_ch_vect ( gcc::context * ctxt)

◆ should_duplicate_loop_header_p()

◆ static_loop_exit()

static edge static_loop_exit ( class loop * l,
basic_block bb,
gimple_ranger & ranger,
path_range_query *& query )
Return edge that is true in the first iteration of the loop
and NULL otherwise.
Formulate corrent ranger query to RANGER.   

References extract_true_false_edges_from_block(), get_range_query(), gimple_bb(), gsi_last_bb(), last, loop_exit_edge_p(), NULL, r, range_false(), path_range_query::range_of_stmt(), range_true(), ranger, and safe_dyn_cast().

Referenced by should_duplicate_loop_header_p().

◆ update_profile_after_ch()

static void update_profile_after_ch ( class loop * loop,
basic_block * region,
basic_block * region_copy,
unsigned n_region,
hash_set< edge > * invariant_exits,
hash_set< edge > * static_exits,
profile_count entry_count )
Update profile after header copying of LOOP.
REGION is the original (in loop) sequence, REGION_COPY is the
duplicated header (now outside of loop). N_REGION is number of
bbs duplicated.
ELIMINATED_EDGE is edge to be removed from duplicated sequence.
INVARIANT_EXITS are edges in the loop body to be elimianted
since they are loop invariants

So We expect the following:

   // region_copy_start entry will be scaled to entry_count
      if (cond1)         <- this condition will become false
                       and we update probabilities
        goto loop_exit;
      if (cond2)         <- this condition is loop invariant
        goto loop_exit;
      goto loop_header   <- this will be redirected to loop.
    // region_copy_end
    // region start
            if (cond1)   <- we need to update probability here
         goto loop_exit;
            if (cond2)   <- and determine scaling factor here.
                       moreover cond2 is now always true
         goto loop_exit;
         goto loop;
    // region end

  Adding support for more exits can be done similarly,
  but only consumer so far is tree-ssa-loop-ch and it uses only this
  to handle the common case of peeling headers which have
  conditionals known to be always true upon entry.   

References profile_probability::always(), as_a(), hash_set< KeyId, Lazy, Traits >::contains(), basic_block_def::count, EDGE_COUNT, EDGE_SUCC, gcc_assert, gcc_checking_assert, gimple_cond_make_false(), gimple_cond_make_true(), gsi_last_bb(), i, hash_set< KeyId, Lazy, Traits >::is_empty(), loop_exit_edge_p(), profile_probability::never(), profile_count::nonzero_p(), profile_count::probability_in(), hash_set< KeyId, Lazy, Traits >::remove(), set_edge_probability_and_rescale_others(), update_bb_profile_for_threading(), and update_stmt().