mirror of https://github.com/gcc-mirror/gcc.git
108 lines
3.8 KiB
C++
108 lines
3.8 KiB
C++
/* Header file for gimple range phi analysis.
|
|
Copyright (C) 2023-2024 Free Software Foundation, Inc.
|
|
Contributed by Andrew MacLeod <amacleod@redhat.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/>. */
|
|
|
|
#ifndef GCC_SSA_RANGE_PHI_H
|
|
#define GCC_SSA_RANGE_PHI_H
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// A PHI_GROUP consists of a set of SSA_NAMES which are all PHI_DEFS, and
|
|
// their arguemnts contain nothing but other PHI defintions, with at most
|
|
// 2 exceptions:
|
|
// 1 - An initial value. This is either a constant, or another non-phi name
|
|
// with a single incoming edge to the cycle group
|
|
// 2 - A modifier statement which adjusts the value. ie, name2 = phi_name + 1
|
|
// The initial range is used to create one bound and the modifier is examined
|
|
// to determine the other bound.
|
|
// All members of the PHI cycle will be given the same range.
|
|
//
|
|
// For example, given the follwoing sequences:
|
|
// qa_20 = qa_10 + 1;
|
|
// qa_9 = PHI <qa_10(3), qa_20(4)>
|
|
// qa_10 = PHI <0(2), qa_9(5)>
|
|
//
|
|
// We can determine the following group:
|
|
//
|
|
// PHI cycle members qa_9, qa_10
|
|
// Initial value : 0
|
|
// modifier stmt: qa_20 = qa_10 + 1;
|
|
//
|
|
// Based on just this analysis, We can project that qa_9 and qa_10 will have
|
|
// a range of [0, +INF].
|
|
|
|
class phi_group
|
|
{
|
|
public:
|
|
phi_group (bitmap bm, irange &init_range, gimple *mod, range_query *q);
|
|
phi_group (const phi_group &g);
|
|
const_bitmap group () const { return m_group; }
|
|
const vrange &range () const { return m_vr; }
|
|
gimple *modifier_stmt () const { return m_modifier; }
|
|
void dump (FILE *);
|
|
protected:
|
|
bool calculate_using_modifier (range_query *q);
|
|
bool refine_using_relation (relation_kind k);
|
|
static unsigned is_modifier_p (gimple *s, const bitmap bm);
|
|
bitmap m_group;
|
|
gimple *m_modifier; // Single stmt which modifies phi group.
|
|
unsigned m_modifier_op; // Operand of group member in modifier stmt.
|
|
int_range_max m_vr;
|
|
friend class phi_analyzer;
|
|
};
|
|
|
|
// The phi anlyzer will return the group that name belongs to.
|
|
// If inforamtion is not known about a name yet, analysis is conducted by
|
|
// looking at the arguments to PHIS and following them to their defs to
|
|
// determine whether the conditions are met to form a new group.
|
|
|
|
class phi_analyzer
|
|
{
|
|
public:
|
|
phi_analyzer (range_query &);
|
|
~phi_analyzer ();
|
|
phi_group *operator[] (tree name);
|
|
void dump (FILE *f);
|
|
protected:
|
|
phi_group *group (tree name) const;
|
|
void process_phi (gphi *phi);
|
|
range_query &m_global;
|
|
vec<tree> m_work;
|
|
|
|
bitmap m_simple; // Processed, not part of a group.
|
|
bitmap m_current; // Potential group currently being analyzed.
|
|
vec<phi_group *> m_phi_groups;
|
|
vec<phi_group *> m_tab;
|
|
bitmap_obstack m_bitmaps;
|
|
};
|
|
|
|
// These are the APIs to start and stop a phi analyzerin a SCEV like manner.
|
|
// There can only be one operating at any given time.
|
|
// When initialized, a range-query if provided to do lookups of values for
|
|
// PHIs and to evaluate modifier and initial value statements.
|
|
// To avoid problems, this should be some form of constant query, like
|
|
// global_range_query or better yet a const_query from a functioning ranger.
|
|
|
|
bool phi_analysis_available_p ();
|
|
phi_analyzer &phi_analysis ();
|
|
void phi_analysis_initialize (range_query &);
|
|
void phi_analysis_finalize ();
|
|
|
|
#endif // GCC_SSA_RANGE_PHI_H
|