GCC Middle and Back End API Reference
unswitch_predicate Struct Reference
Collaboration diagram for unswitch_predicate:

Public Member Functions

 unswitch_predicate (tree cond, tree lhs_, int edge_index_, edge e, const int_range_max &edge_range)
 unswitch_predicate (gcond *stmt)
void copy_merged_ranges ()

Data Fields

tree condition
tree lhs
int_range_max true_range = {}
int_range_max false_range = {}
int_range_max merged_true_range = {}
int_range_max merged_false_range = {}
int edge_index
profile_count count
bool switch_p
unsigned num

Static Public Attributes

static vec< unswitch_predicate * > * predicates

Detailed Description

Loop unswitching. Copyright (C) 2004-2025 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 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/>.
This file implements the loop unswitching, i.e. transformation of loops like while (A) { if (inv) B; X; if (!inv) C; } where inv is the loop invariant, into if (inv) { while (A) { B; X; } } else { while (A) { X; C; } } Inv is considered invariant iff the values it compares are both invariant; tree-ssa-loop-im.cc ensures that all the suitable conditions are in this shape.
Loop unswitching algorithm for innermost loops works in the following steps: 1) Number of instructions is estimated for each BB that belongs to a loop. 2) Unswitching candidates are found for gcond and gswitch statements (note that an unswitching predicate for a gswitch actually corresponds to a non-default edge so it can contain multiple cases). 3) The so called unswitch predicates are stored in a cache where the gimple_uid of the last stmt in a basic-block is an index to the cache. 4) We consider one by one the unswitching candidates and calculate BBs that will be reachable in the unswitch version. 5) A selected predicate is chosen and we simplify the CFG (dead edges) in both versions of the loop. We utilize both Ranger for condition simplification and also symbol equivalence. The folded if conditions are replaced with true/false values, while for gswitch we mark the corresponding edges with a pass-defined unreachable flag. 6) Every time we unswitch a loop, we save unswitch_predicate to a vector together with information if true or false edge was taken. Doing that we have a so called PREDICATE_PATH that is utilized for simplification of the cloned loop. 7) The process is repeated until we reach a growth threshold or all unswitching opportunities are taken.
A tuple that holds a GENERIC condition and value range for an unswitching predicate.

Constructor & Destructor Documentation

◆ unswitch_predicate() [1/2]

unswitch_predicate::unswitch_predicate ( tree cond,
tree lhs_,
int edge_index_,
edge e,
const int_range_max & edge_range )
inline

◆ unswitch_predicate() [2/2]

Member Function Documentation

◆ copy_merged_ranges()

void unswitch_predicate::copy_merged_ranges ( )
inline

Field Documentation

◆ condition

tree unswitch_predicate::condition

◆ count

◆ edge_index

int unswitch_predicate::edge_index

◆ false_range

int_range_max unswitch_predicate::false_range = {}

◆ lhs

tree unswitch_predicate::lhs

◆ merged_false_range

int_range_max unswitch_predicate::merged_false_range = {}

Referenced by copy_merged_ranges().

◆ merged_true_range

int_range_max unswitch_predicate::merged_true_range = {}

Referenced by copy_merged_ranges().

◆ num

unsigned unswitch_predicate::num

◆ predicates

vec< unswitch_predicate * > * unswitch_predicate::predicates
static

◆ switch_p

bool unswitch_predicate::switch_p

◆ true_range

int_range_max unswitch_predicate::true_range = {}

The documentation for this struct was generated from the following file: