#include "basic-block.h"
#include "cfgloop.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
know their exact value. */
static bitmap nonzero_vars;
+/* Bitmap of blocks that are scheduled to be threaded through. This
+ is used to communicate with thread_through_blocks. */
+static bitmap threaded_blocks;
+
/* Stack of SSA_NAMEs which need their NONZERO_VARS property cleared
when the current block is finalized.
with useful information is very low. */
static htab_t vrp_data;
+typedef struct vrp_element *vrp_element_p;
+
+DEF_VEC_P(vrp_element_p);
+DEF_VEC_ALLOC_P(vrp_element_p,heap);
+
/* An entry in the VRP_DATA hash table. We record the variable and a
varray of VRP_ELEMENT records associated with that variable. */
struct vrp_hash_elt
{
tree var;
- varray_type records;
+ VEC(vrp_element_p,heap) *records;
};
/* Array of variables which have their values constrained by operations
}
}
+/* Free an instance of vrp_hash_elt. */
+
+static void
+vrp_free (void *data)
+{
+ struct vrp_hash_elt *elt = data;
+ struct VEC(vrp_element_p,heap) **vrp_elt = &elt->records;
+
+ VEC_free (vrp_element_p, heap, *vrp_elt);
+ free (elt);
+}
+
/* Jump threading, redundancy elimination and const/copy propagation.
This pass may expose new symbols that need to be renamed into SSA. For
/* Create our hash tables. */
avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free);
- vrp_data = htab_create (ceil_log2 (num_ssa_names), vrp_hash, vrp_eq, free);
+ vrp_data = htab_create (ceil_log2 (num_ssa_names), vrp_hash, vrp_eq,
+ vrp_free);
avail_exprs_stack = VEC_alloc (tree, heap, 20);
const_and_copies_stack = VEC_alloc (tree, heap, 20);
nonzero_vars_stack = VEC_alloc (tree, heap, 20);
vrp_variables_stack = VEC_alloc (tree, heap, 20);
stmts_to_rescan = VEC_alloc (tree, heap, 20);
nonzero_vars = BITMAP_ALLOC (NULL);
+ threaded_blocks = BITMAP_ALLOC (NULL);
need_eh_cleanup = BITMAP_ALLOC (NULL);
/* Setup callbacks for the generic dominator tree walker. */
/* Recursively walk the dominator tree optimizing statements. */
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
- /* If we exposed any new variables, go ahead and put them into
- SSA form now, before we handle jump threading. This simplifies
- interactions between rewriting of _DECL nodes into SSA form
- and rewriting SSA_NAME nodes into SSA form after block
- duplication and CFG manipulation. */
- update_ssa (TODO_update_ssa);
-
- free_all_edge_infos ();
-
{
block_stmt_iterator bsi;
basic_block bb;
}
}
+ /* If we exposed any new variables, go ahead and put them into
+ SSA form now, before we handle jump threading. This simplifies
+ interactions between rewriting of _DECL nodes into SSA form
+ and rewriting SSA_NAME nodes into SSA form after block
+ duplication and CFG manipulation. */
+ update_ssa (TODO_update_ssa);
+
+ free_all_edge_infos ();
+
/* Thread jumps, creating duplicate blocks as needed. */
- cfg_altered |= thread_through_all_blocks ();
+ cfg_altered |= thread_through_all_blocks (threaded_blocks);
/* Removal of statements may make some EH edges dead. Purge
such edges from the CFG as needed. */
/* Reinitialize the various tables. */
bitmap_clear (nonzero_vars);
+ bitmap_clear (threaded_blocks);
htab_empty (avail_exprs);
htab_empty (vrp_data);
/* Free nonzero_vars. */
BITMAP_FREE (nonzero_vars);
+ BITMAP_FREE (threaded_blocks);
BITMAP_FREE (need_eh_cleanup);
VEC_free (tree, heap, avail_exprs_stack);
else
edge_info = allocate_edge_info (e);
edge_info->redirection_target = taken_edge;
- bb_ann (e->dest)->incoming_edge_threaded = true;
+ bitmap_set_bit (threaded_blocks, e->dest->index);
}
}
}
the array backwards popping off records associated with our
block. Once we hit a record not associated with our block
we are done. */
- varray_type var_vrp_records;
+ VEC(vrp_element_p,heap) **var_vrp_records;
if (var == NULL)
break;
slot = htab_find_slot (vrp_data, &vrp_hash_elt, NO_INSERT);
vrp_hash_elt_p = (struct vrp_hash_elt *) *slot;
- var_vrp_records = vrp_hash_elt_p->records;
+ var_vrp_records = &vrp_hash_elt_p->records;
- while (VARRAY_ACTIVE_SIZE (var_vrp_records) > 0)
+ while (VEC_length (vrp_element_p, *var_vrp_records) > 0)
{
struct vrp_element *element
- = (struct vrp_element *)VARRAY_TOP_GENERIC_PTR (var_vrp_records);
+ = VEC_last (vrp_element_p, *var_vrp_records);
if (element->bb != bb)
break;
- VARRAY_POP (var_vrp_records);
+ VEC_pop (vrp_element_p, *var_vrp_records);
}
}
int limit;
tree low, high, cond_low, cond_high;
int lowequal, highequal, swapped, no_overlap, subset, cond_inverted;
- varray_type vrp_records;
+ VEC(vrp_element_p,heap) **vrp_records;
struct vrp_element *element;
struct vrp_hash_elt vrp_hash_elt, *vrp_hash_elt_p;
void **slot;
return NULL;
vrp_hash_elt_p = (struct vrp_hash_elt *) *slot;
- vrp_records = vrp_hash_elt_p->records;
- if (vrp_records == NULL)
- return NULL;
+ vrp_records = &vrp_hash_elt_p->records;
- limit = VARRAY_ACTIVE_SIZE (vrp_records);
+ limit = VEC_length (vrp_element_p, *vrp_records);
/* If we have no value range records for this variable, or we are
unable to extract a range for this condition, then there is
conditional into the current range.
These properties also help us avoid unnecessary work. */
- element
- = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records, limit - 1);
+ element = VEC_last (vrp_element_p, *vrp_records);
if (element->high && element->low)
{
{
/* Get the high/low value from the previous element. */
struct vrp_element *prev
- = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records,
- limit - 2);
+ = VEC_index (vrp_element_p, *vrp_records, limit - 2);
low = prev->low;
high = prev->high;
{
struct vrp_hash_elt *vrp_hash_elt;
struct vrp_element *element;
- varray_type *vrp_records_p;
+ VEC(vrp_element_p,heap) **vrp_records_p;
void **slot;
if (*slot == NULL)
*slot = (void *) vrp_hash_elt;
else
- free (vrp_hash_elt);
+ vrp_free (vrp_hash_elt);
vrp_hash_elt = (struct vrp_hash_elt *) *slot;
vrp_records_p = &vrp_hash_elt->records;
element->cond = cond;
element->bb = bb;
- if (*vrp_records_p == NULL)
- VARRAY_GENERIC_PTR_INIT (*vrp_records_p, 2, "vrp records");
-
- VARRAY_PUSH_GENERIC_PTR (*vrp_records_p, element);
+ VEC_safe_push (vrp_element_p, heap, *vrp_records_p, element);
VEC_safe_push (tree, heap, vrp_variables_stack, TREE_OPERAND (cond, 0));
}
}