- USE_OPS (stmt) = new_list.next;
-
-#ifdef ENABLE_CHECKING
- {
- unsigned x = 0;
- for (ptr = USE_OPS (stmt); ptr; ptr = ptr->next)
- x++;
-
- gcc_assert (x == VEC_length (tree, build_uses));
- }
-#endif
-}
-
-
-/* Takes elements from BUILD_VDEFS and turns them into vdef operands of
- STMT. FIXME, for now VDEF operators should have a single operand
- in their RHS. */
-
-static inline void
-finalize_ssa_vdefs (tree stmt)
-{
- unsigned new_i;
- struct voptype_d new_list;
- voptype_p old_ops, ptr, last;
- stmt_ann_t ann = stmt_ann (stmt);
-
- /* Set the symbols referenced by STMT. */
- if (!bitmap_empty_p (build_stores))
- {
- if (ann->operands.stores == NULL)
- ann->operands.stores = BITMAP_ALLOC (&operands_bitmap_obstack);
-
- bitmap_copy (ann->operands.stores, build_stores);
- }
- else
- BITMAP_FREE (ann->operands.stores);
-
- /* If aliases have not been computed, do not instantiate a virtual
- operator on STMT. Initially, we only compute the SSA form on
- GIMPLE registers. The virtual SSA form is only computed after
- alias analysis, so virtual operators will remain unrenamed and
- the verifier will complain. However, alias analysis needs to
- access symbol load/store information, so we need to compute
- those. */
- if (!gimple_aliases_computed_p (cfun))
- return;
-
- new_list.next = NULL;
- last = &new_list;
-
- old_ops = VDEF_OPS (stmt);
- new_i = 0;
- while (old_ops && new_i < VEC_length (tree, build_vdefs))
- {
- tree op = VEC_index (tree, build_vdefs, new_i);
- unsigned new_uid = get_name_decl (op);
- unsigned old_uid = get_name_decl (VDEF_RESULT (old_ops));
-
- /* FIXME, for now each VDEF operator should have at most one
- operand in their RHS. */
- gcc_assert (VDEF_NUM (old_ops) == 1);
-
- if (old_uid == new_uid)
- {
- /* If the symbols are the same, reuse the existing operand. */
- last->next = old_ops;
- last = old_ops;
- old_ops = old_ops->next;
- last->next = NULL;
- set_virtual_use_link (VDEF_OP_PTR (last, 0), stmt);
- new_i++;
- }
- else if (old_uid < new_uid)
- {
- /* If old is less than new, old goes to the free list. */
- voptype_p next;
- delink_imm_use (VDEF_OP_PTR (old_ops, 0));
- next = old_ops->next;
- add_vop_to_freelist (old_ops);
- old_ops = next;
- }
- else
- {
- /* This is a new operand. */
- last = add_vdef_op (stmt, op, 1, last);
- new_i++;
- }
- }
-
- /* If there is anything remaining in BUILD_VDEFS, simply emit it. */
- for ( ; new_i < VEC_length (tree, build_vdefs); new_i++)
- last = add_vdef_op (stmt, VEC_index (tree, build_vdefs, new_i), 1, last);
-
- /* If there is anything in the old list, free it. */
- if (old_ops)
- {
- for (ptr = old_ops; ptr; ptr = last)
- {
- last = ptr->next;
- delink_imm_use (VDEF_OP_PTR (ptr, 0));
- add_vop_to_freelist (ptr);
- }
- }
-
- /* Now set STMT's operands. */
- VDEF_OPS (stmt) = new_list.next;
-
-#ifdef ENABLE_CHECKING
- {
- unsigned x = 0;
- for (ptr = VDEF_OPS (stmt); ptr; ptr = ptr->next)
- x++;
-
- gcc_assert (x == VEC_length (tree, build_vdefs));
- }
-#endif
-}
-
-
-/* Takes elements from BUILD_VUSES and turns them into VUSE operands of
- STMT. */
-
-static inline void
-finalize_ssa_vuse_ops (tree stmt)
-{
- unsigned new_i, old_i;
- voptype_p old_ops, last;
- VEC(tree,heap) *new_ops;
- stmt_ann_t ann;
-
- /* Set the symbols referenced by STMT. */
- ann = stmt_ann (stmt);
- if (!bitmap_empty_p (build_loads))
- {
- if (ann->operands.loads == NULL)
- ann->operands.loads = BITMAP_ALLOC (&operands_bitmap_obstack);
-
- bitmap_copy (ann->operands.loads, build_loads);
- }
- else
- BITMAP_FREE (ann->operands.loads);
-
- /* If aliases have not been computed, do not instantiate a virtual
- operator on STMT. Initially, we only compute the SSA form on
- GIMPLE registers. The virtual SSA form is only computed after
- alias analysis, so virtual operators will remain unrenamed and
- the verifier will complain. However, alias analysis needs to
- access symbol load/store information, so we need to compute
- those. */
- if (!gimple_aliases_computed_p (cfun))
- return;
-
- /* STMT should have at most one VUSE operator. */
- old_ops = VUSE_OPS (stmt);
- gcc_assert (old_ops == NULL || old_ops->next == NULL);
-
- new_ops = NULL;
- new_i = old_i = 0;
- while (old_ops
- && old_i < VUSE_NUM (old_ops)
- && new_i < VEC_length (tree, build_vuses))
- {
- tree new_op = VEC_index (tree, build_vuses, new_i);
- tree old_op = VUSE_OP (old_ops, old_i);
- unsigned new_uid = get_name_decl (new_op);
- unsigned old_uid = get_name_decl (old_op);
-
- if (old_uid == new_uid)
- {
- /* If the symbols are the same, reuse the existing operand. */
- VEC_safe_push (tree, heap, new_ops, old_op);
- new_i++;
- old_i++;
- }
- else if (old_uid < new_uid)
- {
- /* If OLD_UID is less than NEW_UID, the old operand has
- disappeared, skip to the next old operand. */
- old_i++;
- }
- else
- {
- /* This is a new operand. */
- VEC_safe_push (tree, heap, new_ops, new_op);
- new_i++;
- }
- }
-
- /* If there is anything remaining in the build_vuses list, simply emit it. */
- for ( ; new_i < VEC_length (tree, build_vuses); new_i++)
- VEC_safe_push (tree, heap, new_ops, VEC_index (tree, build_vuses, new_i));
-
- /* If there is anything in the old list, free it. */
- if (old_ops)
- {
- for (old_i = 0; old_i < VUSE_NUM (old_ops); old_i++)
- delink_imm_use (VUSE_OP_PTR (old_ops, old_i));
- add_vop_to_freelist (old_ops);
- VUSE_OPS (stmt) = NULL;
- }
-
- /* If there are any operands, instantiate a VUSE operator for STMT. */
- if (new_ops)
- {
- tree op;
- unsigned i;
-
- last = add_vuse_op (stmt, NULL, VEC_length (tree, new_ops), NULL);
-
- for (i = 0; VEC_iterate (tree, new_ops, i, op); i++)
- SET_USE (VUSE_OP_PTR (last, (int) i), op);
-
- VUSE_OPS (stmt) = last;
- VEC_free (tree, heap, new_ops);
- }
-
-#ifdef ENABLE_CHECKING
- {
- unsigned x;
-
- if (VUSE_OPS (stmt))
- {
- gcc_assert (VUSE_OPS (stmt)->next == NULL);
- x = VUSE_NUM (VUSE_OPS (stmt));
- }
- else
- x = 0;
-
- gcc_assert (x == VEC_length (tree, build_vuses));
- }
-#endif
-}
-
-/* Return a new VUSE operand vector for STMT. */
-
-static void
-finalize_ssa_vuses (tree stmt)
-{
- unsigned num, num_vdefs;
- unsigned vuse_index;
-
- /* Remove superfluous VUSE operands. If the statement already has a
- VDEF operator for a variable 'a', then a VUSE for 'a' is not
- needed because VDEFs imply a VUSE of the variable. For instance,
- suppose that variable 'a' is pointed-to by p and q:
-
- # VUSE <a_2>
- # a_3 = VDEF <a_2>
- *p = *q;
-
- The VUSE <a_2> is superfluous because it is implied by the
- VDEF operator. */
- num = VEC_length (tree, build_vuses);
- num_vdefs = VEC_length (tree, build_vdefs);
-
- if (num > 0 && num_vdefs > 0)
- for (vuse_index = 0; vuse_index < VEC_length (tree, build_vuses); )
- {
- tree vuse;
- vuse = VEC_index (tree, build_vuses, vuse_index);
- if (TREE_CODE (vuse) != SSA_NAME)
- {
- var_ann_t ann = var_ann (vuse);
- ann->in_vuse_list = 0;
- if (ann->in_vdef_list)
- {
- VEC_ordered_remove (tree, build_vuses, vuse_index);
- continue;
- }
- }
- vuse_index++;
- }
-
- finalize_ssa_vuse_ops (stmt);