void
ssa_block_ranges::set_bb_range (const basic_block bb, const irange &r)
{
+ gcc_checking_assert ((unsigned) bb->index < m_tab.length ());
irange *m = m_irange_allocator->allocate (r);
m_tab[bb->index] = m;
}
void
ssa_block_ranges::set_bb_varying (const basic_block bb)
{
+ gcc_checking_assert ((unsigned) bb->index < m_tab.length ());
m_tab[bb->index] = m_type_range;
}
bool
ssa_block_ranges::get_bb_range (irange &r, const basic_block bb)
{
+ gcc_checking_assert ((unsigned) bb->index < m_tab.length ());
irange *m = m_tab[bb->index];
if (m)
{
bool
ssa_block_ranges::bb_range_p (const basic_block bb)
{
+ gcc_checking_assert ((unsigned) bb->index < m_tab.length ());
return m_tab[bb->index] != NULL;
}
m_ssa_ranges.release ();
}
-// Return a reference to the m_block_cache for NAME. If it has not been
-// accessed yet, allocate it.
+// Return a reference to the ssa_block_cache for NAME. If it has not been
+// accessed yet, allocate it first.
ssa_block_ranges &
block_range_cache::get_block_ranges (tree name)
m_ssa_ranges.safe_grow_cleared (num_ssa_names + 1);
if (!m_ssa_ranges[v])
- m_ssa_ranges[v] = new ssa_block_ranges (TREE_TYPE (name), m_irange_allocator);
-
+ m_ssa_ranges[v] = new ssa_block_ranges (TREE_TYPE (name),
+ m_irange_allocator);
return *(m_ssa_ranges[v]);
}
+
+// Return a pointer to the ssa_block_cache for NAME. If it has not been
+// accessed yet, return NULL.
+
+ssa_block_ranges *
+block_range_cache::query_block_ranges (tree name)
+{
+ unsigned v = SSA_NAME_VERSION (name);
+ if (v >= m_ssa_ranges.length () || !m_ssa_ranges[v])
+ return NULL;
+ return m_ssa_ranges[v];
+}
+
// Set the range for NAME on entry to block BB to R.
void
bool
block_range_cache::get_bb_range (irange &r, tree name, const basic_block bb)
{
- return get_block_ranges (name).get_bb_range (r, bb);
+ ssa_block_ranges *ptr = query_block_ranges (name);
+ if (ptr)
+ return ptr->get_bb_range (r, bb);
+ return false;
}
// Return true if NAME has a range set in block BB.
bool
block_range_cache::bb_range_p (tree name, const basic_block bb)
{
- return get_block_ranges (name).bb_range_p (bb);
+ ssa_block_ranges *ptr = query_block_ranges (name);
+ if (ptr)
+ return ptr->bb_range_p (bb);
+ return false;
}
// Print all known block caches to file F.
m_update_list.release ();
}
+// Dump the global caches to file F. if GORI_DUMP is true, dump the
+// gori map as well.
+
+void
+ranger_cache::dump (FILE *f, bool gori_dump)
+{
+ m_globals.dump (f);
+ if (gori_dump)
+ {
+ fprintf (f, "\nDUMPING GORI MAP\n");
+ gori_compute::dump (f);
+ }
+ fprintf (f, "\n");
+}
+
+// Dump the caches for basic block BB to file F.
+
+void
+ranger_cache::dump (FILE *f, basic_block bb)
+{
+ m_on_entry.dump (f, bb);
+}
+
+// Get the global range for NAME, and return in R. Return false if the
+// global range is not set.
+
+bool
+ranger_cache::get_global_range (irange &r, tree name) const
+{
+ return m_globals.get_global_range (r, name);
+}
+
+// Set the global range of NAME to R.
+
+void
+ranger_cache::set_global_range (tree name, const irange &r)
+{
+ m_globals.set_global_range (name, r);
+}
+
// Push a request for a new lookup in block BB of name. Return true if
// the request is actually made (ie, isn't a duplicate).
iterative_cache_update (name);
}
}
-
}
private:
vec<class ssa_block_ranges *> m_ssa_ranges;
ssa_block_ranges &get_block_ranges (tree name);
+ ssa_block_ranges *query_block_ranges (tree name);
irange_allocator *m_irange_allocator;
};
virtual void ssa_range_in_bb (irange &r, tree name, basic_block bb);
bool block_range (irange &r, basic_block bb, tree name, bool calc = true);
- ssa_global_cache m_globals;
- block_range_cache m_on_entry;
+ bool get_global_range (irange &r, tree name) const;
+ void set_global_range (tree name, const irange &r);
+
non_null_ref m_non_null;
+
+ void dump (FILE *f, bool dump_gori = true);
+ void dump (FILE *f, basic_block bb);
private:
+ ssa_global_cache m_globals;
+ block_range_cache m_on_entry;
void add_to_update (basic_block bb);
void fill_block_cache (tree name, basic_block bb, basic_block def_bb);
void iterative_cache_update (tree name);
// If there is no statement, just get the global value.
if (!stmt)
{
- if (!m_cache.m_globals.get_global_range (r, expr))
+ if (!m_cache.get_global_range (r, expr))
r = gimple_range_global (expr);
return true;
}
return false;
// If this STMT has already been processed, return that value.
- if (m_cache.m_globals.get_global_range (r, name))
+ if (m_cache.get_global_range (r, name))
return true;
// Avoid infinite recursion by initializing global cache
int_range_max tmp = gimple_range_global (name);
- m_cache.m_globals.set_global_range (name, tmp);
+ m_cache.set_global_range (name, tmp);
calc_stmt (r, s, name);
if (is_a<gphi *> (s))
r.intersect (tmp);
- m_cache.m_globals.set_global_range (name, r);
+ m_cache.set_global_range (name, r);
return true;
}
tree name = ssa_name (x);
if (name && !SSA_NAME_IN_FREE_LIST (name)
&& gimple_range_ssa_p (name)
- && m_cache.m_globals.get_global_range (r, name)
+ && m_cache.get_global_range (r, name)
&& !r.varying_p())
{
// Make sure the new range is a subset of the old range.
edge e;
int_range_max range;
fprintf (f, "\n=========== BB %d ============\n", bb->index);
- m_cache.m_on_entry.dump (f, bb);
+ m_cache.dump (f, bb);
dump_bb (f, bb, 4, TDF_NONE);
tree name = ssa_name (x);
if (gimple_range_ssa_p (name) && SSA_NAME_DEF_STMT (name) &&
gimple_bb (SSA_NAME_DEF_STMT (name)) == bb &&
- m_cache.m_globals.get_global_range (range, name))
+ m_cache.get_global_range (range, name))
{
if (!range.varying_p ())
{
}
}
- m_cache.m_globals.dump (dump_file);
- fprintf (f, "\n");
-
- if (dump_flags & TDF_DETAILS)
- {
- fprintf (f, "\nDUMPING GORI MAP\n");
- m_cache.dump (f);
- fprintf (f, "\n");
- }
+ m_cache.dump (dump_file, (dump_flags & TDF_DETAILS) != 0);
}
// If SCEV has any information about phi node NAME, return it as a range in R.