mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-22 22:01:20 +08:00
lambda-code.c (gcc_loop_to_lambda_loop, [...]): Use generic operand interface.
2005-05-03 Andrew MacLeod <amacleod@redhat.com> * lambda-code.c (gcc_loop_to_lambda_loop, lambda_loopnest_to_gcc_loopnest, phi_loop_edge_uses_def, stmt_is_bumper_for_loop, perfect_nest_p, replace_uses_of_x_with_y): Use generic operand interface. * tree-data-ref.c (find_data_references_in_loop): Use generic interface. * tree-dfa.c (collect_dfa_stats_r, mark_new_vars_to_rename): Use generic operand interface. * tree-flow-inline.h (delink_imm_use, link_imm_use_to_list, link_imm_use, link_imm_use_stmt, relink_imm_use, relink_imm_use_stmt, next_safe_imm_use, has_zero_uses, has_single_use, single_imm_use, num_imm_uses): Use ssa_use_operand_t. (get_def_ops, get_use_ops, get_v_may_def_ops, get_vuse_ops, get_v_must_def_ops): Delete. (get_def_from_ptr, get_phi_result_ptr): Get def directly now. (get_use_op_ptr, get_def_op_ptr, get_v_may_def_result_ptr, get_v_may_def_op_ptr, get_vuse_op_ptr, get_v_must_def_result_ptr, get_v_must_def_kill_ptr): Delete. (delink_stmt_imm_use): Move and use new operand interface. (op_iter_next_use, op_iter_next_def, op_iter_next_tree, op_iter_init, op_iter_next_tree): Use new operand implementation. (clear_and_done_ssa_iter): New. Initialize a blank operand iterator. (op_iter_init_use, op_iter_init_def, op_iter_init_tree): Add iterator type check. (op_iter_next_mustdef, op_iter_next_maydef, op_iter_next_must_and_may_def): Delete. Replace with... (op_iter_next_maymustdef): New. Combine must and may next operations. (op_iter_init_maydef, op_iter_init_mustdef, op_iter_init_must_and_may_def): Use new interface. (single_ssa_tree_operand ): New. Process single operands only as trees. (single_ssa_use_operand): New. Process single operands only as uses. (single_ssa_def_operand): New. Process single operands only as defs. (zero_ssa_operands): New. Return TRUE if there are zero operands of the specified types. (num_ssa_operands): New. Count the number of specified operands. (compare_ssa_operands_equal): New. Compare two statements' operands. (single_phi_def): New. Return true if PHI has one def of the specified operand type. (op_iter_init_phiuse): New. Initialize the iterator for PHI arguments. (op_iter_init_phidef): New. Initialize the iterator for the PHI def. * tree-flow.h (struct immediate_use_iterator_d): Use ssa_use_operand_t. (struct stmt_ann_d): Operands field no longer require GTY(). (vn_compute, vn_lookup_or_add, vn_add, vn_lookup): Change prototype. * tree-into-ssa.c (mark_def_sites): Use SSA_OP_VMUSTKILL. * tree-outof-ssa.c (check_replaceable, find_replaceable_in_bb, dump_replaceable_exprs, rewrite_trees): Use generic interface. * tree-phinodes.c (make_phi_node, release_phi_node, resize_phi_node): Use use_operand_p instead of ssa_imm_use_t *. * tree-pretty-print.c (dump_vops): check if operands are active before dumping virtual operands. * tree-sra.c (sra_walk_function): Use ZERO_SSA_OPERANDS. * tree-ssa-ccp.c (likely_value): Use ZERO_SSA_OPERANDS. (ccp_fold): Use new interface. (ccp_visit_stmt): Remove unused variables and code. (convert_to_gimple_builtin): Insert statements before calling mark_new_vars_to_rename. * tree-ssa-copy.c (stmt_may_generate_copy): Use ZERO_SSA_OPERANDS. (copy_prop_visit_cond_stmt): Use generic interface. * tree-ssa-dom.c (struct expr_hash_elt): Use stmt pointer, not the annotation in table. (thread_across_edge): Use generic interface. (initialize_hash_element): Initialzie with stmt, not annotation. (eliminate_redundant_computations): Use generic interface. (record_equivalences_from_stmt): Pass stmt, not annotation. (avail_expr_hash, real_avail_expr_hash, avail_expr_eq): Use generic interface. * tree-ssa-dse.c (dse_optimize_stmt): Use ZERO_SSA_OPERANDS. * tree-ssa-loop-ivopts.c (find_invariants_stmt, find_interesting_uses_stmt, protect_loop_closed_ssa_form_use): Use generic operand interface. * tree-ssa-loop-niter.c (chain_of_csts_start, get_val_for): Use generic interface. * tree-ssa-loop-unswitch.c (tree_may_unswitch_on): Use Generic operand Interface. * tree-ssa-operands.c (struct opbuild_list_d): New. Operand build type. (build_defs, build_uses, build_v_may_defs, build_vuses, build_v_must_defs): Change type to struct opbuild_list_d. (ops_active): New. Operands active boolean. (operand_memory, operand_memory_index): New. Operand memory managers. (allocate_def_optype, allocate_use_optype, allocate_v_may_def_optype, allocate_vuse_optype, allocate_v_must_def_optype): Delete. (free_uses, free_defs, free_vuses, free_v_may_defs, free_v_must_defs): Change from functions to static variable list heads. (opbuild_initialize_virtual): New. Initialize a virtual build list. (opbuild_initialize_real): New. Initialize a virtual build list. (opbuild_free): New. Free a build list. (opbuild_num_elems): New. Number of items in a list. (opbuild_append_real): New. Add a real (tree *) operand. (opbuild_append_virtual): New. Add and sort a virtual (tree) operand. (opbuild_first): New. Return first element index in a list. (opbuild_next): New. Return next element in a list. (opbuild_elem_real): New. Return real element. (opbuild_elem_virtual): New. Return virtual element. (opbuild_elem_uid): New. Return UID of virtual element. (opbuild_clear): New. Reset an operand list. (opbuild_remove_elem): New. Remove an element form a list. (ssa_operands_active): New. Return true if operand cache is active. (init_ssa_operands, fini_ssa_operands): Initialize new implementation. (ssa_operand_alloc): New. Allocate memory from an operand chunk. (correct_use_link): Use use_operand_p. (finalize_ssa_uses, finalize_ssa_v_may_defs, finalize_ssa_defs, finalize_ssa_vuses, finalize_ssa_v_must_defs): New implmentation. (cleanup_v_may_defs): Use new implmentation. (finalize_ssa_stmt_operands, start_ssa_stmt_operands): New implementation. (append_def, append_use, append_v_may_def, append_vuse, append_v_must_def): Call opbuild_append routine instead of using varray. (build_ssa_operands): Simplify to simply use stmt, don't maintain a global parse_old_ops variable. (free_ssa_operands): New implementation. (update_stmt_operands): Move. Change argument to build_ssa_operands. (copy_virtual_operands): Move. New generic implementation. (create_ssa_artficial_load_stmt): Move. New implementation. (swap_tree_operands): Update for new implementation. (get_expr_operands): Add stmt parameter to calls to swap_tree_operands. (add_call_clobber_ops, add_call_read_ops): Initialize opbuild list rather than a varray. (verify_imm_links): Use use_operand_p. (dump_immediate_uses_for): If the immediate use variable is a virtual variable, show the virtual ops in the stmt. * tree-ssa-operands.h (def_operand_p): No longer a structure. (NULL_DEF_OPERAND_P): Now a #define. (def_optype_d, use_optype_d, v_def_use_operand_type, v_may_def_optype_d, vuse_operand_type, vuse_optype_d, v_must_def_optype_d): Delete. (def_optype_d, use_optype_d, maydef_optype_d, vuse_optype_d, mustdef_optype_d): New. Use Linked list representation. (SSA_OPERAND_MEMORY_SIZE): New. Size of operand memory chunk. (struct ssa_operand_memory_d): New. Allocated Chunk node. (struct stmt_operands_d): Change to new pointers that are not GTY. (STMT_USE_OPS, NUM_USES, SET_USE_OP, STMT_DEF_OPS, NUM_DEFS, SET_DEF_OP, STMT_V_MAY_DEF_OPS, NUM_V_MAY_DEFS, SET_V_MAY_DEF_RESULT, SET_V_MAY_DEF_OP, STMT_VUSE_OPS, NUM_VUSES, SET_VUSE_OP, STMT_V_MUST_DEF_OPS, NUM_V_MUST_DEFS, SET_V_MUST_DEF_RESULT, SET_V_MUST_DEF_KILL): Delete. (V_MAY_DEF_OPS, V_MAY_DEF_RESULT_PTR, V_MAY_DEF_RESULT, V_MAY_DEF_OP_PTR, V_MAY_DEF_OP): Rename to MAYDEF_*. (V_MUST_DEF_OPS, V_MUST_DEF_RESULT_PTR, V_MUST_DEF_RESULT, V_MUST_DEF_KILL_PTR, V_MUST_DEF_KILL): Rename to MUSTDEF_*. (enum ssa_op_iter_type): Operand iterator typechecking values. (struct ssa_operand_iterator_d): Use linked lists of operands. (SSA_OP_VMUSTDEFKILL): Rename to SSA_OP_VMUSTKILL. (FOR_EACH_SSA_MAYDEF_OPERAND, FOR_EACH_SSA_MUSTDEF_OPERAND, FOR_EACH_SSA_MUST_AND_MAY_DEF_OPERAND): Use op_iter_next_maymustdef. (FOR_EACH_PHI_ARG): New. Iterate over PHI arguments. (FOR_EACH_PHI_OR_STMT_USE): New. Iterate over PHI or stmt uses. (FOR_EACH_PHI_OR_STMT_DEF): New. Iterate over PHI or stmt defs. (SINGLE_SSA_TREE_OPERAND, SINGLE_SSA_USE_OPERAND, SINGLE_SSA_DEF_OPERAND, ZERO_SSA_OPERANDS, NUM_SSA_OPERANDS): New. * tree-ssa-opfinalize.h: New. Function templates for expansion. (FINALIZE_ALLOC): Expands into alloc_def, alloc_use, alloc_maydef, alloc_vuse, and alloc_mustdef. (FINALIZE_FUNC): Expands into finalize_ssa_def_ops, finalize_ssa_use_ops, finalize_ssa_v_may_def_ops, finalize_ssa_vuse_ops, and finalize_ssa_v_must_def_ops. * tree-ssa-pre.c (add_to_sets): Pass tree to vn_add. (create_value_expr_from): Use stmt not vuse_optype as a parameter. Pass stmt around. (compute_avail): Use generic iterator interface. * tree-ssa-propagate.c (first_vdef): Use generic operand interface. (stmt_makes_single_load, stmt_makes_single_store): Use ZERO_SSA_OPERANDS. * tree-ssa-sink.c (is_hidden_global_store): Use ZERO_SSA_OPERANDS. (statement_sink_location): Use generic interface. * tree-ssa.c (verify_ssa): Use %p in fprintf. Use generic interface. (delete_tree_ssa): Don't call release_defs. Call release_ssa_name and reset the immediate use link nodes. (stmt_references_memory_p): Use ZERO_SSA_OPERANDS. * tree-ssanames.c (make_ssa_name): Use use_operand_p. * tree-tailcall.c (find_tail_calls): Use ZERO_SSA_OPERANDS. (eliminate_tail_call): Use generic operand interface. * tree-vect-analyze.c (vect_analyze_data_refs): Use ZERO_SSA_OPERANDS. (vect_mark_relevant, vect_mark_stmts_to_be_vectorized): Use generic interface. * tree-vect-transform.c (update_vuses_to_preheader): Use generic interface. * tree-vectorizer.c (rename_variables_in_bb): Use generic interface. * tree-vn.c (struct val_expr_pair_d): Cache statment pointer instead of vuse_optype. (vn_compute, val_expr_pair_hash, vn_add, vn_lookup, vn_lookup_or_add): Use statement pointer instead of vuse_optype. Use generic interface. * tree-vrp.c (maybe_add_assert_expr): Use generic interface. (stmt_interesting_for_vrp, vrp_visit_stmt): Use ZERO_SSA_OPERANDS. * tree.h (struct ssa_imm_use_d): Renamed to ssa_use_operand_d. (tree_ssa_name, phi_arg_d): Use ssa_use_operand_d. * doc/tree-ssa.texi: Update documentation for operand interface. From-SVN: r99155
This commit is contained in:
parent
992d08b1a1
commit
f47c96aac5
187
gcc/ChangeLog
187
gcc/ChangeLog
@ -1,3 +1,190 @@
|
||||
2005-05-03 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
* lambda-code.c (gcc_loop_to_lambda_loop,
|
||||
lambda_loopnest_to_gcc_loopnest, phi_loop_edge_uses_def,
|
||||
stmt_is_bumper_for_loop, perfect_nest_p, replace_uses_of_x_with_y): Use
|
||||
generic operand interface.
|
||||
* tree-data-ref.c (find_data_references_in_loop): Use generic interface.
|
||||
* tree-dfa.c (collect_dfa_stats_r, mark_new_vars_to_rename): Use
|
||||
generic operand interface.
|
||||
* tree-flow-inline.h (delink_imm_use, link_imm_use_to_list,
|
||||
link_imm_use, link_imm_use_stmt, relink_imm_use, relink_imm_use_stmt,
|
||||
next_safe_imm_use, has_zero_uses, has_single_use, single_imm_use,
|
||||
num_imm_uses): Use ssa_use_operand_t.
|
||||
(get_def_ops, get_use_ops, get_v_may_def_ops, get_vuse_ops,
|
||||
get_v_must_def_ops): Delete.
|
||||
(get_def_from_ptr, get_phi_result_ptr): Get def directly now.
|
||||
(get_use_op_ptr, get_def_op_ptr, get_v_may_def_result_ptr,
|
||||
get_v_may_def_op_ptr, get_vuse_op_ptr, get_v_must_def_result_ptr,
|
||||
get_v_must_def_kill_ptr): Delete.
|
||||
(delink_stmt_imm_use): Move and use new operand interface.
|
||||
(op_iter_next_use, op_iter_next_def, op_iter_next_tree, op_iter_init,
|
||||
op_iter_next_tree): Use new operand implementation.
|
||||
(clear_and_done_ssa_iter): New. Initialize a blank operand iterator.
|
||||
(op_iter_init_use, op_iter_init_def, op_iter_init_tree): Add iterator
|
||||
type check.
|
||||
(op_iter_next_mustdef, op_iter_next_maydef,
|
||||
op_iter_next_must_and_may_def): Delete. Replace with...
|
||||
(op_iter_next_maymustdef): New. Combine must and may next operations.
|
||||
(op_iter_init_maydef, op_iter_init_mustdef,
|
||||
op_iter_init_must_and_may_def): Use new interface.
|
||||
(single_ssa_tree_operand ): New. Process single operands only as trees.
|
||||
(single_ssa_use_operand): New. Process single operands only as uses.
|
||||
(single_ssa_def_operand): New. Process single operands only as defs.
|
||||
(zero_ssa_operands): New. Return TRUE if there are zero operands of the
|
||||
specified types.
|
||||
(num_ssa_operands): New. Count the number of specified operands.
|
||||
(compare_ssa_operands_equal): New. Compare two statements' operands.
|
||||
(single_phi_def): New. Return true if PHI has one def of the specified
|
||||
operand type.
|
||||
(op_iter_init_phiuse): New. Initialize the iterator for PHI arguments.
|
||||
(op_iter_init_phidef): New. Initialize the iterator for the PHI def.
|
||||
* tree-flow.h (struct immediate_use_iterator_d): Use ssa_use_operand_t.
|
||||
(struct stmt_ann_d): Operands field no longer require GTY().
|
||||
(vn_compute, vn_lookup_or_add, vn_add, vn_lookup): Change prototype.
|
||||
* tree-into-ssa.c (mark_def_sites): Use SSA_OP_VMUSTKILL.
|
||||
* tree-outof-ssa.c (check_replaceable, find_replaceable_in_bb,
|
||||
dump_replaceable_exprs, rewrite_trees): Use generic interface.
|
||||
* tree-phinodes.c (make_phi_node, release_phi_node, resize_phi_node):
|
||||
Use use_operand_p instead of ssa_imm_use_t *.
|
||||
* tree-pretty-print.c (dump_vops): check if operands are active before
|
||||
dumping virtual operands.
|
||||
* tree-sra.c (sra_walk_function): Use ZERO_SSA_OPERANDS.
|
||||
* tree-ssa-ccp.c (likely_value): Use ZERO_SSA_OPERANDS.
|
||||
(ccp_fold): Use new interface.
|
||||
(ccp_visit_stmt): Remove unused variables and code.
|
||||
(convert_to_gimple_builtin): Insert statements before calling
|
||||
mark_new_vars_to_rename.
|
||||
* tree-ssa-copy.c (stmt_may_generate_copy): Use ZERO_SSA_OPERANDS.
|
||||
(copy_prop_visit_cond_stmt): Use generic interface.
|
||||
* tree-ssa-dom.c (struct expr_hash_elt): Use stmt pointer, not the
|
||||
annotation in table.
|
||||
(thread_across_edge): Use generic interface.
|
||||
(initialize_hash_element): Initialzie with stmt, not annotation.
|
||||
(eliminate_redundant_computations): Use generic interface.
|
||||
(record_equivalences_from_stmt): Pass stmt, not annotation.
|
||||
(avail_expr_hash, real_avail_expr_hash, avail_expr_eq): Use generic
|
||||
interface.
|
||||
* tree-ssa-dse.c (dse_optimize_stmt): Use ZERO_SSA_OPERANDS.
|
||||
* tree-ssa-loop-ivopts.c (find_invariants_stmt,
|
||||
find_interesting_uses_stmt, protect_loop_closed_ssa_form_use): Use
|
||||
generic operand interface.
|
||||
* tree-ssa-loop-niter.c (chain_of_csts_start, get_val_for): Use generic
|
||||
interface.
|
||||
* tree-ssa-loop-unswitch.c (tree_may_unswitch_on): Use Generic operand
|
||||
Interface.
|
||||
* tree-ssa-operands.c (struct opbuild_list_d): New. Operand build type.
|
||||
(build_defs, build_uses, build_v_may_defs, build_vuses,
|
||||
build_v_must_defs): Change type to struct opbuild_list_d.
|
||||
(ops_active): New. Operands active boolean.
|
||||
(operand_memory, operand_memory_index): New. Operand memory managers.
|
||||
(allocate_def_optype, allocate_use_optype, allocate_v_may_def_optype,
|
||||
allocate_vuse_optype, allocate_v_must_def_optype): Delete.
|
||||
(free_uses, free_defs, free_vuses, free_v_may_defs, free_v_must_defs):
|
||||
Change from functions to static variable list heads.
|
||||
(opbuild_initialize_virtual): New. Initialize a virtual build list.
|
||||
(opbuild_initialize_real): New. Initialize a virtual build list.
|
||||
(opbuild_free): New. Free a build list.
|
||||
(opbuild_num_elems): New. Number of items in a list.
|
||||
(opbuild_append_real): New. Add a real (tree *) operand.
|
||||
(opbuild_append_virtual): New. Add and sort a virtual (tree) operand.
|
||||
(opbuild_first): New. Return first element index in a list.
|
||||
(opbuild_next): New. Return next element in a list.
|
||||
(opbuild_elem_real): New. Return real element.
|
||||
(opbuild_elem_virtual): New. Return virtual element.
|
||||
(opbuild_elem_uid): New. Return UID of virtual element.
|
||||
(opbuild_clear): New. Reset an operand list.
|
||||
(opbuild_remove_elem): New. Remove an element form a list.
|
||||
(ssa_operands_active): New. Return true if operand cache is active.
|
||||
(init_ssa_operands, fini_ssa_operands): Initialize new implementation.
|
||||
(ssa_operand_alloc): New. Allocate memory from an operand chunk.
|
||||
(correct_use_link): Use use_operand_p.
|
||||
(finalize_ssa_uses, finalize_ssa_v_may_defs, finalize_ssa_defs,
|
||||
finalize_ssa_vuses, finalize_ssa_v_must_defs): New implmentation.
|
||||
(cleanup_v_may_defs): Use new implmentation.
|
||||
(finalize_ssa_stmt_operands, start_ssa_stmt_operands): New
|
||||
implementation.
|
||||
(append_def, append_use, append_v_may_def, append_vuse,
|
||||
append_v_must_def): Call opbuild_append routine instead of using varray.
|
||||
(build_ssa_operands): Simplify to simply use stmt, don't maintain a
|
||||
global parse_old_ops variable.
|
||||
(free_ssa_operands): New implementation.
|
||||
(update_stmt_operands): Move. Change argument to build_ssa_operands.
|
||||
(copy_virtual_operands): Move. New generic implementation.
|
||||
(create_ssa_artficial_load_stmt): Move. New implementation.
|
||||
(swap_tree_operands): Update for new implementation.
|
||||
(get_expr_operands): Add stmt parameter to calls to swap_tree_operands.
|
||||
(add_call_clobber_ops, add_call_read_ops): Initialize opbuild list
|
||||
rather than a varray.
|
||||
(verify_imm_links): Use use_operand_p.
|
||||
(dump_immediate_uses_for): If the immediate use variable is a virtual
|
||||
variable, show the virtual ops in the stmt.
|
||||
* tree-ssa-operands.h (def_operand_p): No longer a structure.
|
||||
(NULL_DEF_OPERAND_P): Now a #define.
|
||||
(def_optype_d, use_optype_d, v_def_use_operand_type, v_may_def_optype_d,
|
||||
vuse_operand_type, vuse_optype_d, v_must_def_optype_d): Delete.
|
||||
(def_optype_d, use_optype_d, maydef_optype_d, vuse_optype_d,
|
||||
mustdef_optype_d): New. Use Linked list representation.
|
||||
(SSA_OPERAND_MEMORY_SIZE): New. Size of operand memory chunk.
|
||||
(struct ssa_operand_memory_d): New. Allocated Chunk node.
|
||||
(struct stmt_operands_d): Change to new pointers that are not GTY.
|
||||
(STMT_USE_OPS, NUM_USES, SET_USE_OP, STMT_DEF_OPS, NUM_DEFS, SET_DEF_OP,
|
||||
STMT_V_MAY_DEF_OPS, NUM_V_MAY_DEFS, SET_V_MAY_DEF_RESULT,
|
||||
SET_V_MAY_DEF_OP, STMT_VUSE_OPS, NUM_VUSES, SET_VUSE_OP,
|
||||
STMT_V_MUST_DEF_OPS, NUM_V_MUST_DEFS, SET_V_MUST_DEF_RESULT,
|
||||
SET_V_MUST_DEF_KILL): Delete.
|
||||
(V_MAY_DEF_OPS, V_MAY_DEF_RESULT_PTR, V_MAY_DEF_RESULT,
|
||||
V_MAY_DEF_OP_PTR, V_MAY_DEF_OP): Rename to MAYDEF_*.
|
||||
(V_MUST_DEF_OPS, V_MUST_DEF_RESULT_PTR, V_MUST_DEF_RESULT,
|
||||
V_MUST_DEF_KILL_PTR, V_MUST_DEF_KILL): Rename to MUSTDEF_*.
|
||||
(enum ssa_op_iter_type): Operand iterator typechecking values.
|
||||
(struct ssa_operand_iterator_d): Use linked lists of operands.
|
||||
(SSA_OP_VMUSTDEFKILL): Rename to SSA_OP_VMUSTKILL.
|
||||
(FOR_EACH_SSA_MAYDEF_OPERAND, FOR_EACH_SSA_MUSTDEF_OPERAND,
|
||||
FOR_EACH_SSA_MUST_AND_MAY_DEF_OPERAND): Use op_iter_next_maymustdef.
|
||||
(FOR_EACH_PHI_ARG): New. Iterate over PHI arguments.
|
||||
(FOR_EACH_PHI_OR_STMT_USE): New. Iterate over PHI or stmt uses.
|
||||
(FOR_EACH_PHI_OR_STMT_DEF): New. Iterate over PHI or stmt defs.
|
||||
(SINGLE_SSA_TREE_OPERAND, SINGLE_SSA_USE_OPERAND,
|
||||
SINGLE_SSA_DEF_OPERAND, ZERO_SSA_OPERANDS, NUM_SSA_OPERANDS): New.
|
||||
* tree-ssa-opfinalize.h: New. Function templates for expansion.
|
||||
(FINALIZE_ALLOC): Expands into alloc_def, alloc_use, alloc_maydef,
|
||||
alloc_vuse, and alloc_mustdef.
|
||||
(FINALIZE_FUNC): Expands into finalize_ssa_def_ops,
|
||||
finalize_ssa_use_ops, finalize_ssa_v_may_def_ops, finalize_ssa_vuse_ops,
|
||||
and finalize_ssa_v_must_def_ops.
|
||||
* tree-ssa-pre.c (add_to_sets): Pass tree to vn_add.
|
||||
(create_value_expr_from): Use stmt not vuse_optype as a parameter. Pass
|
||||
stmt around.
|
||||
(compute_avail): Use generic iterator interface.
|
||||
* tree-ssa-propagate.c (first_vdef): Use generic operand interface.
|
||||
(stmt_makes_single_load, stmt_makes_single_store): Use
|
||||
ZERO_SSA_OPERANDS.
|
||||
* tree-ssa-sink.c (is_hidden_global_store): Use ZERO_SSA_OPERANDS.
|
||||
(statement_sink_location): Use generic interface.
|
||||
* tree-ssa.c (verify_ssa): Use %p in fprintf. Use generic interface.
|
||||
(delete_tree_ssa): Don't call release_defs. Call release_ssa_name and
|
||||
reset the immediate use link nodes.
|
||||
(stmt_references_memory_p): Use ZERO_SSA_OPERANDS.
|
||||
* tree-ssanames.c (make_ssa_name): Use use_operand_p.
|
||||
* tree-tailcall.c (find_tail_calls): Use ZERO_SSA_OPERANDS.
|
||||
(eliminate_tail_call): Use generic operand interface.
|
||||
* tree-vect-analyze.c (vect_analyze_data_refs): Use ZERO_SSA_OPERANDS.
|
||||
(vect_mark_relevant, vect_mark_stmts_to_be_vectorized): Use generic
|
||||
interface.
|
||||
* tree-vect-transform.c (update_vuses_to_preheader): Use generic
|
||||
interface.
|
||||
* tree-vectorizer.c (rename_variables_in_bb): Use generic interface.
|
||||
* tree-vn.c (struct val_expr_pair_d): Cache statment pointer instead of
|
||||
vuse_optype.
|
||||
(vn_compute, val_expr_pair_hash, vn_add, vn_lookup, vn_lookup_or_add):
|
||||
Use statement pointer instead of vuse_optype. Use generic interface.
|
||||
* tree-vrp.c (maybe_add_assert_expr): Use generic interface.
|
||||
(stmt_interesting_for_vrp, vrp_visit_stmt): Use ZERO_SSA_OPERANDS.
|
||||
* tree.h (struct ssa_imm_use_d): Renamed to ssa_use_operand_d.
|
||||
(tree_ssa_name, phi_arg_d): Use ssa_use_operand_d.
|
||||
* doc/tree-ssa.texi: Update documentation for operand interface.
|
||||
|
||||
2005-05-03 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* config/darwin.c (machopic_define_symbol): Use gcc_assert or
|
||||
|
@ -705,8 +705,8 @@ Almost every GIMPLE statement will contain a reference to a variable
|
||||
or memory location. Since statements come in different shapes and
|
||||
sizes, their operands are going to be located at various spots inside
|
||||
the statement's tree. To facilitate access to the statement's
|
||||
operands, they are organized into arrays associated inside each
|
||||
statement's annotation. Each element in an operand array is a pointer
|
||||
operands, they are organized into lists associated inside each
|
||||
statement's annotation. Each element in an operand list is a pointer
|
||||
to a @code{VAR_DECL}, @code{PARM_DECL} or @code{SSA_NAME} tree node.
|
||||
This provides a very convenient way of examining and replacing
|
||||
operands.
|
||||
@ -810,82 +810,6 @@ function is converted into SSA form. This will be used to link all
|
||||
the non-killing definitions to prevent optimizations from making
|
||||
incorrect assumptions about them.
|
||||
|
||||
Operands are collected by @file{tree-ssa-operands.c}. They are stored
|
||||
inside each statement's annotation and can be accessed with
|
||||
@code{DEF_OPS}, @code{USE_OPS}, @code{V_MAY_DEF_OPS},
|
||||
@code{V_MUST_DEF_OPS} and @code{VUSE_OPS}. The following are all the
|
||||
accessor macros available to access USE operands. To access all the
|
||||
other operand arrays, just change the name accordingly. Note that
|
||||
this interface to the operands is deprecated, and is slated for
|
||||
removal in a future version of gcc. The preferred interface is the
|
||||
operand iterator interface. Unless you need to discover the number of
|
||||
operands of a given type on a statement, you are strongly urged not to
|
||||
use this interface.
|
||||
|
||||
@defmac USE_OPS (@var{ann})
|
||||
Returns the array of operands used by the statement with annotation
|
||||
@var{ann}.
|
||||
@end defmac
|
||||
|
||||
@defmac STMT_USE_OPS (@var{stmt})
|
||||
Alternate version of USE_OPS that takes the statement @var{stmt} as
|
||||
input.
|
||||
@end defmac
|
||||
|
||||
@defmac NUM_USES (@var{ops})
|
||||
Return the number of USE operands in array @var{ops}.
|
||||
@end defmac
|
||||
|
||||
@defmac USE_OP_PTR (@var{ops}, @var{i})
|
||||
Return a pointer to the @var{i}th operand in array @var{ops}.
|
||||
@end defmac
|
||||
|
||||
@defmac USE_OP (@var{ops}, @var{i})
|
||||
Return the @var{i}th operand in array @var{ops}.
|
||||
@end defmac
|
||||
|
||||
The following function shows how to print all the operands of a given
|
||||
statement:
|
||||
|
||||
@smallexample
|
||||
void
|
||||
print_ops (tree stmt)
|
||||
@{
|
||||
vuse_optype vuses;
|
||||
v_may_def_optype v_may_defs;
|
||||
v_must_def_optype v_must_defs;
|
||||
def_optype defs;
|
||||
use_optype uses;
|
||||
stmt_ann_t ann;
|
||||
size_t i;
|
||||
|
||||
ann = stmt_ann (stmt);
|
||||
|
||||
defs = DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_DEFS (defs); i++)
|
||||
print_generic_expr (stderr, DEF_OP (defs, i), 0);
|
||||
|
||||
uses = USE_OPS (ann);
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
print_generic_expr (stderr, USE_OP (uses, i), 0);
|
||||
|
||||
v_may_defs = V_MAY_DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
|
||||
@{
|
||||
print_generic_expr (stderr, V_MAY_DEF_OP (v_may_defs, i), 0);
|
||||
print_generic_expr (stderr, V_MAY_DEF_RESULT (v_may_defs, i), 0);
|
||||
@}
|
||||
|
||||
v_must_defs = V_MUST_DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
|
||||
print_generic_expr (stderr, V_MUST_DEF_OP (v_must_defs, i), 0);
|
||||
|
||||
vuses = VUSE_OPS (ann);
|
||||
for (i = 0; i < NUM_VUSES (vuses); i++)
|
||||
print_generic_expr (stderr, VUSE_OP (vuses, i), 0);
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
Operands are updated as soon as the statement is finished via a call
|
||||
to @code{update_stmt}. If statement elements are changed via
|
||||
@code{SET_USE} or @code{SET_DEF}, then no further action is required
|
||||
@ -895,13 +819,49 @@ must be made to @code{update_stmt} when complete. Calling one of the
|
||||
@code{bsi_insert} routines or @code{bsi_replace} performs an implicit
|
||||
call to @code{update_stmt}.
|
||||
|
||||
@subsection Operand Iterators
|
||||
@cindex Operand Iterators
|
||||
@subsection Operand Iterators And Access Routines
|
||||
@cindex Operand Iterators
|
||||
@cindex Operand Access Routines
|
||||
|
||||
There is an alternative to iterating over the operands in a statement.
|
||||
It is especially useful when you wish to perform the same operation on
|
||||
more than one type of operand. The previous example could be
|
||||
rewritten as follows:
|
||||
Operands are collected by @file{tree-ssa-operands.c}. They are stored
|
||||
inside each statement's annotation and can be accessed through either the
|
||||
operand iterators or an access routine.
|
||||
|
||||
The following access routines are available for examining operands:
|
||||
|
||||
@enumerate
|
||||
@item @code{SINGLE_SSA_@{USE,DEF,TREE@}_OPERAND}: These accessors will return
|
||||
NULL unless there is exactly one operand mathcing the specified flags. If
|
||||
there is exactly one operand, the operand is returned as either a @code{tree},
|
||||
@code{def_operand_p}, or @code{use_operand_p}.
|
||||
|
||||
@smallexample
|
||||
tree t = SINGLE_SSA_TREE_OPERAND (stmt, flags);
|
||||
use_operand_p u = SINGLE_SSA_USE_OPERAND (stmt, SSA_ALL_VIRTUAL_USES);
|
||||
def_operand_p d = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_ALL_DEFS);
|
||||
@end smallexample
|
||||
|
||||
@item @code{ZERO_SSA_OPERANDS}: This macro returns true if there are no
|
||||
operands matching the specified flags.
|
||||
|
||||
@smallexample
|
||||
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
|
||||
return;
|
||||
@end smallexample
|
||||
|
||||
@item @code{NUM_SSA_OPERANDS}: This macro Returns the number of operands
|
||||
matching 'flags'. This actually executes a loop to perform the count, so
|
||||
only use this if it is really needed.
|
||||
|
||||
@smallexample
|
||||
int count = NUM_SSA_OPERANDS (stmt, flags)
|
||||
@end smallexample
|
||||
@end enumerate
|
||||
|
||||
|
||||
If you wish to iterate over some or all operands, use the
|
||||
@code{FOR_EACH_SSA_@{USE,DEF,TREE@}_OPERAND} iterator. For example, to print
|
||||
all the operands for a statement:
|
||||
|
||||
@smallexample
|
||||
void
|
||||
@ -911,11 +871,13 @@ print_ops (tree stmt)
|
||||
tree var;
|
||||
|
||||
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_OPERANDS)
|
||||
print_generic_expr (stderr, var, 0);
|
||||
print_generic_expr (stderr, var, TDF_SLIM);
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
|
||||
How to choose the appropriate iterator:
|
||||
|
||||
@enumerate
|
||||
@item Determine whether you are need to see the operand pointers, or just the
|
||||
trees, and choose the appropriate macro:
|
||||
@ -966,7 +928,7 @@ So if you want to look at the use pointers for all the @code{USE} and
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
The @code{_TREE_} macro is basically the same as the @code{USE} and
|
||||
The @code{TREE} macro is basically the same as the @code{USE} and
|
||||
@code{DEF} macros, only with the use or def dereferenced via
|
||||
@code{USE_FROM_PTR (use_p)} and @code{DEF_FROM_PTR (def_p)}. Since we
|
||||
aren't using operand pointers, use and defs flags can be mixed.
|
||||
@ -1002,7 +964,7 @@ this one.
|
||||
|
||||
@code{V_MUST_DEF}s are broken into two flags, one for the
|
||||
@code{DEF} portion (@code{SSA_OP_VMUSTDEF}) and one for the kill portion
|
||||
(@code{SSA_OP_VMUSTDEFKILL}). If all you want to look at are the
|
||||
(@code{SSA_OP_VMUSTKILL}). If all you want to look at are the
|
||||
@code{V_MUST_DEF}s together, there is a fourth iterator macro for this,
|
||||
which returns both a def_operand_p and a use_operand_p for each
|
||||
@code{V_MUST_DEF} in the statement. Note that you don't need any flags for
|
||||
@ -1023,6 +985,46 @@ this one.
|
||||
There are many examples in the code as well, as well as the
|
||||
documentation in @file{tree-ssa-operands.h}.
|
||||
|
||||
There are also a couple of variants on the stmt iterators regarding PHI
|
||||
nodes.
|
||||
|
||||
@code{FOR_EACH_PHI_ARG} Works exactly like
|
||||
@code{FOR_EACH_SSA_USE_OPERAND}, except it works over @code{PHI} arguments
|
||||
instead of statement operands.
|
||||
|
||||
@smallexample
|
||||
/* Look at every virtual PHI use. */
|
||||
FOR_EACH_PHI_ARG (use_p, phi_stmt, iter, SSA_OP_VIRTUAL_USES)
|
||||
@{
|
||||
my_code;
|
||||
@}
|
||||
|
||||
/* Look at every real PHI use. */
|
||||
FOR_EACH_PHI_ARG (use_p, phi_stmt, iter, SSA_OP_USES)
|
||||
my_code;
|
||||
|
||||
/* Look at every every PHI use. */
|
||||
FOR_EACH_PHI_ARG (use_p, phi_stmt, iter, SSA_OP_ALL_USES)
|
||||
my_code;
|
||||
@end smallexample
|
||||
|
||||
@code{FOR_EACH_PHI_OR_STMT_@{USE,DEF@}} works exactly like
|
||||
@code{FOR_EACH_SSA_@{USE,DEF@}_OPERAND}, except it will function on
|
||||
either a statement or a @code{PHI} node. These should be used when it is
|
||||
appropriate but they are not quite as efficient as the individual
|
||||
@code{FOR_EACH_PHI} and @code{FOR_EACH_SSA} routines.
|
||||
|
||||
@smallexample
|
||||
FOR_EACH_PHI_OR_STMT_USE (use_operand_p, stmt, iter, flags)
|
||||
@{
|
||||
my_code;
|
||||
@}
|
||||
|
||||
FOR_EACH_PHI_OR_STMT_DEF (def_operand_p, phi, iter, flags)
|
||||
@{
|
||||
my_code;
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
@subsection Immediate Uses
|
||||
@cindex Immediate Uses
|
||||
|
@ -1266,7 +1266,6 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
|
||||
int stepint;
|
||||
int extra = 0;
|
||||
tree lboundvar, uboundvar, uboundresult;
|
||||
use_optype uses;
|
||||
|
||||
/* Find out induction var and exit condition. */
|
||||
inductionvar = find_induction_var_from_exit_cond (loop);
|
||||
@ -1295,9 +1294,8 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
|
||||
phi = SSA_NAME_DEF_STMT (inductionvar);
|
||||
if (TREE_CODE (phi) != PHI_NODE)
|
||||
{
|
||||
uses = STMT_USE_OPS (phi);
|
||||
|
||||
if (!uses)
|
||||
phi = SINGLE_SSA_TREE_OPERAND (phi, SSA_OP_USE);
|
||||
if (!phi)
|
||||
{
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
@ -1307,7 +1305,6 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
phi = USE_OP (uses, 0);
|
||||
phi = SSA_NAME_DEF_STMT (phi);
|
||||
if (TREE_CODE (phi) != PHI_NODE)
|
||||
{
|
||||
@ -1972,12 +1969,11 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
|
||||
tree oldiv_def;
|
||||
tree oldiv_stmt = SSA_NAME_DEF_STMT (oldiv);
|
||||
|
||||
gcc_assert (TREE_CODE (oldiv_stmt) == PHI_NODE
|
||||
|| NUM_DEFS (STMT_DEF_OPS (oldiv_stmt)) == 1);
|
||||
if (TREE_CODE (oldiv_stmt) == PHI_NODE)
|
||||
oldiv_def = PHI_RESULT (oldiv_stmt);
|
||||
oldiv_def = PHI_RESULT (oldiv_stmt);
|
||||
else
|
||||
oldiv_def = DEF_OP (STMT_DEF_OPS (oldiv_stmt), 0);
|
||||
oldiv_def = SINGLE_SSA_TREE_OPERAND (oldiv_stmt, SSA_OP_DEF);
|
||||
gcc_assert (oldiv_def != NULL_TREE);
|
||||
|
||||
FOR_EACH_IMM_USE_SAFE (imm_use, imm_iter, oldiv_def)
|
||||
{
|
||||
@ -2069,16 +2065,11 @@ phi_loop_edge_uses_def (struct loop *loop, tree phi, tree def)
|
||||
static bool
|
||||
stmt_uses_phi_result (tree stmt, tree phi_result)
|
||||
{
|
||||
use_optype uses = STMT_USE_OPS (stmt);
|
||||
tree use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
|
||||
|
||||
/* This is conservatively true, because we only want SIMPLE bumpers
|
||||
of the form x +- constant for our pass. */
|
||||
if (NUM_USES (uses) != 1)
|
||||
return false;
|
||||
if (USE_OP (uses, 0) == phi_result)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return (use == phi_result);
|
||||
}
|
||||
|
||||
/* STMT is a bumper stmt for LOOP if the version it defines is used in the
|
||||
@ -2092,13 +2083,13 @@ stmt_is_bumper_for_loop (struct loop *loop, tree stmt)
|
||||
{
|
||||
tree use;
|
||||
tree def;
|
||||
def_optype defs = STMT_DEF_OPS (stmt);
|
||||
imm_use_iterator iter;
|
||||
use_operand_p use_p;
|
||||
|
||||
if (NUM_DEFS (defs) != 1)
|
||||
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
|
||||
if (!def)
|
||||
return false;
|
||||
def = DEF_OP (defs, 0);
|
||||
|
||||
FOR_EACH_IMM_USE_FAST (use_p, iter, def)
|
||||
{
|
||||
use = USE_STMT (use_p);
|
||||
@ -2179,12 +2170,13 @@ perfect_nest_p (struct loop *loop)
|
||||
static void
|
||||
replace_uses_of_x_with_y (tree stmt, tree x, tree y)
|
||||
{
|
||||
use_optype uses = STMT_USE_OPS (stmt);
|
||||
size_t i;
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
ssa_op_iter iter;
|
||||
use_operand_p use_p;
|
||||
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
if (USE_OP (uses, i) == x)
|
||||
SET_USE_OP (uses, i, y);
|
||||
if (USE_FROM_PTR (use_p) == x)
|
||||
SET_USE (use_p, y);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2193,11 +2185,12 @@ replace_uses_of_x_with_y (tree stmt, tree x, tree y)
|
||||
static bool
|
||||
stmt_uses_op (tree stmt, tree op)
|
||||
{
|
||||
use_optype uses = STMT_USE_OPS (stmt);
|
||||
size_t i;
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
ssa_op_iter iter;
|
||||
tree use;
|
||||
|
||||
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
if (USE_OP (uses, i) == op)
|
||||
if (use == op)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -2231,14 +2231,11 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
tree stmt = bsi_stmt (bsi);
|
||||
stmt_ann_t ann = stmt_ann (stmt);
|
||||
|
||||
if (TREE_CODE (stmt) != MODIFY_EXPR)
|
||||
continue;
|
||||
|
||||
if (!VUSE_OPS (ann)
|
||||
&& !V_MUST_DEF_OPS (ann)
|
||||
&& !V_MAY_DEF_OPS (ann))
|
||||
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
|
||||
continue;
|
||||
|
||||
/* In the GIMPLE representation, a modify expression
|
||||
@ -2269,8 +2266,7 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
|
||||
}
|
||||
|
||||
/* When there are no defs in the loop, the loop is parallel. */
|
||||
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) > 0
|
||||
|| NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) > 0)
|
||||
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
|
||||
bb->loop_father->parallel_p = false;
|
||||
}
|
||||
|
||||
|
@ -482,15 +482,13 @@ collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
||||
{
|
||||
case STMT_ANN:
|
||||
{
|
||||
stmt_ann_t ann = (stmt_ann_t) t->common.ann;
|
||||
dfa_stats_p->num_stmt_anns++;
|
||||
dfa_stats_p->num_defs += NUM_DEFS (DEF_OPS (ann));
|
||||
dfa_stats_p->num_uses += NUM_USES (USE_OPS (ann));
|
||||
dfa_stats_p->num_v_may_defs +=
|
||||
NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann));
|
||||
dfa_stats_p->num_vuses += NUM_VUSES (VUSE_OPS (ann));
|
||||
dfa_stats_p->num_v_must_defs +=
|
||||
NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann));
|
||||
dfa_stats_p->num_defs += NUM_SSA_OPERANDS (t, SSA_OP_DEF);
|
||||
dfa_stats_p->num_uses += NUM_SSA_OPERANDS (t, SSA_OP_USE);
|
||||
dfa_stats_p->num_v_may_defs += NUM_SSA_OPERANDS (t, SSA_OP_VMAYDEF);
|
||||
dfa_stats_p->num_vuses += NUM_SSA_OPERANDS (t, SSA_OP_VUSE);
|
||||
dfa_stats_p->num_v_must_defs +=
|
||||
NUM_SSA_OPERANDS (t, SSA_OP_VMUSTDEF);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -642,8 +640,8 @@ mark_new_vars_to_rename (tree stmt)
|
||||
We flag them in a separate bitmap because we don't really want to
|
||||
rename them if there are not any newly exposed symbols in the
|
||||
statement operands. */
|
||||
v_may_defs_before = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt));
|
||||
v_must_defs_before = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt));
|
||||
v_may_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF);
|
||||
v_must_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF);
|
||||
|
||||
FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter,
|
||||
SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF)
|
||||
@ -657,8 +655,8 @@ mark_new_vars_to_rename (tree stmt)
|
||||
exposed variables. */
|
||||
update_stmt (stmt);
|
||||
|
||||
v_may_defs_after = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt));
|
||||
v_must_defs_after = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt));
|
||||
v_may_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF);
|
||||
v_must_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF);
|
||||
|
||||
FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_ALL_OPERANDS)
|
||||
if (DECL_P (val))
|
||||
|
@ -186,7 +186,7 @@ stmt_modified_p (tree t)
|
||||
|
||||
/* Delink an immediate_uses node from its chain. */
|
||||
static inline void
|
||||
delink_imm_use (ssa_imm_use_t *linknode)
|
||||
delink_imm_use (ssa_use_operand_t *linknode)
|
||||
{
|
||||
/* Return if this node is not in a list. */
|
||||
if (linknode->prev == NULL)
|
||||
@ -200,7 +200,7 @@ delink_imm_use (ssa_imm_use_t *linknode)
|
||||
|
||||
/* Link ssa_imm_use node LINKNODE into the chain for LIST. */
|
||||
static inline void
|
||||
link_imm_use_to_list (ssa_imm_use_t *linknode, ssa_imm_use_t *list)
|
||||
link_imm_use_to_list (ssa_use_operand_t *linknode, ssa_use_operand_t *list)
|
||||
{
|
||||
/* Link the new node at the head of the list. If we are in the process of
|
||||
traversing the list, we won't visit any new nodes added to it. */
|
||||
@ -212,9 +212,9 @@ link_imm_use_to_list (ssa_imm_use_t *linknode, ssa_imm_use_t *list)
|
||||
|
||||
/* Link ssa_imm_use node LINKNODE into the chain for DEF. */
|
||||
static inline void
|
||||
link_imm_use (ssa_imm_use_t *linknode, tree def)
|
||||
link_imm_use (ssa_use_operand_t *linknode, tree def)
|
||||
{
|
||||
ssa_imm_use_t *root;
|
||||
ssa_use_operand_t *root;
|
||||
|
||||
if (!def || TREE_CODE (def) != SSA_NAME)
|
||||
linknode->prev = NULL;
|
||||
@ -241,7 +241,7 @@ set_ssa_use_from_ptr (use_operand_p use, tree val)
|
||||
/* Link ssa_imm_use node LINKNODE into the chain for DEF, with use occuring
|
||||
in STMT. */
|
||||
static inline void
|
||||
link_imm_use_stmt (ssa_imm_use_t *linknode, tree def, tree stmt)
|
||||
link_imm_use_stmt (ssa_use_operand_t *linknode, tree def, tree stmt)
|
||||
{
|
||||
if (stmt)
|
||||
link_imm_use (linknode, def);
|
||||
@ -252,7 +252,7 @@ link_imm_use_stmt (ssa_imm_use_t *linknode, tree def, tree stmt)
|
||||
|
||||
/* Relink a new node in place of an old node in the list. */
|
||||
static inline void
|
||||
relink_imm_use (ssa_imm_use_t *node, ssa_imm_use_t *old)
|
||||
relink_imm_use (ssa_use_operand_t *node, ssa_use_operand_t *old)
|
||||
{
|
||||
/* The node one had better be in the same list. */
|
||||
gcc_assert (*(old->use) == *(node->use));
|
||||
@ -270,7 +270,7 @@ relink_imm_use (ssa_imm_use_t *node, ssa_imm_use_t *old)
|
||||
/* Relink ssa_imm_use node LINKNODE into the chain for OLD, with use occuring
|
||||
in STMT. */
|
||||
static inline void
|
||||
relink_imm_use_stmt (ssa_imm_use_t *linknode, ssa_imm_use_t *old, tree stmt)
|
||||
relink_imm_use_stmt (ssa_use_operand_t *linknode, ssa_use_operand_t *old, tree stmt)
|
||||
{
|
||||
if (stmt)
|
||||
relink_imm_use (linknode, old);
|
||||
@ -318,7 +318,7 @@ first_safe_imm_use (imm_use_iterator *imm, tree var)
|
||||
static inline use_operand_p
|
||||
next_safe_imm_use (imm_use_iterator *imm)
|
||||
{
|
||||
ssa_imm_use_t *ptr;
|
||||
ssa_use_operand_t *ptr;
|
||||
use_operand_p old;
|
||||
|
||||
old = imm->imm_use;
|
||||
@ -405,7 +405,7 @@ next_readonly_imm_use (imm_use_iterator *imm)
|
||||
static inline bool
|
||||
has_zero_uses (tree var)
|
||||
{
|
||||
ssa_imm_use_t *ptr;
|
||||
ssa_use_operand_t *ptr;
|
||||
ptr = &(SSA_NAME_IMM_USE_NODE (var));
|
||||
/* A single use means there is no items in the list. */
|
||||
return (ptr == ptr->next);
|
||||
@ -415,7 +415,7 @@ has_zero_uses (tree var)
|
||||
static inline bool
|
||||
has_single_use (tree var)
|
||||
{
|
||||
ssa_imm_use_t *ptr;
|
||||
ssa_use_operand_t *ptr;
|
||||
ptr = &(SSA_NAME_IMM_USE_NODE (var));
|
||||
/* A single use means there is one item in the list. */
|
||||
return (ptr != ptr->next && ptr == ptr->next->next);
|
||||
@ -426,7 +426,7 @@ has_single_use (tree var)
|
||||
static inline bool
|
||||
single_imm_use (tree var, use_operand_p *use_p, tree *stmt)
|
||||
{
|
||||
ssa_imm_use_t *ptr;
|
||||
ssa_use_operand_t *ptr;
|
||||
|
||||
ptr = &(SSA_NAME_IMM_USE_NODE (var));
|
||||
if (ptr != ptr->next && ptr == ptr->next->next)
|
||||
@ -444,7 +444,7 @@ single_imm_use (tree var, use_operand_p *use_p, tree *stmt)
|
||||
static inline unsigned int
|
||||
num_imm_uses (tree var)
|
||||
{
|
||||
ssa_imm_use_t *ptr, *start;
|
||||
ssa_use_operand_t *ptr, *start;
|
||||
unsigned int num;
|
||||
|
||||
start = &(SSA_NAME_IMM_USE_NODE (var));
|
||||
@ -455,46 +455,6 @@ num_imm_uses (tree var)
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Return the definitions present in ANN, a statement annotation.
|
||||
Return NULL if this annotation contains no definitions. */
|
||||
static inline def_optype
|
||||
get_def_ops (stmt_ann_t ann)
|
||||
{
|
||||
return ann ? ann->operands.def_ops : NULL;
|
||||
}
|
||||
|
||||
/* Return the uses present in ANN, a statement annotation.
|
||||
Return NULL if this annotation contains no uses. */
|
||||
static inline use_optype
|
||||
get_use_ops (stmt_ann_t ann)
|
||||
{
|
||||
return ann ? ann->operands.use_ops : NULL;
|
||||
}
|
||||
|
||||
/* Return the virtual may-defs present in ANN, a statement
|
||||
annotation.
|
||||
Return NULL if this annotation contains no virtual may-defs. */
|
||||
static inline v_may_def_optype
|
||||
get_v_may_def_ops (stmt_ann_t ann)
|
||||
{
|
||||
return ann ? ann->operands.v_may_def_ops : NULL;
|
||||
}
|
||||
|
||||
/* Return the virtual uses present in ANN, a statement annotation.
|
||||
Return NULL if this annotation contains no virtual uses. */
|
||||
static inline vuse_optype
|
||||
get_vuse_ops (stmt_ann_t ann)
|
||||
{
|
||||
return ann ? ann->operands.vuse_ops : NULL;
|
||||
}
|
||||
|
||||
/* Return the virtual must-defs present in ANN, a statement
|
||||
annotation. Return NULL if this annotation contains no must-defs.*/
|
||||
static inline v_must_def_optype
|
||||
get_v_must_def_ops (stmt_ann_t ann)
|
||||
{
|
||||
return ann ? ann->operands.v_must_def_ops : NULL;
|
||||
}
|
||||
|
||||
/* Return the tree pointer to by USE. */
|
||||
static inline tree
|
||||
@ -507,80 +467,14 @@ get_use_from_ptr (use_operand_p use)
|
||||
static inline tree
|
||||
get_def_from_ptr (def_operand_p def)
|
||||
{
|
||||
return *(def.def);
|
||||
}
|
||||
|
||||
/* Return a pointer to the tree that is at INDEX in the USES array. */
|
||||
static inline use_operand_p
|
||||
get_use_op_ptr (use_optype uses, unsigned int index)
|
||||
{
|
||||
gcc_assert (index < uses->num_uses);
|
||||
return &(uses->uses[index]);
|
||||
}
|
||||
|
||||
/* Return a def_operand_p pointer for element INDEX of DEFS. */
|
||||
static inline def_operand_p
|
||||
get_def_op_ptr (def_optype defs, unsigned int index)
|
||||
{
|
||||
gcc_assert (index < defs->num_defs);
|
||||
return defs->defs[index];
|
||||
}
|
||||
|
||||
/* Return the def_operand_p that is the V_MAY_DEF_RESULT for the V_MAY_DEF
|
||||
at INDEX in the V_MAY_DEFS array. */
|
||||
static inline def_operand_p
|
||||
get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index)
|
||||
{
|
||||
def_operand_p op;
|
||||
gcc_assert (index < v_may_defs->num_v_may_defs);
|
||||
op.def = &(v_may_defs->v_may_defs[index].def);
|
||||
return op;
|
||||
}
|
||||
|
||||
/* Return a use_operand_p that is the V_MAY_DEF_OP for the V_MAY_DEF at
|
||||
INDEX in the V_MAY_DEFS array. */
|
||||
static inline use_operand_p
|
||||
get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index)
|
||||
{
|
||||
gcc_assert (index < v_may_defs->num_v_may_defs);
|
||||
return &(v_may_defs->v_may_defs[index].imm_use);
|
||||
}
|
||||
|
||||
/* Return a use_operand_p that is at INDEX in the VUSES array. */
|
||||
static inline use_operand_p
|
||||
get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
|
||||
{
|
||||
gcc_assert (index < vuses->num_vuses);
|
||||
return &(vuses->vuses[index].imm_use);
|
||||
}
|
||||
|
||||
/* Return a def_operand_p that is the V_MUST_DEF_RESULT for the
|
||||
V_MUST_DEF at INDEX in the V_MUST_DEFS array. */
|
||||
static inline def_operand_p
|
||||
get_v_must_def_result_ptr (v_must_def_optype v_must_defs, unsigned int index)
|
||||
{
|
||||
def_operand_p op;
|
||||
gcc_assert (index < v_must_defs->num_v_must_defs);
|
||||
op.def = &(v_must_defs->v_must_defs[index].def);
|
||||
return op;
|
||||
}
|
||||
|
||||
/* Return a use_operand_p that is the V_MUST_DEF_KILL for the
|
||||
V_MUST_DEF at INDEX in the V_MUST_DEFS array. */
|
||||
static inline use_operand_p
|
||||
get_v_must_def_kill_ptr (v_must_def_optype v_must_defs, unsigned int index)
|
||||
{
|
||||
gcc_assert (index < v_must_defs->num_v_must_defs);
|
||||
return &(v_must_defs->v_must_defs[index].imm_use);
|
||||
return *def;
|
||||
}
|
||||
|
||||
/* Return a def_operand_p pointer for the result of PHI. */
|
||||
static inline def_operand_p
|
||||
get_phi_result_ptr (tree phi)
|
||||
{
|
||||
def_operand_p op;
|
||||
op.def = &(PHI_RESULT_TREE (phi));
|
||||
return op;
|
||||
return &(PHI_RESULT_TREE (phi));
|
||||
}
|
||||
|
||||
/* Return a use_operand_p pointer for argument I of phinode PHI. */
|
||||
@ -590,29 +484,6 @@ get_phi_arg_def_ptr (tree phi, int i)
|
||||
return &(PHI_ARG_IMM_USE_NODE (phi,i));
|
||||
}
|
||||
|
||||
/* Delink all immediate_use information for STMT. */
|
||||
static inline void
|
||||
delink_stmt_imm_use (tree stmt)
|
||||
{
|
||||
unsigned int x;
|
||||
use_optype uses = STMT_USE_OPS (stmt);
|
||||
vuse_optype vuses = STMT_VUSE_OPS (stmt);
|
||||
v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
|
||||
v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
|
||||
|
||||
for (x = 0; x < NUM_USES (uses); x++)
|
||||
delink_imm_use (&(uses->uses[x]));
|
||||
|
||||
for (x = 0; x < NUM_VUSES (vuses); x++)
|
||||
delink_imm_use (&(vuses->vuses[x].imm_use));
|
||||
|
||||
for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
|
||||
delink_imm_use (&(v_may_defs->v_may_defs[x].imm_use));
|
||||
|
||||
for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++)
|
||||
delink_imm_use (&(v_must_defs->v_must_defs[x].imm_use));
|
||||
}
|
||||
|
||||
|
||||
/* Return the bitmap of addresses taken by STMT, or NULL if it takes
|
||||
no addresses. */
|
||||
@ -963,23 +834,37 @@ op_iter_done (ssa_op_iter *ptr)
|
||||
static inline use_operand_p
|
||||
op_iter_next_use (ssa_op_iter *ptr)
|
||||
{
|
||||
if (ptr->use_i < ptr->num_use)
|
||||
use_operand_p use_p;
|
||||
#ifdef ENABLE_CHECKING
|
||||
gcc_assert (ptr->iter_type == ssa_op_iter_use);
|
||||
#endif
|
||||
if (ptr->uses)
|
||||
{
|
||||
return USE_OP_PTR (ptr->ops->use_ops, (ptr->use_i)++);
|
||||
use_p = USE_OP_PTR (ptr->uses);
|
||||
ptr->uses = ptr->uses->next;
|
||||
return use_p;
|
||||
}
|
||||
if (ptr->vuse_i < ptr->num_vuse)
|
||||
if (ptr->vuses)
|
||||
{
|
||||
return VUSE_OP_PTR (ptr->ops->vuse_ops, (ptr->vuse_i)++);
|
||||
use_p = VUSE_OP_PTR (ptr->vuses);
|
||||
ptr->vuses = ptr->vuses->next;
|
||||
return use_p;
|
||||
}
|
||||
if (ptr->v_mayu_i < ptr->num_v_mayu)
|
||||
if (ptr->mayuses)
|
||||
{
|
||||
return V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops,
|
||||
(ptr->v_mayu_i)++);
|
||||
use_p = MAYDEF_OP_PTR (ptr->mayuses);
|
||||
ptr->mayuses = ptr->mayuses->next;
|
||||
return use_p;
|
||||
}
|
||||
if (ptr->v_mustu_i < ptr->num_v_mustu)
|
||||
if (ptr->mustkills)
|
||||
{
|
||||
return V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops,
|
||||
(ptr->v_mustu_i)++);
|
||||
use_p = MUSTDEF_KILL_PTR (ptr->mustkills);
|
||||
ptr->mustkills = ptr->mustkills->next;
|
||||
return use_p;
|
||||
}
|
||||
if (ptr->phi_i < ptr->num_phi)
|
||||
{
|
||||
return PHI_ARG_DEF_PTR (ptr->phi_stmt, (ptr->phi_i)++);
|
||||
}
|
||||
ptr->done = true;
|
||||
return NULL_USE_OPERAND_P;
|
||||
@ -989,19 +874,27 @@ op_iter_next_use (ssa_op_iter *ptr)
|
||||
static inline def_operand_p
|
||||
op_iter_next_def (ssa_op_iter *ptr)
|
||||
{
|
||||
if (ptr->def_i < ptr->num_def)
|
||||
def_operand_p def_p;
|
||||
#ifdef ENABLE_CHECKING
|
||||
gcc_assert (ptr->iter_type == ssa_op_iter_def);
|
||||
#endif
|
||||
if (ptr->defs)
|
||||
{
|
||||
return DEF_OP_PTR (ptr->ops->def_ops, (ptr->def_i)++);
|
||||
def_p = DEF_OP_PTR (ptr->defs);
|
||||
ptr->defs = ptr->defs->next;
|
||||
return def_p;
|
||||
}
|
||||
if (ptr->v_mustd_i < ptr->num_v_mustd)
|
||||
if (ptr->mustdefs)
|
||||
{
|
||||
return V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops,
|
||||
(ptr->v_mustd_i)++);
|
||||
def_p = MUSTDEF_RESULT_PTR (ptr->mustdefs);
|
||||
ptr->mustdefs = ptr->mustdefs->next;
|
||||
return def_p;
|
||||
}
|
||||
if (ptr->v_mayd_i < ptr->num_v_mayd)
|
||||
if (ptr->maydefs)
|
||||
{
|
||||
return V_MAY_DEF_RESULT_PTR (ptr->ops->v_may_def_ops,
|
||||
(ptr->v_mayd_i)++);
|
||||
def_p = MAYDEF_RESULT_PTR (ptr->maydefs);
|
||||
ptr->maydefs = ptr->maydefs->next;
|
||||
return def_p;
|
||||
}
|
||||
ptr->done = true;
|
||||
return NULL_DEF_OPERAND_P;
|
||||
@ -1011,68 +904,100 @@ op_iter_next_def (ssa_op_iter *ptr)
|
||||
static inline tree
|
||||
op_iter_next_tree (ssa_op_iter *ptr)
|
||||
{
|
||||
if (ptr->use_i < ptr->num_use)
|
||||
tree val;
|
||||
#ifdef ENABLE_CHECKING
|
||||
gcc_assert (ptr->iter_type == ssa_op_iter_tree);
|
||||
#endif
|
||||
if (ptr->uses)
|
||||
{
|
||||
return USE_OP (ptr->ops->use_ops, (ptr->use_i)++);
|
||||
val = USE_OP (ptr->uses);
|
||||
ptr->uses = ptr->uses->next;
|
||||
return val;
|
||||
}
|
||||
if (ptr->vuse_i < ptr->num_vuse)
|
||||
if (ptr->vuses)
|
||||
{
|
||||
return VUSE_OP (ptr->ops->vuse_ops, (ptr->vuse_i)++);
|
||||
val = VUSE_OP (ptr->vuses);
|
||||
ptr->vuses = ptr->vuses->next;
|
||||
return val;
|
||||
}
|
||||
if (ptr->v_mayu_i < ptr->num_v_mayu)
|
||||
if (ptr->mayuses)
|
||||
{
|
||||
return V_MAY_DEF_OP (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
|
||||
val = MAYDEF_OP (ptr->mayuses);
|
||||
ptr->mayuses = ptr->mayuses->next;
|
||||
return val;
|
||||
}
|
||||
if (ptr->v_mustu_i < ptr->num_v_mustu)
|
||||
if (ptr->mustkills)
|
||||
{
|
||||
return V_MUST_DEF_KILL (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++);
|
||||
val = MUSTDEF_KILL (ptr->mustkills);
|
||||
ptr->mustkills = ptr->mustkills->next;
|
||||
return val;
|
||||
}
|
||||
if (ptr->def_i < ptr->num_def)
|
||||
if (ptr->defs)
|
||||
{
|
||||
return DEF_OP (ptr->ops->def_ops, (ptr->def_i)++);
|
||||
val = DEF_OP (ptr->defs);
|
||||
ptr->defs = ptr->defs->next;
|
||||
return val;
|
||||
}
|
||||
if (ptr->v_mustd_i < ptr->num_v_mustd)
|
||||
if (ptr->mustdefs)
|
||||
{
|
||||
return V_MUST_DEF_RESULT (ptr->ops->v_must_def_ops,
|
||||
(ptr->v_mustd_i)++);
|
||||
val = MUSTDEF_RESULT (ptr->mustdefs);
|
||||
ptr->mustdefs = ptr->mustdefs->next;
|
||||
return val;
|
||||
}
|
||||
if (ptr->v_mayd_i < ptr->num_v_mayd)
|
||||
if (ptr->maydefs)
|
||||
{
|
||||
return V_MAY_DEF_RESULT (ptr->ops->v_may_def_ops,
|
||||
(ptr->v_mayd_i)++);
|
||||
val = MAYDEF_RESULT (ptr->maydefs);
|
||||
ptr->maydefs = ptr->maydefs->next;
|
||||
return val;
|
||||
}
|
||||
|
||||
ptr->done = true;
|
||||
return NULL_TREE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* This functiins clears the iterator PTR, and marks it done. This is normally
|
||||
used to prevent warnings in the compile about might be uninitailzied
|
||||
components. */
|
||||
|
||||
static inline void
|
||||
clear_and_done_ssa_iter (ssa_op_iter *ptr)
|
||||
{
|
||||
ptr->defs = NULL;
|
||||
ptr->uses = NULL;
|
||||
ptr->vuses = NULL;
|
||||
ptr->maydefs = NULL;
|
||||
ptr->mayuses = NULL;
|
||||
ptr->mustdefs = NULL;
|
||||
ptr->mustkills = NULL;
|
||||
ptr->iter_type = ssa_op_iter_none;
|
||||
ptr->phi_i = 0;
|
||||
ptr->num_phi = 0;
|
||||
ptr->phi_stmt = NULL_TREE;
|
||||
ptr->done = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the iterator PTR to the virtual defs in STMT. */
|
||||
static inline void
|
||||
op_iter_init (ssa_op_iter *ptr, tree stmt, int flags)
|
||||
{
|
||||
stmt_operands_p ops;
|
||||
stmt_ann_t ann = get_stmt_ann (stmt);
|
||||
#ifdef ENABLE_CHECKING
|
||||
gcc_assert (stmt_ann (stmt));
|
||||
#endif
|
||||
|
||||
ops = &(ann->operands);
|
||||
ptr->defs = (flags & SSA_OP_DEF) ? DEF_OPS (stmt) : NULL;
|
||||
ptr->uses = (flags & SSA_OP_USE) ? USE_OPS (stmt) : NULL;
|
||||
ptr->vuses = (flags & SSA_OP_VUSE) ? VUSE_OPS (stmt) : NULL;
|
||||
ptr->maydefs = (flags & SSA_OP_VMAYDEF) ? MAYDEF_OPS (stmt) : NULL;
|
||||
ptr->mayuses = (flags & SSA_OP_VMAYUSE) ? MAYDEF_OPS (stmt) : NULL;
|
||||
ptr->mustdefs = (flags & SSA_OP_VMUSTDEF) ? MUSTDEF_OPS (stmt) : NULL;
|
||||
ptr->mustkills = (flags & SSA_OP_VMUSTKILL) ? MUSTDEF_OPS (stmt) : NULL;
|
||||
ptr->done = false;
|
||||
ptr->ops = ops;
|
||||
ptr->num_def = (flags & SSA_OP_DEF) ? NUM_DEFS (ops->def_ops) : 0;
|
||||
ptr->num_use = (flags & SSA_OP_USE) ? NUM_USES (ops->use_ops) : 0;
|
||||
ptr->num_vuse = (flags & SSA_OP_VUSE) ? NUM_VUSES (ops->vuse_ops) : 0;
|
||||
ptr->num_v_mayu = (flags & SSA_OP_VMAYUSE)
|
||||
? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
|
||||
ptr->num_v_mayd = (flags & SSA_OP_VMAYDEF)
|
||||
? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
|
||||
ptr->num_v_mustu = (flags & SSA_OP_VMUSTDEFKILL)
|
||||
? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
|
||||
ptr->num_v_mustd = (flags & SSA_OP_VMUSTDEF)
|
||||
? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
|
||||
ptr->def_i = 0;
|
||||
ptr->use_i = 0;
|
||||
ptr->vuse_i = 0;
|
||||
ptr->v_mayu_i = 0;
|
||||
ptr->v_mayd_i = 0;
|
||||
ptr->v_mustu_i = 0;
|
||||
ptr->v_mustd_i = 0;
|
||||
|
||||
ptr->phi_i = 0;
|
||||
ptr->num_phi = 0;
|
||||
ptr->phi_stmt = NULL_TREE;
|
||||
}
|
||||
|
||||
/* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return
|
||||
@ -1081,6 +1006,7 @@ static inline use_operand_p
|
||||
op_iter_init_use (ssa_op_iter *ptr, tree stmt, int flags)
|
||||
{
|
||||
op_iter_init (ptr, stmt, flags);
|
||||
ptr->iter_type = ssa_op_iter_use;
|
||||
return op_iter_next_use (ptr);
|
||||
}
|
||||
|
||||
@ -1090,6 +1016,7 @@ static inline def_operand_p
|
||||
op_iter_init_def (ssa_op_iter *ptr, tree stmt, int flags)
|
||||
{
|
||||
op_iter_init (ptr, stmt, flags);
|
||||
ptr->iter_type = ssa_op_iter_def;
|
||||
return op_iter_next_def (ptr);
|
||||
}
|
||||
|
||||
@ -1099,76 +1026,41 @@ static inline tree
|
||||
op_iter_init_tree (ssa_op_iter *ptr, tree stmt, int flags)
|
||||
{
|
||||
op_iter_init (ptr, stmt, flags);
|
||||
ptr->iter_type = ssa_op_iter_tree;
|
||||
return op_iter_next_tree (ptr);
|
||||
}
|
||||
|
||||
/* Get the next iterator mustdef value for PTR, returning the mustdef values in
|
||||
KILL and DEF. */
|
||||
static inline void
|
||||
op_iter_next_mustdef (use_operand_p *kill, def_operand_p *def, ssa_op_iter *ptr)
|
||||
op_iter_next_maymustdef (use_operand_p *use, def_operand_p *def,
|
||||
ssa_op_iter *ptr)
|
||||
{
|
||||
if (ptr->v_mustu_i < ptr->num_v_mustu)
|
||||
#ifdef ENABLE_CHECKING
|
||||
gcc_assert (ptr->iter_type == ssa_op_iter_maymustdef);
|
||||
#endif
|
||||
if (ptr->mayuses)
|
||||
{
|
||||
*def = V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops, ptr->v_mustu_i);
|
||||
*kill = V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++);
|
||||
*def = MAYDEF_RESULT_PTR (ptr->mayuses);
|
||||
*use = MAYDEF_OP_PTR (ptr->mayuses);
|
||||
ptr->mayuses = ptr->mayuses->next;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
if (ptr->mustkills)
|
||||
{
|
||||
*def = NULL_DEF_OPERAND_P;
|
||||
*kill = NULL_USE_OPERAND_P;
|
||||
*def = MUSTDEF_RESULT_PTR (ptr->mustkills);
|
||||
*use = MUSTDEF_KILL_PTR (ptr->mustkills);
|
||||
ptr->mustkills = ptr->mustkills->next;
|
||||
return;
|
||||
}
|
||||
|
||||
*def = NULL_DEF_OPERAND_P;
|
||||
*use = NULL_USE_OPERAND_P;
|
||||
ptr->done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the next iterator maydef value for PTR, returning the maydef values in
|
||||
USE and DEF. */
|
||||
static inline void
|
||||
op_iter_next_maydef (use_operand_p *use, def_operand_p *def, ssa_op_iter *ptr)
|
||||
{
|
||||
if (ptr->v_mayu_i < ptr->num_v_mayu)
|
||||
{
|
||||
*def = V_MAY_DEF_RESULT_PTR (ptr->ops->v_may_def_ops, ptr->v_mayu_i);
|
||||
*use = V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
*def = NULL_DEF_OPERAND_P;
|
||||
*use = NULL_USE_OPERAND_P;
|
||||
}
|
||||
ptr->done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the next iterator mustdef or maydef value for PTR, returning the
|
||||
mustdef or maydef values in KILL and DEF. */
|
||||
static inline void
|
||||
op_iter_next_must_and_may_def (use_operand_p *kill,
|
||||
def_operand_p *def,
|
||||
ssa_op_iter *ptr)
|
||||
{
|
||||
if (ptr->v_mustu_i < ptr->num_v_mustu)
|
||||
{
|
||||
*def = V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops, ptr->v_mustu_i);
|
||||
*kill = V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++);
|
||||
return;
|
||||
}
|
||||
else if (ptr->v_mayu_i < ptr->num_v_mayu)
|
||||
{
|
||||
*def = V_MAY_DEF_RESULT_PTR (ptr->ops->v_may_def_ops, ptr->v_mayu_i);
|
||||
*kill = V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
*def = NULL_DEF_OPERAND_P;
|
||||
*kill = NULL_USE_OPERAND_P;
|
||||
}
|
||||
ptr->done = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize iterator PTR to the operands in STMT. Return the first operands
|
||||
in USE and DEF. */
|
||||
@ -1176,8 +1068,11 @@ static inline void
|
||||
op_iter_init_maydef (ssa_op_iter *ptr, tree stmt, use_operand_p *use,
|
||||
def_operand_p *def)
|
||||
{
|
||||
gcc_assert (TREE_CODE (stmt) != PHI_NODE);
|
||||
|
||||
op_iter_init (ptr, stmt, SSA_OP_VMAYUSE);
|
||||
op_iter_next_maydef (use, def, ptr);
|
||||
ptr->iter_type = ssa_op_iter_maymustdef;
|
||||
op_iter_next_maymustdef (use, def, ptr);
|
||||
}
|
||||
|
||||
|
||||
@ -1187,8 +1082,11 @@ static inline void
|
||||
op_iter_init_mustdef (ssa_op_iter *ptr, tree stmt, use_operand_p *kill,
|
||||
def_operand_p *def)
|
||||
{
|
||||
op_iter_init (ptr, stmt, SSA_OP_VMUSTDEFKILL);
|
||||
op_iter_next_mustdef (kill, def, ptr);
|
||||
gcc_assert (TREE_CODE (stmt) != PHI_NODE);
|
||||
|
||||
op_iter_init (ptr, stmt, SSA_OP_VMUSTKILL);
|
||||
ptr->iter_type = ssa_op_iter_maymustdef;
|
||||
op_iter_next_maymustdef (kill, def, ptr);
|
||||
}
|
||||
|
||||
/* Initialize iterator PTR to the operands in STMT. Return the first operands
|
||||
@ -1197,10 +1095,241 @@ static inline void
|
||||
op_iter_init_must_and_may_def (ssa_op_iter *ptr, tree stmt,
|
||||
use_operand_p *kill, def_operand_p *def)
|
||||
{
|
||||
op_iter_init (ptr, stmt, SSA_OP_VMUSTDEFKILL | SSA_OP_VMAYUSE);
|
||||
op_iter_next_must_and_may_def (kill, def, ptr);
|
||||
gcc_assert (TREE_CODE (stmt) != PHI_NODE);
|
||||
|
||||
op_iter_init (ptr, stmt, SSA_OP_VMUSTKILL|SSA_OP_VMAYUSE);
|
||||
ptr->iter_type = ssa_op_iter_maymustdef;
|
||||
op_iter_next_maymustdef (kill, def, ptr);
|
||||
}
|
||||
|
||||
|
||||
/* If there is a single opernad in STMT matching FLAGS, return it. Otherwise
|
||||
return NULL. PTR is the iterator to use. */
|
||||
static inline tree
|
||||
single_ssa_tree_operand (tree stmt, int flags)
|
||||
{
|
||||
tree var;
|
||||
ssa_op_iter iter;
|
||||
|
||||
var = op_iter_init_tree (&iter, stmt, flags);
|
||||
if (op_iter_done (&iter))
|
||||
return NULL_TREE;
|
||||
op_iter_next_tree (&iter);
|
||||
if (op_iter_done (&iter))
|
||||
return var;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
|
||||
/* If there is a single opernad in STMT matching FLAGS, return it. Otherwise
|
||||
return NULL. PTR is the iterator to use. */
|
||||
static inline use_operand_p
|
||||
single_ssa_use_operand (tree stmt, int flags)
|
||||
{
|
||||
use_operand_p var;
|
||||
ssa_op_iter iter;
|
||||
|
||||
var = op_iter_init_use (&iter, stmt, flags);
|
||||
if (op_iter_done (&iter))
|
||||
return NULL_USE_OPERAND_P;
|
||||
op_iter_next_use (&iter);
|
||||
if (op_iter_done (&iter))
|
||||
return var;
|
||||
return NULL_USE_OPERAND_P;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* If there is a single opernad in STMT matching FLAGS, return it. Otherwise
|
||||
return NULL. PTR is the iterator to use. */
|
||||
static inline def_operand_p
|
||||
single_ssa_def_operand (tree stmt, int flags)
|
||||
{
|
||||
def_operand_p var;
|
||||
ssa_op_iter iter;
|
||||
|
||||
var = op_iter_init_def (&iter, stmt, flags);
|
||||
if (op_iter_done (&iter))
|
||||
return NULL_DEF_OPERAND_P;
|
||||
op_iter_next_def (&iter);
|
||||
if (op_iter_done (&iter))
|
||||
return var;
|
||||
return NULL_DEF_OPERAND_P;
|
||||
}
|
||||
|
||||
|
||||
/* If there is a single opernad in STMT matching FLAGS, return it. Otherwise
|
||||
return NULL. PTR is the iterator to use. */
|
||||
static inline bool
|
||||
zero_ssa_operands (tree stmt, int flags)
|
||||
{
|
||||
ssa_op_iter iter;
|
||||
|
||||
op_iter_init_tree (&iter, stmt, flags);
|
||||
return op_iter_done (&iter);
|
||||
}
|
||||
|
||||
|
||||
/* Return the number of opernads mathcing FLAGS in STMT. */
|
||||
static inline int
|
||||
num_ssa_operands (tree stmt, int flags)
|
||||
{
|
||||
ssa_op_iter iter;
|
||||
int num = 0;
|
||||
|
||||
op_iter_init (&iter, stmt, flags);
|
||||
for ( ; iter.defs; iter.defs = iter.defs->next)
|
||||
num++;
|
||||
for ( ; iter.uses; iter.uses = iter.uses->next)
|
||||
num++;
|
||||
for ( ; iter.vuses; iter.vuses = iter.vuses->next)
|
||||
num++;
|
||||
for ( ; iter.maydefs; iter.maydefs = iter.maydefs->next)
|
||||
num++;
|
||||
for ( ; iter.mayuses; iter.mayuses = iter.mayuses->next)
|
||||
num++;
|
||||
for ( ; iter.mustdefs; iter.mustdefs = iter.mustdefs->next)
|
||||
num++;
|
||||
for ( ; iter.mustkills; iter.mustkills = iter.mustkills->next)
|
||||
num++;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
/* Delink all immediate_use information for STMT. */
|
||||
static inline void
|
||||
delink_stmt_imm_use (tree stmt)
|
||||
{
|
||||
ssa_op_iter iter;
|
||||
use_operand_p use_p;
|
||||
|
||||
if (ssa_operands_active ())
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
|
||||
(SSA_OP_ALL_USES | SSA_OP_ALL_KILLS))
|
||||
delink_imm_use (use_p);
|
||||
}
|
||||
|
||||
|
||||
/* This routine will compare all the operands matching FLAGS in STMT1 to those
|
||||
in STMT2. TRUE is returned if they are the same. STMTs can be NULL. */
|
||||
static inline bool
|
||||
compare_ssa_operands_equal (tree stmt1, tree stmt2, int flags)
|
||||
{
|
||||
ssa_op_iter iter1, iter2;
|
||||
tree op1 = NULL_TREE;
|
||||
tree op2 = NULL_TREE;
|
||||
bool look1, look2;
|
||||
|
||||
if (stmt1 == stmt2)
|
||||
return true;
|
||||
|
||||
look1 = stmt1 && stmt_ann (stmt1);
|
||||
look2 = stmt2 && stmt_ann (stmt2);
|
||||
|
||||
if (look1)
|
||||
{
|
||||
op1 = op_iter_init_tree (&iter1, stmt1, flags);
|
||||
if (!look2)
|
||||
return op_iter_done (&iter1);
|
||||
}
|
||||
else
|
||||
clear_and_done_ssa_iter (&iter1);
|
||||
|
||||
if (look2)
|
||||
{
|
||||
op2 = op_iter_init_tree (&iter2, stmt2, flags);
|
||||
if (!look1)
|
||||
return op_iter_done (&iter2);
|
||||
}
|
||||
else
|
||||
clear_and_done_ssa_iter (&iter2);
|
||||
|
||||
while (!op_iter_done (&iter1) && !op_iter_done (&iter2))
|
||||
{
|
||||
if (op1 != op2)
|
||||
return false;
|
||||
op1 = op_iter_next_tree (&iter1);
|
||||
op2 = op_iter_next_tree (&iter2);
|
||||
}
|
||||
|
||||
return (op_iter_done (&iter1) && op_iter_done (&iter2));
|
||||
}
|
||||
|
||||
|
||||
/* If there is a single DEF in the PHI node which matches FLAG, return it.
|
||||
Otherwise return NULL_DEF_OPERAND_P. */
|
||||
static inline tree
|
||||
single_phi_def (tree stmt, int flags)
|
||||
{
|
||||
tree def = PHI_RESULT (stmt);
|
||||
if ((flags & SSA_OP_DEF) && is_gimple_reg (def))
|
||||
return def;
|
||||
if ((flags & SSA_OP_VIRTUAL_DEFS) && !is_gimple_reg (def))
|
||||
return def;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Initialize the iterator PTR for uses matching FLAGS in PHI. FLAGS should
|
||||
be either SSA_OP_USES or SAS_OP_VIRTUAL_USES. */
|
||||
static inline use_operand_p
|
||||
op_iter_init_phiuse (ssa_op_iter *ptr, tree phi, int flags)
|
||||
{
|
||||
tree phi_def = PHI_RESULT (phi);
|
||||
int comp;
|
||||
|
||||
clear_and_done_ssa_iter (ptr);
|
||||
ptr->done = false;
|
||||
|
||||
gcc_assert ((flags & (SSA_OP_USE | SSA_OP_VIRTUAL_USES)) != 0);
|
||||
|
||||
comp = (is_gimple_reg (phi_def) ? SSA_OP_USE : SSA_OP_VIRTUAL_USES);
|
||||
|
||||
/* if the PHI node deosn't the operand type we care about, we're done. */
|
||||
if ((flags & comp) == 0)
|
||||
{
|
||||
ptr->done = true;
|
||||
return NULL_USE_OPERAND_P;
|
||||
}
|
||||
|
||||
ptr->phi_stmt = phi;
|
||||
ptr->num_phi = PHI_NUM_ARGS (phi);
|
||||
ptr->iter_type = ssa_op_iter_use;
|
||||
return op_iter_next_use (ptr);
|
||||
}
|
||||
|
||||
|
||||
/* Start an iterator for a PHI defintion. */
|
||||
|
||||
static inline def_operand_p
|
||||
op_iter_init_phidef (ssa_op_iter *ptr, tree phi, int flags)
|
||||
{
|
||||
tree phi_def = PHI_RESULT (phi);
|
||||
int comp;
|
||||
|
||||
clear_and_done_ssa_iter (ptr);
|
||||
ptr->done = false;
|
||||
|
||||
gcc_assert ((flags & (SSA_OP_DEF | SSA_OP_VIRTUAL_DEFS)) != 0);
|
||||
|
||||
comp = (is_gimple_reg (phi_def) ? SSA_OP_DEF : SSA_OP_VIRTUAL_DEFS);
|
||||
|
||||
/* if the PHI node deosn't the operand type we care about, we're done. */
|
||||
if ((flags & comp) == 0)
|
||||
{
|
||||
ptr->done = true;
|
||||
return NULL_USE_OPERAND_P;
|
||||
}
|
||||
|
||||
ptr->iter_type = ssa_op_iter_def;
|
||||
/* The first call to op_iter_next_def will terminate the iterator since
|
||||
all the fields are NULL. Simply return the result here as the first and
|
||||
therefore only result. */
|
||||
return PHI_RESULT_PTR (phi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return true if VAR cannot be modified by the program. */
|
||||
|
||||
static inline bool
|
||||
|
@ -264,9 +264,9 @@ struct var_ann_d GTY(())
|
||||
|
||||
typedef struct immediate_use_iterator_d
|
||||
{
|
||||
ssa_imm_use_t *imm_use;
|
||||
ssa_imm_use_t *end_p;
|
||||
ssa_imm_use_t iter_node;
|
||||
ssa_use_operand_t *imm_use;
|
||||
ssa_use_operand_t *end_p;
|
||||
ssa_use_operand_t iter_node;
|
||||
} imm_use_iterator;
|
||||
|
||||
|
||||
@ -315,7 +315,7 @@ struct stmt_ann_d GTY(())
|
||||
basic_block GTY ((skip (""))) bb;
|
||||
|
||||
/* Operand cache for stmt. */
|
||||
struct stmt_operands_d operands;
|
||||
struct stmt_operands_d GTY ((skip (""))) operands;
|
||||
|
||||
/* Set of variables that have had their address taken in the statement. */
|
||||
bitmap addresses_taken;
|
||||
@ -362,10 +362,6 @@ static inline int get_lineno (tree);
|
||||
static inline const char *get_filename (tree);
|
||||
static inline bool is_exec_stmt (tree);
|
||||
static inline bool is_label_stmt (tree);
|
||||
static inline v_may_def_optype get_v_may_def_ops (stmt_ann_t);
|
||||
static inline vuse_optype get_vuse_ops (stmt_ann_t);
|
||||
static inline use_optype get_use_ops (stmt_ann_t);
|
||||
static inline def_optype get_def_ops (stmt_ann_t);
|
||||
static inline bitmap addresses_taken (tree);
|
||||
static inline void set_default_def (tree, tree);
|
||||
static inline tree default_def (tree);
|
||||
@ -765,10 +761,10 @@ void print_value_expressions (FILE *, tree);
|
||||
/* In tree-vn.c */
|
||||
bool expressions_equal_p (tree, tree);
|
||||
tree get_value_handle (tree);
|
||||
hashval_t vn_compute (tree, hashval_t, vuse_optype);
|
||||
tree vn_lookup_or_add (tree, vuse_optype);
|
||||
void vn_add (tree, tree, vuse_optype);
|
||||
tree vn_lookup (tree, vuse_optype);
|
||||
hashval_t vn_compute (tree, hashval_t, tree);
|
||||
tree vn_lookup_or_add (tree, tree);
|
||||
void vn_add (tree, tree, tree);
|
||||
tree vn_lookup (tree, tree);
|
||||
void vn_init (void);
|
||||
void vn_delete (void);
|
||||
|
||||
|
@ -616,7 +616,7 @@ add_new_name_mapping (tree new, tree old)
|
||||
for every variable in the function. For every statement S in block
|
||||
BB:
|
||||
|
||||
1- Variables defined by S in DEF_OPS(S) are marked in the bitmap
|
||||
1- Variables defined by S in the DEFS of S are marked in the bitmap
|
||||
WALK_DATA->GLOBAL_DATA->KILLS.
|
||||
|
||||
2- If S uses a variable VAR and there is no preceding kill of VAR,
|
||||
@ -648,7 +648,7 @@ mark_def_sites (struct dom_walk_data *walk_data,
|
||||
/* If a variable is used before being set, then the variable is live
|
||||
across a block boundary, so mark it live-on-entry to BB. */
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
|
||||
SSA_OP_USE | SSA_OP_VUSE | SSA_OP_VMUSTDEFKILL)
|
||||
SSA_OP_USE | SSA_OP_VUSE | SSA_OP_VMUSTKILL)
|
||||
{
|
||||
tree sym = USE_FROM_PTR (use_p);
|
||||
gcc_assert (DECL_P (sym));
|
||||
|
@ -1444,12 +1444,8 @@ add_dependance (temp_expr_table_p tab, int version, tree var)
|
||||
static bool
|
||||
check_replaceable (temp_expr_table_p tab, tree stmt)
|
||||
{
|
||||
stmt_ann_t ann;
|
||||
vuse_optype vuseops;
|
||||
def_optype defs;
|
||||
use_optype uses;
|
||||
tree var, def;
|
||||
int num_use_ops, version;
|
||||
int version;
|
||||
var_map map = tab->map;
|
||||
ssa_op_iter iter;
|
||||
tree call_expr;
|
||||
@ -1457,22 +1453,16 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
|
||||
if (TREE_CODE (stmt) != MODIFY_EXPR)
|
||||
return false;
|
||||
|
||||
ann = stmt_ann (stmt);
|
||||
defs = DEF_OPS (ann);
|
||||
|
||||
/* Punt if there is more than 1 def, or more than 1 use. */
|
||||
if (NUM_DEFS (defs) != 1)
|
||||
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
|
||||
if (!def)
|
||||
return false;
|
||||
def = DEF_OP (defs, 0);
|
||||
|
||||
if (version_ref_count (map, def) != 1)
|
||||
return false;
|
||||
|
||||
/* There must be no V_MAY_DEFS. */
|
||||
if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) != 0)
|
||||
return false;
|
||||
|
||||
/* There must be no V_MUST_DEFS. */
|
||||
if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) != 0)
|
||||
/* There must be no V_MAY_DEFS or V_MUST_DEFS. */
|
||||
if (!(ZERO_SSA_OPERANDS (stmt, (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF))))
|
||||
return false;
|
||||
|
||||
/* Float expressions must go through memory if float-store is on. */
|
||||
@ -1488,21 +1478,6 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
|
||||
return false;
|
||||
}
|
||||
|
||||
uses = USE_OPS (ann);
|
||||
num_use_ops = NUM_USES (uses);
|
||||
vuseops = VUSE_OPS (ann);
|
||||
|
||||
/* Any expression which has no virtual operands and no real operands
|
||||
should have been propagated if it's possible to do anything with them.
|
||||
If this happens here, it probably exists that way for a reason, so we
|
||||
won't touch it. An example is:
|
||||
b_4 = &tab
|
||||
There are no virtual uses nor any real uses, so we just leave this
|
||||
alone to be safe. */
|
||||
|
||||
if (num_use_ops == 0 && NUM_VUSES (vuseops) == 0)
|
||||
return false;
|
||||
|
||||
version = SSA_NAME_VERSION (def);
|
||||
|
||||
/* Add this expression to the dependency list for each use partition. */
|
||||
@ -1512,7 +1487,7 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
|
||||
}
|
||||
|
||||
/* If there are VUSES, add a dependence on virtual defs. */
|
||||
if (NUM_VUSES (vuseops) != 0)
|
||||
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
|
||||
{
|
||||
add_value_to_list (tab, (value_expr_p *)&(tab->version_info[version]),
|
||||
VIRTUAL_PARTITION (tab));
|
||||
@ -1687,12 +1662,8 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
|
||||
free_value_expr (tab, p);
|
||||
}
|
||||
|
||||
/* A V_MAY_DEF kills any expression using a virtual operand. */
|
||||
if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0)
|
||||
kill_virtual_exprs (tab, true);
|
||||
|
||||
/* A V_MUST_DEF kills any expression using a virtual operand. */
|
||||
if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0)
|
||||
/* A V_{MAY,MUST}_DEF kills any expression using a virtual operand. */
|
||||
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
|
||||
kill_virtual_exprs (tab, true);
|
||||
}
|
||||
}
|
||||
@ -1743,7 +1714,8 @@ dump_replaceable_exprs (FILE *f, tree *expr)
|
||||
if (expr[x])
|
||||
{
|
||||
stmt = expr[x];
|
||||
var = DEF_OP (STMT_DEF_OPS (stmt), 0);
|
||||
var = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
|
||||
gcc_assert (var != NULL_TREE);
|
||||
print_generic_expr (f, var, TDF_SLIM);
|
||||
fprintf (f, " replace with --> ");
|
||||
print_generic_expr (f, TREE_OPERAND (stmt, 1), TDF_SLIM);
|
||||
@ -1874,13 +1846,11 @@ rewrite_trees (var_map map, tree *values)
|
||||
{
|
||||
for (si = bsi_start (bb); !bsi_end_p (si); )
|
||||
{
|
||||
size_t num_uses, num_defs;
|
||||
use_optype uses;
|
||||
def_optype defs;
|
||||
tree stmt = bsi_stmt (si);
|
||||
use_operand_p use_p;
|
||||
use_operand_p use_p, copy_use_p;
|
||||
def_operand_p def_p;
|
||||
int remove = 0, is_copy = 0;
|
||||
bool remove = false, is_copy = false;
|
||||
int num_uses = 0;
|
||||
stmt_ann_t ann;
|
||||
ssa_op_iter iter;
|
||||
|
||||
@ -1889,44 +1859,46 @@ rewrite_trees (var_map map, tree *values)
|
||||
|
||||
if (TREE_CODE (stmt) == MODIFY_EXPR
|
||||
&& (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME))
|
||||
is_copy = 1;
|
||||
is_copy = true;
|
||||
|
||||
uses = USE_OPS (ann);
|
||||
num_uses = NUM_USES (uses);
|
||||
copy_use_p = NULL_USE_OPERAND_P;
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
if (replace_use_variable (map, use_p, values))
|
||||
changed = true;
|
||||
changed = true;
|
||||
copy_use_p = use_p;
|
||||
num_uses++;
|
||||
}
|
||||
|
||||
defs = DEF_OPS (ann);
|
||||
num_defs = NUM_DEFS (defs);
|
||||
if (num_uses != 1)
|
||||
is_copy = false;
|
||||
|
||||
/* Mark this stmt for removal if it is the list of replaceable
|
||||
expressions. */
|
||||
if (values && num_defs == 1)
|
||||
def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF);
|
||||
|
||||
if (def_p != NULL)
|
||||
{
|
||||
tree def = DEF_OP (defs, 0);
|
||||
tree val;
|
||||
val = values[SSA_NAME_VERSION (def)];
|
||||
if (val)
|
||||
remove = 1;
|
||||
}
|
||||
if (!remove)
|
||||
{
|
||||
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
|
||||
/* Mark this stmt for removal if it is the list of replaceable
|
||||
expressions. */
|
||||
if (values && values[SSA_NAME_VERSION (DEF_FROM_PTR (def_p))])
|
||||
remove = true;
|
||||
else
|
||||
{
|
||||
if (replace_def_variable (map, def_p, NULL))
|
||||
changed = true;
|
||||
|
||||
/* If both SSA_NAMEs coalesce to the same variable,
|
||||
mark the now redundant copy for removal. */
|
||||
if (is_copy
|
||||
&& num_uses == 1
|
||||
&& (DEF_FROM_PTR (def_p) == USE_OP (uses, 0)))
|
||||
remove = 1;
|
||||
if (is_copy)
|
||||
{
|
||||
gcc_assert (copy_use_p != NULL_USE_OPERAND_P);
|
||||
if (DEF_FROM_PTR (def_p) == USE_FROM_PTR (copy_use_p))
|
||||
remove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
|
||||
if (replace_def_variable (map, def_p, NULL))
|
||||
changed = true;
|
||||
|
||||
/* Remove any stmts marked for removal. */
|
||||
if (remove)
|
||||
|
@ -226,7 +226,7 @@ make_phi_node (tree var, int len)
|
||||
|
||||
for (i = 0; i < capacity; i++)
|
||||
{
|
||||
ssa_imm_use_t * imm;
|
||||
use_operand_p imm;
|
||||
imm = &(PHI_ARG_IMM_USE_NODE (phi, i));
|
||||
imm->use = &(PHI_ARG_DEF_TREE (phi, i));
|
||||
imm->prev = NULL;
|
||||
@ -247,7 +247,7 @@ release_phi_node (tree phi)
|
||||
|
||||
for (x = 0; x < PHI_NUM_ARGS (phi); x++)
|
||||
{
|
||||
ssa_imm_use_t * imm;
|
||||
use_operand_p imm;
|
||||
imm = &(PHI_ARG_IMM_USE_NODE (phi, x));
|
||||
delink_imm_use (imm);
|
||||
}
|
||||
@ -282,7 +282,7 @@ resize_phi_node (tree *phi, int len)
|
||||
|
||||
for (i = 0; i < PHI_NUM_ARGS (new_phi); i++)
|
||||
{
|
||||
ssa_imm_use_t *imm, *old_imm;
|
||||
use_operand_p imm, old_imm;
|
||||
imm = &(PHI_ARG_IMM_USE_NODE (new_phi, i));
|
||||
old_imm = &(PHI_ARG_IMM_USE_NODE (*phi, i));
|
||||
imm->use = &(PHI_ARG_DEF_TREE (new_phi, i));
|
||||
@ -293,7 +293,7 @@ resize_phi_node (tree *phi, int len)
|
||||
|
||||
for (i = PHI_NUM_ARGS (new_phi); i < len; i++)
|
||||
{
|
||||
ssa_imm_use_t * imm;
|
||||
use_operand_p imm;
|
||||
imm = &(PHI_ARG_IMM_USE_NODE (new_phi, i));
|
||||
imm->use = &(PHI_ARG_DEF_TREE (new_phi, i));
|
||||
imm->prev = NULL;
|
||||
|
@ -2098,6 +2098,9 @@ dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
|
||||
use_operand_p kill_p;
|
||||
ssa_op_iter iter;
|
||||
|
||||
if (!ssa_operands_active ())
|
||||
return;
|
||||
|
||||
FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
|
||||
{
|
||||
pp_string (buffer, "# ");
|
||||
|
@ -897,9 +897,7 @@ sra_walk_function (const struct sra_walk_fns *fns)
|
||||
|
||||
/* If the statement has no virtual operands, then it doesn't
|
||||
make any structure references that we care about. */
|
||||
if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0
|
||||
&& NUM_VUSES (VUSE_OPS (ann)) == 0
|
||||
&& NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
|
||||
if (ZERO_SSA_OPERANDS (stmt, (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)))
|
||||
continue;
|
||||
|
||||
switch (TREE_CODE (stmt))
|
||||
|
@ -457,9 +457,7 @@ likely_value (tree stmt)
|
||||
if (!do_store_ccp
|
||||
&& (ann->makes_aliased_stores
|
||||
|| ann->makes_aliased_loads
|
||||
|| NUM_VUSES (VUSE_OPS (ann)) > 0
|
||||
|| NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0
|
||||
|| NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0))
|
||||
|| !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)))
|
||||
return VARYING;
|
||||
|
||||
|
||||
@ -495,8 +493,8 @@ likely_value (tree stmt)
|
||||
}
|
||||
|
||||
if (found_constant
|
||||
|| NUM_USES (USE_OPS (ann)) == 0
|
||||
|| NUM_VUSES (VUSE_OPS (ann)) == 0)
|
||||
|| ZERO_SSA_OPERANDS (stmt, SSA_OP_USE)
|
||||
|| ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
|
||||
return CONSTANT;
|
||||
|
||||
return UNDEFINED;
|
||||
@ -934,17 +932,18 @@ ccp_fold (tree stmt)
|
||||
== FUNCTION_DECL)
|
||||
&& DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)))
|
||||
{
|
||||
use_optype uses = STMT_USE_OPS (stmt);
|
||||
if (NUM_USES (uses) != 0)
|
||||
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_USE))
|
||||
{
|
||||
tree *orig;
|
||||
tree *orig, var;
|
||||
tree fndecl, arglist;
|
||||
size_t i;
|
||||
size_t i = 0;
|
||||
ssa_op_iter iter;
|
||||
use_operand_p var_p;
|
||||
|
||||
/* Preserve the original values of every operand. */
|
||||
orig = xmalloc (sizeof (tree) * NUM_USES (uses));
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
orig[i] = USE_OP (uses, i);
|
||||
orig = xmalloc (sizeof (tree) * NUM_SSA_OPERANDS (stmt, SSA_OP_USE));
|
||||
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
|
||||
orig[i++] = var;
|
||||
|
||||
/* Substitute operands with their values and try to fold. */
|
||||
replace_uses_in (stmt, NULL, const_val);
|
||||
@ -953,8 +952,9 @@ ccp_fold (tree stmt)
|
||||
retval = fold_builtin (fndecl, arglist, false);
|
||||
|
||||
/* Restore operands to their original form. */
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
SET_USE_OP (uses, i, orig[i]);
|
||||
i = 0;
|
||||
FOR_EACH_SSA_USE_OPERAND (var_p, stmt, iter, SSA_OP_USE)
|
||||
SET_USE (var_p, orig[i++]);
|
||||
free (orig);
|
||||
}
|
||||
}
|
||||
@ -1188,9 +1188,6 @@ visit_cond_stmt (tree stmt, edge *taken_edge_p)
|
||||
static enum ssa_prop_result
|
||||
ccp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
|
||||
{
|
||||
stmt_ann_t ann;
|
||||
v_may_def_optype v_may_defs;
|
||||
v_must_def_optype v_must_defs;
|
||||
tree def;
|
||||
ssa_op_iter iter;
|
||||
|
||||
@ -1201,10 +1198,6 @@ ccp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
ann = stmt_ann (stmt);
|
||||
|
||||
v_must_defs = V_MUST_DEF_OPS (ann);
|
||||
v_may_defs = V_MAY_DEF_OPS (ann);
|
||||
if (TREE_CODE (stmt) == MODIFY_EXPR)
|
||||
{
|
||||
/* If the statement is an assignment that produces a single
|
||||
@ -2206,17 +2199,18 @@ convert_to_gimple_builtin (block_stmt_iterator *si_p, tree expr)
|
||||
tmp = get_initialized_tmp_var (expr, &stmts, NULL);
|
||||
pop_gimplify_context (NULL);
|
||||
|
||||
/* The replacement can expose previously unreferenced variables. */
|
||||
for (ti = tsi_start (stmts); !tsi_end_p (ti); tsi_next (&ti))
|
||||
{
|
||||
find_new_referenced_vars (tsi_stmt_ptr (ti));
|
||||
mark_new_vars_to_rename (tsi_stmt (ti));
|
||||
}
|
||||
|
||||
if (EXPR_HAS_LOCATION (stmt))
|
||||
annotate_all_with_locus (&stmts, EXPR_LOCATION (stmt));
|
||||
|
||||
bsi_insert_before (si_p, stmts, BSI_SAME_STMT);
|
||||
/* The replacement can expose previously unreferenced variables. */
|
||||
for (ti = tsi_start (stmts); !tsi_end_p (ti); tsi_next (&ti))
|
||||
{
|
||||
tree new_stmt = tsi_stmt (ti);
|
||||
find_new_referenced_vars (tsi_stmt_ptr (ti));
|
||||
bsi_insert_before (si_p, new_stmt, BSI_NEW_STMT);
|
||||
mark_new_vars_to_rename (bsi_stmt (*si_p));
|
||||
bsi_next (si_p);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
@ -360,9 +360,7 @@ stmt_may_generate_copy (tree stmt)
|
||||
/* If we are not doing store copy-prop, statements with loads and/or
|
||||
stores will never generate a useful copy. */
|
||||
if (!do_store_copy_prop
|
||||
&& (NUM_VUSES (VUSE_OPS (ann)) > 0
|
||||
|| NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0
|
||||
|| NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0))
|
||||
&& !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
|
||||
return false;
|
||||
|
||||
/* Otherwise, the only statements that generate useful copies are
|
||||
@ -596,26 +594,31 @@ copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
|
||||
{
|
||||
enum ssa_prop_result retval;
|
||||
tree cond;
|
||||
use_optype uses;
|
||||
use_operand_p use_p;
|
||||
ssa_op_iter iter;
|
||||
unsigned num;
|
||||
|
||||
|
||||
cond = COND_EXPR_COND (stmt);
|
||||
uses = STMT_USE_OPS (stmt);
|
||||
retval = SSA_PROP_VARYING;
|
||||
num = NUM_SSA_OPERANDS (stmt, SSA_OP_USE);
|
||||
|
||||
/* The only conditionals that we may be able to compute statically
|
||||
are predicates involving at least one SSA_NAME. */
|
||||
if (COMPARISON_CLASS_P (cond)
|
||||
&& NUM_USES (uses) >= 1)
|
||||
&& num >= 1)
|
||||
{
|
||||
unsigned i;
|
||||
tree *orig;
|
||||
|
||||
/* Save the original operands. */
|
||||
orig = xmalloc (sizeof (tree) * NUM_USES (uses));
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
orig = xmalloc (sizeof (tree) * num);
|
||||
i = 0;
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
orig[i] = USE_OP (uses, i);
|
||||
SET_USE_OP (uses, i, get_last_copy_of (USE_OP (uses, i)));
|
||||
tree use = USE_FROM_PTR (use_p);
|
||||
orig[i++] = use;
|
||||
SET_USE (use_p, get_last_copy_of (use));
|
||||
}
|
||||
|
||||
/* See if we can determine the predicate's value. */
|
||||
@ -638,8 +641,9 @@ copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
|
||||
}
|
||||
|
||||
/* Restore the original operands. */
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
SET_USE_OP (uses, i, orig[i]);
|
||||
i = 0;
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||||
SET_USE (use_p, orig[i++]);
|
||||
free (orig);
|
||||
}
|
||||
|
||||
|
@ -124,8 +124,8 @@ struct expr_hash_elt
|
||||
/* The expression (rhs) we want to record. */
|
||||
tree rhs;
|
||||
|
||||
/* The annotation if this element corresponds to a statement. */
|
||||
stmt_ann_t ann;
|
||||
/* The stmt pointer if this element corresponds to a statement. */
|
||||
tree stmt;
|
||||
|
||||
/* The hash value for RHS/ann. */
|
||||
hashval_t hash;
|
||||
@ -675,36 +675,26 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
||||
else
|
||||
{
|
||||
/* Copy the operands. */
|
||||
stmt_ann_t ann = stmt_ann (stmt);
|
||||
use_optype uses = USE_OPS (ann);
|
||||
vuse_optype vuses = VUSE_OPS (ann);
|
||||
tree *uses_copy = xmalloc (NUM_USES (uses) * sizeof (tree));
|
||||
tree *vuses_copy = xmalloc (NUM_VUSES (vuses) * sizeof (tree));
|
||||
unsigned int i;
|
||||
tree *copy;
|
||||
ssa_op_iter iter;
|
||||
use_operand_p use_p;
|
||||
unsigned int num, i = 0;
|
||||
|
||||
/* Make a copy of the uses into USES_COPY, then cprop into
|
||||
the use operands. */
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
num = NUM_SSA_OPERANDS (stmt, (SSA_OP_USE | SSA_OP_VUSE));
|
||||
copy = xcalloc (num, sizeof (tree));
|
||||
|
||||
/* Make a copy of the uses & vuses into USES_COPY, then cprop into
|
||||
the operands. */
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
|
||||
{
|
||||
tree tmp = NULL;
|
||||
tree use = USE_FROM_PTR (use_p);
|
||||
|
||||
uses_copy[i] = USE_OP (uses, i);
|
||||
if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME)
|
||||
tmp = SSA_NAME_VALUE (USE_OP (uses, i));
|
||||
copy[i++] = use;
|
||||
if (TREE_CODE (use) == SSA_NAME)
|
||||
tmp = SSA_NAME_VALUE (use);
|
||||
if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
|
||||
SET_USE_OP (uses, i, tmp);
|
||||
}
|
||||
|
||||
/* Similarly for virtual uses. */
|
||||
for (i = 0; i < NUM_VUSES (vuses); i++)
|
||||
{
|
||||
tree tmp = NULL;
|
||||
|
||||
vuses_copy[i] = VUSE_OP (vuses, i);
|
||||
if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME)
|
||||
tmp = SSA_NAME_VALUE (VUSE_OP (vuses, i));
|
||||
if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
|
||||
SET_VUSE_OP (vuses, i, tmp);
|
||||
SET_USE (use_p, tmp);
|
||||
}
|
||||
|
||||
/* Try to fold/lookup the new expression. Inserting the
|
||||
@ -715,15 +705,13 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
||||
&& !is_gimple_min_invariant (cached_lhs))
|
||||
cached_lhs = lookup_avail_expr (stmt, false);
|
||||
|
||||
|
||||
/* Restore the statement's original uses/defs. */
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
SET_USE_OP (uses, i, uses_copy[i]);
|
||||
i = 0;
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
|
||||
SET_USE (use_p, copy[i++]);
|
||||
|
||||
for (i = 0; i < NUM_VUSES (vuses); i++)
|
||||
SET_VUSE_OP (vuses, i, vuses_copy[i]);
|
||||
|
||||
free (uses_copy);
|
||||
free (vuses_copy);
|
||||
free (copy);
|
||||
}
|
||||
|
||||
/* Record the context sensitive equivalence if we were able
|
||||
@ -885,32 +873,32 @@ initialize_hash_element (tree expr, tree lhs, struct expr_hash_elt *element)
|
||||
we want to record the expression the statement evaluates. */
|
||||
if (COMPARISON_CLASS_P (expr) || TREE_CODE (expr) == TRUTH_NOT_EXPR)
|
||||
{
|
||||
element->ann = NULL;
|
||||
element->stmt = NULL;
|
||||
element->rhs = expr;
|
||||
}
|
||||
else if (TREE_CODE (expr) == COND_EXPR)
|
||||
{
|
||||
element->ann = stmt_ann (expr);
|
||||
element->stmt = expr;
|
||||
element->rhs = COND_EXPR_COND (expr);
|
||||
}
|
||||
else if (TREE_CODE (expr) == SWITCH_EXPR)
|
||||
{
|
||||
element->ann = stmt_ann (expr);
|
||||
element->stmt = expr;
|
||||
element->rhs = SWITCH_COND (expr);
|
||||
}
|
||||
else if (TREE_CODE (expr) == RETURN_EXPR && TREE_OPERAND (expr, 0))
|
||||
{
|
||||
element->ann = stmt_ann (expr);
|
||||
element->stmt = expr;
|
||||
element->rhs = TREE_OPERAND (TREE_OPERAND (expr, 0), 1);
|
||||
}
|
||||
else if (TREE_CODE (expr) == GOTO_EXPR)
|
||||
{
|
||||
element->ann = stmt_ann (expr);
|
||||
element->stmt = expr;
|
||||
element->rhs = GOTO_DESTINATION (expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
element->ann = stmt_ann (expr);
|
||||
element->stmt = expr;
|
||||
element->rhs = TREE_OPERAND (expr, 1);
|
||||
}
|
||||
|
||||
@ -2608,7 +2596,6 @@ static bool
|
||||
eliminate_redundant_computations (struct dom_walk_data *walk_data,
|
||||
tree stmt, stmt_ann_t ann)
|
||||
{
|
||||
v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
|
||||
tree *expr_p, def = NULL_TREE;
|
||||
bool insert = true;
|
||||
tree cached_lhs;
|
||||
@ -2623,7 +2610,7 @@ eliminate_redundant_computations (struct dom_walk_data *walk_data,
|
||||
|| ! def
|
||||
|| TREE_CODE (def) != SSA_NAME
|
||||
|| SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
|
||||
|| NUM_V_MAY_DEFS (v_may_defs) != 0
|
||||
|| !ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF)
|
||||
/* Do not record equivalences for increments of ivs. This would create
|
||||
overlapping live ranges for a very questionable gain. */
|
||||
|| simple_iv_increment_p (stmt))
|
||||
@ -2804,7 +2791,7 @@ record_equivalences_from_stmt (tree stmt,
|
||||
/* Build a new statement with the RHS and LHS exchanged. */
|
||||
new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs);
|
||||
|
||||
create_ssa_artficial_load_stmt (&(ann->operands), new);
|
||||
create_ssa_artficial_load_stmt (new, stmt);
|
||||
|
||||
/* Finally enter the statement into the available expression
|
||||
table. */
|
||||
@ -3391,11 +3378,11 @@ vrp_eq (const void *p1, const void *p2)
|
||||
static hashval_t
|
||||
avail_expr_hash (const void *p)
|
||||
{
|
||||
stmt_ann_t ann = ((struct expr_hash_elt *)p)->ann;
|
||||
tree stmt = ((struct expr_hash_elt *)p)->stmt;
|
||||
tree rhs = ((struct expr_hash_elt *)p)->rhs;
|
||||
tree vuse;
|
||||
ssa_op_iter iter;
|
||||
hashval_t val = 0;
|
||||
size_t i;
|
||||
vuse_optype vuses;
|
||||
|
||||
/* iterative_hash_expr knows how to deal with any expression and
|
||||
deals with commutative operators as well, so just use it instead
|
||||
@ -3405,16 +3392,15 @@ avail_expr_hash (const void *p)
|
||||
/* If the hash table entry is not associated with a statement, then we
|
||||
can just hash the expression and not worry about virtual operands
|
||||
and such. */
|
||||
if (!ann)
|
||||
if (!stmt || !stmt_ann (stmt))
|
||||
return val;
|
||||
|
||||
/* Add the SSA version numbers of every vuse operand. This is important
|
||||
because compound variables like arrays are not renamed in the
|
||||
operands. Rather, the rename is done on the virtual variable
|
||||
representing all the elements of the array. */
|
||||
vuses = VUSE_OPS (ann);
|
||||
for (i = 0; i < NUM_VUSES (vuses); i++)
|
||||
val = iterative_hash_expr (VUSE_OP (vuses, i), val);
|
||||
FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, iter, SSA_OP_VUSE)
|
||||
val = iterative_hash_expr (vuse, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
@ -3428,13 +3414,13 @@ real_avail_expr_hash (const void *p)
|
||||
static int
|
||||
avail_expr_eq (const void *p1, const void *p2)
|
||||
{
|
||||
stmt_ann_t ann1 = ((struct expr_hash_elt *)p1)->ann;
|
||||
tree stmt1 = ((struct expr_hash_elt *)p1)->stmt;
|
||||
tree rhs1 = ((struct expr_hash_elt *)p1)->rhs;
|
||||
stmt_ann_t ann2 = ((struct expr_hash_elt *)p2)->ann;
|
||||
tree stmt2 = ((struct expr_hash_elt *)p2)->stmt;
|
||||
tree rhs2 = ((struct expr_hash_elt *)p2)->rhs;
|
||||
|
||||
/* If they are the same physical expression, return true. */
|
||||
if (rhs1 == rhs2 && ann1 == ann2)
|
||||
if (rhs1 == rhs2 && stmt1 == stmt2)
|
||||
return true;
|
||||
|
||||
/* If their codes are not equal, then quit now. */
|
||||
@ -3447,36 +3433,10 @@ avail_expr_eq (const void *p1, const void *p2)
|
||||
|| lang_hooks.types_compatible_p (TREE_TYPE (rhs1), TREE_TYPE (rhs2)))
|
||||
&& operand_equal_p (rhs1, rhs2, OEP_PURE_SAME))
|
||||
{
|
||||
vuse_optype ops1 = NULL;
|
||||
vuse_optype ops2 = NULL;
|
||||
size_t num_ops1 = 0;
|
||||
size_t num_ops2 = 0;
|
||||
size_t i;
|
||||
|
||||
if (ann1)
|
||||
{
|
||||
ops1 = VUSE_OPS (ann1);
|
||||
num_ops1 = NUM_VUSES (ops1);
|
||||
}
|
||||
|
||||
if (ann2)
|
||||
{
|
||||
ops2 = VUSE_OPS (ann2);
|
||||
num_ops2 = NUM_VUSES (ops2);
|
||||
}
|
||||
|
||||
/* If the number of virtual uses is different, then we consider
|
||||
them not equal. */
|
||||
if (num_ops1 != num_ops2)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < num_ops1; i++)
|
||||
if (VUSE_OP (ops1, i) != VUSE_OP (ops2, i))
|
||||
return false;
|
||||
|
||||
gcc_assert (((struct expr_hash_elt *)p1)->hash
|
||||
bool ret = compare_ssa_operands_equal (stmt1, stmt2, SSA_OP_VUSE);
|
||||
gcc_assert (!ret || ((struct expr_hash_elt *)p1)->hash
|
||||
== ((struct expr_hash_elt *)p2)->hash);
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -167,16 +167,10 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
|
||||
struct dse_global_data *dse_gd = walk_data->global_data;
|
||||
tree stmt = bsi_stmt (bsi);
|
||||
stmt_ann_t ann = stmt_ann (stmt);
|
||||
v_may_def_optype v_may_defs;
|
||||
v_must_def_optype v_must_defs;
|
||||
|
||||
v_may_defs = V_MAY_DEF_OPS (ann);
|
||||
v_must_defs = V_MUST_DEF_OPS (ann);
|
||||
|
||||
/* If this statement has no virtual defs, then there is nothing
|
||||
to do. */
|
||||
if (NUM_V_MAY_DEFS (v_may_defs) == 0
|
||||
&& NUM_V_MUST_DEFS (v_must_defs) == 0)
|
||||
if (ZERO_SSA_OPERANDS (stmt, (SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF)))
|
||||
return;
|
||||
|
||||
/* We know we have virtual definitions. If this is a MODIFY_EXPR that's
|
||||
|
@ -1578,25 +1578,13 @@ fail:
|
||||
static void
|
||||
find_invariants_stmt (struct ivopts_data *data, tree stmt)
|
||||
{
|
||||
use_optype uses = NULL;
|
||||
unsigned i, n;
|
||||
ssa_op_iter iter;
|
||||
use_operand_p use_p;
|
||||
tree op;
|
||||
|
||||
if (TREE_CODE (stmt) == PHI_NODE)
|
||||
n = PHI_NUM_ARGS (stmt);
|
||||
else
|
||||
FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
uses = STMT_USE_OPS (stmt);
|
||||
n = NUM_USES (uses);
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (TREE_CODE (stmt) == PHI_NODE)
|
||||
op = PHI_ARG_DEF (stmt, i);
|
||||
else
|
||||
op = USE_OP (uses, i);
|
||||
|
||||
op = USE_FROM_PTR (use_p);
|
||||
record_invariant (data, op, false);
|
||||
}
|
||||
}
|
||||
@ -1608,8 +1596,8 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
|
||||
{
|
||||
struct iv *iv;
|
||||
tree op, lhs, rhs;
|
||||
use_optype uses = NULL;
|
||||
unsigned i, n;
|
||||
ssa_op_iter iter;
|
||||
use_operand_p use_p;
|
||||
|
||||
find_invariants_stmt (data, stmt);
|
||||
|
||||
@ -1677,20 +1665,9 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
|
||||
return;
|
||||
}
|
||||
|
||||
if (TREE_CODE (stmt) == PHI_NODE)
|
||||
n = PHI_NUM_ARGS (stmt);
|
||||
else
|
||||
FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
uses = STMT_USE_OPS (stmt);
|
||||
n = NUM_USES (uses);
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (TREE_CODE (stmt) == PHI_NODE)
|
||||
op = PHI_ARG_DEF (stmt, i);
|
||||
else
|
||||
op = USE_OP (uses, i);
|
||||
op = USE_FROM_PTR (use_p);
|
||||
|
||||
if (TREE_CODE (op) != SSA_NAME)
|
||||
continue;
|
||||
@ -5577,22 +5554,11 @@ protect_loop_closed_ssa_form_use (edge exit, use_operand_p op_p)
|
||||
static void
|
||||
protect_loop_closed_ssa_form (edge exit, tree stmt)
|
||||
{
|
||||
use_optype uses;
|
||||
vuse_optype vuses;
|
||||
v_may_def_optype v_may_defs;
|
||||
unsigned i;
|
||||
ssa_op_iter iter;
|
||||
use_operand_p use_p;
|
||||
|
||||
uses = STMT_USE_OPS (stmt);
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
protect_loop_closed_ssa_form_use (exit, USE_OP_PTR (uses, i));
|
||||
|
||||
vuses = STMT_VUSE_OPS (stmt);
|
||||
for (i = 0; i < NUM_VUSES (vuses); i++)
|
||||
protect_loop_closed_ssa_form_use (exit, VUSE_OP_PTR (vuses, i));
|
||||
|
||||
v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
|
||||
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
|
||||
protect_loop_closed_ssa_form_use (exit, V_MAY_DEF_OP_PTR (v_may_defs, i));
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
|
||||
protect_loop_closed_ssa_form_use (exit, use_p);
|
||||
}
|
||||
|
||||
/* STMTS compute a value of a phi argument OP on EXIT of a loop. Arrange things
|
||||
|
@ -1081,8 +1081,8 @@ static tree
|
||||
chain_of_csts_start (struct loop *loop, tree x)
|
||||
{
|
||||
tree stmt = SSA_NAME_DEF_STMT (x);
|
||||
tree use;
|
||||
basic_block bb = bb_for_stmt (stmt);
|
||||
use_optype uses;
|
||||
|
||||
if (!bb
|
||||
|| !flow_bb_inside_loop_p (loop, bb))
|
||||
@ -1099,19 +1099,16 @@ chain_of_csts_start (struct loop *loop, tree x)
|
||||
if (TREE_CODE (stmt) != MODIFY_EXPR)
|
||||
return NULL_TREE;
|
||||
|
||||
if (NUM_VUSES (STMT_VUSE_OPS (stmt)) > 0)
|
||||
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
|
||||
return NULL_TREE;
|
||||
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) > 0)
|
||||
return NULL_TREE;
|
||||
if (NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) > 0)
|
||||
return NULL_TREE;
|
||||
if (NUM_DEFS (STMT_DEF_OPS (stmt)) > 1)
|
||||
return NULL_TREE;
|
||||
uses = STMT_USE_OPS (stmt);
|
||||
if (NUM_USES (uses) != 1)
|
||||
if (SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
|
||||
return NULL_TREE;
|
||||
|
||||
return chain_of_csts_start (loop, USE_OP (uses, 0));
|
||||
use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
|
||||
if (use == NULL_USE_OPERAND_P)
|
||||
return NULL_TREE;
|
||||
|
||||
return chain_of_csts_start (loop, use);
|
||||
}
|
||||
|
||||
/* Determines whether the expression X is derived from a result of a phi node
|
||||
@ -1164,8 +1161,8 @@ static tree
|
||||
get_val_for (tree x, tree base)
|
||||
{
|
||||
tree stmt, nx, val;
|
||||
use_optype uses;
|
||||
use_operand_p op;
|
||||
ssa_op_iter iter;
|
||||
|
||||
if (!x)
|
||||
return base;
|
||||
@ -1174,16 +1171,19 @@ get_val_for (tree x, tree base)
|
||||
if (TREE_CODE (stmt) == PHI_NODE)
|
||||
return base;
|
||||
|
||||
uses = STMT_USE_OPS (stmt);
|
||||
op = USE_OP_PTR (uses, 0);
|
||||
FOR_EACH_SSA_USE_OPERAND (op, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
nx = USE_FROM_PTR (op);
|
||||
val = get_val_for (nx, base);
|
||||
SET_USE (op, val);
|
||||
val = fold (TREE_OPERAND (stmt, 1));
|
||||
SET_USE (op, nx);
|
||||
/* only iterate loop once. */
|
||||
return val;
|
||||
}
|
||||
|
||||
nx = USE_FROM_PTR (op);
|
||||
val = get_val_for (nx, base);
|
||||
SET_USE (op, val);
|
||||
val = fold (TREE_OPERAND (stmt, 1));
|
||||
SET_USE (op, nx);
|
||||
|
||||
return val;
|
||||
/* Should never reach here. */
|
||||
gcc_unreachable();
|
||||
}
|
||||
|
||||
/* Tries to count the number of iterations of LOOP till it exits by EXIT
|
||||
|
@ -113,10 +113,9 @@ tree_ssa_unswitch_loops (struct loops *loops)
|
||||
static tree
|
||||
tree_may_unswitch_on (basic_block bb, struct loop *loop)
|
||||
{
|
||||
tree stmt, def, cond;
|
||||
tree stmt, def, cond, use;
|
||||
basic_block def_bb;
|
||||
use_optype uses;
|
||||
unsigned i;
|
||||
ssa_op_iter iter;
|
||||
|
||||
/* BB must end in a simple conditional jump. */
|
||||
stmt = last_stmt (bb);
|
||||
@ -124,10 +123,9 @@ tree_may_unswitch_on (basic_block bb, struct loop *loop)
|
||||
return NULL_TREE;
|
||||
|
||||
/* Condition must be invariant. */
|
||||
uses = STMT_USE_OPS (stmt);
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
def = SSA_NAME_DEF_STMT (USE_OP (uses, i));
|
||||
def = SSA_NAME_DEF_STMT (use);
|
||||
def_bb = bb_for_stmt (def);
|
||||
if (def_bb
|
||||
&& flow_bb_inside_loop_p (loop, def_bb))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,155 +25,116 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
|
||||
/* This represents a pointer to a DEF operand. */
|
||||
typedef struct def_operand_ptr GTY(())
|
||||
{
|
||||
tree * GTY((skip(""))) def;
|
||||
} def_operand_p;
|
||||
typedef tree *def_operand_p;
|
||||
|
||||
/* This represents a pointer to a USE operand. */
|
||||
typedef ssa_imm_use_t *use_operand_p;
|
||||
typedef ssa_use_operand_t *use_operand_p;
|
||||
|
||||
/* NULL operand types. */
|
||||
#define NULL_USE_OPERAND_P NULL
|
||||
extern def_operand_p NULL_DEF_OPERAND_P;
|
||||
#define NULL_DEF_OPERAND_P NULL
|
||||
|
||||
/* This represents the DEF operands of a stmt. */
|
||||
typedef struct def_optype_d GTY(())
|
||||
struct def_optype_d
|
||||
{
|
||||
unsigned num_defs;
|
||||
struct def_operand_ptr GTY((length("%h.num_defs"))) defs[1];
|
||||
} def_optype_t;
|
||||
|
||||
typedef def_optype_t *def_optype;
|
||||
|
||||
/* Operand type which uses a pointer to a tree ihn an immediate use. */
|
||||
typedef ssa_imm_use_t use_operand_type_t;
|
||||
struct def_optype_d *next;
|
||||
tree *def_ptr;
|
||||
};
|
||||
typedef struct def_optype_d *def_optype_p;
|
||||
|
||||
/* This represents the USE operands of a stmt. */
|
||||
typedef struct use_optype_d GTY(())
|
||||
struct use_optype_d
|
||||
{
|
||||
unsigned num_uses;
|
||||
struct ssa_imm_use_d GTY((length("%h.num_uses"))) uses[1];
|
||||
} use_optype_t;
|
||||
|
||||
typedef use_optype_t *use_optype;
|
||||
|
||||
/* Operand type which stores a def a use, and an immediate use. */
|
||||
typedef struct v_def_use_operand_type GTY(())
|
||||
{
|
||||
tree def;
|
||||
tree use;
|
||||
ssa_imm_use_t imm_use;
|
||||
} v_def_use_operand_type_t;
|
||||
struct use_optype_d *next;
|
||||
struct ssa_use_operand_d use_ptr;
|
||||
};
|
||||
typedef struct use_optype_d *use_optype_p;
|
||||
|
||||
/* This represents the MAY_DEFS for a stmt. */
|
||||
typedef struct v_may_def_optype_d GTY(())
|
||||
struct maydef_optype_d
|
||||
{
|
||||
unsigned num_v_may_defs;
|
||||
struct v_def_use_operand_type GTY((length ("%h.num_v_may_defs")))
|
||||
v_may_defs[1];
|
||||
} v_may_def_optype_t;
|
||||
|
||||
typedef v_may_def_optype_t *v_may_def_optype;
|
||||
|
||||
/* Operand type which stores a tree and an immeidate_use. */
|
||||
typedef struct vuse_operand_type GTY(())
|
||||
{
|
||||
tree use;
|
||||
ssa_imm_use_t imm_use;
|
||||
} vuse_operand_type_t;
|
||||
struct maydef_optype_d *next;
|
||||
tree def_var;
|
||||
tree use_var;
|
||||
struct ssa_use_operand_d use_ptr;
|
||||
};
|
||||
typedef struct maydef_optype_d *maydef_optype_p;
|
||||
|
||||
/* This represents the VUSEs for a stmt. */
|
||||
typedef struct vuse_optype_d GTY(())
|
||||
struct vuse_optype_d
|
||||
{
|
||||
unsigned num_vuses;
|
||||
struct vuse_operand_type GTY((length ("%h.num_vuses"))) vuses[1];
|
||||
} vuse_optype_t;
|
||||
|
||||
typedef vuse_optype_t *vuse_optype;
|
||||
|
||||
struct vuse_optype_d *next;
|
||||
tree use_var;
|
||||
struct ssa_use_operand_d use_ptr;
|
||||
};
|
||||
typedef struct vuse_optype_d *vuse_optype_p;
|
||||
|
||||
/* This represents the V_MUST_DEFS for a stmt. */
|
||||
typedef struct v_must_def_optype_d GTY(())
|
||||
struct mustdef_optype_d
|
||||
{
|
||||
unsigned num_v_must_defs;
|
||||
v_def_use_operand_type_t GTY((length("%h.num_v_must_defs"))) v_must_defs[1];
|
||||
} v_must_def_optype_t;
|
||||
struct mustdef_optype_d *next;
|
||||
tree def_var;
|
||||
tree kill_var;
|
||||
struct ssa_use_operand_d use_ptr;
|
||||
};
|
||||
typedef struct mustdef_optype_d *mustdef_optype_p;
|
||||
|
||||
|
||||
#define SSA_OPERAND_MEMORY_SIZE (2048 - sizeof (void *))
|
||||
|
||||
struct ssa_operand_memory_d GTY((chain_next("%h.next")))
|
||||
{
|
||||
struct ssa_operand_memory_d *next;
|
||||
char mem[SSA_OPERAND_MEMORY_SIZE];
|
||||
};
|
||||
|
||||
typedef v_must_def_optype_t *v_must_def_optype;
|
||||
|
||||
/* This represents the operand cache for a stmt. */
|
||||
typedef struct stmt_operands_d GTY(())
|
||||
struct stmt_operands_d
|
||||
{
|
||||
/* Statement operands. */
|
||||
struct def_optype_d * GTY (()) def_ops;
|
||||
struct use_optype_d * GTY (()) use_ops;
|
||||
|
||||
struct def_optype_d * def_ops;
|
||||
struct use_optype_d * use_ops;
|
||||
|
||||
/* Virtual operands (V_MAY_DEF, VUSE, and V_MUST_DEF). */
|
||||
struct v_may_def_optype_d * GTY (()) v_may_def_ops;
|
||||
struct vuse_optype_d * GTY (()) vuse_ops;
|
||||
struct v_must_def_optype_d * GTY (()) v_must_def_ops;
|
||||
} stmt_operands_t;
|
||||
struct maydef_optype_d * maydef_ops;
|
||||
struct vuse_optype_d * vuse_ops;
|
||||
struct mustdef_optype_d * mustdef_ops;
|
||||
};
|
||||
|
||||
typedef struct stmt_operands_d *stmt_operands_p;
|
||||
|
||||
#define USE_FROM_PTR(PTR) get_use_from_ptr (PTR)
|
||||
#define DEF_FROM_PTR(PTR) get_def_from_ptr (PTR)
|
||||
#define SET_USE(USE, V) set_ssa_use_from_ptr (USE, V)
|
||||
#define SET_DEF(DEF, V) ((*(DEF)) = (V))
|
||||
|
||||
typedef stmt_operands_t *stmt_operands_p;
|
||||
#define USE_STMT(USE) (USE)->stmt
|
||||
|
||||
#define USE_FROM_PTR(OP) get_use_from_ptr (OP)
|
||||
#define DEF_FROM_PTR(OP) get_def_from_ptr (OP)
|
||||
#define SET_USE(OP, V) set_ssa_use_from_ptr (OP, V)
|
||||
#define SET_DEF(OP, V) ((*((OP).def)) = (V))
|
||||
#define DEF_OPS(STMT) (stmt_ann (STMT)->operands.def_ops)
|
||||
#define USE_OPS(STMT) (stmt_ann (STMT)->operands.use_ops)
|
||||
#define VUSE_OPS(STMT) (stmt_ann (STMT)->operands.vuse_ops)
|
||||
#define MAYDEF_OPS(STMT) (stmt_ann (STMT)->operands.maydef_ops)
|
||||
#define MUSTDEF_OPS(STMT) (stmt_ann (STMT)->operands.mustdef_ops)
|
||||
|
||||
#define USE_STMT(OP) (OP)->stmt
|
||||
#define USE_OP_PTR(OP) (&((OP)->use_ptr))
|
||||
#define USE_OP(OP) (USE_FROM_PTR (USE_OP_PTR (OP)))
|
||||
|
||||
#define USE_OPS(ANN) get_use_ops (ANN)
|
||||
#define STMT_USE_OPS(STMT) get_use_ops (stmt_ann (STMT))
|
||||
#define NUM_USES(OPS) ((OPS) ? (OPS)->num_uses : 0)
|
||||
#define USE_OP_PTR(OPS, I) get_use_op_ptr ((OPS), (I))
|
||||
#define USE_OP(OPS, I) (USE_FROM_PTR (USE_OP_PTR ((OPS), (I))))
|
||||
#define SET_USE_OP(OPS, I, V) (SET_USE (USE_OP_PTR ((OPS), (I)), (V)))
|
||||
#define DEF_OP_PTR(OP) ((OP)->def_ptr)
|
||||
#define DEF_OP(OP) (DEF_FROM_PTR (DEF_OP_PTR (OP)))
|
||||
|
||||
#define VUSE_OP_PTR(OP) USE_OP_PTR(OP)
|
||||
#define VUSE_OP(OP) ((OP)->use_var)
|
||||
|
||||
#define MAYDEF_RESULT_PTR(OP) (&((OP)->def_var))
|
||||
#define MAYDEF_RESULT(OP) ((OP)->def_var)
|
||||
#define MAYDEF_OP_PTR(OP) USE_OP_PTR (OP)
|
||||
#define MAYDEF_OP(OP) ((OP)->use_var)
|
||||
|
||||
#define DEF_OPS(ANN) get_def_ops (ANN)
|
||||
#define STMT_DEF_OPS(STMT) get_def_ops (stmt_ann (STMT))
|
||||
#define NUM_DEFS(OPS) ((OPS) ? (OPS)->num_defs : 0)
|
||||
#define DEF_OP_PTR(OPS, I) get_def_op_ptr ((OPS), (I))
|
||||
#define DEF_OP(OPS, I) (DEF_FROM_PTR (DEF_OP_PTR ((OPS), (I))))
|
||||
#define SET_DEF_OP(OPS, I, V) (SET_DEF (DEF_OP_PTR ((OPS), (I)), (V)))
|
||||
|
||||
|
||||
|
||||
#define V_MAY_DEF_OPS(ANN) get_v_may_def_ops (ANN)
|
||||
#define STMT_V_MAY_DEF_OPS(STMT) get_v_may_def_ops (stmt_ann(STMT))
|
||||
#define NUM_V_MAY_DEFS(OPS) ((OPS) ? (OPS)->num_v_may_defs : 0)
|
||||
#define V_MAY_DEF_RESULT_PTR(OPS, I) get_v_may_def_result_ptr ((OPS), (I))
|
||||
#define V_MAY_DEF_RESULT(OPS, I) \
|
||||
(DEF_FROM_PTR (V_MAY_DEF_RESULT_PTR ((OPS), (I))))
|
||||
#define SET_V_MAY_DEF_RESULT(OPS, I, V) \
|
||||
(SET_DEF (V_MAY_DEF_RESULT_PTR ((OPS), (I)), (V)))
|
||||
#define V_MAY_DEF_OP_PTR(OPS, I) get_v_may_def_op_ptr ((OPS), (I))
|
||||
#define V_MAY_DEF_OP(OPS, I) \
|
||||
(USE_FROM_PTR (V_MAY_DEF_OP_PTR ((OPS), (I))))
|
||||
#define SET_V_MAY_DEF_OP(OPS, I, V) \
|
||||
(SET_USE (V_MAY_DEF_OP_PTR ((OPS), (I)), (V)))
|
||||
|
||||
|
||||
#define VUSE_OPS(ANN) get_vuse_ops (ANN)
|
||||
#define STMT_VUSE_OPS(STMT) get_vuse_ops (stmt_ann(STMT))
|
||||
#define NUM_VUSES(OPS) ((OPS) ? (OPS)->num_vuses : 0)
|
||||
#define VUSE_OP_PTR(OPS, I) get_vuse_op_ptr ((OPS), (I))
|
||||
#define VUSE_OP(OPS, I) (USE_FROM_PTR (VUSE_OP_PTR ((OPS), (I))))
|
||||
#define SET_VUSE_OP(OPS, I, V) (SET_USE (VUSE_OP_PTR ((OPS), (I)), (V)))
|
||||
|
||||
|
||||
#define V_MUST_DEF_OPS(ANN) get_v_must_def_ops (ANN)
|
||||
#define STMT_V_MUST_DEF_OPS(STMT) get_v_must_def_ops (stmt_ann (STMT))
|
||||
#define NUM_V_MUST_DEFS(OPS) ((OPS) ? (OPS)->num_v_must_defs : 0)
|
||||
#define V_MUST_DEF_RESULT_PTR(OPS, I) get_v_must_def_result_ptr ((OPS), (I))
|
||||
#define V_MUST_DEF_RESULT(OPS, I) \
|
||||
(DEF_FROM_PTR (V_MUST_DEF_RESULT_PTR ((OPS), (I))))
|
||||
#define SET_V_MUST_DEF_RESULT(OPS, I, V) \
|
||||
(SET_DEF (V_MUST_DEF_RESULT_PTR ((OPS), (I)), (V)))
|
||||
#define V_MUST_DEF_KILL_PTR(OPS, I) get_v_must_def_kill_ptr ((OPS), (I))
|
||||
#define V_MUST_DEF_KILL(OPS, I) (USE_FROM_PTR (V_MUST_DEF_KILL_PTR ((OPS), (I))))
|
||||
#define SET_V_MUST_DEF_KILL(OPS, I, V) (SET_USE (V_MUST_DEF_KILL_PTR ((OPS), (I)), (V)))
|
||||
#define MUSTDEF_RESULT_PTR(OP) (&((OP)->def_var))
|
||||
#define MUSTDEF_RESULT(OP) ((OP)->def_var)
|
||||
#define MUSTDEF_KILL_PTR(OP) USE_OP_PTR (OP)
|
||||
#define MUSTDEF_KILL(OP) ((OP)->kill_var)
|
||||
|
||||
#define PHI_RESULT_PTR(PHI) get_phi_result_ptr (PHI)
|
||||
#define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI))
|
||||
@ -196,7 +157,7 @@ extern void update_stmt_operands (tree);
|
||||
extern bool verify_imm_links (FILE *f, tree var);
|
||||
|
||||
extern void copy_virtual_operands (tree, tree);
|
||||
extern void create_ssa_artficial_load_stmt (stmt_operands_p, tree);
|
||||
extern void create_ssa_artficial_load_stmt (tree, tree);
|
||||
|
||||
extern void dump_immediate_uses (FILE *file);
|
||||
extern void dump_immediate_uses_for (FILE *file, tree var);
|
||||
@ -206,6 +167,15 @@ extern void debug_immediate_uses_for (tree var);
|
||||
extern bool ssa_call_clobbered_cache_valid;
|
||||
extern bool ssa_ro_call_cache_valid;
|
||||
|
||||
extern bool ssa_operands_active (void);
|
||||
|
||||
enum ssa_op_iter_type {
|
||||
ssa_op_iter_none = 0,
|
||||
ssa_op_iter_tree,
|
||||
ssa_op_iter_use,
|
||||
ssa_op_iter_def,
|
||||
ssa_op_iter_maymustdef
|
||||
};
|
||||
/* This structure is used in the operand iterator loops. It contains the
|
||||
items required to determine which operand is retrieved next. During
|
||||
optimization, this structure is scalarized, and any unused fields are
|
||||
@ -213,21 +183,17 @@ extern bool ssa_ro_call_cache_valid;
|
||||
|
||||
typedef struct ssa_operand_iterator_d
|
||||
{
|
||||
int num_use;
|
||||
int num_def;
|
||||
int num_vuse;
|
||||
int num_v_mayu;
|
||||
int num_v_mayd;
|
||||
int num_v_mustu;
|
||||
int num_v_mustd;
|
||||
int use_i;
|
||||
int def_i;
|
||||
int vuse_i;
|
||||
int v_mayu_i;
|
||||
int v_mayd_i;
|
||||
int v_mustu_i;
|
||||
int v_mustd_i;
|
||||
stmt_operands_p ops;
|
||||
def_optype_p defs;
|
||||
use_optype_p uses;
|
||||
vuse_optype_p vuses;
|
||||
maydef_optype_p maydefs;
|
||||
maydef_optype_p mayuses;
|
||||
mustdef_optype_p mustdefs;
|
||||
mustdef_optype_p mustkills;
|
||||
enum ssa_op_iter_type iter_type;
|
||||
int phi_i;
|
||||
int num_phi;
|
||||
tree phi_stmt;
|
||||
bool done;
|
||||
} ssa_op_iter;
|
||||
|
||||
@ -239,17 +205,19 @@ typedef struct ssa_operand_iterator_d
|
||||
#define SSA_OP_VMAYUSE 0x08 /* USE portion of V_MAY_DEFS. */
|
||||
#define SSA_OP_VMAYDEF 0x10 /* DEF portion of V_MAY_DEFS. */
|
||||
#define SSA_OP_VMUSTDEF 0x20 /* V_MUST_DEF definitions. */
|
||||
#define SSA_OP_VMUSTDEFKILL 0x40 /* V_MUST_DEF kills. */
|
||||
#define SSA_OP_VMUSTKILL 0x40 /* V_MUST_DEF kills. */
|
||||
|
||||
/* These are commonly grouped operand flags. */
|
||||
#define SSA_OP_VIRTUAL_USES (SSA_OP_VUSE | SSA_OP_VMAYUSE)
|
||||
#define SSA_OP_VIRTUAL_DEFS (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF)
|
||||
#define SSA_OP_VIRTUAL_KILLS (SSA_OP_VMUSTDEFKILL)
|
||||
#define SSA_OP_ALL_VIRTUALS (SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS | SSA_OP_VIRTUAL_DEFS)
|
||||
#define SSA_OP_VIRTUAL_KILLS (SSA_OP_VMUSTKILL)
|
||||
#define SSA_OP_ALL_VIRTUALS (SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS \
|
||||
| SSA_OP_VIRTUAL_DEFS)
|
||||
#define SSA_OP_ALL_USES (SSA_OP_VIRTUAL_USES | SSA_OP_USE)
|
||||
#define SSA_OP_ALL_DEFS (SSA_OP_VIRTUAL_DEFS | SSA_OP_DEF)
|
||||
#define SSA_OP_ALL_KILLS (SSA_OP_VIRTUAL_KILLS)
|
||||
#define SSA_OP_ALL_OPERANDS (SSA_OP_ALL_USES | SSA_OP_ALL_DEFS | SSA_OP_ALL_KILLS)
|
||||
#define SSA_OP_ALL_OPERANDS (SSA_OP_ALL_USES | SSA_OP_ALL_DEFS \
|
||||
| SSA_OP_ALL_KILLS)
|
||||
|
||||
/* This macro executes a loop over the operands of STMT specified in FLAG,
|
||||
returning each operand as a 'tree' in the variable TREEVAR. ITER is an
|
||||
@ -281,7 +249,7 @@ typedef struct ssa_operand_iterator_d
|
||||
#define FOR_EACH_SSA_MAYDEF_OPERAND(DEFVAR, USEVAR, STMT, ITER) \
|
||||
for (op_iter_init_maydef (&(ITER), STMT, &(USEVAR), &(DEFVAR)); \
|
||||
!op_iter_done (&(ITER)); \
|
||||
op_iter_next_maydef (&(USEVAR), &(DEFVAR), &(ITER)))
|
||||
op_iter_next_maymustdef (&(USEVAR), &(DEFVAR), &(ITER)))
|
||||
|
||||
/* This macro executes a loop over the V_MUST_DEF operands of STMT. The def
|
||||
and kill for each V_MUST_DEF is returned in DEFVAR and KILLVAR.
|
||||
@ -289,7 +257,7 @@ typedef struct ssa_operand_iterator_d
|
||||
#define FOR_EACH_SSA_MUSTDEF_OPERAND(DEFVAR, KILLVAR, STMT, ITER) \
|
||||
for (op_iter_init_mustdef (&(ITER), STMT, &(KILLVAR), &(DEFVAR)); \
|
||||
!op_iter_done (&(ITER)); \
|
||||
op_iter_next_mustdef (&(KILLVAR), &(DEFVAR), &(ITER)))
|
||||
op_iter_next_maymustdef (&(KILLVAR), &(DEFVAR), &(ITER)))
|
||||
|
||||
/* This macro executes a loop over the V_{MUST,MAY}_DEF of STMT. The def
|
||||
and kill for each V_{MUST,MAY}_DEF is returned in DEFVAR and KILLVAR.
|
||||
@ -297,5 +265,56 @@ typedef struct ssa_operand_iterator_d
|
||||
#define FOR_EACH_SSA_MUST_AND_MAY_DEF_OPERAND(DEFVAR, KILLVAR, STMT, ITER)\
|
||||
for (op_iter_init_must_and_may_def (&(ITER), STMT, &(KILLVAR), &(DEFVAR));\
|
||||
!op_iter_done (&(ITER)); \
|
||||
op_iter_next_must_and_may_def (&(KILLVAR), &(DEFVAR), &(ITER)))
|
||||
op_iter_next_maymustdef (&(KILLVAR), &(DEFVAR), &(ITER)))
|
||||
|
||||
/* This macro will execute a loop over all the arguemnts of a PHI which
|
||||
match FLAGS. A use_operand_p is alwasy returned via USEVAR. FLAGS
|
||||
can be eiother SSA_OP_USE or SSA_OP_VIRTUAL_USES or SSA_OP_ALL_USES. */
|
||||
#define FOR_EACH_PHI_ARG (USEVAR, STMT, ITER, FLAGS) \
|
||||
for ((USEVAR) = op_iter_init_phiuse (&(ITER), STMT, FLAGS); \
|
||||
!op_iter_done (&(ITER)); \
|
||||
(USEVAR) = op_iter_next_use (&(ITER)))
|
||||
|
||||
|
||||
/* This macro will execute a loop over a stmt, regardless of whether it is
|
||||
a real stmt or a PHI node, looking at the USE nodes matching FLAGS. */
|
||||
#define FOR_EACH_PHI_OR_STMT_USE(USEVAR, STMT, ITER, FLAGS) \
|
||||
for ((USEVAR) = (TREE_CODE (STMT) == PHI_NODE \
|
||||
? op_iter_init_phiuse (&(ITER), STMT, FLAGS) \
|
||||
: op_iter_init_use (&(ITER), STMT, FLAGS)); \
|
||||
!op_iter_done (&(ITER)); \
|
||||
(USEVAR) = op_iter_next_use (&(ITER)))
|
||||
|
||||
/* This macro will execute a loop over a stmt, regardless of whether it is
|
||||
a real stmt or a PHI node, looking at the DEF nodes matching FLAGS. */
|
||||
#define FOR_EACH_PHI_OR_STMT_DEF(DEFVAR, STMT, ITER, FLAGS) \
|
||||
for ((DEFVAR) = (TREE_CODE (STMT) == PHI_NODE \
|
||||
? op_iter_init_phidef (&(ITER), STMT, FLAGS) \
|
||||
: op_iter_init_def (&(ITER), STMT, FLAGS)); \
|
||||
!op_iter_done (&(ITER)); \
|
||||
(DEFVAR) = op_iter_next_def (&(ITER)))
|
||||
|
||||
/* This macro returns an operand in STMT as a tree if it is the ONLY
|
||||
operand matching FLAGS. If there are 0 or more than 1 operand matching
|
||||
FLAGS, then NULL_TREE is returned. */
|
||||
#define SINGLE_SSA_TREE_OPERAND(STMT, FLAGS) \
|
||||
single_ssa_tree_operand (STMT, FLAGS)
|
||||
|
||||
/* This macro returns an operand in STMT as a use_operand_p if it is the ONLY
|
||||
operand matching FLAGS. If there are 0 or more than 1 operand matching
|
||||
FLAGS, then NULL_USE_OPERAND_P is returned. */
|
||||
#define SINGLE_SSA_USE_OPERAND(STMT, FLAGS) \
|
||||
single_ssa_use_operand (STMT, FLAGS)
|
||||
|
||||
/* This macro returns an operand in STMT as a def_operand_p if it is the ONLY
|
||||
operand matching FLAGS. If there are 0 or more than 1 operand matching
|
||||
FLAGS, then NULL_DEF_OPERAND_P is returned. */
|
||||
#define SINGLE_SSA_DEF_OPERAND(STMT, FLAGS) \
|
||||
single_ssa_def_operand (STMT, FLAGS)
|
||||
/* This macro returns TRUE if there are no operands matching FLAGS in STMT. */
|
||||
#define ZERO_SSA_OPERANDS(STMT, FLAGS) zero_ssa_operands (STMT, FLAGS)
|
||||
|
||||
/* THis macro counts the number of operands in STMT matching FLAGS. */
|
||||
#define NUM_SSA_OPERANDS(STMT, FLAGS) num_ssa_operands (STMT, FLAGS)
|
||||
|
||||
#endif /* GCC_TREE_SSA_OPERANDS_H */
|
||||
|
175
gcc/tree-ssa-opfinalize.h
Normal file
175
gcc/tree-ssa-opfinalize.h
Normal file
@ -0,0 +1,175 @@
|
||||
/* SSA operand allocation and finalizing.
|
||||
Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
|
||||
/* This file contains common code which is used by each of the 5 operand
|
||||
types. Macros are defined to specify the varying componenets.
|
||||
|
||||
FINALIZE_FUNC - name of finalize function.
|
||||
FINALIZE_ALLOC - name of allocation routine.
|
||||
FINALIZE_FREE - name of free list.
|
||||
FINALIZE_TYPE - type of node.
|
||||
FINALIZE_OPS - Lead element in list.
|
||||
FINALIZE_USE_PTR - How to get the use_operand_p, if this is a use operand.
|
||||
FINALIZE_INITIALIZE - How to initialize an element.
|
||||
FINALIZE_ELEM - How to retreive an element.
|
||||
FINALIZE_BASE - How to retreive the base variable of an element.
|
||||
FINALIZE_BASE_TYPE - Type of the base variable.
|
||||
FINALIZE_OPBUILD - Opbuild array for these nodes.
|
||||
FINALIZE_OPBUILD_ELEM - How to get an element from the opbuild list.
|
||||
FINALIZE_OPBUILD_BASE - How to get an element base from the opbuild list.
|
||||
FINALIZE_BASE_ZERO - How to zero an element. */
|
||||
|
||||
|
||||
/* This routine will either pick up a node from the free list, or allocate a
|
||||
new one if need be. */
|
||||
|
||||
static inline FINALIZE_TYPE *
|
||||
FINALIZE_ALLOC (void)
|
||||
{
|
||||
FINALIZE_TYPE *ret;
|
||||
if (FINALIZE_FREE)
|
||||
{
|
||||
ret = FINALIZE_FREE;
|
||||
FINALIZE_FREE = FINALIZE_FREE->next;
|
||||
}
|
||||
else
|
||||
ret = (FINALIZE_TYPE *)ssa_operand_alloc (sizeof (FINALIZE_TYPE));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This routine will take the new operands from FINALIZE_OPBUILD and turn them
|
||||
into the new operands for STMT. All required linking and deleting is u
|
||||
performed here. */
|
||||
static inline void
|
||||
FINALIZE_FUNC (tree stmt)
|
||||
{
|
||||
int new_i;
|
||||
FINALIZE_TYPE *old_ops, *ptr, *last;
|
||||
FINALIZE_BASE_TYPE old_base;
|
||||
FINALIZE_TYPE new_list;
|
||||
|
||||
new_list.next = NULL;
|
||||
last = &new_list;
|
||||
|
||||
old_ops = FINALIZE_OPS (stmt);
|
||||
if (old_ops)
|
||||
old_base = FINALIZE_BASE (FINALIZE_ELEM (old_ops));
|
||||
else
|
||||
old_base = FINALIZE_BASE_ZERO;
|
||||
|
||||
new_i = opbuild_first (&FINALIZE_OPBUILD);
|
||||
while (old_ops && new_i != OPBUILD_LAST)
|
||||
{
|
||||
FINALIZE_BASE_TYPE new_base = FINALIZE_OPBUILD_BASE (new_i);
|
||||
if (old_base == new_base)
|
||||
{
|
||||
/* if variables are the same, reuse this node. */
|
||||
last->next = old_ops;
|
||||
last = old_ops;
|
||||
#ifdef FINALIZE_USE_PTR
|
||||
correct_use_link (FINALIZE_USE_PTR (last), stmt);
|
||||
#endif
|
||||
old_ops = old_ops->next;
|
||||
new_i = opbuild_next (&FINALIZE_OPBUILD, new_i);
|
||||
}
|
||||
else
|
||||
if (old_base < new_base)
|
||||
{
|
||||
/* if old is less than new, old goes to the free list. */
|
||||
#ifdef FINALIZE_USE_PTR
|
||||
use_operand_p use_p = FINALIZE_USE_PTR (old_ops);
|
||||
delink_imm_use (use_p);
|
||||
#endif
|
||||
ptr = old_ops;
|
||||
old_ops = old_ops->next;
|
||||
ptr->next = FINALIZE_FREE;
|
||||
FINALIZE_FREE = ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is a new operand. */
|
||||
ptr = FINALIZE_ALLOC ();
|
||||
FINALIZE_INITIALIZE (ptr, FINALIZE_OPBUILD_ELEM (new_i), stmt);
|
||||
last->next = ptr;
|
||||
last = ptr;
|
||||
new_i = opbuild_next (&FINALIZE_OPBUILD, new_i);
|
||||
}
|
||||
if (old_ops)
|
||||
old_base = FINALIZE_BASE (FINALIZE_ELEM (old_ops));
|
||||
}
|
||||
|
||||
/* If there is anything remaining in the opbuild list, simply emit them. */
|
||||
for ( ;
|
||||
new_i != OPBUILD_LAST;
|
||||
new_i = opbuild_next (&FINALIZE_OPBUILD, new_i))
|
||||
{
|
||||
ptr = FINALIZE_ALLOC ();
|
||||
FINALIZE_INITIALIZE (ptr, FINALIZE_OPBUILD_ELEM (new_i), stmt);
|
||||
last->next = ptr;
|
||||
last = ptr;
|
||||
}
|
||||
|
||||
last->next = NULL;
|
||||
|
||||
/* If there is anything in the old list, free them. */
|
||||
if (old_ops)
|
||||
{
|
||||
#ifdef FINALIZE_USE_PTR
|
||||
for (ptr = old_ops; ptr; ptr = ptr->next)
|
||||
{
|
||||
use_operand_p use_p = FINALIZE_USE_PTR (ptr);
|
||||
delink_imm_use (use_p);
|
||||
}
|
||||
#endif
|
||||
old_ops->next = FINALIZE_FREE;
|
||||
FINALIZE_FREE = old_ops;
|
||||
}
|
||||
|
||||
/* NOw set the stmt's operands. */
|
||||
FINALIZE_OPS (stmt) = new_list.next;
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
{
|
||||
unsigned x = 0;
|
||||
for (ptr = FINALIZE_OPS (stmt); ptr; ptr = ptr->next)
|
||||
x++;
|
||||
|
||||
gcc_assert (x == opbuild_num_elems (&FINALIZE_OPBUILD));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef FINALIZE_FUNC
|
||||
#undef FINALIZE_ALLOC
|
||||
#undef FINALIZE_FREE
|
||||
#undef FINALIZE_TYPE
|
||||
#undef FINALIZE_OPS
|
||||
#undef FINALIZE_USE_PTR
|
||||
#undef FINALIZE_INITIALIZE
|
||||
#undef FINALIZE_ELEM
|
||||
#undef FINALIZE_BASE
|
||||
#undef FINALIZE_BASE_TYPE
|
||||
#undef FINALIZE_OPBUILD
|
||||
#undef FINALIZE_OPBUILD_ELEM
|
||||
#undef FINALIZE_OPBUILD_BASE
|
||||
#undef FINALIZE_BASE_ZERO
|
@ -1758,17 +1758,17 @@ is_undefined_value (tree expr)
|
||||
any). They are used when computing the hash value for EXPR. */
|
||||
|
||||
static inline void
|
||||
add_to_sets (tree var, tree expr, vuse_optype vuses, bitmap_set_t s1,
|
||||
add_to_sets (tree var, tree expr, tree stmt, bitmap_set_t s1,
|
||||
bitmap_set_t s2)
|
||||
{
|
||||
tree val = vn_lookup_or_add (expr, vuses);
|
||||
tree val = vn_lookup_or_add (expr, stmt);
|
||||
|
||||
/* VAR and EXPR may be the same when processing statements for which
|
||||
we are not computing value numbers (e.g., non-assignments, or
|
||||
statements that make aliased stores). In those cases, we are
|
||||
only interested in making VAR available as its own value. */
|
||||
if (var != expr)
|
||||
vn_add (var, val, NULL);
|
||||
vn_add (var, val, NULL_TREE);
|
||||
|
||||
if (s1)
|
||||
bitmap_insert_into_set (s1, var);
|
||||
@ -1785,9 +1785,7 @@ add_to_sets (tree var, tree expr, vuse_optype vuses, bitmap_set_t s1,
|
||||
Insert EXPR's operands into the EXP_GEN set for BLOCK. */
|
||||
|
||||
static inline tree
|
||||
create_value_expr_from (tree expr, basic_block block,
|
||||
vuse_optype vuses)
|
||||
|
||||
create_value_expr_from (tree expr, basic_block block, tree stmt)
|
||||
{
|
||||
int i;
|
||||
enum tree_code code = TREE_CODE (expr);
|
||||
@ -1829,9 +1827,9 @@ create_value_expr_from (tree expr, basic_block block,
|
||||
/* Recursively value-numberize reference ops */
|
||||
if (REFERENCE_CLASS_P (op))
|
||||
{
|
||||
tree tempop = create_value_expr_from (op, block, vuses);
|
||||
tree tempop = create_value_expr_from (op, block, stmt);
|
||||
op = tempop ? tempop : op;
|
||||
val = vn_lookup_or_add (op, vuses);
|
||||
val = vn_lookup_or_add (op, stmt);
|
||||
}
|
||||
else
|
||||
/* Create a value handle for OP and add it to VEXPR. */
|
||||
@ -1922,7 +1920,8 @@ compute_avail (void)
|
||||
for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
stmt_ann_t ann;
|
||||
size_t j;
|
||||
ssa_op_iter iter;
|
||||
tree op;
|
||||
|
||||
stmt = bsi_stmt (bsi);
|
||||
ann = stmt_ann (stmt);
|
||||
@ -1938,7 +1937,6 @@ compute_avail (void)
|
||||
{
|
||||
tree lhs = TREE_OPERAND (stmt, 0);
|
||||
tree rhs = TREE_OPERAND (stmt, 1);
|
||||
vuse_optype vuses = STMT_VUSE_OPS (stmt);
|
||||
|
||||
STRIP_USELESS_TYPE_CONVERSION (rhs);
|
||||
if (UNARY_CLASS_P (rhs)
|
||||
@ -1950,10 +1948,10 @@ compute_avail (void)
|
||||
create a duplicate expression with the operands
|
||||
replaced with the value handles of the original
|
||||
RHS. */
|
||||
tree newt = create_value_expr_from (rhs, block, vuses);
|
||||
tree newt = create_value_expr_from (rhs, block, stmt);
|
||||
if (newt)
|
||||
{
|
||||
add_to_sets (lhs, newt, vuses, TMP_GEN (block),
|
||||
add_to_sets (lhs, newt, stmt, TMP_GEN (block),
|
||||
AVAIL_OUT (block));
|
||||
value_insert_into_set (EXP_GEN (block), newt);
|
||||
continue;
|
||||
@ -1968,7 +1966,7 @@ compute_avail (void)
|
||||
/* Compute a value number for the RHS of the statement
|
||||
and add its value to the AVAIL_OUT set for the block.
|
||||
Add the LHS to TMP_GEN. */
|
||||
add_to_sets (lhs, rhs, vuses, TMP_GEN (block),
|
||||
add_to_sets (lhs, rhs, stmt, TMP_GEN (block),
|
||||
AVAIL_OUT (block));
|
||||
|
||||
if (TREE_CODE (rhs) == SSA_NAME
|
||||
@ -1981,18 +1979,11 @@ compute_avail (void)
|
||||
/* For any other statement that we don't recognize, simply
|
||||
make the names generated by the statement available in
|
||||
AVAIL_OUT and TMP_GEN. */
|
||||
for (j = 0; j < NUM_DEFS (STMT_DEF_OPS (stmt)); j++)
|
||||
{
|
||||
tree def = DEF_OP (STMT_DEF_OPS (stmt), j);
|
||||
add_to_sets (def, def, NULL, TMP_GEN (block),
|
||||
AVAIL_OUT (block));
|
||||
}
|
||||
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
|
||||
add_to_sets (op, op, NULL, TMP_GEN (block), AVAIL_OUT (block));
|
||||
|
||||
for (j = 0; j < NUM_USES (STMT_USE_OPS (stmt)); j++)
|
||||
{
|
||||
tree use = USE_OP (STMT_USE_OPS (stmt), j);
|
||||
add_to_sets (use, use, NULL, NULL, AVAIL_OUT (block));
|
||||
}
|
||||
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
|
||||
add_to_sets (op, op, NULL, NULL , AVAIL_OUT (block));
|
||||
}
|
||||
|
||||
/* Put the dominator children of BLOCK on the worklist of blocks
|
||||
|
@ -678,12 +678,14 @@ ssa_propagate (ssa_prop_visit_stmt_fn visit_stmt,
|
||||
tree
|
||||
first_vdef (tree stmt)
|
||||
{
|
||||
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) > 0)
|
||||
return V_MAY_DEF_RESULT (STMT_V_MAY_DEF_OPS (stmt), 0);
|
||||
else if (NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) > 0)
|
||||
return V_MUST_DEF_RESULT (STMT_V_MUST_DEF_OPS (stmt), 0);
|
||||
else
|
||||
gcc_unreachable ();
|
||||
ssa_op_iter iter;
|
||||
tree op;
|
||||
|
||||
/* Simply return the first operand we arrive at. */
|
||||
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_DEFS)
|
||||
return (op);
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
|
||||
@ -700,8 +702,7 @@ stmt_makes_single_load (tree stmt)
|
||||
if (TREE_CODE (stmt) != MODIFY_EXPR)
|
||||
return false;
|
||||
|
||||
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0
|
||||
&& NUM_VUSES (STMT_VUSE_OPS (stmt)) == 0)
|
||||
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF|SSA_OP_VUSE))
|
||||
return false;
|
||||
|
||||
rhs = TREE_OPERAND (stmt, 1);
|
||||
@ -726,8 +727,7 @@ stmt_makes_single_store (tree stmt)
|
||||
if (TREE_CODE (stmt) != MODIFY_EXPR)
|
||||
return false;
|
||||
|
||||
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0
|
||||
&& NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) == 0)
|
||||
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF))
|
||||
return false;
|
||||
|
||||
lhs = TREE_OPERAND (stmt, 0);
|
||||
|
@ -138,16 +138,10 @@ all_immediate_uses_same_place (tree stmt)
|
||||
bool
|
||||
is_hidden_global_store (tree stmt)
|
||||
{
|
||||
stmt_ann_t ann = stmt_ann (stmt);
|
||||
v_may_def_optype v_may_defs;
|
||||
v_must_def_optype v_must_defs;
|
||||
|
||||
/* Check virtual definitions. If we get here, the only virtual
|
||||
definitions we should see are those generated by assignment
|
||||
statements. */
|
||||
v_may_defs = V_MAY_DEF_OPS (ann);
|
||||
v_must_defs = V_MUST_DEF_OPS (ann);
|
||||
if (NUM_V_MAY_DEFS (v_may_defs) > 0 || NUM_V_MUST_DEFS (v_must_defs) > 0)
|
||||
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
|
||||
{
|
||||
tree lhs;
|
||||
|
||||
@ -324,13 +318,13 @@ statement_sink_location (tree stmt, basic_block frombb)
|
||||
|
||||
*/
|
||||
ann = stmt_ann (stmt);
|
||||
if (NUM_VUSES (STMT_VUSE_OPS (stmt)) != 0
|
||||
|| stmt_ends_bb_p (stmt)
|
||||
if (stmt_ends_bb_p (stmt)
|
||||
|| TREE_SIDE_EFFECTS (rhs)
|
||||
|| TREE_CODE (rhs) == EXC_PTR_EXPR
|
||||
|| TREE_CODE (rhs) == FILTER_EXPR
|
||||
|| is_hidden_global_store (stmt)
|
||||
|| ann->has_volatile_ops)
|
||||
|| ann->has_volatile_ops
|
||||
|| !ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
|
||||
return NULL;
|
||||
|
||||
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)
|
||||
@ -397,18 +391,10 @@ statement_sink_location (tree stmt, basic_block frombb)
|
||||
}
|
||||
|
||||
/* Note that at this point, all uses must be in the same statement, so it
|
||||
doesn't matter which def op we choose. */
|
||||
if (STMT_DEF_OPS (stmt) == NULL)
|
||||
{
|
||||
if (STMT_V_MAY_DEF_OPS (stmt) != NULL)
|
||||
def = V_MAY_DEF_RESULT (STMT_V_MAY_DEF_OPS (stmt), 0);
|
||||
else if (STMT_V_MUST_DEF_OPS (stmt) != NULL)
|
||||
def = V_MUST_DEF_RESULT (STMT_V_MUST_DEF_OPS (stmt), 0);
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else
|
||||
def = DEF_OP (STMT_DEF_OPS (stmt), 0);
|
||||
doesn't matter which def op we choose, pick the first one. */
|
||||
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
|
||||
break;
|
||||
|
||||
|
||||
sinkbb = find_bb_for_arg (use, def);
|
||||
if (!sinkbb)
|
||||
|
@ -709,8 +709,8 @@ verify_ssa (bool check_modified_stmt)
|
||||
|
||||
if (check_modified_stmt && stmt_modified_p (stmt))
|
||||
{
|
||||
error ("Stmt (0x%x) marked modified after optimization pass : ",
|
||||
(unsigned long)stmt);
|
||||
error ("Stmt (%p) marked modified after optimization pass : ",
|
||||
(void *)stmt);
|
||||
print_generic_stmt (stderr, stmt, TDF_VOPS);
|
||||
goto err;
|
||||
}
|
||||
@ -725,8 +725,7 @@ verify_ssa (bool check_modified_stmt)
|
||||
|
||||
if (base_address
|
||||
&& SSA_VAR_P (base_address)
|
||||
&& NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0
|
||||
&& NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) == 0)
|
||||
&& ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF))
|
||||
{
|
||||
error ("Statement makes a memory store, but has no "
|
||||
"V_MAY_DEFS nor V_MUST_DEFS");
|
||||
@ -737,7 +736,7 @@ verify_ssa (bool check_modified_stmt)
|
||||
|
||||
|
||||
if (stmt_ann (stmt)->makes_aliased_stores
|
||||
&& NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0)
|
||||
&& ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF))
|
||||
{
|
||||
error ("Statement makes aliased stores, but has no V_MAY_DEFS");
|
||||
print_generic_stmt (stderr, stmt, TDF_VOPS);
|
||||
@ -806,12 +805,23 @@ delete_tree_ssa (void)
|
||||
basic_block bb;
|
||||
block_stmt_iterator bsi;
|
||||
|
||||
/* Release any ssa_names still in use. */
|
||||
for (i = 0; i < num_ssa_names; i++)
|
||||
{
|
||||
tree var = ssa_name (i);
|
||||
if (var && TREE_CODE (var) == SSA_NAME)
|
||||
{
|
||||
SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
|
||||
SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
|
||||
}
|
||||
release_ssa_name (var);
|
||||
}
|
||||
|
||||
/* Remove annotations from every tree in the function. */
|
||||
FOR_EACH_BB (bb)
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
tree stmt = bsi_stmt (bsi);
|
||||
release_defs (stmt);
|
||||
ggc_free (stmt->common.ann);
|
||||
stmt->common.ann = NULL;
|
||||
}
|
||||
@ -943,9 +953,7 @@ stmt_references_memory_p (tree stmt)
|
||||
if (ann->has_volatile_ops)
|
||||
return true;
|
||||
|
||||
return (NUM_VUSES (VUSE_OPS (ann)) > 0
|
||||
|| NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0
|
||||
|| NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0);
|
||||
return (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS));
|
||||
}
|
||||
|
||||
/* Internal helper for walk_use_def_chains. VAR, FN and DATA are as
|
||||
|
@ -121,7 +121,7 @@ tree
|
||||
make_ssa_name (tree var, tree stmt)
|
||||
{
|
||||
tree t;
|
||||
ssa_imm_use_t *imm;
|
||||
use_operand_p imm;
|
||||
|
||||
gcc_assert (DECL_P (var)
|
||||
|| TREE_CODE (var) == INDIRECT_REF);
|
||||
@ -205,7 +205,7 @@ release_ssa_name (tree var)
|
||||
{
|
||||
tree saved_ssa_name_var = SSA_NAME_VAR (var);
|
||||
int saved_ssa_name_version = SSA_NAME_VERSION (var);
|
||||
ssa_imm_use_t *imm = &(SSA_NAME_IMM_USE_NODE (var));
|
||||
use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (var));
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
verify_imm_links (stderr, var);
|
||||
|
@ -413,9 +413,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
|
||||
|
||||
/* If the statement has virtual or volatile operands, fail. */
|
||||
ann = stmt_ann (stmt);
|
||||
if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann))
|
||||
|| NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann))
|
||||
|| NUM_VUSES (VUSE_OPS (ann))
|
||||
if (!ZERO_SSA_OPERANDS (stmt, (SSA_OP_VUSE | SSA_OP_VIRTUAL_DEFS))
|
||||
|| ann->has_volatile_ops)
|
||||
return;
|
||||
}
|
||||
@ -679,13 +677,13 @@ eliminate_tail_call (struct tailcall *t)
|
||||
basic_block bb, first;
|
||||
edge e;
|
||||
tree phi;
|
||||
stmt_ann_t ann;
|
||||
v_may_def_optype v_may_defs;
|
||||
unsigned i;
|
||||
block_stmt_iterator bsi;
|
||||
use_operand_p mayuse;
|
||||
def_operand_p maydef;
|
||||
ssa_op_iter iter;
|
||||
tree orig_stmt;
|
||||
|
||||
stmt = bsi_stmt (t->call_bsi);
|
||||
ann = stmt_ann (stmt);
|
||||
stmt = orig_stmt = bsi_stmt (t->call_bsi);
|
||||
bb = t->call_block;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
@ -748,10 +746,9 @@ eliminate_tail_call (struct tailcall *t)
|
||||
}
|
||||
|
||||
/* Add phi nodes for the call clobbered variables. */
|
||||
v_may_defs = V_MAY_DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
|
||||
FOR_EACH_SSA_MAYDEF_OPERAND (maydef, mayuse, orig_stmt, iter)
|
||||
{
|
||||
param = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i));
|
||||
param = SSA_NAME_VAR (DEF_FROM_PTR (maydef));
|
||||
for (phi = phi_nodes (first); phi; phi = PHI_CHAIN (phi))
|
||||
if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
|
||||
break;
|
||||
@ -782,7 +779,7 @@ eliminate_tail_call (struct tailcall *t)
|
||||
gcc_assert (EDGE_COUNT (first->preds) <= 2);
|
||||
}
|
||||
|
||||
add_phi_arg (phi, V_MAY_DEF_OP (v_may_defs, i), e);
|
||||
add_phi_arg (phi, USE_FROM_PTR (mayuse), e);
|
||||
}
|
||||
|
||||
/* Update the values of accumulators. */
|
||||
|
@ -1943,29 +1943,25 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
|
||||
bool is_read = false;
|
||||
tree stmt = bsi_stmt (si);
|
||||
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
|
||||
v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
|
||||
v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
|
||||
vuse_optype vuses = STMT_VUSE_OPS (stmt);
|
||||
varray_type *datarefs = NULL;
|
||||
int nvuses, nv_may_defs, nv_must_defs;
|
||||
tree memref = NULL;
|
||||
tree scalar_type, vectype;
|
||||
tree base, offset, misalign, step, tag;
|
||||
struct ptr_info_def *ptr_info;
|
||||
bool base_aligned;
|
||||
subvar_t subvars = NULL;
|
||||
bool no_vuse, no_vmaymust;
|
||||
|
||||
/* Assumption: there exists a data-ref in stmt, if and only if
|
||||
it has vuses/vdefs. */
|
||||
|
||||
if (!vuses && !v_may_defs && !v_must_defs)
|
||||
no_vuse = ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE);
|
||||
no_vmaymust = ZERO_SSA_OPERANDS (stmt,
|
||||
SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF);
|
||||
if (no_vuse && no_vmaymust)
|
||||
continue;
|
||||
|
||||
nvuses = NUM_VUSES (vuses);
|
||||
nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
|
||||
nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
|
||||
|
||||
if (nvuses && (nv_may_defs || nv_must_defs))
|
||||
if (!no_vuse && !no_vmaymust)
|
||||
{
|
||||
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
|
||||
{
|
||||
@ -1985,7 +1981,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vuses)
|
||||
if (!no_vuse)
|
||||
{
|
||||
memref = TREE_OPERAND (stmt, 1);
|
||||
datarefs = &(LOOP_VINFO_DATAREF_READS (loop_vinfo));
|
||||
@ -2106,49 +2102,29 @@ vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt)
|
||||
static bool
|
||||
vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo)
|
||||
{
|
||||
v_may_def_optype v_may_defs;
|
||||
v_must_def_optype v_must_defs;
|
||||
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
|
||||
ssa_op_iter op_iter;
|
||||
imm_use_iterator imm_iter;
|
||||
use_operand_p use_p;
|
||||
tree var;
|
||||
def_operand_p def_p;
|
||||
|
||||
/* cond stmt other than loop exit cond. */
|
||||
if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
|
||||
return true;
|
||||
|
||||
/* changing memory. */
|
||||
if (TREE_CODE (stmt) == PHI_NODE)
|
||||
{
|
||||
if (!is_gimple_reg (PHI_RESULT (stmt)))
|
||||
return false;
|
||||
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, PHI_RESULT (stmt))
|
||||
{
|
||||
basic_block bb = bb_for_stmt (USE_STMT (use_p));
|
||||
if (!flow_bb_inside_loop_p (loop, bb))
|
||||
{
|
||||
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
|
||||
fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
|
||||
v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
|
||||
if (v_may_defs || v_must_defs)
|
||||
{
|
||||
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
|
||||
fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
|
||||
return true;
|
||||
}
|
||||
if (TREE_CODE (stmt) != PHI_NODE)
|
||||
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
|
||||
{
|
||||
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
|
||||
fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
|
||||
return true;
|
||||
}
|
||||
|
||||
/* uses outside the loop. */
|
||||
FOR_EACH_SSA_TREE_OPERAND (var, stmt, op_iter, SSA_OP_DEF)
|
||||
FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
|
||||
{
|
||||
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
|
||||
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
|
||||
{
|
||||
basic_block bb = bb_for_stmt (USE_STMT (use_p));
|
||||
if (!flow_bb_inside_loop_p (loop, bb))
|
||||
@ -2188,11 +2164,10 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
|
||||
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
|
||||
unsigned int nbbs = loop->num_nodes;
|
||||
block_stmt_iterator si;
|
||||
tree stmt;
|
||||
stmt_ann_t ann;
|
||||
tree stmt, use;
|
||||
ssa_op_iter iter;
|
||||
unsigned int i;
|
||||
int j;
|
||||
use_optype use_ops;
|
||||
stmt_vec_info stmt_info;
|
||||
basic_block bb;
|
||||
tree phi;
|
||||
@ -2291,12 +2266,8 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
|
||||
}
|
||||
}
|
||||
|
||||
ann = stmt_ann (stmt);
|
||||
use_ops = USE_OPS (ann);
|
||||
|
||||
for (i = 0; i < NUM_USES (use_ops); i++)
|
||||
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
tree use = USE_OP (use_ops, i);
|
||||
|
||||
/* We are only interested in uses that need to be vectorized. Uses
|
||||
that are used for address computation are not considered relevant.
|
||||
|
@ -1499,13 +1499,12 @@ update_vuses_to_preheader (tree stmt, struct loop *loop)
|
||||
{
|
||||
basic_block header_bb = loop->header;
|
||||
edge preheader_e = loop_preheader_edge (loop);
|
||||
vuse_optype vuses = STMT_VUSE_OPS (stmt);
|
||||
int nvuses = NUM_VUSES (vuses);
|
||||
int i;
|
||||
ssa_op_iter iter;
|
||||
use_operand_p use_p;
|
||||
|
||||
for (i = 0; i < nvuses; i++)
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VUSE)
|
||||
{
|
||||
tree ssa_name = VUSE_OP (vuses, i);
|
||||
tree ssa_name = USE_FROM_PTR (use_p);
|
||||
tree def_stmt = SSA_NAME_DEF_STMT (ssa_name);
|
||||
tree name_var = SSA_NAME_VAR (ssa_name);
|
||||
basic_block bb = bb_for_stmt (def_stmt);
|
||||
@ -1524,8 +1523,7 @@ update_vuses_to_preheader (tree stmt, struct loop *loop)
|
||||
{
|
||||
if (SSA_NAME_VAR (PHI_RESULT (phi)) == name_var)
|
||||
{
|
||||
SET_VUSE_OP (vuses, i,
|
||||
PHI_ARG_DEF (phi, preheader_e->dest_idx));
|
||||
SET_USE (use_p, PHI_ARG_DEF (phi, preheader_e->dest_idx));
|
||||
updated = true;
|
||||
break;
|
||||
}
|
||||
|
@ -215,12 +215,8 @@ rename_variables_in_bb (basic_block bb)
|
||||
tree phi;
|
||||
block_stmt_iterator bsi;
|
||||
tree stmt;
|
||||
stmt_ann_t ann;
|
||||
use_optype uses;
|
||||
vuse_optype vuses;
|
||||
v_may_def_optype v_may_defs;
|
||||
v_must_def_optype v_must_defs;
|
||||
unsigned i;
|
||||
use_operand_p use_p;
|
||||
ssa_op_iter iter;
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
struct loop *loop = bb->loop_father;
|
||||
@ -228,23 +224,9 @@ rename_variables_in_bb (basic_block bb)
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
stmt = bsi_stmt (bsi);
|
||||
ann = stmt_ann (stmt);
|
||||
|
||||
uses = USE_OPS (ann);
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
rename_use_op (USE_OP_PTR (uses, i));
|
||||
|
||||
vuses = VUSE_OPS (ann);
|
||||
for (i = 0; i < NUM_VUSES (vuses); i++)
|
||||
rename_use_op (VUSE_OP_PTR (vuses, i));
|
||||
|
||||
v_may_defs = V_MAY_DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
|
||||
rename_use_op (V_MAY_DEF_OP_PTR (v_may_defs, i));
|
||||
|
||||
v_must_defs = V_MUST_DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
|
||||
rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i));
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
|
||||
(SSA_OP_ALL_USES | SSA_OP_ALL_KILLS))
|
||||
rename_use_op (use_p);
|
||||
}
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
|
@ -48,8 +48,8 @@ typedef struct val_expr_pair_d
|
||||
/* Associated expression. */
|
||||
tree e;
|
||||
|
||||
/* Virtual uses in E. */
|
||||
vuse_optype vuses;
|
||||
/* for comparing Virtual uses in E. */
|
||||
tree stmt;
|
||||
|
||||
/* E's hash value. */
|
||||
hashval_t hashcode;
|
||||
@ -79,13 +79,13 @@ make_value_handle (tree type)
|
||||
VAL can be used to iterate by passing previous value numbers (it is
|
||||
used by iterative_hash_expr).
|
||||
|
||||
VUSES is the set of virtual use operands associated with EXPR. It
|
||||
may be NULL if EXPR has no virtual operands. */
|
||||
STMT is the stmt associated with EXPR for comparing virtual operands. */
|
||||
|
||||
hashval_t
|
||||
vn_compute (tree expr, hashval_t val, vuse_optype vuses)
|
||||
vn_compute (tree expr, hashval_t val, tree stmt)
|
||||
{
|
||||
size_t i;
|
||||
ssa_op_iter iter;
|
||||
tree vuse;
|
||||
|
||||
/* EXPR must not be a statement. We are only interested in value
|
||||
numbering expressions on the RHS of assignments. */
|
||||
@ -97,8 +97,9 @@ vn_compute (tree expr, hashval_t val, vuse_optype vuses)
|
||||
|
||||
/* If the expression has virtual uses, incorporate them into the
|
||||
hash value computed for EXPR. */
|
||||
for (i = 0; i < NUM_VUSES (vuses); i++)
|
||||
val = iterative_hash_expr (VUSE_OP (vuses, i), val);
|
||||
if (stmt)
|
||||
FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, iter, SSA_OP_VUSE)
|
||||
val = iterative_hash_expr (vuse, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
@ -146,22 +147,15 @@ val_expr_pair_hash (const void *p)
|
||||
static int
|
||||
val_expr_pair_expr_eq (const void *p1, const void *p2)
|
||||
{
|
||||
bool ret;
|
||||
const val_expr_pair_t ve1 = (val_expr_pair_t) p1;
|
||||
const val_expr_pair_t ve2 = (val_expr_pair_t) p2;
|
||||
size_t i;
|
||||
|
||||
if (! expressions_equal_p (ve1->e, ve2->e))
|
||||
return false;
|
||||
|
||||
if (NUM_VUSES (ve1->vuses) != NUM_VUSES (ve2->vuses))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < NUM_VUSES (ve1->vuses); i++)
|
||||
if (! expressions_equal_p (VUSE_OP (ve1->vuses, i),
|
||||
VUSE_OP (ve2->vuses, i)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
ret = compare_ssa_operands_equal (ve1->stmt, ve2->stmt, SSA_OP_VUSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -181,12 +175,11 @@ set_value_handle (tree e, tree v)
|
||||
|
||||
|
||||
/* Insert EXPR into VALUE_TABLE with value VAL, and add expression
|
||||
EXPR to the value set for value VAL. VUSES represent the virtual
|
||||
use operands associated with EXPR (if any). They are used when
|
||||
computing the hash value for EXPR. */
|
||||
EXPR to the value set for value VAL. STMT represent the stmt
|
||||
associated with EXPR. It is used when computing a hash value for EXPR. */
|
||||
|
||||
void
|
||||
vn_add (tree expr, tree val, vuse_optype vuses)
|
||||
vn_add (tree expr, tree val, tree stmt)
|
||||
{
|
||||
void **slot;
|
||||
val_expr_pair_t new_pair;
|
||||
@ -194,8 +187,8 @@ vn_add (tree expr, tree val, vuse_optype vuses)
|
||||
new_pair = xmalloc (sizeof (struct val_expr_pair_d));
|
||||
new_pair->e = expr;
|
||||
new_pair->v = val;
|
||||
new_pair->vuses = vuses;
|
||||
new_pair->hashcode = vn_compute (expr, 0, vuses);
|
||||
new_pair->stmt = stmt;
|
||||
new_pair->hashcode = vn_compute (expr, 0, stmt);
|
||||
slot = htab_find_slot_with_hash (value_table, new_pair, new_pair->hashcode,
|
||||
INSERT);
|
||||
if (*slot)
|
||||
@ -208,12 +201,12 @@ vn_add (tree expr, tree val, vuse_optype vuses)
|
||||
|
||||
|
||||
/* Search in VALUE_TABLE for an existing instance of expression EXPR,
|
||||
and return its value, or NULL if none has been set. VUSES
|
||||
represent the virtual use operands associated with EXPR (if any).
|
||||
They are used when computing the hash value for EXPR. */
|
||||
and return its value, or NULL if none has been set. STMT
|
||||
represent the stmt associated with EXPR. It is arused when computing the
|
||||
hash value for EXPR. */
|
||||
|
||||
tree
|
||||
vn_lookup (tree expr, vuse_optype vuses)
|
||||
vn_lookup (tree expr, tree stmt)
|
||||
{
|
||||
void **slot;
|
||||
struct val_expr_pair_d vep = {NULL, NULL, NULL, 0};
|
||||
@ -223,8 +216,8 @@ vn_lookup (tree expr, vuse_optype vuses)
|
||||
return expr;
|
||||
|
||||
vep.e = expr;
|
||||
vep.vuses = vuses;
|
||||
vep.hashcode = vn_compute (expr, 0, vuses);
|
||||
vep.stmt = stmt;
|
||||
vep.hashcode = vn_compute (expr, 0, stmt);
|
||||
slot = htab_find_slot_with_hash (value_table, &vep, vep.hashcode, NO_INSERT);
|
||||
if (!slot)
|
||||
return NULL_TREE;
|
||||
@ -235,14 +228,13 @@ vn_lookup (tree expr, vuse_optype vuses)
|
||||
|
||||
/* Like vn_lookup, but creates a new value for expression EXPR, if
|
||||
EXPR doesn't already have a value. Return the existing/created
|
||||
value for EXPR. VUSES represent the virtual use operands
|
||||
associated with EXPR (if any). They are used when computing the
|
||||
hash value for EXPR. */
|
||||
value for EXPR. STMT represent the stmt associated with EXPR. It is used
|
||||
when computing the hash value for EXPR. */
|
||||
|
||||
tree
|
||||
vn_lookup_or_add (tree expr, vuse_optype vuses)
|
||||
vn_lookup_or_add (tree expr, tree stmt)
|
||||
{
|
||||
tree v = vn_lookup (expr, vuses);
|
||||
tree v = vn_lookup (expr, stmt);
|
||||
if (v == NULL_TREE)
|
||||
{
|
||||
v = make_value_handle (TREE_TYPE (expr));
|
||||
@ -256,7 +248,7 @@ vn_lookup_or_add (tree expr, vuse_optype vuses)
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
vn_add (expr, v, vuses);
|
||||
vn_add (expr, v, stmt);
|
||||
}
|
||||
|
||||
set_value_handle (expr, v);
|
||||
|
@ -1544,7 +1544,6 @@ maybe_add_assert_expr (basic_block bb)
|
||||
block_stmt_iterator si;
|
||||
tree last;
|
||||
bool added;
|
||||
use_optype uses;
|
||||
|
||||
/* Step 1. Mark all the SSA names used in BB in bitmap FOUND. */
|
||||
added = false;
|
||||
@ -1628,16 +1627,20 @@ maybe_add_assert_expr (basic_block bb)
|
||||
if (last
|
||||
&& TREE_CODE (last) == COND_EXPR
|
||||
&& !fp_predicate (COND_EXPR_COND (last))
|
||||
&& NUM_USES (uses = STMT_USE_OPS (last)) > 0)
|
||||
&& !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
tree op, cond;
|
||||
basic_block son;
|
||||
ssa_op_iter iter;
|
||||
|
||||
cond = COND_EXPR_COND (last);
|
||||
|
||||
op = USE_OP (uses, 0);
|
||||
/* Get just the first use operand. */
|
||||
FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
|
||||
break;
|
||||
gcc_assert (op != NULL);
|
||||
|
||||
/* Do not attempt to infer anything in names that flow through
|
||||
abnormal edges. */
|
||||
@ -1819,14 +1822,11 @@ stmt_interesting_for_vrp (tree stmt)
|
||||
else if (TREE_CODE (stmt) == MODIFY_EXPR)
|
||||
{
|
||||
tree lhs = TREE_OPERAND (stmt, 0);
|
||||
stmt_ann_t ann = stmt_ann (stmt);
|
||||
|
||||
if (TREE_CODE (lhs) == SSA_NAME
|
||||
&& (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|
||||
|| POINTER_TYPE_P (TREE_TYPE (lhs)))
|
||||
&& NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0
|
||||
&& NUM_VUSES (VUSE_OPS (ann)) == 0
|
||||
&& NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
|
||||
&& ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
|
||||
return true;
|
||||
}
|
||||
else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
|
||||
@ -2080,9 +2080,7 @@ vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
|
||||
|
||||
ann = stmt_ann (stmt);
|
||||
if (TREE_CODE (stmt) == MODIFY_EXPR
|
||||
&& NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0
|
||||
&& NUM_VUSES (VUSE_OPS (ann)) == 0
|
||||
&& NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
|
||||
&& ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
|
||||
return vrp_visit_assignment (stmt, output_p);
|
||||
else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
|
||||
return vrp_visit_cond_stmt (stmt, taken_edge_p);
|
||||
|
12
gcc/tree.h
12
gcc/tree.h
@ -1355,13 +1355,13 @@ struct value_range_def;
|
||||
|
||||
/* Immediate use linking structure. This structure is used for maintaining
|
||||
a doubly linked list of uses of an SSA_NAME. */
|
||||
typedef struct ssa_imm_use_d GTY(())
|
||||
typedef struct ssa_use_operand_d GTY(())
|
||||
{
|
||||
struct ssa_imm_use_d* GTY((skip(""))) prev;
|
||||
struct ssa_imm_use_d* GTY((skip(""))) next;
|
||||
struct ssa_use_operand_d* GTY((skip(""))) prev;
|
||||
struct ssa_use_operand_d* GTY((skip(""))) next;
|
||||
tree GTY((skip(""))) stmt;
|
||||
tree *GTY((skip(""))) use;
|
||||
} ssa_imm_use_t;
|
||||
} ssa_use_operand_t;
|
||||
|
||||
/* Return the immediate_use information for an SSA_NAME. */
|
||||
#define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses
|
||||
@ -1393,7 +1393,7 @@ struct tree_ssa_name GTY(())
|
||||
PTR GTY((skip)) aux;
|
||||
|
||||
/* Immediate uses list for this SSA_NAME. */
|
||||
struct ssa_imm_use_d imm_uses;
|
||||
struct ssa_use_operand_d imm_uses;
|
||||
};
|
||||
|
||||
/* In a PHI_NODE node. */
|
||||
@ -1424,7 +1424,7 @@ struct phi_arg_d GTY(())
|
||||
{
|
||||
/* imm_use MUST be the first element in struct because we do some
|
||||
pointer arithmetic with it. See phi_arg_index_from_use. */
|
||||
struct ssa_imm_use_d imm_use;
|
||||
struct ssa_use_operand_d imm_use;
|
||||
tree def;
|
||||
bool nonzero;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user