From 389dd41bd043170e7dc7660304f14a5f16af3562 Mon Sep 17 00:00:00 2001 From: manu Date: Thu, 16 Jul 2009 22:29:52 +0000 Subject: =?UTF-8?q?2009-07-17=20=20Aldy=20Hernandez=20=20=20=09=20=20=20=20Manuel=20L=C3=B3pez-Ib=C3=A1=C3=B1ez=20=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR 40435 * tree-complex.c, tree-loop-distribution.c, tree.c, tree.h, builtins.c, fold-const.c, omp-low.c, cgraphunit.c, tree-ssa-ccp.c, tree-ssa-dom.c, gimple-low.c, expr.c, tree-ssa-ifcombine.c, c-decl.c, stor-layout.c, tree-if-conv.c, c-typeck.c, gimplify.c, calls.c, tree-sra.c, tree-mudflap.c, tree-ssa-copy.c, tree-ssa-forwprop.c, c-convert.c, c-omp.c, varasm.c, tree-inline.c, c-common.c, c-common.h, gimple.c, tree-switch-conversion.c, gimple.h, tree-cfg.c, c-parser.c, convert.c: Add location argument to fold_{unary,binary,ternary}, fold_build[123], build_call_expr, build_size_arg, build_fold_addr_expr, build_call_array, non_lvalue, size_diffop, fold_build1_initializer, fold_build2_initializer, fold_build3_initializer, fold_build_call_array, fold_build_call_array_initializer, fold_single_bit_test, omit_one_operand, omit_two_operands, invert_truthvalue, fold_truth_not_expr, build_fold_indirect_ref, fold_indirect_ref, combine_comparisons, fold_builtin_*, fold_call_expr, build_range_check, maybe_fold_offset_to_address, round_up, round_down. objc/ * objc-act.c: Add location argument to all calls to build_fold_addr_expr. testsuite/ * gcc.dg/pr36902.c: Add column info. * g++.dg/gcov/gcov-2.C: Change count for definition. cp/ * typeck.c, init.c, class.c, method.c, rtti.c, except.c, error.c, tree.c, cp-gimplify.c, cxx-pretty-print.c, pt.c, semantics.c, call.c, cvt.c, mangle.c: Add location argument to fold_{unary,binary,ternary}, fold_build[123], build_call_expr, build_size_arg, build_fold_addr_expr, build_call_array, non_lvalue, size_diffop, fold_build1_initializer, fold_build2_initializer, fold_build3_initializer, fold_build_call_array, fold_build_call_array_initializer, fold_single_bit_test, omit_one_operand, omit_two_operands, invert_truthvalue, fold_truth_not_expr, build_fold_indirect_ref, fold_indirect_ref, combine_comparisons, fold_builtin_*, fold_call_expr, build_range_check, maybe_fold_offset_to_address, round_up, round_down. fortran/ * trans-expr.c, trans-array.c, trans-openmp.c, trans-stmt.c, trans.c, trans-io.c, trans-decl.c, trans-intrinsic.c: Add location argument to fold_{unary,binary,ternary}, fold_build[123], build_call_expr, build_size_arg, build_fold_addr_expr, build_call_array, non_lvalue, size_diffop, fold_build1_initializer, fold_build2_initializer, fold_build3_initializer, fold_build_call_array, fold_build_call_array_initializer, fold_single_bit_test, omit_one_operand, omit_two_operands, invert_truthvalue, fold_truth_not_expr, build_fold_indirect_ref, fold_indirect_ref, combine_comparisons, fold_builtin_*, fold_call_expr, build_range_check, maybe_fold_offset_to_address, round_up, round_down. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149722 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index c1b05328fa6..bfd0c293156 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -271,10 +271,11 @@ tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, { tree c, c2; edge true_edge, false_edge; + location_t loc = gimple_location (stmt); gcc_assert (gimple_code (stmt) == GIMPLE_COND); - c = fold_build2 (gimple_cond_code (stmt), boolean_type_node, + c = fold_build2_loc (loc, gimple_cond_code (stmt), boolean_type_node, gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); extract_true_false_edges_from_block (gimple_bb (stmt), @@ -286,7 +287,7 @@ tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, add_to_dst_predicate_list (loop, true_edge, cond, c, gsi); /* If 'c' is false then FALSE_EDGE is taken. */ - c2 = invert_truthvalue (unshare_expr (c)); + c2 = invert_truthvalue_loc (loc, unshare_expr (c)); add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi); /* Now this conditional statement is redundant. Remove it. @@ -615,7 +616,8 @@ add_to_predicate_list (basic_block bb, tree new_cond) tree cond = (tree) bb->aux; if (cond) - cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, + cond = fold_build2_loc (EXPR_LOCATION (cond), + TRUTH_OR_EXPR, boolean_type_node, unshare_expr (cond), new_cond); else cond = new_cond; -- cgit v1.2.1 From 9845d1202fec65574ca05d780859eb8c25489566 Mon Sep 17 00:00:00 2001 From: aoliva Date: Wed, 2 Sep 2009 02:42:21 +0000 Subject: gcc/ChangeLog: * doc/invoke.texi (-fvar-tracking-assignments): New. (-fvar-tracking-assignments-toggle): New. (-fdump-final-insns=file): Mark filename as optional. (--param min-nondebug-insn-uid): New. (-gdwarf-@{version}): Mention version 4. * opts.c (common_handle_option): Accept it. * tree-vrp.c (find_assert_locations_1): Skip debug stmts. * regrename.c (regrename_optimize): Drop last. Don't count debug insns as uses. Don't reject change because of debug insn. (do_replace): Reject DEBUG_INSN as chain starter. Take base_regno from the chain starter, and check for inexact matches in DEBUG_INSNS. (scan_rtx_reg): Accept inexact matches in DEBUG_INSNs. (build_def_use): Simplify and fix the marking of DEBUG_INSNs. * sched-ebb.c (schedule_ebbs): Skip boundary debug insns. * fwprop.c (forward_propagate_and_simplify): ...into debug insns. * doc/gimple.texi (is_gimple_debug): New. (gimple_debug_bind_p): New. (is_gimple_call, gimple_assign_cast_p): End sentence with period. * doc/install.texi (bootstrap-debug): More details. (bootstrap-debug-big, bootstrap-debug-lean): Document. (bootstrap-debug-lib): More details. (bootstrap-debug-ckovw): Update. (bootstrap-time): New. * tree-into-ssa.c (mark_def_sites): Skip debug stmts. (insert_phi_nodes_for): Insert debug stmts. (rewrite_stmt): Take iterator. Insert debug stmts. (rewrite_enter_block): Adjust. (maybe_replace_use_in_debug_stmt): New. (rewrite_update_stmt): Use it. (mark_use_interesting): Return early for debug stmts. * tree-ssa-loop-im.c (rewrite_bittest): Propagate DEFs into debug stmts before replacing stmt. (move_computations_stmt): Likewise. * ira-conflicts.c (add_copies): Skip debug insns. * regstat.c (regstat_init_n_sets_and_refs): Discount debug insns. (regstat_bb_compute_ri): Skip debug insns. * tree-ssa-threadupdate.c (redirection_block_p): Skip debug stmts. * tree-ssa-loop-manip.c (find_uses_to_rename_stmt, check_loop_closed_ssa_stmt): Skip debug stmts. * tree-tailcall.c (find_tail_calls): Likewise. * tree-ssa-loop-ch.c (should_duplicate_loop_header_p): Likewise. * tree.h (MAY_HAVE_DEBUG_STMTS): New. (build_var_debug_value_stat): Declare. (build_var_debug_value): Define. (target_for_debug_bind): Declare. * reload.c (find_equiv_reg): Skip debug insns. * rtlanal.c (reg_used_between_p): Skip debug insns. (side_effects_p): Likewise. (canonicalize_condition): Likewise. * ddg.c (create_ddg_dep_from_intra_loop_link): Check that non-debug insns never depend on debug insns. (create_ddg_dep_no_link): Likewise. (add_cross_iteration_register_deps): Use ANTI_DEP for debug insns. Don't add inter-loop dependencies for debug insns. (build_intra_loop_deps): Likewise. (create_ddg): Count debug insns. * ddg.h (struct ddg::num_debug): New. (num_backargs): Pair up with previous int field. * diagnostic.c (diagnostic_report_diagnostic): Skip notes on -fcompare-debug-second. * final.c (get_attr_length_1): Skip debug insns. (rest_of_clean-state): Don't dump CFA_RESTORE_STATE. * gcc.c (invoke_as): Call compare-debug-dump-opt. (driver_self_specs): Map -fdump-final-insns to -fdump-final-insns=.. (get_local_tick): New. (compare_debug_dump_opt_spec_function): Test for . argument and compute output name. Compute temp output spec without flag name. Compute -frandom-seed. (OPT): Undef after use. * cfgloopanal.c (num_loop_insns): Skip debug insns. (average_num_loop_insns): Likewise. * params.h (MIN_NONDEBUG_INSN_UID): New. * gimple.def (GIMPLE_DEBUG): New. * ipa-reference.c (scan_stmt_for_static_refs): Skip debug stmts. * auto-inc-dec.c (merge_in_block): Skip debug insns. (merge_in_block): Fix whitespace. * toplev.c (flag_var_tracking): Update comment. (flag_var_tracking_assignments): New. (flag_var_tracking_assignments_toggle): New. (process_options): Don't open final insns dump file if we're not going to write to it. Compute defaults for var_tracking. * df-scan.c (df_insn_rescan_debug_internal): New. (df_uses_record): Handle debug insns. * haifa-sched.c (ready): Initialize n_debug. (contributes_to_priority): Skip debug insns. (dep_list_size): New. (priority): Use it. (rank_for_schedule): Likewise. Schedule debug insns as soon as they're ready. Disregard previous debug insns to make decisions. (queue_insn): Never queue debug insns. (ready_add, ready_remove_first, ready_remove): Count debug insns. (schedule_insn): Don't reject debug insns because of issue rate. (get_ebb_head_tail, no_real_insns_p): Skip boundary debug insns. (queue_to_ready): Skip and discount debug insns. (choose_ready): Let debug insns through. (schedule_block): Check boundary debug insns. Discount debug insns, schedule them early. Adjust whitespace. (set_priorities): Check for boundary debug insns. (add_jump_dependencies): Use dep_list_size. (prev_non_location_insn): New. (check_cfg): Use it. * tree-ssa-loop-ivopts.c (find-interesting_users): Skip debug stmts. (remove_unused_ivs): Reset debug stmts. * modulo-sched.c (const_iteration_count): Skip debug insns. (res_MII): Discount debug insns. (loop_single_full_bb_p): Skip debug insns. (sms_schedule): Likewise. (sms_schedule_by_order): Likewise. (ps_has_conflicts): Likewise. * caller-save.c (refmarker_fn): New. (save_call_clobbered_regs): Replace regs with saved mem in debug insns. (mark_referenced_regs): Take pointer, mark and arg. Adjust. Call refmarker_fn mark for hardregnos. (mark_reg_as_referenced): New. (replace_reg_with_saved_mem): New. * ipa-pure-const.c (check_stmt): Skip debug stmts. * cse.c (cse_insn): Canonicalize debug insns. Skip them when searching back. (cse_extended_basic_block): Skip debug insns. (count_reg_usage): Likewise. (is_dead_reg): New, split out of... (set_live_p): ... here. (insn_live_p): Use it for debug insns. * tree-stdarg.c (check_all_va_list_escapes): Skip debug stmts. (execute_optimize_stdarg): Likewise. * tree-ssa-dom.c (propagate_rhs_into_lhs): Likewise. * tree-ssa-propagate.c (substitute_and_fold): Don't regard changes in debug stmts as changes. * sel-sched.c (moving_insn_creates_bookkeeping_block_p): New. (moveup_expr): Don't move across debug insns. Don't move debug insn if it would create a bookkeeping block. (moveup_expr_cached): Don't use cache for debug insns that are heads of blocks. (compute_av_set_inside_bb): Skip debug insns. (sel_rank_for_schedule): Schedule debug insns first. Remove dead code. (block_valid_for_bookkeeping_p); Support lax searches. (create_block_for_bookkeeping): Adjust block numbers when encountering debug-only blocks. (find_place_for_bookkeeping): Deal with debug-only blocks. (generate_bookkeeping_insn): Accept no place to insert. (remove_temp_moveop_nops): New argument full_tidying. (prepare_place_to_insert): Deal with debug insns. (advance_state_on_fence): Debug insns don't start cycles. (update_boundaries): Take fence as argument. Deal with debug insns. (schedule_expr_on_boundary): No full_tidying on debug insns. (fill_insns): Deal with debug insns. (track_scheduled_insns_and_blocks): Don't count debug insns. (need_nop_to_preserve_insn_bb): New, split out of... (remove_insn_from_stream): ... this. (fur_orig_expr_not_found): Skip debug insns. * rtl.def (VALUE): Move up. (DEBUG_INSN): New. * tree-ssa-sink.c (all_immediate_uses_same_place): Skip debug stmts. (nearest_common_dominator_of_uses): Take debug_stmts argument. Set it if debug stmts are found. (statement_sink_location): Skip debug stmts. Propagate moving defs into debug stmts. * ifcvt.c (first_active_insn): Skip debug insns. (last_active_insns): Likewise. (cond_exec_process_insns): Likewise. (noce_process_if_block): Likewise. (check_cond_move_block): Likewise. (cond_move_convert_if_block): Likewise. (block_jumps_and_fallthru_p): Likewise. (dead_or_predicable): Likewise. * dwarf2out.c (debug_str_hash_forced): New. (find_AT_string): Add comment. (gen_label_for_indirect_string): New. (get_debug_string_label): New. (AT_string_form): Use it. (mem_loc_descriptor): Handle non-TLS symbols. Handle MINUS , DIV, MOD, AND, IOR, XOR, NOT, ABS, NEG, and CONST_STRING. Accept but discard COMPARE, IF_THEN_ELSE, ROTATE, ROTATERT, TRUNCATE and several operations that cannot be represented with DWARF opcodes. (loc_descriptor): Ignore SIGN_EXTEND and ZERO_EXTEND. Require dwarf_version 4 for DW_OP_implicit_value and DW_OP_stack_value. (dwarf2out_var_location): Take during-call mark into account. (output_indirect_string): Update comment. Output if there are label and references. (prune_indirect_string): New. (prune_unused_types): Call it if debug_str_hash_forced. More in dwarf2out.c, from Jakub Jelinek : (dw_long_long_const): Remove. (struct dw_val_struct): Change val_long_long type to rtx. (print_die, attr_checksum, same_dw_val_p, loc_descriptor): Adjust for val_long_long change to CONST_DOUBLE rtx from a long hi/lo pair. (output_die): Likewise. Use HOST_BITS_PER_WIDE_INT size of each component instead of HOST_BITS_PER_LONG. (output_loc_operands): Likewise. For const8* assert HOST_BITS_PER_WIDE_INT rather than HOST_BITS_PER_LONG is >= 64. (output_loc_operands_raw): For const8* assert HOST_BITS_PER_WIDE_INT rather than HOST_BITS_PER_LONG is >= 64. (add_AT_long_long): Remove val_hi and val_lo arguments, add val_const_double. (size_of_die): Use HOST_BITS_PER_WIDE_INT size multiplier instead of HOST_BITS_PER_LONG for dw_val_class_long_long. (add_const_value_attribute): Adjust add_AT_long_long caller. Don't handle TLS SYMBOL_REFs. If CONST wraps a constant, tail recurse. (dwarf_stack_op_name): Handle DW_OP_implicit_value and DW_OP_stack_value. (size_of_loc_descr, output_loc_operands, output_loc_operands_raw): Handle DW_OP_implicit_value. (extract_int): Move prototype earlier. (mem_loc_descriptor): For SUBREG punt if inner mode size is wider than DWARF2_ADDR_SIZE. Handle SIGN_EXTEND and ZERO_EXTEND by DW_OP_shl and DW_OP_shr{a,}. Handle EQ, NE, GT, GE, LT, LE, GTU, GEU, LTU, LEU, SMIN, SMAX, UMIN, UMAX, SIGN_EXTRACT, ZERO_EXTRACT. (loc_descriptor): Compare mode size with DWARF2_ADDR_SIZE instead of Pmode size. (loc_descriptor): Add MODE argument. Handle CONST_INT, CONST_DOUBLE, CONST_VECTOR, CONST, LABEL_REF and SYMBOL_REF if mode != VOIDmode, attempt to handle other expressions. Don't handle TLS SYMBOL_REFs. (concat_loc_descriptor, concatn_loc_descriptor, loc_descriptor_from_tree_1): Adjust loc_descriptor callers. (add_location_or_const_value_attribute): Likewise. For single location loc_lists attempt to use add_const_value_attribute for constant decls. Add DW_AT_const_value even if NOTE_VAR_LOCATION is VAR_LOCATION with CONSTANT_P or CONST_STRING in its expression. * cfgbuild.c (inside_basic_block_p): Handle debug insns. (control_flow_insn_p): Likewise. * tree-parloops.c (eliminate_local_variables_stmt): Handle debug stmt. (separate_decls_in_region_debug_bind): New. (separate_decls_in_region): Process debug bind stmts afterwards. * recog.c (verify_changes): Handle debug insns. (extract_insn): Likewise. (peephole2_optimize): Skip debug insns. * dse.c (scan_insn): Skip debug insns. * sel-sched-ir.c (return_nop_to_pool): Take full_tidying argument. Pass it on. (setup_id_for_insn): Handle debug insns. (maybe_tidy_empty_bb): Adjust whitespace. (tidy_control_flow): Skip debug insns. (sel_remove_insn): Adjust for debug insns. (sel_estimate_number_of_insns): Skip debug insns. (create_insn_rtx_from_pattern): Handle debug insns. (create_copy_of_insn_rtx): Likewise. * sel-sched-.h (sel_bb_end): Declare. (sel_bb_empty_or_nop_p): New. (get_all_loop_exits): Use it. (_eligible_successor_edge_p): Likewise. (return_nop_to_pool): Adjust. * tree-eh.c (tre_empty_eh_handler_p): Skip debug stmts. * ira-lives.c (process_bb_node_lives): Skip debug insns. * gimple-pretty-print.c (dump_gimple_debug): New. (dump_gimple_stmt): Use it. (dump_bb_header): Skip gimple debug stmts. * regmove.c (optimize_reg_copy_1): Discount debug insns. (fixup_match_2): Likewise. (regmove_backward_pass): Likewise. Simplify combined replacement. Handle debug insns. * function.c (instantiate_virtual_regs): Handle debug insns. * function.h (struct emit_status): Add x_cur_debug_insn_uid. * print-rtl.h: Include cselib.h. (print_rtx): Print VALUEs. Split out and recurse for VAR_LOCATIONs. * df.h (df_inns_rescan_debug_internal): Declare. * gcse.c (alloc_hash_table): Estimate n_insns. (cprop_insn): Don't regard debug insns as changes. (bypass_conditional_jumps): Skip debug insns. (one_pre_gcse_pass): Adjust. (one_code_hoisting_pass): Likewise. (compute_ld_motion_mems): Skip debug insns. (one_cprop_pass): Adjust. * tree-if-conv.c (tree_if_convert_stmt): Reset debug stmts. (if_convertible_stmt_p): Handle debug stmts. * init-regs.c (initialize_uninitialized_regs): Skip debug insns. * tree-vect-loop.c (vect_is_simple_reduction): Skip debug stmts. * ira-build.c (create_bb_allocnos): Skip debug insns. * tree-flow-inline.h (has_zero_uses): Discount debug stmts. (has_single_use): Likewise. (single_imm_use): Likewise. (num_imm_uses): Likewise. * tree-ssa-phiopt.c (empty_block_p): Skip debug stmts. * tree-ssa-coalesce.c (build_ssa_conflict_graph): Skip debug stmts. (create_outofssa_var_map): Likewise. * lower-subreg.c (adjust_decomposed_uses): New. (resolve_debug): New. (decompose_multiword_subregs): Use it. * tree-dfa.c (find_referenced_vars): Skip debug stmts. * emit-rtl.c: Include params.h. (cur_debug_insn_uid): Define. (set_new_first_and_last_insn): Set cur_debug_insn_uid too. (copy_rtx_if_shared_1): Handle debug insns. (reset_used_flags): Likewise. (set_used_flags): LIkewise. (get_max_insn_count): New. (next_nondebug_insn): New. (prev_nondebug_insn): New. (make_debug_insn_raw): New. (emit_insn_before_noloc): Handle debug insns. (emit_jump_insn_before_noloc): Likewise. (emit_call_insn_before_noloc): Likewise. (emit_debug_insn_before_noloc): New. (emit_insn_after_noloc): Handle debug insns. (emit_jump_insn_after_noloc): Likewise. (emit_call_insn_after_noloc): Likewise. (emit_debug_insn_after_noloc): Likewise. (emit_insn_after): Take loc from earlier non-debug insn. (emit_jump_insn_after): Likewise. (emit_call_insn_after): Likewise. (emit_debug_insn_after_setloc): New. (emit_debug_insn_after): New. (emit_insn_before): Take loc from later non-debug insn. (emit_jump_insn_before): Likewise. (emit_call_insn_before): Likewise. (emit_debug_insn_before_setloc): New. (emit_debug_insn_before): New. (emit_insn): Handle debug insns. (emit_debug_insn): New. (emit_jump_insn): Handle debug insns. (emit_call_insn): Likewise. (emit): Likewise. (init_emit): Take min-nondebug-insn-uid into account. Initialize cur_debug_insn_uid. (emit_copy_of_insn_after): Handle debug insns. * cfgexpand.c (gimple_assign_rhs_to_tree): Do not overwrite location of single rhs in place. (maybe_dump_rtl_for_gimple_stmt): Dump lineno. (floor_sdiv_adjust): New. (cell_sdiv_adjust): New. (cell_udiv_adjust): New. (round_sdiv_adjust): New. (round_udiv_adjust): New. (wrap_constant): Moved from cselib. (unwrap_constant): New. (expand_debug_expr): New. (expand_debug_locations): New. (expand_gimple_basic_block): Drop hiding redeclaration. Expand debug bind stmts. (gimple_expand_cfg): Expand debug locations. * cselib.c: Include tree-pass.h. (struct expand_value_data): New. (cselib_record_sets_hook): New. (PRESERVED_VALUE_P, LONG_TERM_PRESERVED_VALUE_P): New. (cselib_clear_table): Move, and implemnet in terms of... (cselib_reset_table_with_next_value): ... this. (cselib_get_next_unknown_value): New. (discard_useless_locs): Don't discard preserved values. (cselib_preserve_value): New. (cselib_preserved_value_p): New. (cselib_preserve_definitely): New. (cselib_clear_preserve): New. (cselib_preserve_only_values): New. (new_cselib_val): Take rtx argument. Dump it in details. (cselib_lookup_mem): Adjust. (expand_loc): Take regs_active in struct. Adjust. Silence dumps unless details are requested. (cselib_expand_value_rtx_cb): New. (cselib_expand_value_rtx): Rename and reimplment in terms of... (cselib_expand_value_rtx_1): ... this. Adjust. Silence dumps without details. Copy more subregs. Try to resolve values using a callback. Wrap constants. (cselib_subst_to_values): Adjust. (cselib_log_lookup): New. (cselib_lookup): Call it. (cselib_invalidate_regno): Don't count preserved values as useless. (cselib_invalidate_mem): Likewise. (cselib_record_set): Likewise. (struct set): Renamed to cselib_set, moved to cselib.h. (cselib_record_sets): Adjust. Call hook. (cselib_process_insn): Reset table when it would be cleared. (dump_cselib_val): New. (dump_cselib_table): New. * tree-cfgcleanup.c (tree_forwarded_block_p): Skip debug stmts. (remove_forwarder_block): Support moving debug stmts. * cselib.h (cselib_record_sets_hook): Declare. (cselib_expand_callback): New type. (cselib_expand_value_rtx_cb): Declare. (cselib_reset_table_with_next_value): Declare. (cselib_get_next_unknown_value): Declare. (cselib_preserve_value): Declare. (cselib_preserved_value_p): Declare. (cselib_preserve_only_values): Declare. (dump_cselib_table): Declare. * cfgcleanup.c (flow_find_cross_jump): Skip debug insns. (try_crossjump_to_edge): Likewise. (delete_unreachable_blocks): Remove dominant GIMPLE blocks after dominated blocks when debug stmts are present. * simplify-rtx.c (delegitimize_mem_from_attrs): New. * tree-ssa-live.c (remove_unused_locals): Skip debug stmts. (set_var_live_on_entry): Likewise. * loop-invariant.c (find_invariants_bb): Skip debug insns. * cfglayout.c (curr_location, last_location): Make static. (set_curr_insn_source_location): Don't avoid bouncing. (get_curr_insn_source_location): New. (get_curr_insn_block): New. (duplicate_insn_chain): Handle debug insns. * tree-ssa-forwprop.c (forward_propagate_addr_expr): Propagate into debug stmts. * common.opt (fcompare-debug): Move to sort order. (fdump-unnumbered-links): Likewise. (fvar-tracking-assignments): New. (fvar-tracking-assignments-toggle): New. * tree-ssa-dce.c (mark_stmt_necessary): Don't mark blocks because of debug stmts. (mark_stmt_if_obviously_necessary): Mark debug stmts. (eliminate_unnecessary_stmts): Walk dominated blocks before dominators. * tree-ssa-ter.c (find_replaceable_in_bb): Skip debug stmts. * ira.c (memref_used_between_p): Skip debug insns. (update_equiv_regs): Likewise. * sched-deps.c (sd_lists_size): Accept empty list. (sd_init_insn): Mark debug insns. (sd_finish_insn): Unmark them. (sd_add_dep): Reject non-debug deps on debug insns. (fixup_sched_groups): Give debug insns group treatment. Skip debug insns. (sched_analyze_reg): Don't mark debug insns for sched before call. (sched_analyze_2): Handle debug insns. (sched_analyze_insn): Compute next non-debug insn. Handle debug insns. (deps_analyze_insn): Handle debug insns. (deps_start_bb): Skip debug insns. (init_deps): Initialize last_debug_insn. * tree-ssa.c (target_for_debug_bind): New. (find_released_ssa_name): New. (propagate_var_def_into_debug_stmts): New. (propagate_defs_into_debug_stmts): New. (verify_ssa): Skip debug bind stmts without values. (warn_uninialized_vars): Skip debug stmts. * target-def.h (TARGET_DELEGITIMIZE_ADDRESS): Set default. * rtl.c (rtx_equal_p_cb): Handle VALUEs. (rtx_equal_p): Likewise. * ira-costs.c (scan_one_insn): Skip debug insns. (process_bb_node_for_hard_reg_moves): Likewise. * rtl.h (DEBUG_INSN_P): New. (NONDEBUG_INSN_P): New. (MAY_HAVE_DEBUG_INSNS): New. (INSN_P): Accept debug insns. (RTX_FRAME_RELATED_P): Likewise. (INSN_DELETED_P): Likewise (PAT_VAR_LOCATION_DECL): New. (PAT_VAR_LOCATION_LOC): New. (PAT_VAR_OCATION_STATUS): New. (NOTE_VAR_LOCATION_DECL): Reimplement. (NOTE_VAR_LOCATION_LOC): Likewise. (NOTE_VAR_LOCATION_STATUS): Likewise. (INSN_VAR_LOCATION): New. (INSN_VAR_LOCATION_DECL): New. (INSN_VAR_LOCATION_LOC): New. (INSN_VAR_LOCATION_STATUS): New. (gen_rtx_UNKNOWN_VAR_LOC): New. (VAR_LOC_UNKNOWN_P): New. (NOTE_DURING_CALL_P): New. (SCHED_GROUP_P): Accept debug insns. (emit_debug_insn_before): Declare. (emit_debug_insn_before_noloc): Declare. (emit_debug_insn_beore_setloc): Declare. (emit_debug_insn_after): Declare. (emit_debug_insn_after_noloc): Declare. (emit_debug_insn_after_setloc): Declare. (emit_debug_insn): Declare. (make_debug_insn_raw): Declare. (prev_nondebug_insn): Declare. (next_nondebug_insn): Declare. (delegitimize_mem_from_attrs): Declare. (get_max_insn_count): Declare. (wrap_constant): Declare. (unwrap_constant): Declare. (get_curr_insn_source_location): Declare. (get_curr_insn_block): Declare. * tree-inline.c (insert_debug_decl_map): New. (processing_debug_stmt): New. (remap_decl): Don't create new mappings in debug stmts. (remap_gimple_op_r): Don't add references in debug stmts. (copy_tree_body_r): Likewise. (remap_gimple_stmt): Handle debug bind stmts. (copy_bb): Skip debug stmts. (copy_edges_for_bb): Likewise. (copy_debug_stmt): New. (copy_debug_stmts): New. (copy_body): Copy debug stmts at the end. (insert_init_debug_bind): New. (insert_init_stmt): Take id. Skip and emit debug stmts. (setup_one_parameter): Remap variable earlier, register debug mapping. (estimate_num_insns): Skip debug stmts. (expand_call_inline): Preserve debug_map. (optimize_inline_calls): Check for no debug_stmts left-overs. (unsave_expr_now): Preserve debug_map. (copy_gimple_seq_and_replace_locals): Likewise. (tree_function_versioning): Check for no debug_stmts left-overs. Init and destroy debug_map as needed. Split edges unconditionally. (build_duplicate_type): Init and destroy debug_map as needed. * tree-inline.h: Include gimple.h instead of pointer-set.h. (struct copy_body_data): Add debug_stmts and debug_map. * sched-int.h (struct ready_list): Add n_debug. (struct deps): Add last_debug_insn. (DEBUG_INSN_SCHED_P): New. (BOUNDARY_DEBUG_INSN_P): New. (SCHEDULE_DEBUG_INSN_P): New. (sd_iterator_cond): Accept empty list. * combine.c (create_log_links): Skip debug insns. (combine_instructions): Likewise. (cleanup_auto_inc_dec): New. From Jakub Jelinek: Make sure the return value is always unshared. (struct rtx_subst_pair): New. (auto_adjust_pair): New. (propagate_for_debug_subst): New. (propagate_for_debug): New. (try_combine): Skip debug insns. Propagate removed defs into debug insns. (next_nonnote_nondebug_insn): New. (distribute_notes): Use it. Skip debug insns. (distribute_links): Skip debug insns. * tree-outof-ssa.c (set_location_for_edge): Likewise. * resource.c (mark_target_live_regs): Likewise. * var-tracking.c: Include cselib.h and target.h. (enum micro_operation_type): Add MO_VAL_USE, MO_VAL_LOC, and MO_VAL_SET. (micro_operation_type_name): New. (enum emit_note_where): Add EMIT_NOTE_AFTER_CALL_INSN. (struct micro_operation_def): Update comments. (decl_or_value): New type. Use instead of decls. (struct emit_note_data_def): Add vars. (struct attrs_def): Use decl_or_value. (struct variable_tracking_info_def): Add permp, flooded. (struct location_chain_def): Update comment. (struct variable_part_def): Use decl_or_value. (struct variable_def): Make var_part a variable length array. (valvar_pool): New. (scratch_regs): New. (cselib_hook_called): New. (dv_is_decl_p): New. (dv_is_value_p): New. (dv_as_decl): New. (dv_as_value): New. (dv_as_opaque): New. (dv_onepart_p): New. (dv_pool): New. (IS_DECL_CODE): New. (check_value_is_not_decl): New. (dv_from_decl): New. (dv_from_value): New. (dv_htab_hash): New. (variable_htab_hash): Use it. (variable_htab_eq): Support values. (variable_htab_free): Free from the right pool. (attrs_list_member, attrs_list_insert): Use decl_or_value. (attrs_list_union): Adjust. (attrs_list_mpdv_union): New. (tie_break_pointers): New. (canon_value_cmp): New. (unshare_variable): Return possibly-modified slot. (vars_copy_1): Adjust. (var_reg_decl_set): Adjust. Split out of... (var_reg_set): ... this. (get_init_value): Adjust. (var_reg_delete_and_set): Adjust. (var_reg_delete): Adjust. (var_regno_delete): Adjust. (var_mem_decl_set): Split out of... (var_mem_set): ... this. (var_mem_delete_and_set): Adjust. (var_mem_delete): Adjust. (val_store): New. (val_reset): New. (val_resolve): New. (variable_union): Adjust. Speed up merge of 1-part vars. (variable_canonicalize): Use unshared slot. (VALUED_RECURSED_INTO): New. (find_loc_in_1pdv): New. (struct dfset_merge): New. (insert_into_intersection): New. (intersect_loc_chains): New. (loc_cmp): New. (canonicalize_loc_order_check): New. (canonicalize_values_mark): New. (canonicalize_values_star): New. (variable_merge_over_cur): New. (variable_merge_over_src): New. (dataflow_set_merge): New. (dataflow_set_equiv_regs): New. (remove_duplicate_values): New. (struct dfset_post_merge): New. (variable_post_merge_new_vals): New. (variable_post_merge_perm_vals): New. (dataflow_post_merge_adjust): New. (find_mem_expr_in_1pdv): New. (dataflow_set_preserve_mem_locs): New. (dataflow_set_remove_mem_locs): New. (dataflow_set_clear_at_call): New. (onepart_variable_different_p): New. (variable_different_p): Use it. (dataflow_set_different_1): Adjust. Make detailed dump more verbose. (track_expr_p): Add need_rtl parameter. Don't generate rtl if not needed. (track_loc_p): Pass it true. (struct count_use_info): New. (find_use_val): New. (replace_expr_with_values): New. (log_op_type): New. (use_type): New, partially split out of... (count_uses): ... this. Count new micro-ops. (count_uses_1): Adjust. (count_stores): Adjust. (count_with_sets): New. (VAL_NEEDS_RESOLUTION): New. (VAL_HOLDS_TRACK_EXPR): New. (VAL_EXPR_IS_COPIED): New. (VAL_EXPR_IS_CLOBBERED): New. (add_uses): Adjust. Generate new micro-ops. (add_uses_1): Adjust. (add_stores): Generate new micro-ops. (add_with_sets): New. (find_src_status): Adjust. (find_src_set_src): Adjust. (compute_bb_dataflow): Use dataflow_set_clear_at_call. Handle new micro-ops. Canonicalize value equivalances. (vt_find_locations): Compute total size of hash tables for dumping. Perform merge for var-tracking-assignments. Don't disregard single-block loops. (dump_attrs_list): Handle decl_or_value. (dump_variable): Take variable. Deal with decl_or_value. (dump_variable_slot): New. (dump_vars): Use it. (dump_dataflow_sets): Adjust. (set_slot_part): New, extended to support one-part variables after splitting out of... (set_variable_part): ... this. (clobber_slot_part): New, split out of... (clobber_variable_part): ... this. (delete_slot_part): New, split out of... (delete_variable_part): .... this. (check_wrap_constant): New. (vt_expand_loc_callback): New. (vt_expand_loc): New. (emit_note_insn_var_location): Adjust. Handle values. Handle EMIT_NOTE_AFTER_CALL_INSN. (emit_notes_for_differences_1): Adjust. Handle values. (emit_notes_for_differences_2): Likewise. (emit_notes_for_differences): Adjust. (emit_notes_in_bb): Take pointer to set. Emit AFTER_CALL_INSN notes. Adjust. Handle new micro-ops. (vt_add_function_parameters): Adjust. Create and bind values. (vt_initialize): Adjust. Initialize scratch_regs and valvar_pool, flooded and perm.. Initialize and use cselib. Log operations. Move some code to count_with_sets and add_with_sets. (delete_debug_insns): New. (vt_debug_insns_local): New. (vt_finalize): Release permp, valvar_pool, scratch_regs. Finish cselib. (var_tracking_main): If var-tracking-assignments is enabled but var-tracking isn't, delete debug insns and leave. Likewise if we exceed limits or fail the stack adjustments tests, and after all var-tracking processing. More in var-tracking, from Jakub Jelinek : (dataflow_set): Add traversed_vars. (value_chain, const_value_chain): New typedefs. (value_chain_pool, value_chains): New variables. (value_chain_htab_hash, value_chain_htab_eq, add_value_chain, add_value_chains, add_cselib_value_chains, remove_value_chain, remove_value_chains, remove_cselib_value_chains): New functions. (shared_hash_find_slot_unshare_1, shared_hash_find_slot_1, shared_hash_find_slot_noinsert_1, shared_hash_find_1): New static inlines. (shared_hash_find_slot_unshare, shared_hash_find_slot, shared_hash_find_slot_noinsert, shared_hash_find): Update. (dst_can_be_shared): New variable. (unshare_variable): Unshare set->vars if shared, use shared_hash_*. Clear dst_can_be_shared. If set->traversed_vars is non-NULL and different from set->vars, look up slot again instead of using the passed in slot. (dataflow_set_init): Initialize traversed_vars. (variable_union): Use shared_hash_*. Use initially NO_INSERT lookup if set->vars is shared. Don't keep slot cleared before calling unshare_variable. Unshare set->vars if needed. Adjust unshare_variable callers. Clear dst_can_be_shared if needed. Even ->refcount == 1 vars must be unshared if set->vars is shared and var needs to be modified. (dataflow_set_union): Set traversed_vars during canonicalization. (VALUE_CHANGED, DECL_CHANGED): Define. (set_dv_changed, dv_changed_p): New static inlines. (track_expr_p): Clear DECL_CHANGED. (dump_dataflow_sets): Set it. (variable_was_changed): Call set_dv_changed. (emit_note_insn_var_location): Likewise. (changed_variables_stack): New variable. (check_changed_vars_1, check_changed_vars_2): New functions. (emit_notes_for_changes): Do nothing if changed_variables is empty. Traverse changed_variables with check_changed_vars_1, call check_changed_vars_2 on each changed_variables_stack entry. (emit_notes_in_bb): Add SET argument. Just clear it at the beginning, use it instead of local &set, don't destroy it at the end. (vt_emit_notes): Call dataflow_set_clear early on all VTI(bb)->out sets, never use them, instead use emit_notes_in_bb computed set, dataflow_set_clear also VTI(bb)->in when we are done with the basic block. Initialize changed_variables_stack, free it afterwards. If ENABLE_CHECKING verify that after noting differences to an empty set value_chains hash table is empty. (vt_initialize): Initialize value_chains and value_chain_pool. (vt_finalize): Delete value_chains htab, free value_chain_pool. (variable_tracking_main): Call dump_dataflow_sets before calling vt_emit_notes, not after it. * tree-flow.h (propagate_defs_into_debug_stmts): Declare. (propagate_var_def_into_debug_stmts): Declare. * df-problems.c (df_lr_bb_local_compute): Skip debug insns. (df_set_note): Reject debug insns. (df_whole_mw_reg_dead_p): Take added_notes_p argument. Don't add notes to debug insns. (df_note_bb_compute): Adjust. Likewise. (df_simulate_uses): Skip debug insns. (df_simulate_initialize_backwards): Likewise. * reg-stack.c (subst_stack_regs_in_debug_insn): New. (subst_stack_regs_pat): Reject debug insns. (convert_regs_1): Handle debug insns. * Makefile.in (TREE_INLINE_H): Take pointer-set.h from GIMPLE_H. (print-rtl.o): Depend on cselib.h. (cselib.o): Depend on TREE_PASS_H. (var-tracking.o): Depend on cselib.h and TARGET_H. * sched-rgn.c (rgn_estimate_number_of_insns): Discount debug insns. (init_ready_list): Skip boundary debug insns. (add_branch_dependences): Skip debug insns. (free_block_dependencies): Check for blocks with only debug insns. (compute_priorities): Likewise. * gimple.c (gss_for_code): Handle GIMPLE_DEBUG. (gimple_build_with_ops_stat): Take subcode as unsigned. Adjust all callers. (gimple_build_debug_bind_stat): New. (empty_body_p): Skip debug stmts. (gimple_has_side_effects): Likewise. (gimple_rhs_has_side_effects): Likewise. * gimple.h (enum gimple_debug_subcode, GIMPLE_DEBUG_BIND): New. (gimple_build_debug_bind_stat): Declare. (gimple_build_debug_bind): Define. (is_gimple_debug): New. (gimple_debug_bind_p): New. (gimple_debug_bind_get_var): New. (gimple_debug_bind_get_value): New. (gimple_debug_bind_get_value_ptr): New. (gimple_debug_bind_set_var): New. (gimple_debug_bind_set_value): New. (GIMPLE_DEBUG_BIND_NOVALUE): New internal temporary macro. (gimple_debug_bind_reset_value): New. (gimple_debug_bind_has_value_p): New. (gsi_next_nondebug): New. (gsi_prev_nondebug): New. (gsi_start_nondebug_bb): New. (gsi_last_nondebug_bb): New. * sched-vis.c (print_pattern): Handle VAR_LOCATION. (print_insn): Handle DEBUG_INSN. * tree-cfg.c (remove_bb): Walk stmts backwards. Let loc of first insn prevail. (first_stmt): Skip debug stmts. (first_non_label_stmt): Likewise. (last_stmt): Likewise. (has_zero_uses_1): New. (single_imm_use_1): New. (verify_gimple_debug): New. (verify_types_in_gimple_stmt): Handle debug stmts. (verify_stmt): Likewise. (debug_loop_num): Skip debug stmts. (remove_edge_and_dominated_blocks): Remove dominators last. * tree-ssa-reasssoc.c (rewrite_expr_tree): Propagate into debug stmts. (linearize_expr): Likewise. * config/i386/i386.c (ix86_delegitimize_address): Call default implementation. * config/ia64/ia64.c (ia64_safe_itanium_class): Handle debug insns. (group_barrier_needed): Skip debug insns. (emit_insn_group_barriers): Likewise. (emit_all_insn_group_barriers): Likewise. (ia64_variable_issue): Handle debug insns. (ia64_dfa_new_cycle): Likewise. (final_emit_insn_group_barriers): Skip debug insns. (ia64_dwarf2out_def_steady_cfa): Take frame argument. Don't def cfa without frame. (process_set): Likewise. (process_for_unwind_directive): Pass frame on. * config/rs6000/rs6000.c (TARGET_DELEGITIMIZE_ADDRESS): Define. (rs6000_delegitimize_address): New. (rs6000_debug_adjust_cost): Handle debug insns. (is_microcoded_insn): Likewise. (is_cracked_insn): Likewise. (is_nonpipeline_insn): Likewise. (insn_must_be_first_in_group): Likewise. (insn_must_be_last_in_group): Likewise. (force_new_group): Likewise. * cfgrtl.c (rtl_split_block): Emit INSN_DELETED note if block contains only debug insns. (rtl_merge_blocks): Skip debug insns. (purge_dead_edges): Likewise. (rtl_block_ends_with_call_p): Skip debug insns. * dce.c (deletable_insn_p): Handle VAR_LOCATION. (mark_reg_dependencies): Skip debug insns. * params.def (PARAM_MIN_NONDEBUG_INSN_UID): New. * tree-ssanames.c (release_ssa_name): Propagate def into debug stmts. * tree-ssa-threadedge.c (record_temporary_equivalences_from_stmts): Skip debug stmts. * regcprop.c (replace_oldest_value_addr): Skip debug insns. (replace_oldest_value_mem): Use ALL_REGS for debug insns. (copyprop_hardreg_forward_1): Handle debug insns. * reload1.c (reload): Skip debug insns. Replace unassigned pseudos in debug insns with their equivalences. (eliminate_regs_in_insn): Skip debug insns. (emit_input_reload_insns): Skip debug insns at first, adjust them later. * tree-ssa-operands.c (add_virtual_operand): Reject debug stmts. (get_indirect_ref_operands): Pass opf_no_vops on. (get_expr_operands): Likewise. Skip debug stmts. (parse_ssa_operands): Scan debug insns with opf_no_vops. gcc/testsuite/ChangeLog: * gcc.dg/guality/guality.c: New. * gcc.dg/guality/guality.h: New. * gcc.dg/guality/guality.exp: New. * gcc.dg/guality/example.c: New. * lib/gcc-dg.exp (cleanup-dump): Remove .gk files. (cleanup-saved-temps): Likewise, .gkd files too. gcc/cp/ChangeLog: * cp-tree.h (TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS): New. * cp-lang.c (cxx_dwarf_name): Pass it. * error.c (count_non_default_template_args): Take flags as argument. Adjust all callers. Skip counting of default arguments if the new flag is given. ChangeLog: * Makefile.tpl (BUILD_CONFIG): Default to bootstrap-debug. * Makefile.in: Rebuilt. contrib/ChangeLog: * compare-debug: Look for .gkd files and compare them. config/ChangeLog: * bootstrap-debug.mk: Add comments. * bootstrap-debug-big.mk: New. * bootstrap-debug-lean.mk: New. * bootstrap-debug-ckovw.mk: Add comments. * bootstrap-debug-lib.mk: Drop CFLAGS for stages. Use -g0 for TFLAGS in stage1. Drop -fvar-tracking-assignments-toggle. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151312 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index bfd0c293156..7f00a63453f 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -239,6 +239,15 @@ tree_if_convert_stmt (struct loop * loop, gimple t, tree cond, case GIMPLE_LABEL: break; + case GIMPLE_DEBUG: + /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */ + if (gimple_debug_bind_p (gsi_stmt (*gsi))) + { + gimple_debug_bind_reset_value (gsi_stmt (*gsi)); + update_stmt (gsi_stmt (*gsi)); + } + break; + case GIMPLE_ASSIGN: /* This GIMPLE_ASSIGN is killing previous value of LHS. Appropriate value will be selected by PHI node based on condition. It is possible @@ -423,8 +432,10 @@ if_convertible_stmt_p (struct loop *loop, basic_block bb, gimple stmt) case GIMPLE_LABEL: break; - case GIMPLE_ASSIGN: + case GIMPLE_DEBUG: + break; + case GIMPLE_ASSIGN: if (!if_convertible_gimple_assign_stmt_p (loop, bb, stmt)) return false; break; -- cgit v1.2.1 From 48e1416a24d50cacbb2a5e06a9ee61dd8cbee313 Mon Sep 17 00:00:00 2001 From: hjl Date: Wed, 25 Nov 2009 10:55:54 +0000 Subject: Remove trailing white spaces. 2009-11-25 H.J. Lu * alias.c: Remove trailing white spaces. * alloc-pool.c: Likewise. * alloc-pool.h: Likewise. * attribs.c: Likewise. * auto-inc-dec.c: Likewise. * basic-block.h: Likewise. * bb-reorder.c: Likewise. * bt-load.c: Likewise. * builtins.c: Likewise. * builtins.def: Likewise. * c-common.c: Likewise. * c-common.h: Likewise. * c-cppbuiltin.c: Likewise. * c-decl.c: Likewise. * c-format.c: Likewise. * c-lex.c: Likewise. * c-omp.c: Likewise. * c-opts.c: Likewise. * c-parser.c: Likewise. * c-pretty-print.c: Likewise. * c-tree.h: Likewise. * c-typeck.c: Likewise. * caller-save.c: Likewise. * calls.c: Likewise. * cfg.c: Likewise. * cfganal.c: Likewise. * cfgexpand.c: Likewise. * cfghooks.c: Likewise. * cfghooks.h: Likewise. * cfglayout.c: Likewise. * cfgloop.c: Likewise. * cfgloop.h: Likewise. * cfgloopmanip.c: Likewise. * cfgrtl.c: Likewise. * cgraph.c: Likewise. * cgraph.h: Likewise. * cgraphbuild.c: Likewise. * cgraphunit.c: Likewise. * cif-code.def: Likewise. * collect2.c: Likewise. * combine.c: Likewise. * convert.c: Likewise. * coverage.c: Likewise. * crtstuff.c: Likewise. * cse.c: Likewise. * cselib.c: Likewise. * dbgcnt.c: Likewise. * dbgcnt.def: Likewise. * dbgcnt.h: Likewise. * dbxout.c: Likewise. * dce.c: Likewise. * ddg.c: Likewise. * ddg.h: Likewise. * defaults.h: Likewise. * df-byte-scan.c: Likewise. * df-core.c: Likewise. * df-problems.c: Likewise. * df-scan.c: Likewise. * df.h: Likewise. * dfp.c: Likewise. * diagnostic.c: Likewise. * diagnostic.h: Likewise. * dominance.c: Likewise. * domwalk.c: Likewise. * double-int.c: Likewise. * double-int.h: Likewise. * dse.c: Likewise. * dwarf2asm.c: Likewise. * dwarf2asm.h: Likewise. * dwarf2out.c: Likewise. * ebitmap.c: Likewise. * ebitmap.h: Likewise. * emit-rtl.c: Likewise. * et-forest.c: Likewise. * except.c: Likewise. * except.h: Likewise. * expmed.c: Likewise. * expr.c: Likewise. * expr.h: Likewise. * final.c: Likewise. * flags.h: Likewise. * fold-const.c: Likewise. * function.c: Likewise. * function.h: Likewise. * fwprop.c: Likewise. * gcc.c: Likewise. * gcov-dump.c: Likewise. * gcov-io.c: Likewise. * gcov-io.h: Likewise. * gcov.c: Likewise. * gcse.c: Likewise. * genattr.c: Likewise. * genattrtab.c: Likewise. * genautomata.c: Likewise. * genchecksum.c: Likewise. * genconfig.c: Likewise. * genflags.c: Likewise. * gengtype-parse.c: Likewise. * gengtype.c: Likewise. * gengtype.h: Likewise. * genmddeps.c: Likewise. * genmodes.c: Likewise. * genopinit.c: Likewise. * genpreds.c: Likewise. * gensupport.c: Likewise. * ggc-common.c: Likewise. * ggc-page.c: Likewise. * ggc-zone.c: Likewise. * ggc.h: Likewise. * gimple-iterator.c: Likewise. * gimple-low.c: Likewise. * gimple-pretty-print.c: Likewise. * gimple.c: Likewise. * gimple.def: Likewise. * gimple.h: Likewise. * gimplify.c: Likewise. * graphds.c: Likewise. * graphite-clast-to-gimple.c: Likewise. * gthr-nks.h: Likewise. * gthr-posix.c: Likewise. * gthr-posix.h: Likewise. * gthr-posix95.h: Likewise. * gthr-single.h: Likewise. * gthr-tpf.h: Likewise. * gthr-vxworks.h: Likewise. * gthr.h: Likewise. * haifa-sched.c: Likewise. * hard-reg-set.h: Likewise. * hooks.c: Likewise. * hooks.h: Likewise. * hosthooks.h: Likewise. * hwint.h: Likewise. * ifcvt.c: Likewise. * incpath.c: Likewise. * init-regs.c: Likewise. * integrate.c: Likewise. * ipa-cp.c: Likewise. * ipa-inline.c: Likewise. * ipa-prop.c: Likewise. * ipa-pure-const.c: Likewise. * ipa-reference.c: Likewise. * ipa-struct-reorg.c: Likewise. * ipa-struct-reorg.h: Likewise. * ipa-type-escape.c: Likewise. * ipa-type-escape.h: Likewise. * ipa-utils.c: Likewise. * ipa-utils.h: Likewise. * ipa.c: Likewise. * ira-build.c: Likewise. * ira-color.c: Likewise. * ira-conflicts.c: Likewise. * ira-costs.c: Likewise. * ira-emit.c: Likewise. * ira-int.h: Likewise. * ira-lives.c: Likewise. * ira.c: Likewise. * jump.c: Likewise. * lambda-code.c: Likewise. * lambda-mat.c: Likewise. * lambda-trans.c: Likewise. * lambda.h: Likewise. * langhooks.c: Likewise. * lcm.c: Likewise. * libgcov.c: Likewise. * lists.c: Likewise. * loop-doloop.c: Likewise. * loop-init.c: Likewise. * loop-invariant.c: Likewise. * loop-iv.c: Likewise. * loop-unroll.c: Likewise. * lower-subreg.c: Likewise. * lto-cgraph.c: Likewise. * lto-compress.c: Likewise. * lto-opts.c: Likewise. * lto-section-in.c: Likewise. * lto-section-out.c: Likewise. * lto-streamer-in.c: Likewise. * lto-streamer-out.c: Likewise. * lto-streamer.c: Likewise. * lto-streamer.h: Likewise. * lto-symtab.c: Likewise. * lto-wpa-fixup.c: Likewise. * matrix-reorg.c: Likewise. * mcf.c: Likewise. * mode-switching.c: Likewise. * modulo-sched.c: Likewise. * omega.c: Likewise. * omega.h: Likewise. * omp-low.c: Likewise. * optabs.c: Likewise. * optabs.h: Likewise. * opts-common.c: Likewise. * opts.c: Likewise. * params.def: Likewise. * params.h: Likewise. * passes.c: Likewise. * plugin.c: Likewise. * postreload-gcse.c: Likewise. * postreload.c: Likewise. * predict.c: Likewise. * predict.def: Likewise. * pretty-print.c: Likewise. * pretty-print.h: Likewise. * print-rtl.c: Likewise. * print-tree.c: Likewise. * profile.c: Likewise. * read-rtl.c: Likewise. * real.c: Likewise. * recog.c: Likewise. * reg-stack.c: Likewise. * regcprop.c: Likewise. * reginfo.c: Likewise. * regmove.c: Likewise. * regrename.c: Likewise. * regs.h: Likewise. * regstat.c: Likewise. * reload.c: Likewise. * reload1.c: Likewise. * resource.c: Likewise. * rtl.c: Likewise. * rtl.def: Likewise. * rtl.h: Likewise. * rtlanal.c: Likewise. * sbitmap.c: Likewise. * sched-deps.c: Likewise. * sched-ebb.c: Likewise. * sched-int.h: Likewise. * sched-rgn.c: Likewise. * sched-vis.c: Likewise. * sdbout.c: Likewise. * sel-sched-dump.c: Likewise. * sel-sched-dump.h: Likewise. * sel-sched-ir.c: Likewise. * sel-sched-ir.h: Likewise. * sel-sched.c: Likewise. * sel-sched.h: Likewise. * sese.c: Likewise. * sese.h: Likewise. * simplify-rtx.c: Likewise. * stack-ptr-mod.c: Likewise. * stmt.c: Likewise. * stor-layout.c: Likewise. * store-motion.c: Likewise. * stringpool.c: Likewise. * stub-objc.c: Likewise. * sync-builtins.def: Likewise. * target-def.h: Likewise. * target.h: Likewise. * targhooks.c: Likewise. * targhooks.h: Likewise. * timevar.c: Likewise. * tlink.c: Likewise. * toplev.c: Likewise. * toplev.h: Likewise. * tracer.c: Likewise. * tree-affine.c: Likewise. * tree-affine.h: Likewise. * tree-browser.def: Likewise. * tree-call-cdce.c: Likewise. * tree-cfg.c: Likewise. * tree-cfgcleanup.c: Likewise. * tree-chrec.c: Likewise. * tree-chrec.h: Likewise. * tree-complex.c: Likewise. * tree-data-ref.c: Likewise. * tree-data-ref.h: Likewise. * tree-dfa.c: Likewise. * tree-dump.c: Likewise. * tree-dump.h: Likewise. * tree-eh.c: Likewise. * tree-flow-inline.h: Likewise. * tree-flow.h: Likewise. * tree-if-conv.c: Likewise. * tree-inline.c: Likewise. * tree-into-ssa.c: Likewise. * tree-loop-distribution.c: Likewise. * tree-loop-linear.c: Likewise. * tree-mudflap.c: Likewise. * tree-nested.c: Likewise. * tree-nomudflap.c: Likewise. * tree-nrv.c: Likewise. * tree-object-size.c: Likewise. * tree-optimize.c: Likewise. * tree-outof-ssa.c: Likewise. * tree-parloops.c: Likewise. * tree-pass.h: Likewise. * tree-phinodes.c: Likewise. * tree-predcom.c: Likewise. * tree-pretty-print.c: Likewise. * tree-profile.c: Likewise. * tree-scalar-evolution.c: Likewise. * tree-ssa-address.c: Likewise. * tree-ssa-alias.c: Likewise. * tree-ssa-ccp.c: Likewise. * tree-ssa-coalesce.c: Likewise. * tree-ssa-copy.c: Likewise. * tree-ssa-copyrename.c: Likewise. * tree-ssa-dce.c: Likewise. * tree-ssa-dom.c: Likewise. * tree-ssa-dse.c: Likewise. * tree-ssa-forwprop.c: Likewise. * tree-ssa-ifcombine.c: Likewise. * tree-ssa-live.c: Likewise. * tree-ssa-live.h: Likewise. * tree-ssa-loop-ch.c: Likewise. * tree-ssa-loop-im.c: Likewise. * tree-ssa-loop-ivcanon.c: Likewise. * tree-ssa-loop-ivopts.c: Likewise. * tree-ssa-loop-manip.c: Likewise. * tree-ssa-loop-niter.c: Likewise. * tree-ssa-loop-prefetch.c: Likewise. * tree-ssa-loop-unswitch.c: Likewise. * tree-ssa-loop.c: Likewise. * tree-ssa-math-opts.c: Likewise. * tree-ssa-operands.c: Likewise. * tree-ssa-operands.h: Likewise. * tree-ssa-phiopt.c: Likewise. * tree-ssa-phiprop.c: Likewise. * tree-ssa-pre.c: Likewise. * tree-ssa-propagate.c: Likewise. * tree-ssa-reassoc.c: Likewise. * tree-ssa-sccvn.c: Likewise. * tree-ssa-sink.c: Likewise. * tree-ssa-structalias.c: Likewise. * tree-ssa-ter.c: Likewise. * tree-ssa-threadedge.c: Likewise. * tree-ssa-threadupdate.c: Likewise. * tree-ssa-uncprop.c: Likewise. * tree-ssa.c: Likewise. * tree-ssanames.c: Likewise. * tree-switch-conversion.c: Likewise. * tree-tailcall.c: Likewise. * tree-vect-data-refs.c: Likewise. * tree-vect-generic.c: Likewise. * tree-vect-loop-manip.c: Likewise. * tree-vect-loop.c: Likewise. * tree-vect-patterns.c: Likewise. * tree-vect-slp.c: Likewise. * tree-vect-stmts.c: Likewise. * tree-vectorizer.c: Likewise. * tree-vectorizer.h: Likewise. * tree-vrp.c: Likewise. * tree.c: Likewise. * tree.def: Likewise. * tree.h: Likewise. * treestruct.def: Likewise. * unwind-compat.c: Likewise. * unwind-dw2-fde-glibc.c: Likewise. * unwind-dw2.c: Likewise. * value-prof.c: Likewise. * value-prof.h: Likewise. * var-tracking.c: Likewise. * varasm.c: Likewise. * varpool.c: Likewise. * vec.c: Likewise. * vec.h: Likewise. * vmsdbgout.c: Likewise. * web.c: Likewise. * xcoffout.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154645 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 7f00a63453f..7f193ec98b0 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -252,7 +252,7 @@ tree_if_convert_stmt (struct loop * loop, gimple t, tree cond, /* This GIMPLE_ASSIGN is killing previous value of LHS. Appropriate value will be selected by PHI node based on condition. It is possible that before this transformation, PHI nodes was selecting default - value and now it will use this new value. This is OK because it does + value and now it will use this new value. This is OK because it does not change validity the program. */ break; @@ -489,7 +489,7 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) fprintf (dump_file, "non empty basic block after exit bb\n"); return false; } - else if (bb == loop->latch + else if (bb == loop->latch && bb != exit_bb && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb)) { @@ -706,7 +706,7 @@ clean_predicate_lists (struct loop *loop) whose phi arguments are selected when cond is true. */ static basic_block -find_phi_replacement_condition (struct loop *loop, +find_phi_replacement_condition (struct loop *loop, basic_block bb, tree *cond, gimple_stmt_iterator *gsi) { @@ -724,7 +724,7 @@ find_phi_replacement_condition (struct loop *loop, S2: x = c ? b : a; S2 is preferred over S1. Make 'b' first_bb and use its condition. - + 2) Do not make loop header first_bb. 3) @@ -735,7 +735,7 @@ find_phi_replacement_condition (struct loop *loop, S3: x = (c == d) ? b : a; - S3 is preferred over S1 and S2*, Make 'b' first_bb and use + S3 is preferred over S1 and S2*, Make 'b' first_bb and use its condition. 4) If pred B is dominated by pred A then use pred B's condition. @@ -832,7 +832,7 @@ replace_phi_with_cond_gimple_assign_stmt (gimple phi, tree cond, tree arg_0, arg_1; gcc_assert (gimple_code (phi) == GIMPLE_PHI); - + /* If this is not filtered earlier, then now it is too late. */ gcc_assert (gimple_phi_num_args (phi) == 2); -- cgit v1.2.1 From a29ec3eb5f80f228a12550e1ce7a1448c4550e4e Mon Sep 17 00:00:00 2001 From: spop Date: Tue, 6 Apr 2010 19:20:29 +0000 Subject: Always execute verify_loop_closed_ssa at LNO level. 2010-04-06 Sebastian Pop * passes.c (execute_function_todo): Call verify_loop_closed_ssa for all the passes of the LNO having LOOP_CLOSED_SSA. * tree-if-conv.c (pass_if_conversion): Remove TODO_verify_loops. * tree-loop-distribution.c (pass_loop_distribution): Same. * tree-pass.h (TODO_verify_loops): Removed. * tree-ssa-loop.c (pass_tree_loop_init): Same. (pass_lim): Same. (pass_tree_unswitch): Same. (pass_predcom): Same. (pass_vectorize): Same. (pass_linear_transform): Same. (pass_graphite_transforms): Same. (pass_iv_canon): Same. (pass_complete_unroll): Same. (pass_complete_unrolli): Same. (pass_parallelize_loops): Same. (pass_loop_prefetch): Same. (pass_iv_optimize): Same. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158020 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 7f193ec98b0..a0083844c5d 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1180,7 +1180,7 @@ struct gimple_opt_pass pass_if_conversion = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_loops | TODO_verify_stmts | TODO_verify_flow + TODO_dump_func | TODO_verify_stmts | TODO_verify_flow /* todo_flags_finish */ } }; -- cgit v1.2.1 From a1660ced55eace29923703c1ff4e8ae6b16b4c41 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 7 Apr 2010 06:33:35 +0000 Subject: Fix comments in ifconvert. 2010-04-07 Sebastian Pop * tree-if-conv.c: Fix indentation and comments. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158039 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 125 +++++++++++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 65 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index a0083844c5d..5ff864478de 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -134,12 +134,12 @@ static bool bb_with_exit_edge_p (struct loop *, basic_block); /* List of basic blocks in if-conversion-suitable order. */ static basic_block *ifc_bbs; -/* Main entry point. - Apply if-conversion to the LOOP. Return true if successful otherwise return - false. If false is returned then loop remains unchanged. - FOR_VECTORIZER is a boolean flag. It indicates whether if-conversion is used - for vectorizer or not. If it is used for vectorizer, additional checks are - used. (Vectorization checks are not yet implemented). */ +/* Main entry point. Apply if-conversion to the LOOP. Return true if + successful otherwise return false. If false is returned then loop + remains unchanged. FOR_VECTORIZER is a boolean flag. It indicates + whether if-conversion is used for vectorizer or not. If it is used + for vectorizer, additional checks are used. (Vectorization checks + are not yet implemented). */ static bool tree_if_conversion (struct loop *loop, bool for_vectorizer) @@ -150,8 +150,8 @@ tree_if_conversion (struct loop *loop, bool for_vectorizer) ifc_bbs = NULL; - /* if-conversion is not appropriate for all loops. First, check if loop is - if-convertible or not. */ + /* If-conversion is not appropriate for all loops. First, check if + loop is if-convertible or not. */ if (!if_convertible_loop_p (loop, for_vectorizer)) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -192,7 +192,7 @@ tree_if_conversion (struct loop *loop, bool for_vectorizer) { basic_block bb_n = single_succ (bb); - /* Successor bb inherits predicate of its predecessor. If there + /* Successor bb inherits predicate of its predecessor. If there is no predicate in predecessor bb, then consider successor bb as always executed. */ if (cond == NULL_TREE) @@ -203,7 +203,7 @@ tree_if_conversion (struct loop *loop, bool for_vectorizer) } /* Now, all statements are if-converted and basic blocks are - annotated appropriately. Combine all basic block into one huge + annotated appropriately. Combine all basic block into one huge basic block. */ combine_blocks (loop); @@ -215,12 +215,12 @@ tree_if_conversion (struct loop *loop, bool for_vectorizer) return true; } -/* if-convert stmt T which is part of LOOP. +/* If-convert stmt T which is part of LOOP. If T is a GIMPLE_ASSIGN then it is converted into conditional modify expression using COND. For conditional expressions, add condition in the destination basic block's predicate list and remove conditional - expression itself. BSI is the iterator used to traverse statements of - loop. It is used here when it is required to delete current statement. */ + expression itself. BSI is the iterator used to traverse statements of + loop. It is used here when it is required to delete current statement. */ static tree tree_if_convert_stmt (struct loop * loop, gimple t, tree cond, @@ -249,11 +249,11 @@ tree_if_convert_stmt (struct loop * loop, gimple t, tree cond, break; case GIMPLE_ASSIGN: - /* This GIMPLE_ASSIGN is killing previous value of LHS. Appropriate - value will be selected by PHI node based on condition. It is possible + /* This GIMPLE_ASSIGN is killing previous value of LHS. Appropriate + value will be selected by PHI node based on condition. It is possible that before this transformation, PHI nodes was selecting default - value and now it will use this new value. This is OK because it does - not change validity the program. */ + value and now it will use this new value. This is OK because it does + not change the validity of the program. */ break; case GIMPLE_COND: @@ -269,10 +269,10 @@ tree_if_convert_stmt (struct loop * loop, gimple t, tree cond, return cond; } -/* STMT is a GIMPLE_COND. Update two destination's predicate list. - Remove COND_EXPR, if it is not the loop exit condition. Otherwise +/* STMT is a GIMPLE_COND. Update two destination's predicate list. + Remove COND_EXPR, if it is not the loop exit condition. Otherwise update loop exit condition appropriately. GSI is the iterator - used to traverse statement list. STMT is part of loop LOOP. */ + used to traverse statement list. STMT is part of loop LOOP. */ static void tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, @@ -292,15 +292,15 @@ tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, /* Add new condition into destination's predicate list. */ - /* If C is true then TRUE_EDGE is taken. */ + /* If C is true, then TRUE_EDGE is taken. */ add_to_dst_predicate_list (loop, true_edge, cond, c, gsi); - /* If 'c' is false then FALSE_EDGE is taken. */ + /* If C is false, then FALSE_EDGE is taken. */ c2 = invert_truthvalue_loc (loc, unshare_expr (c)); add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi); - /* Now this conditional statement is redundant. Remove it. - But, do not remove exit condition! Update exit condition + /* Now this conditional statement is redundant. Remove it. + But, do not remove exit condition! Update exit condition using new condition. */ if (!bb_with_exit_edge_p (loop, gimple_bb (stmt))) { @@ -310,12 +310,12 @@ tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, return; } -/* Return true, iff PHI is if-convertible. PHI is part of loop LOOP +/* Return true, iff PHI is if-convertible. PHI is part of loop LOOP and it belongs to basic block BB. PHI is not if-convertible - - if it has more than 2 arguments. - - Virtual PHI is immediately used in another PHI node. - - Virtual PHI on BB other than header. */ + - if it has more than 2 arguments, + - virtual PHI is immediately used in another PHI node, + - virtual PHI on BB other than header. */ static bool if_convertible_phi_p (struct loop *loop, basic_block bb, gimple phi) @@ -360,10 +360,10 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gimple phi) /* Return true, if STMT is if-convertible. GIMPLE_ASSIGN statement is not if-convertible if, - - It is not movable. - - It could trap. + - it is not movable, + - it could trap, - LHS is not var decl. - GIMPLE_ASSIGN is part of block BB, which is inside loop LOOP. */ + GIMPLE_ASSIGN is part of block BB, which is inside loop LOOP. */ static bool if_convertible_gimple_assign_stmt_p (struct loop *loop, basic_block bb, @@ -420,8 +420,8 @@ if_convertible_gimple_assign_stmt_p (struct loop *loop, basic_block bb, /* Return true, iff STMT is if-convertible. Statement is if-convertible if, - - It is if-convertible GIMPLE_ASSGIN - - It is GIMPLE_LABEL or GIMPLE_COND. + - it is if-convertible GIMPLE_ASSGIN, + - it is GIMPLE_LABEL or GIMPLE_COND. STMT is inside block BB, which is inside loop LOOP. */ static bool @@ -459,10 +459,10 @@ if_convertible_stmt_p (struct loop *loop, basic_block bb, gimple stmt) /* Return true, iff BB is if-convertible. Note: This routine does _not_ check basic block statements and phis. - Basic block is not if-convertible if, - - Basic block is non-empty and it is after exit block (in BFS order). - - Basic block is after exit block but before latch. - - Basic block edge(s) is not normal. + Basic block is not if-convertible if: + - basic block is non-empty and it is after exit block (in BFS order), + - basic block is after exit block but before latch, + - basic block edge(s) is not normal. EXIT_BB_SEEN is true if basic block with exit edge is already seen. BB is inside loop LOOP. */ @@ -513,15 +513,16 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) } /* Return true, iff LOOP is if-convertible. - LOOP is if-convertible if, - - It is innermost. - - It has two or more basic blocks. - - It has only one exit. - - Loop header is not the exit edge. - - If its basic blocks and phi nodes are if convertible. See above for + LOOP is if-convertible if: + - it is innermost, + - it has two or more basic blocks, + - it has only one exit, + - loop header is not the exit edge, + - if its basic blocks and phi nodes are if convertible. See above for more info. - FOR_VECTORIZER enables vectorizer specific checks. For example, support - for vector conditions, data dependency checks etc.. (Not implemented yet). */ + FOR_VECTORIZER enables vectorizer specific checks, for example, support + for vector conditions, data dependency checks, etc. + (Not implemented yet). */ static bool if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED) @@ -587,21 +588,16 @@ if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED) if (!if_convertible_bb_p (loop, bb, exit_bb)) return false; - /* Check statements. */ for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr)) if (!if_convertible_stmt_p (loop, bb, gsi_stmt (itr))) return false; - /* ??? Check data dependency for vectorizer. */ - /* What about phi nodes ? */ itr = gsi_start_phis (bb); - /* Clear aux field of incoming edges to a bb with a phi node. */ if (!gsi_end_p (itr)) FOR_EACH_EDGE (e, ei, bb->preds) e->aux = NULL; - /* Check statements. */ for (; !gsi_end_p (itr); gsi_next (&itr)) if (!if_convertible_phi_p (loop, bb, gsi_stmt (itr))) return false; @@ -610,8 +606,6 @@ if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED) exit_bb = bb; } - /* OK. Did not find any potential issues so go ahead in if-convert - this loop. Now there is no looking back. */ if (dump_file) fprintf (dump_file,"Applying if-conversion\n"); @@ -679,7 +673,7 @@ add_to_dst_predicate_list (struct loop * loop, edge e, } /* During if-conversion aux field from basic block structure is used to hold - predicate list. Clean each basic block's predicate list for the given LOOP. + predicate list. Clean each basic block's predicate list for the given LOOP. Also clean aux field of successor edges, used to hold true and false condition from conditional expression. */ @@ -702,7 +696,7 @@ clean_predicate_lists (struct loop *loop) } /* Basic block BB has two predecessors. Using predecessor's aux field, set - appropriate condition COND for the PHI node replacement. Return true block + appropriate condition COND for the PHI node replacement. Return true block whose phi arguments are selected when cond is true. */ static basic_block @@ -1013,7 +1007,7 @@ combine_blocks (struct loop *loop) } /* Now if possible, merge loop header and block with exit edge. - This reduces number of basic blocks to 2. Auto vectorizer addresses + This reduces number of basic blocks to 2. Auto vectorizer addresses loops with two nodes only. FIXME: Use cleanup_tree_cfg(). */ if (exit_bb && exit_bb != loop->header @@ -1021,7 +1015,7 @@ combine_blocks (struct loop *loop) merge_blocks (loop->header, exit_bb); } -/* Make a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP +/* Make a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP to the new variable. */ static gimple @@ -1064,11 +1058,11 @@ pred_blocks_visited_p (basic_block bb, bitmap *visited) return true; } -/* Get body of a LOOP in suitable order for if-conversion. - It is caller's responsibility to deallocate basic block - list. If-conversion suitable order is, BFS order with one - additional constraint. Select block in BFS block, if all - pred are already selected. */ +/* Get body of a LOOP in suitable order for if-conversion. It is + caller's responsibility to deallocate basic block list. + If-conversion suitable order is, breadth first sort (BFS) order + with an additional constraint: select a block only if all its + predecessors are already selected. */ static basic_block * get_loop_body_in_if_conv_order (const struct loop *loop) @@ -1099,6 +1093,7 @@ get_loop_body_in_if_conv_order (const struct loop *loop) free (blocks); return NULL; } + if (!bitmap_bit_p (visited, bb->index)) { if (pred_blocks_visited_p (bb, &visited) @@ -1109,13 +1104,13 @@ get_loop_body_in_if_conv_order (const struct loop *loop) blocks[visited_count++] = bb; } } + index++; + if (index == loop->num_nodes && visited_count != loop->num_nodes) - { - /* Not done yet. */ - index = 0; - } + /* Not done yet. */ + index = 0; } free (blocks_in_bfs_order); BITMAP_FREE (visited); -- cgit v1.2.1 From 1055d96ad26254636bc4c564b0522a27aa221df3 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 7 Apr 2010 06:33:45 +0000 Subject: Sort static functions in topological order. 2010-04-07 Sebastian Pop * tree-if-conv.c: Sort static functions in topological order. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158040 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 597 +++++++++++++++++++++++++---------------------------- 1 file changed, 281 insertions(+), 316 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 5ff864478de..3b2386aa329 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -100,119 +100,150 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "target.h" - -/* local function prototypes */ -static unsigned int main_tree_if_conversion (void); -static tree tree_if_convert_stmt (struct loop *loop, gimple, tree, - gimple_stmt_iterator *); -static void tree_if_convert_cond_stmt (struct loop *, gimple, tree, - gimple_stmt_iterator *); -static bool if_convertible_phi_p (struct loop *, basic_block, gimple); -static bool if_convertible_gimple_assign_stmt_p (struct loop *, basic_block, - gimple); -static bool if_convertible_stmt_p (struct loop *, basic_block, gimple); -static bool if_convertible_bb_p (struct loop *, basic_block, basic_block); -static bool if_convertible_loop_p (struct loop *, bool); -static void add_to_predicate_list (basic_block, tree); -static tree add_to_dst_predicate_list (struct loop * loop, edge, - tree, tree, - gimple_stmt_iterator *); -static void clean_predicate_lists (struct loop *loop); -static basic_block find_phi_replacement_condition (struct loop *loop, - basic_block, tree *, - gimple_stmt_iterator *); -static void replace_phi_with_cond_gimple_assign_stmt (gimple, tree, - basic_block, - gimple_stmt_iterator *); -static void process_phi_nodes (struct loop *); -static void combine_blocks (struct loop *); -static gimple ifc_temp_var (tree, tree); -static bool pred_blocks_visited_p (basic_block, bitmap *); -static basic_block * get_loop_body_in_if_conv_order (const struct loop *loop); -static bool bb_with_exit_edge_p (struct loop *, basic_block); - /* List of basic blocks in if-conversion-suitable order. */ static basic_block *ifc_bbs; -/* Main entry point. Apply if-conversion to the LOOP. Return true if - successful otherwise return false. If false is returned then loop - remains unchanged. FOR_VECTORIZER is a boolean flag. It indicates - whether if-conversion is used for vectorizer or not. If it is used - for vectorizer, additional checks are used. (Vectorization checks - are not yet implemented). */ +/* Make a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP + to the new variable. */ -static bool -tree_if_conversion (struct loop *loop, bool for_vectorizer) +static gimple +ifc_temp_var (tree type, tree exp) { - basic_block bb; - gimple_stmt_iterator itr; - unsigned int i; + const char *name = "_ifc_"; + tree var, new_name; + gimple stmt; - ifc_bbs = NULL; + /* Create new temporary variable. */ + var = create_tmp_var (type, name); + add_referenced_var (var); - /* If-conversion is not appropriate for all loops. First, check if - loop is if-convertible or not. */ - if (!if_convertible_loop_p (loop, for_vectorizer)) + /* Build new statement to assign EXP to new variable. */ + stmt = gimple_build_assign (var, exp); + + /* Get SSA name for the new variable and set make new statement + its definition statement. */ + new_name = make_ssa_name (var, stmt); + gimple_assign_set_lhs (stmt, new_name); + SSA_NAME_DEF_STMT (new_name) = stmt; + update_stmt (stmt); + + return stmt; +} + +/* Add condition COND into predicate list of basic block BB. */ + +static void +add_to_predicate_list (basic_block bb, tree new_cond) +{ + tree cond = (tree) bb->aux; + + if (cond) + cond = fold_build2_loc (EXPR_LOCATION (cond), + TRUTH_OR_EXPR, boolean_type_node, + unshare_expr (cond), new_cond); + else + cond = new_cond; + + bb->aux = cond; +} + +/* Add condition COND into BB's predicate list. PREV_COND is + existing condition. */ + +static tree +add_to_dst_predicate_list (struct loop *loop, edge e, + tree prev_cond, tree cond, + gimple_stmt_iterator *gsi) +{ + tree new_cond = NULL_TREE; + + if (!flow_bb_inside_loop_p (loop, e->dest)) + return NULL_TREE; + + if (prev_cond == boolean_true_node || !prev_cond) + new_cond = unshare_expr (cond); + else { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file,"-------------------------\n"); - if (ifc_bbs) - { - free (ifc_bbs); - ifc_bbs = NULL; - } - free_dominance_info (CDI_POST_DOMINATORS); - return false; + tree tmp; + gimple tmp_stmt = NULL; + + prev_cond = force_gimple_operand_gsi (gsi, unshare_expr (prev_cond), + true, NULL, true, GSI_SAME_STMT); + + cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), + true, NULL, true, GSI_SAME_STMT); + + /* Add the condition to aux field of the edge. In case edge + destination is a PHI node, this condition will be ANDed with + block predicate to construct complete condition. */ + e->aux = cond; + + tmp = build2 (TRUTH_AND_EXPR, boolean_type_node, + unshare_expr (prev_cond), cond); + tmp_stmt = ifc_temp_var (boolean_type_node, tmp); + gsi_insert_before (gsi, tmp_stmt, GSI_SAME_STMT); + new_cond = gimple_assign_lhs (tmp_stmt); } - /* Do actual work now. */ - for (i = 0; i < loop->num_nodes; i++) - { - tree cond; + add_to_predicate_list (e->dest, new_cond); + return new_cond; +} - bb = ifc_bbs [i]; +/* Return true if one of the basic block BB edge is exit of LOOP. */ - /* Update condition using predicate list. */ - cond = (tree) bb->aux; +static bool +bb_with_exit_edge_p (struct loop *loop, basic_block bb) +{ + edge e; + edge_iterator ei; + bool exit_edge_found = false; - /* Process all statements in this basic block. - Remove conditional expression, if any, and annotate - destination basic block(s) appropriately. */ - for (itr = gsi_start_bb (bb); !gsi_end_p (itr); /* empty */) - { - gimple t = gsi_stmt (itr); - cond = tree_if_convert_stmt (loop, t, cond, &itr); - if (!gsi_end_p (itr)) - gsi_next (&itr); - } + FOR_EACH_EDGE (e, ei, bb->succs) + if (loop_exit_edge_p (loop, e)) + { + exit_edge_found = true; + break; + } - /* If current bb has only one successor, then consider it as an - unconditional goto. */ - if (single_succ_p (bb)) - { - basic_block bb_n = single_succ (bb); + return exit_edge_found; +} - /* Successor bb inherits predicate of its predecessor. If there - is no predicate in predecessor bb, then consider successor bb - as always executed. */ - if (cond == NULL_TREE) - cond = boolean_true_node; +/* STMT is a GIMPLE_COND. Update two destination's predicate list. + Remove COND_EXPR, if it is not the loop exit condition. Otherwise + update loop exit condition appropriately. GSI is the iterator + used to traverse statement list. STMT is part of loop LOOP. */ - add_to_predicate_list (bb_n, cond); - } - } +static void +tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, + gimple_stmt_iterator *gsi) +{ + tree c2; + edge true_edge, false_edge; + location_t loc = gimple_location (stmt); + tree c = fold_build2_loc (loc, gimple_cond_code (stmt), boolean_type_node, + gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); - /* Now, all statements are if-converted and basic blocks are - annotated appropriately. Combine all basic block into one huge - basic block. */ - combine_blocks (loop); + extract_true_false_edges_from_block (gimple_bb (stmt), + &true_edge, &false_edge); - /* clean up */ - clean_predicate_lists (loop); - free (ifc_bbs); - ifc_bbs = NULL; + /* Add new condition into destination's predicate list. */ - return true; + /* If C is true, then TRUE_EDGE is taken. */ + add_to_dst_predicate_list (loop, true_edge, cond, c, gsi); + + /* If C is false, then FALSE_EDGE is taken. */ + c2 = invert_truthvalue_loc (loc, unshare_expr (c)); + add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi); + + /* Now this conditional statement is redundant. Remove it. + But, do not remove exit condition! Update exit condition + using new condition. */ + if (!bb_with_exit_edge_p (loop, gimple_bb (stmt))) + { + gsi_remove (gsi, true); + cond = NULL_TREE; + } + return; } /* If-convert stmt T which is part of LOOP. @@ -269,47 +300,6 @@ tree_if_convert_stmt (struct loop * loop, gimple t, tree cond, return cond; } -/* STMT is a GIMPLE_COND. Update two destination's predicate list. - Remove COND_EXPR, if it is not the loop exit condition. Otherwise - update loop exit condition appropriately. GSI is the iterator - used to traverse statement list. STMT is part of loop LOOP. */ - -static void -tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, - gimple_stmt_iterator *gsi) -{ - tree c, c2; - edge true_edge, false_edge; - location_t loc = gimple_location (stmt); - - gcc_assert (gimple_code (stmt) == GIMPLE_COND); - - c = fold_build2_loc (loc, gimple_cond_code (stmt), boolean_type_node, - gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); - - extract_true_false_edges_from_block (gimple_bb (stmt), - &true_edge, &false_edge); - - /* Add new condition into destination's predicate list. */ - - /* If C is true, then TRUE_EDGE is taken. */ - add_to_dst_predicate_list (loop, true_edge, cond, c, gsi); - - /* If C is false, then FALSE_EDGE is taken. */ - c2 = invert_truthvalue_loc (loc, unshare_expr (c)); - add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi); - - /* Now this conditional statement is redundant. Remove it. - But, do not remove exit condition! Update exit condition - using new condition. */ - if (!bb_with_exit_edge_p (loop, gimple_bb (stmt))) - { - gsi_remove (gsi, true); - cond = NULL_TREE; - } - return; -} - /* Return true, iff PHI is if-convertible. PHI is part of loop LOOP and it belongs to basic block BB. PHI is not if-convertible @@ -485,31 +475,105 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) } else if (!empty_block_p (bb)) { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "non empty basic block after exit bb\n"); - return false; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "non empty basic block after exit bb\n"); + return false; + } + else if (bb == loop->latch + && bb != exit_bb + && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "latch is not dominated by exit_block\n"); + return false; + } + } + + /* Be less adventurous and handle only normal edges. */ + FOR_EACH_EDGE (e, ei, bb->succs) + if (e->flags & + (EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file,"Difficult to handle edges\n"); + return false; + } + + return true; +} + +/* Return TRUE iff, all pred blocks of BB are visited. + Bitmap VISITED keeps history of visited blocks. */ + +static bool +pred_blocks_visited_p (basic_block bb, bitmap *visited) +{ + edge e; + edge_iterator ei; + FOR_EACH_EDGE (e, ei, bb->preds) + if (!bitmap_bit_p (*visited, e->src->index)) + return false; + + return true; +} + +/* Get body of a LOOP in suitable order for if-conversion. It is + caller's responsibility to deallocate basic block list. + If-conversion suitable order is, breadth first sort (BFS) order + with an additional constraint: select a block only if all its + predecessors are already selected. */ + +static basic_block * +get_loop_body_in_if_conv_order (const struct loop *loop) +{ + basic_block *blocks, *blocks_in_bfs_order; + basic_block bb; + bitmap visited; + unsigned int index = 0; + unsigned int visited_count = 0; + + gcc_assert (loop->num_nodes); + gcc_assert (loop->latch != EXIT_BLOCK_PTR); + + blocks = XCNEWVEC (basic_block, loop->num_nodes); + visited = BITMAP_ALLOC (NULL); + + blocks_in_bfs_order = get_loop_body_in_bfs_order (loop); + + index = 0; + while (index < loop->num_nodes) + { + bb = blocks_in_bfs_order [index]; + + if (bb->flags & BB_IRREDUCIBLE_LOOP) + { + free (blocks_in_bfs_order); + BITMAP_FREE (visited); + free (blocks); + return NULL; + } + + if (!bitmap_bit_p (visited, bb->index)) + { + if (pred_blocks_visited_p (bb, &visited) + || bb == loop->header) + { + /* This block is now visited. */ + bitmap_set_bit (visited, bb->index); + blocks[visited_count++] = bb; + } } - else if (bb == loop->latch - && bb != exit_bb - && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "latch is not dominated by exit_block\n"); - return false; - } - } - /* Be less adventurous and handle only normal edges. */ - FOR_EACH_EDGE (e, ei, bb->succs) - if (e->flags & - (EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file,"Difficult to handle edges\n"); - return false; - } + index++; - return true; + if (index == loop->num_nodes + && visited_count != loop->num_nodes) + /* Not done yet. */ + index = 0; + } + free (blocks_in_bfs_order); + BITMAP_FREE (visited); + return blocks; } /* Return true, iff LOOP is if-convertible. @@ -613,65 +677,6 @@ if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED) return true; } -/* Add condition COND into predicate list of basic block BB. */ - -static void -add_to_predicate_list (basic_block bb, tree new_cond) -{ - tree cond = (tree) bb->aux; - - if (cond) - cond = fold_build2_loc (EXPR_LOCATION (cond), - TRUTH_OR_EXPR, boolean_type_node, - unshare_expr (cond), new_cond); - else - cond = new_cond; - - bb->aux = cond; -} - -/* Add condition COND into BB's predicate list. PREV_COND is - existing condition. */ - -static tree -add_to_dst_predicate_list (struct loop * loop, edge e, - tree prev_cond, tree cond, - gimple_stmt_iterator *gsi) -{ - tree new_cond = NULL_TREE; - - if (!flow_bb_inside_loop_p (loop, e->dest)) - return NULL_TREE; - - if (prev_cond == boolean_true_node || !prev_cond) - new_cond = unshare_expr (cond); - else - { - tree tmp; - gimple tmp_stmt = NULL; - - prev_cond = force_gimple_operand_gsi (gsi, unshare_expr (prev_cond), - true, NULL, true, GSI_SAME_STMT); - - cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), - true, NULL, true, GSI_SAME_STMT); - - /* Add the condition to aux field of the edge. In case edge - destination is a PHI node, this condition will be ANDed with - block predicate to construct complete condition. */ - e->aux = cond; - - /* new_cond == prev_cond AND cond */ - tmp = build2 (TRUTH_AND_EXPR, boolean_type_node, - unshare_expr (prev_cond), cond); - tmp_stmt = ifc_temp_var (boolean_type_node, tmp); - gsi_insert_before (gsi, tmp_stmt, GSI_SAME_STMT); - new_cond = gimple_assign_lhs (tmp_stmt); - } - add_to_predicate_list (e->dest, new_cond); - return new_cond; -} - /* During if-conversion aux field from basic block structure is used to hold predicate list. Clean each basic block's predicate list for the given LOOP. Also clean aux field of successor edges, used to hold true and false @@ -1015,125 +1020,85 @@ combine_blocks (struct loop *loop) merge_blocks (loop->header, exit_bb); } -/* Make a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP - to the new variable. */ - -static gimple -ifc_temp_var (tree type, tree exp) -{ - const char *name = "_ifc_"; - tree var, new_name; - gimple stmt; - - /* Create new temporary variable. */ - var = create_tmp_var (type, name); - add_referenced_var (var); - - /* Build new statement to assign EXP to new variable. */ - stmt = gimple_build_assign (var, exp); - - /* Get SSA name for the new variable and set make new statement - its definition statement. */ - new_name = make_ssa_name (var, stmt); - gimple_assign_set_lhs (stmt, new_name); - SSA_NAME_DEF_STMT (new_name) = stmt; - update_stmt (stmt); - - return stmt; -} - - -/* Return TRUE iff, all pred blocks of BB are visited. - Bitmap VISITED keeps history of visited blocks. */ +/* Main entry point. Apply if-conversion to the LOOP. Return true if + successful otherwise return false. If false is returned then loop + remains unchanged. FOR_VECTORIZER is a boolean flag. It indicates + whether if-conversion is used for vectorizer or not. If it is used + for vectorizer, additional checks are used. (Vectorization checks + are not yet implemented). */ static bool -pred_blocks_visited_p (basic_block bb, bitmap *visited) -{ - edge e; - edge_iterator ei; - FOR_EACH_EDGE (e, ei, bb->preds) - if (!bitmap_bit_p (*visited, e->src->index)) - return false; - - return true; -} - -/* Get body of a LOOP in suitable order for if-conversion. It is - caller's responsibility to deallocate basic block list. - If-conversion suitable order is, breadth first sort (BFS) order - with an additional constraint: select a block only if all its - predecessors are already selected. */ - -static basic_block * -get_loop_body_in_if_conv_order (const struct loop *loop) +tree_if_conversion (struct loop *loop, bool for_vectorizer) { - basic_block *blocks, *blocks_in_bfs_order; basic_block bb; - bitmap visited; - unsigned int index = 0; - unsigned int visited_count = 0; - - gcc_assert (loop->num_nodes); - gcc_assert (loop->latch != EXIT_BLOCK_PTR); + gimple_stmt_iterator itr; + unsigned int i; - blocks = XCNEWVEC (basic_block, loop->num_nodes); - visited = BITMAP_ALLOC (NULL); + ifc_bbs = NULL; - blocks_in_bfs_order = get_loop_body_in_bfs_order (loop); + /* If-conversion is not appropriate for all loops. First, check if + loop is if-convertible or not. */ + if (!if_convertible_loop_p (loop, for_vectorizer)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file,"-------------------------\n"); + if (ifc_bbs) + { + free (ifc_bbs); + ifc_bbs = NULL; + } + free_dominance_info (CDI_POST_DOMINATORS); + return false; + } - index = 0; - while (index < loop->num_nodes) + /* Do actual work now. */ + for (i = 0; i < loop->num_nodes; i++) { - bb = blocks_in_bfs_order [index]; + tree cond; - if (bb->flags & BB_IRREDUCIBLE_LOOP) + bb = ifc_bbs [i]; + + /* Update condition using predicate list. */ + cond = (tree) bb->aux; + + /* Process all statements in this basic block. + Remove conditional expression, if any, and annotate + destination basic block(s) appropriately. */ + for (itr = gsi_start_bb (bb); !gsi_end_p (itr); /* empty */) { - free (blocks_in_bfs_order); - BITMAP_FREE (visited); - free (blocks); - return NULL; + gimple t = gsi_stmt (itr); + cond = tree_if_convert_stmt (loop, t, cond, &itr); + if (!gsi_end_p (itr)) + gsi_next (&itr); } - if (!bitmap_bit_p (visited, bb->index)) + /* If current bb has only one successor, then consider it as an + unconditional goto. */ + if (single_succ_p (bb)) { - if (pred_blocks_visited_p (bb, &visited) - || bb == loop->header) - { - /* This block is now visited. */ - bitmap_set_bit (visited, bb->index); - blocks[visited_count++] = bb; - } - } + basic_block bb_n = single_succ (bb); - index++; + /* Successor bb inherits predicate of its predecessor. If there + is no predicate in predecessor bb, then consider successor bb + as always executed. */ + if (cond == NULL_TREE) + cond = boolean_true_node; - if (index == loop->num_nodes - && visited_count != loop->num_nodes) - /* Not done yet. */ - index = 0; + add_to_predicate_list (bb_n, cond); + } } - free (blocks_in_bfs_order); - BITMAP_FREE (visited); - return blocks; -} -/* Return true if one of the basic block BB edge is exit of LOOP. */ - -static bool -bb_with_exit_edge_p (struct loop *loop, basic_block bb) -{ - edge e; - edge_iterator ei; - bool exit_edge_found = false; + /* Now, all statements are if-converted and basic blocks are + annotated appropriately. Combine all basic block into one huge + basic block. */ + combine_blocks (loop); - FOR_EACH_EDGE (e, ei, bb->succs) - if (loop_exit_edge_p (loop, e)) - { - exit_edge_found = true; - break; - } + /* clean up */ + clean_predicate_lists (loop); + free (ifc_bbs); + ifc_bbs = NULL; - return exit_edge_found; + return true; } /* Tree if-conversion pass management. */ -- cgit v1.2.1 From 9cfdcdb12e11dc261417e8a04e3e36e29c9ebf99 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 7 Apr 2010 06:33:55 +0000 Subject: Fix comments. 2010-04-07 Sebastian Pop * tree-if-conv.c: Fix indentation and comments. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158041 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 3b2386aa329..4a563f32311 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -130,7 +130,7 @@ ifc_temp_var (tree type, tree exp) return stmt; } -/* Add condition COND into predicate list of basic block BB. */ +/* Add condition NEW_COND into predicate list of basic block BB. */ static void add_to_predicate_list (basic_block bb, tree new_cond) @@ -139,16 +139,18 @@ add_to_predicate_list (basic_block bb, tree new_cond) if (cond) cond = fold_build2_loc (EXPR_LOCATION (cond), - TRUTH_OR_EXPR, boolean_type_node, - unshare_expr (cond), new_cond); + TRUTH_OR_EXPR, boolean_type_node, + unshare_expr (cond), new_cond); else cond = new_cond; bb->aux = cond; } -/* Add condition COND into BB's predicate list. PREV_COND is - existing condition. */ +/* And condition COND to the previous condition PREV_COND and add this + to the predicate list of the destination of edge E. GSI is the + place where the gimplification of the resulting condition should + output code. LOOP is the loop to be if-converted. */ static tree add_to_dst_predicate_list (struct loop *loop, edge e, @@ -254,7 +256,7 @@ tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, loop. It is used here when it is required to delete current statement. */ static tree -tree_if_convert_stmt (struct loop * loop, gimple t, tree cond, +tree_if_convert_stmt (struct loop *loop, gimple t, tree cond, gimple_stmt_iterator *gsi) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -872,8 +874,8 @@ replace_phi_with_cond_gimple_assign_stmt (gimple phi, tree cond, } } -/* Process phi nodes for the given LOOP. Replace phi nodes with cond - modify expr. */ +/* Process phi nodes for the given LOOP. Replace phi nodes with + conditional modify expressions. */ static void process_phi_nodes (struct loop *loop) @@ -882,7 +884,6 @@ process_phi_nodes (struct loop *loop) unsigned int orig_loop_num_nodes = loop->num_nodes; unsigned int i; - /* Replace phi nodes with cond. modify expr. */ for (i = 1; i < orig_loop_num_nodes; i++) { gimple phi; @@ -897,7 +898,7 @@ process_phi_nodes (struct loop *loop) phi_gsi = gsi_start_phis (bb); gsi = gsi_after_labels (bb); - /* BB has two predecessors. Using predecessor's aux field, set + /* BB has two predecessors. Using predecessor's aux field, set appropriate condition for the PHI node replacement. */ if (!gsi_end_p (phi_gsi)) true_bb = find_phi_replacement_condition (loop, bb, &cond, &gsi); @@ -914,8 +915,8 @@ process_phi_nodes (struct loop *loop) return; } -/* Combine all basic block from the given LOOP into one or two super - basic block. Replace PHI nodes with conditional modify expression. */ +/* Combine all the basic blocks from LOOP into one or two super basic + blocks. Replace PHI nodes with conditional modify expressions. */ static void combine_blocks (struct loop *loop) -- cgit v1.2.1 From 5ead86d3e2b4433a2aae669801b3978215c79eba Mon Sep 17 00:00:00 2001 From: spop Date: Thu, 8 Apr 2010 17:32:17 +0000 Subject: Remove unused parameter. 2010-04-08 Sebastian Pop * tree-if-conv.c (if_convertible_loop_p): Remove unused parameter. (tree_if_conversion): Same. Update call to if_convertible_loop_p. (main_tree_if_conversion): Update call to tree_if_conversion. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158135 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 4a563f32311..3a2034e100f 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -584,14 +584,10 @@ get_loop_body_in_if_conv_order (const struct loop *loop) - it has two or more basic blocks, - it has only one exit, - loop header is not the exit edge, - - if its basic blocks and phi nodes are if convertible. See above for - more info. - FOR_VECTORIZER enables vectorizer specific checks, for example, support - for vector conditions, data dependency checks, etc. - (Not implemented yet). */ + - if its basic blocks and phi nodes are if convertible. */ static bool -if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED) +if_convertible_loop_p (struct loop *loop) { basic_block bb; gimple_stmt_iterator itr; @@ -1023,13 +1019,10 @@ combine_blocks (struct loop *loop) /* Main entry point. Apply if-conversion to the LOOP. Return true if successful otherwise return false. If false is returned then loop - remains unchanged. FOR_VECTORIZER is a boolean flag. It indicates - whether if-conversion is used for vectorizer or not. If it is used - for vectorizer, additional checks are used. (Vectorization checks - are not yet implemented). */ + remains unchanged. */ static bool -tree_if_conversion (struct loop *loop, bool for_vectorizer) +tree_if_conversion (struct loop *loop) { basic_block bb; gimple_stmt_iterator itr; @@ -1039,7 +1032,7 @@ tree_if_conversion (struct loop *loop, bool for_vectorizer) /* If-conversion is not appropriate for all loops. First, check if loop is if-convertible or not. */ - if (!if_convertible_loop_p (loop, for_vectorizer)) + if (!if_convertible_loop_p (loop)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file,"-------------------------\n"); @@ -1114,9 +1107,8 @@ main_tree_if_conversion (void) return 0; FOR_EACH_LOOP (li, loop, 0) - { - tree_if_conversion (loop, true); - } + tree_if_conversion (loop); + return 0; } -- cgit v1.2.1 From b01e3c9b070c5c767aa625572fa1972da0691b07 Mon Sep 17 00:00:00 2001 From: spop Date: Thu, 8 Apr 2010 17:32:23 +0000 Subject: Fix comments, simplify logic. 2010-04-08 Sebastian Pop * tree-if-conv.c: Fix comments and simplify logic. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158136 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 227 ++++++++++++++++++++++++----------------------------- 1 file changed, 104 insertions(+), 123 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 3a2034e100f..43b04c1900e 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -19,8 +19,9 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ -/* This pass implements tree level if-conversion transformation of loops. - Initial goal is to help vectorizer vectorize loops with conditions. +/* This pass implements a tree level if-conversion of loops. Its + initial goal is to help the vectorizer to vectorize loops with + conditions. A short description of if-conversion: @@ -103,7 +104,7 @@ along with GCC; see the file COPYING3. If not see /* List of basic blocks in if-conversion-suitable order. */ static basic_block *ifc_bbs; -/* Make a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP +/* Create a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP to the new variable. */ static gimple @@ -130,7 +131,7 @@ ifc_temp_var (tree type, tree exp) return stmt; } -/* Add condition NEW_COND into predicate list of basic block BB. */ +/* Add condition NEW_COND to the predicate list of basic block BB. */ static void add_to_predicate_list (basic_block bb, tree new_cond) @@ -147,7 +148,7 @@ add_to_predicate_list (basic_block bb, tree new_cond) bb->aux = cond; } -/* And condition COND to the previous condition PREV_COND and add this +/* Add the condition COND to the previous condition PREV_COND, and add this to the predicate list of the destination of edge E. GSI is the place where the gimplification of the resulting condition should output code. LOOP is the loop to be if-converted. */ @@ -175,9 +176,9 @@ add_to_dst_predicate_list (struct loop *loop, edge e, cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true, NULL, true, GSI_SAME_STMT); - /* Add the condition to aux field of the edge. In case edge - destination is a PHI node, this condition will be ANDed with - block predicate to construct complete condition. */ + /* Add the condition COND to the e->aux field. In case the edge + destination is a PHI node, this condition will be added to + the block predicate to construct a complete condition. */ e->aux = cond; tmp = build2 (TRUTH_AND_EXPR, boolean_type_node, @@ -191,29 +192,25 @@ add_to_dst_predicate_list (struct loop *loop, edge e, return new_cond; } -/* Return true if one of the basic block BB edge is exit of LOOP. */ +/* Return true if one of the successor edges of BB exits LOOP. */ static bool bb_with_exit_edge_p (struct loop *loop, basic_block bb) { edge e; edge_iterator ei; - bool exit_edge_found = false; FOR_EACH_EDGE (e, ei, bb->succs) if (loop_exit_edge_p (loop, e)) - { - exit_edge_found = true; - break; - } + return true; - return exit_edge_found; + return false; } /* STMT is a GIMPLE_COND. Update two destination's predicate list. - Remove COND_EXPR, if it is not the loop exit condition. Otherwise - update loop exit condition appropriately. GSI is the iterator - used to traverse statement list. STMT is part of loop LOOP. */ + Remove COND_EXPR, if it is not the exit condition of LOOP. + Otherwise update the exit condition of LOOP appropriately. GSI + points to the statement STMT. */ static void tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, @@ -237,23 +234,23 @@ tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, c2 = invert_truthvalue_loc (loc, unshare_expr (c)); add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi); - /* Now this conditional statement is redundant. Remove it. - But, do not remove exit condition! Update exit condition - using new condition. */ + /* Now this conditional statement is redundant. Remove it. But, do + not remove the exit condition! Update the exit condition using + the new condition. */ if (!bb_with_exit_edge_p (loop, gimple_bb (stmt))) { gsi_remove (gsi, true); cond = NULL_TREE; } - return; } /* If-convert stmt T which is part of LOOP. - If T is a GIMPLE_ASSIGN then it is converted into conditional modify - expression using COND. For conditional expressions, add condition in the - destination basic block's predicate list and remove conditional - expression itself. BSI is the iterator used to traverse statements of - loop. It is used here when it is required to delete current statement. */ + + If T is a GIMPLE_ASSIGN then it is converted into a conditional + modify expression using COND. For conditional expressions, add + a condition in the destination basic block's predicate list and + remove the conditional expression itself. GSI points to the + statement T. */ static tree tree_if_convert_stmt (struct loop *loop, gimple t, tree cond, @@ -299,13 +296,15 @@ tree_if_convert_stmt (struct loop *loop, gimple t, tree cond, default: gcc_unreachable (); } + return cond; } -/* Return true, iff PHI is if-convertible. PHI is part of loop LOOP +/* Return true when PHI is if-convertible. PHI is part of loop LOOP and it belongs to basic block BB. - PHI is not if-convertible - - if it has more than 2 arguments, + + PHI is not if-convertible if: + - it has more than 2 arguments, - virtual PHI is immediately used in another PHI node, - virtual PHI on BB other than header. */ @@ -350,21 +349,20 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gimple phi) return true; } -/* Return true, if STMT is if-convertible. +/* Return true when STMT is if-convertible. + GIMPLE_ASSIGN statement is not if-convertible if, - it is not movable, - it could trap, - LHS is not var decl. + GIMPLE_ASSIGN is part of block BB, which is inside loop LOOP. */ static bool if_convertible_gimple_assign_stmt_p (struct loop *loop, basic_block bb, gimple stmt) { - tree lhs; - - if (!is_gimple_assign (stmt)) - return false; + tree lhs = gimple_assign_lhs (stmt); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -372,8 +370,6 @@ if_convertible_gimple_assign_stmt_p (struct loop *loop, basic_block bb, print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); } - lhs = gimple_assign_lhs (stmt); - /* Some of these constrains might be too conservative. */ if (stmt_ends_bb_p (stmt) || gimple_has_volatile_ops (stmt) @@ -410,11 +406,13 @@ if_convertible_gimple_assign_stmt_p (struct loop *loop, basic_block bb, return true; } -/* Return true, iff STMT is if-convertible. - Statement is if-convertible if, - - it is if-convertible GIMPLE_ASSGIN, - - it is GIMPLE_LABEL or GIMPLE_COND. - STMT is inside block BB, which is inside loop LOOP. */ +/* Return true when STMT is if-convertible. + + A statement is if-convertible if: + - it is an if-convertible GIMPLE_ASSGIN, + - it is a GIMPLE_LABEL or a GIMPLE_COND. + + STMT is inside BB, which is inside loop LOOP. */ static bool if_convertible_stmt_p (struct loop *loop, basic_block bb, gimple stmt) @@ -422,18 +420,12 @@ if_convertible_stmt_p (struct loop *loop, basic_block bb, gimple stmt) switch (gimple_code (stmt)) { case GIMPLE_LABEL: - break; - case GIMPLE_DEBUG: - break; + case GIMPLE_COND: + return true; case GIMPLE_ASSIGN: - if (!if_convertible_gimple_assign_stmt_p (loop, bb, stmt)) - return false; - break; - - case GIMPLE_COND: - break; + return if_convertible_gimple_assign_stmt_p (loop, bb, stmt); default: /* Don't know what to do with 'em so don't do anything. */ @@ -449,14 +441,16 @@ if_convertible_stmt_p (struct loop *loop, basic_block bb, gimple stmt) return true; } -/* Return true, iff BB is if-convertible. - Note: This routine does _not_ check basic block statements and phis. - Basic block is not if-convertible if: - - basic block is non-empty and it is after exit block (in BFS order), - - basic block is after exit block but before latch, - - basic block edge(s) is not normal. - EXIT_BB_SEEN is true if basic block with exit edge is already seen. - BB is inside loop LOOP. */ +/* Return true when BB is if-convertible. This routine does not check + basic block's statements and phis. + + A basic block is not if-convertible if: + - it is non-empty and it is after the exit block (in BFS order), + - it is after the exit block but before the latch, + - its edges are not normal. + + EXIT_BB is the basic block containing the exit of the LOOP. BB is + inside LOOP. */ static bool if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) @@ -497,15 +491,15 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) (EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP)) { if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file,"Difficult to handle edges\n"); + fprintf (dump_file, "Difficult to handle edges\n"); return false; } return true; } -/* Return TRUE iff, all pred blocks of BB are visited. - Bitmap VISITED keeps history of visited blocks. */ +/* Return true when all predecessor blocks of BB are visited. The + VISITED bitmap keeps track of the visited blocks. */ static bool pred_blocks_visited_p (basic_block bb, bitmap *visited) @@ -578,7 +572,7 @@ get_loop_body_in_if_conv_order (const struct loop *loop) return blocks; } -/* Return true, iff LOOP is if-convertible. +/* Return true when LOOP is if-convertible. LOOP is if-convertible if: - it is innermost, - it has two or more basic blocks, @@ -675,10 +669,11 @@ if_convertible_loop_p (struct loop *loop) return true; } -/* During if-conversion aux field from basic block structure is used to hold - predicate list. Clean each basic block's predicate list for the given LOOP. - Also clean aux field of successor edges, used to hold true and false - condition from conditional expression. */ +/* During if-conversion, the bb->aux field is used to hold a predicate + list. This function cleans for all the basic blocks in the given + LOOP their predicate list. It also cleans up the e->aux field of + all the successor edges: e->aux is used to hold the true and false + conditions for conditional expressions. */ static void clean_predicate_lists (struct loop *loop) @@ -698,9 +693,11 @@ clean_predicate_lists (struct loop *loop) free (bb); } -/* Basic block BB has two predecessors. Using predecessor's aux field, set - appropriate condition COND for the PHI node replacement. Return true block - whose phi arguments are selected when cond is true. */ +/* Basic block BB has two predecessors. Using predecessor's bb->aux + field, set appropriate condition COND for the PHI node replacement. + Return true block whose phi arguments are selected when cond is + true. LOOP is the loop containing the if-converted region, GSI is + the place to insert the code for the if-conversion. */ static basic_block find_phi_replacement_condition (struct loop *loop, @@ -759,15 +756,13 @@ find_phi_replacement_condition (struct loop *loop, { *cond = (tree) (second_edge->src)->aux; - /* If there is a condition on an incoming edge, - AND it with the incoming bb predicate. */ + /* If there is a condition on an incoming edge, add it to the + incoming bb predicate. */ if (second_edge->aux) *cond = build2 (TRUTH_AND_EXPR, boolean_type_node, *cond, (tree) second_edge->aux); if (TREE_CODE (*cond) == TRUTH_NOT_EXPR) - /* We can be smart here and choose inverted - condition without switching bbs. */ *cond = invert_truthvalue (*cond); else /* Select non loop header bb. */ @@ -775,21 +770,20 @@ find_phi_replacement_condition (struct loop *loop, } else { - /* FIRST_BB is not loop header */ *cond = (tree) (first_edge->src)->aux; - /* If there is a condition on an incoming edge, - AND it with the incoming bb predicate. */ + /* If there is a condition on an incoming edge, add it to the + incoming bb predicate. */ if (first_edge->aux) *cond = build2 (TRUTH_AND_EXPR, boolean_type_node, *cond, (tree) first_edge->aux); } - /* Create temp. for the condition. Vectorizer prefers to have gimple - value as condition. Various targets use different means to communicate - condition in vector compare operation. Using gimple value allows - compiler to emit vector compare and select RTL without exposing - compare's result. */ + /* Gimplify the condition: the vectorizer prefers to have gimple + values as conditions. Various targets use different means to + communicate conditions in vector compare operations. Using a + gimple value allows the compiler to emit vector compare and + select RTL without exposing compare's result. */ *cond = force_gimple_operand_gsi (gsi, unshare_expr (*cond), false, NULL_TREE, true, GSI_SAME_STMT); @@ -807,16 +801,17 @@ find_phi_replacement_condition (struct loop *loop, return first_edge->src; } +/* Replace PHI node with conditional modify expr using COND. This + routine does not handle PHI nodes with more than two arguments. -/* Replace PHI node with conditional modify expr using COND. - This routine does not handle PHI nodes with more than two arguments. For example, S1: A = PHI header) { - /* Connect this node with loop header. */ + /* Connect this node to loop header. */ make_edge (loop->header, exit_bb, EDGE_FALLTHRU); set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header); } @@ -972,7 +958,7 @@ combine_blocks (struct loop *loop) } else { - /* If the loop does not have exit then reconnect header and latch. */ + /* If the loop does not have an exit, reconnect header and latch. */ make_edge (loop->header, loop->latch, EDGE_FALLTHRU); set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header); } @@ -1008,30 +994,30 @@ combine_blocks (struct loop *loop) delete_basic_block (bb); } - /* Now if possible, merge loop header and block with exit edge. - This reduces number of basic blocks to 2. Auto vectorizer addresses - loops with two nodes only. FIXME: Use cleanup_tree_cfg(). */ + /* If possible, merge loop header to the block with the exit edge. + This reduces the number of basic blocks to two, to please the + vectorizer that handles only loops with two nodes. + + FIXME: Call cleanup_tree_cfg. */ if (exit_bb && exit_bb != loop->header && can_merge_blocks_p (loop->header, exit_bb)) merge_blocks (loop->header, exit_bb); } -/* Main entry point. Apply if-conversion to the LOOP. Return true if - successful otherwise return false. If false is returned then loop - remains unchanged. */ +/* Main entry point: return true when LOOP is if-converted, otherwise + the loop remains unchanged. */ static bool tree_if_conversion (struct loop *loop) { - basic_block bb; gimple_stmt_iterator itr; unsigned int i; ifc_bbs = NULL; /* If-conversion is not appropriate for all loops. First, check if - loop is if-convertible or not. */ + the loop is if-convertible. */ if (!if_convertible_loop_p (loop)) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -1045,17 +1031,12 @@ tree_if_conversion (struct loop *loop) return false; } - /* Do actual work now. */ for (i = 0; i < loop->num_nodes; i++) { - tree cond; - - bb = ifc_bbs [i]; - - /* Update condition using predicate list. */ - cond = (tree) bb->aux; + basic_block bb = ifc_bbs [i]; + tree cond = (tree) bb->aux; - /* Process all statements in this basic block. + /* Process all the statements in this basic block. Remove conditional expression, if any, and annotate destination basic block(s) appropriately. */ for (itr = gsi_start_bb (bb); !gsi_end_p (itr); /* empty */) @@ -1072,9 +1053,9 @@ tree_if_conversion (struct loop *loop) { basic_block bb_n = single_succ (bb); - /* Successor bb inherits predicate of its predecessor. If there - is no predicate in predecessor bb, then consider successor bb - as always executed. */ + /* The successor bb inherits the predicate of its + predecessor. If there is no predicate in the predecessor + bb, then consider the successor bb as always executed. */ if (cond == NULL_TREE) cond = boolean_true_node; @@ -1083,8 +1064,8 @@ tree_if_conversion (struct loop *loop) } /* Now, all statements are if-converted and basic blocks are - annotated appropriately. Combine all basic block into one huge - basic block. */ + annotated appropriately. Combine all the basic blocks into one + huge basic block. */ combine_blocks (loop); /* clean up */ -- cgit v1.2.1 From 3f9da5596a39ec1c557502bf3f559aaeaf48fc0d Mon Sep 17 00:00:00 2001 From: steven Date: Fri, 30 Apr 2010 11:58:49 +0000 Subject: gcc/ChangeLog: * toplev.c: Include varray.h for statistics dumping. * tree.h: Do not declare varray_head_tag. * tree-into-ssa.c, tree-ssa-uninit.c, tree-phinodes.c, omega.c, regs.h, lto-cgraph.c, tree-ssa-loop-ivopts.c, tree-nomudflap.c, c-objc-common.c, lto-streamer-out.c, tree-ssa-propagate.c, gimple-low.c, c-semantics.c, dwarf2out.c, lto-streamer-in.c, lto-section-in.c, alias.c, tree-if-conv.c, gimplify.c, ggc-zone.c, tree-ssa.c, tree-ssa-loop-prefetch.c, integrate.h, c-gimplify.c, c-common.c, c-common.h, reg-stack.c, basic-block.h, tree-ssa-structalias.c, lto-section-out.c, tree-ssanames.c: Do not include varray.h. * Makefile.in: Update for abovementioned changes. objc/ChangeLog: * objc-act.c: Do not include varray.h. objcp/ChangeLog: * objcp-decl.c: Do not include varray.h. cp/ChangeLog: * optimize.c, parser.c,mangle.c, cp-tree.h: DO not include varray.h. * Make-lang.in: Don't include varray.h dependency in CXX_TREE_H. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158933 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 1 - 1 file changed, 1 deletion(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 43b04c1900e..fbdaa0df36c 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -88,7 +88,6 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "flags.h" #include "timevar.h" -#include "varray.h" #include "rtl.h" #include "basic-block.h" #include "diagnostic.h" -- cgit v1.2.1 From a7a4626828090600459358ca745c4482cf9551a1 Mon Sep 17 00:00:00 2001 From: steven Date: Fri, 21 May 2010 13:53:22 +0000 Subject: gcc/ChangeLog: * tree.h: Include real.h and fixed-value.h as basic datatypes. * dfp.c, convert.c, reload1.c, reginfo.c, tree-flow.h, tree-ssa-threadedge.c, tree-ssanames.c, tree-loop-linear.c, tree-into-ssa.c, tree-vect-generic.c, tree-ssa-structalias.c, tree-ssa-loop-im.c, tree-dump.c, tree-complex.c, tree-ssa-uninit.c, genrecog.c, tree-ssa-threadupdate.c, tree-ssa-loop-niter.c, tree-pretty-print.c, tree-loop-distribution.c, tree-ssa-loop-unswitch.c, c-lex.c, optabs.c, postreload-gcse.c, tree-ssa-loop-manip.c, postreload.c, tree-ssa-loop-ch.c, tree-tailcall.c, tree.c, reload.c, tree-scalar-evolution.c, rtlanal.c, tree-phinodes.c, builtins.c, final.c, genoutput.c, fold-const.c, tree-ssa-dse.c, genautomata.c, tree-ssa-uncprop.c, toplev.c, tree-chrec.c, genemit.c, c-cppbuiltin.c, tree-ssa-sccvn.c, tree-ssa-ccp.c, tree-ssa-loop-ivopts.c, mode-switching.c, tree-call-cdce.c, cse.c, genpeep.c, tree-ssa-math-opts.c, tree-ssa-dom.c, tree-nrv.c, tree-ssa-propagate.c, tree-ssa-alias.c, tree-ssa-sink.c, jump.c, ifcvt.c, dwarf2out.c, expr.c, genattrtab.c, genconditions.c, tree-ssa-loop-ivcanon.c, tree-ssa-loop.c, tree-parloops.c, recog.c, tree-ssa-address.c, lcm.c, tree-eh.c, gimple-pretty-print.c, c-pretty-print.c, print-rtl.c, gcse.c, tree-if-conv.c, tree-data-ref.c, tree-affine.c, gimplify.c, tree-ssa-phiopt.c, implicit-zee.c, expmed.c, tree-dfa.c, emit-rtl.c, store-motion.c, cselib.c, tree-cfgcleanup.c, simplify-rtx.c, tree-ssa-pre.c, genpreds.c, tree-mudflap.c, print-tree.c, tree-ssa-copy.c, tree-ssa-forwprop.c, tree-ssa-dce.c, varasm.c, tree-nested.c, tree-ssa.c, tree-ssa-loop-prefetch.c, rtl.c, tree-inline.c, integrate.c, tree-optimize.c, tree-ssa-phiprop.c, fixed-value.c, combine.c, tree-profile.c, c-common.c, sched-vis.c, tree-cfg.c, passes.c, tree-ssa-reassoc.c, config/alpha/alpha.c, config/frv/frv.c, config/s390/s390.c, config/m32c/m32c.c, config/spu/spu.c, config/sparc/sparc.c, config/mep/mep.c, config/m32r/m32r.c, config/rx/rx.c, config/i386/i386.c, config/sh/sh.c, config/pdp11/pdp11.c, config/avr/avr.c, config/crx/crx.c, config/xtensa/xtensa.c, config/stormy16/stormy16.c, config/fr30/fr30.c, config/lm32/lm32.c, config/moxie/moxie.c, config/m68hc11/m68hc11.c, config/cris/cris.c, config/iq2000/iq2000.c, config/mn10300/mn10300.c, config/ia64/ia64.c, config/m68k/m68k.c, config/rs6000/rs6000.c, config/picochip/picochip.c, config/darwin.c, config/arc/arc.c, config/mcore/mcore.c, config/score/score3.c, config/score/score7.c, config/score/score.c, config/arm/arm.c, config/pa/pa.c, config/mips/mips.c, config/vax/vax.c, config/h8300/h8300.c, config/v850/v850.c, config/mmix/mmix.c, config/bfin/bfin.c: Clean up redundant includes. * Makefile.in: Update accordingly. java/ChangeLog: * typeck.c, decl.c, jcf-parse.c, except.c, expr.c: cp/Changelog: * error.c, tree.c, typeck2.c, cxx-pretty-print.c, mangle.c: Clean up redundant includes. fortran/ChangeLog: * trans-const.c, trans-types.c, trans-intrinsic.c: Clean up redundant includes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159663 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index fbdaa0df36c..9084954e5e6 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -88,7 +88,6 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "flags.h" #include "timevar.h" -#include "rtl.h" #include "basic-block.h" #include "diagnostic.h" #include "tree-flow.h" @@ -98,7 +97,6 @@ along with GCC; see the file COPYING3. If not see #include "tree-data-ref.h" #include "tree-scalar-evolution.h" #include "tree-pass.h" -#include "target.h" /* List of basic blocks in if-conversion-suitable order. */ static basic_block *ifc_bbs; -- cgit v1.2.1 From ce084dfc1cd60d867d38dbed86a914d82fa908d1 Mon Sep 17 00:00:00 2001 From: jsm28 Date: Fri, 21 May 2010 22:34:26 +0000 Subject: * diagnostic.c: Don't include tm.h, tree.h, tm_p.h, langhooks.h or langhooks-def.h. (diagnostic_initialize): Initialize x_data not last_function. (diagnostic_report_current_function): Move to tree-diagnostic.c. (default_diagnostic_starter): Call diagnostic_report_current_module not diagnostic_report_current_function. (diagnostic_report_diagnostic): Initialize x_data not abstract_origin. (verbatim): Likewise. * diagnostic.h (struct diagnostic_info): Change abstract_origin to x_data. (struct diagnostic_context): Change last_function to x_data. (diagnostic_auxiliary_data): Replace with diagnostic_context_auxiliary_data and diagnostic_info_auxiliary_data. (diagnostic_last_function_changed, diagnostic_set_last_function, diagnostic_report_current_function): Move to tree-diagnostic.h. (print_declaration, dump_generic_node, print_generic_stmt, print_generic_stmt_indented, print_generic_expr, print_generic_decl, debug_c_tree, dump_omp_clauses, print_call_name, debug_generic_expr, debug_generic_stmt, debug_tree_chain, default_tree_printer): Move to tree-pretty-print.h. (debug_gimple_stmt, debug_gimple_seq, print_gimple_seq, print_gimple_stmt, print_gimple_expr, dump_gimple_stmt): Move to gimple-pretty-print.h. * pretty-print.c: Don't include tree.h (pp_base_format): Don't handle %K here. (pp_base_tree_identifier): Move to tree-pretty-print.c. * pretty-print.h (text_info): Change abstract_origin to x_data. (pp_tree_identifier, pp_unsupported_tree, pp_base_tree_identifier): Move to tree-pretty-print.h. * gimple-pretty-print.h, tree-diagnostic.c, tree-diagnostic.h, tree-pretty-print.h: New files. * tree-pretty-print.c: Include tree-pretty-print.h. (percent_K_format): New. Moved from pretty-print.c. (pp_base_tree_identifier): Move from pretty-print.c. * c-objc-common.c: Include tree-pretty-print.h. (c_tree_printer): Handle %K here. * langhooks.c: Include tree-diagnostic.h. (lhd_print_error_function): Use diagnostic_abstract_origin macro. * toplev.c: Include tree-diagnostic.h and tree-pretty-print.h. (default_tree_printer): Handle %K using percent_K_format. (general_init): Use default_tree_diagnostic_starter. * tree.c: Include tree-diagnostic.h and tree-pretty-print.h. (free_lang_data): Use default_tree_diagnostic_starter. * c-pretty-print.c: Include tree-pretty-print.h. * cfgexpand.c: Include tree-pretty-print.h and gimple-pretty-print.h. * cgraphunit.c: Include tree-pretty-print.h and gimple-pretty-print.h. * dwarf2out.c: Include tree-pretty-print.h. * except.c: Include tree-pretty-print.h. * gimple-pretty-print.c: Include tree-pretty-print.h and gimple-pretty-print.h. * gimplify.c: Include tree-pretty-print.h. * graphite-poly.c: Include tree-pretty-print.h and gimple-pretty-print.h. * ipa-cp.c: Include tree-pretty-print.h. * ipa-inline.c: Include gimple-pretty-print.h. * ipa-prop.c: Include tree-pretty-print.h and gimple-pretty-print.h. * ipa-pure-const.c: Include gimple-pretty-print.h. * ipa-struct-reorg.c: Include tree-pretty-print.h and gimple-pretty-print.h. * ipa-type-escape.c: Include tree-pretty-print.h. * print-rtl.c: Include tree-pretty-print.h. * print-tree.c: Include gimple-pretty-print.h. * sese.c: Include tree-pretty-print.h. * tree-affine.c: Include tree-pretty-print.h. * tree-browser.c: Include tree-pretty-print.h. * tree-call-cdce.c: Include gimple-pretty-print.h. * tree-cfg.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-chrec.c: Include tree-pretty-print.h. * tree-data-ref.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-dfa.c: Include tree-pretty-print.h. * tree-if-conv.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-inline.c: Include tree-pretty-print.h. * tree-into-ssa.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-nrv.c: Include tree-pretty-print.h. * tree-object-size.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-outof-ssa.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-parloops.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-predcom.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-scalar-evolution.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-sra.c: Include tree-pretty-print.h. * tree-ssa-address.c: Include tree-pretty-print.h. * tree-ssa-alias.c: Include tree-pretty-print.h. * tree-ssa-ccp.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-coalesce.c: Include tree-pretty-print.h. * tree-ssa-copy.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-copyrename.c: Include tree-pretty-print.h. * tree-ssa-dce.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-dom.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-dse.c: Include gimple-pretty-print.h. * tree-ssa-forwprop.c: Include tree-pretty-print.h. * tree-ssa-ifcombine.c: Include tree-pretty-print.h. * tree-ssa-live.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-im.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-ivcanon.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-ivopts.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-niter.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-loop-prefetch.c: Include tree-pretty-print.h. * tree-ssa-math-opts.c: Include gimple-pretty-print.h. * tree-ssa-operands.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-phiprop.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-pre.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-propagate.c: Include gimple-pretty-print.h. * tree-ssa-reassoc.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-sccvn.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-sink.c: Include gimple-pretty-print.h. * tree-ssa-ter.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-ssa-uninit.c: Include gimple-pretty-print.h. * tree-ssa.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-stdarg.c: Include gimple-pretty-print.h. * tree-switch-conversion.c: Include gimple-pretty-print.h. * tree-tailcall.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-data-refs.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-loop-manip.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-loop.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-patterns.c: Include gimple-pretty-print.h. * tree-vect-slp.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vect-stmts.c: Include tree-pretty-print.h and gimple-pretty-print.h. * tree-vectorizer.c: Include tree-pretty-print.h. * tree-vrp.c: Include tree-pretty-print.h and gimple-pretty-print.h. * value-prof.c: Include tree-pretty-print.h and gimple-pretty-print.h. * var-tracking.c: Include tree-pretty-print.h. * Makefile.in (OBJS-common): Add tree-diagnostic.o. (tree-diagnostic.o): New dependencies. (c-objc-common.o, c-pretty-print.o, langhooks.o, tree.o, tree-inline.o, print-tree.o, stor-layout.o, tree-ssa-uninit.o, tree-ssa.o, tree-into-ssa.o, tree-ssa-ter.o, tree-ssa-coalesce.o, tree-outof-ssa.o, tree-ssa-forwprop.o, tree-ssa-phiprop.o, tree-ssa-ifcombine.o, tree-nrv.o, tree-ssa-copy.o, tree-ssa-propagate.o, tree-ssa-dom.o, tree-ssa-uncprop.o, tree-ssa-live.o, tree-ssa-copyrename.o, tree-ssa-pre.o, tree-ssa-sccvn.o, tree-vrp.o, tree-cfg.o, tree-tailcall.o, tree-ssa-sink.o, tree-if-conv.o, tree-dfa.o, tree-ssa-operands.o, tree-ssa-address.o, tree-ssa-loop-niter.o, tree-ssa-loop-ivcanon.o, tree-ssa-loop-prefetch.o, tree-predcom.o, tree-ssa-loop-ivopts.o, tree-affine.o, tree-ssa-loop-im.o, tree-ssa-math-opts.o, tree-ssa-alias.o, tree-ssa-reassoc.o, gimplify.o, tree-browser.o, tree-chrec.o, tree-scalar-evolution.o, tree-data-ref.o, sese.o, graphite-poly.o, tree-vect-loop.o, tree-vect-loop-manip.o, tree-vect-patterns.o, tree-vect-slp.o, tree-vect-stmts.o, tree-vect-data-refs.o, tree-vectorizer.o, tree-parloops.o, tree-stdarg.o, tree-object-size.o, gimple-pretty-print.o, tree-pretty-print.o, diagnostic.o, toplev.o, print-rtl.o, except.o, dwarf2out.o, cgraphunit.o, ipa-prop.o, ipa-cp.o, ipa-inline.o, ipa-pure-const.o, ipa-type-escape.o, ipa-struct-reorg.o, tree-ssa-dce.o, tree-call-cdce.o, tree-ssa-ccp.o, tree-sra.o, tree-switch-conversion.o, var-tracking.o, value-prof.o, cfgexpand.o, pretty-print.o): Update dependencies. cp: * error.c: Include tree-diagnostic.h and tree-pretty-print.h. (cp_print_error_function): Use diagnostic_abstract_origin macro. (cp_printer): Handle %K here using percent_K_format. * cxx-pretty-print.c: Include tree-pretty-print.h. * Make-lang.in (cp/error.o, cp/cxx-pretty-print.o): Update dependencies. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159685 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 9084954e5e6..adbdfd8fcc2 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1,5 +1,5 @@ /* If-conversion for vectorizer. - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Devang Patel @@ -90,6 +90,8 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "basic-block.h" #include "diagnostic.h" +#include "tree-pretty-print.h" +#include "gimple-pretty-print.h" #include "tree-flow.h" #include "tree-dump.h" #include "cfgloop.h" -- cgit v1.2.1 From d11c70fa87b29086fc127f15a4b8da865439919d Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 26 May 2010 16:45:47 +0000 Subject: Fix comments. 2010-05-26 Sebastian Pop * tree-if-conv.c: Update copyright years. Fix comments. Fix indentation. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159880 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index adbdfd8fcc2..127b5e36b59 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -589,11 +589,11 @@ if_convertible_loop_p (struct loop *loop) edge_iterator ei; basic_block exit_bb = NULL; - /* Handle only inner most loop. */ + /* Handle only innermost loop. */ if (!loop || loop->inner) { if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "not inner most loop\n"); + fprintf (dump_file, "not innermost loop\n"); return false; } @@ -631,7 +631,7 @@ if_convertible_loop_p (struct loop *loop) if (!ifc_bbs) { if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file,"Irreducible loop\n"); + fprintf (dump_file, "Irreducible loop\n"); free_dominance_info (CDI_POST_DOMINATORS); return false; } @@ -662,7 +662,7 @@ if_convertible_loop_p (struct loop *loop) } if (dump_file) - fprintf (dump_file,"Applying if-conversion\n"); + fprintf (dump_file, "Applying if-conversion\n"); free_dominance_info (CDI_POST_DOMINATORS); return true; @@ -1020,7 +1020,7 @@ tree_if_conversion (struct loop *loop) if (!if_convertible_loop_p (loop)) { if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file,"-------------------------\n"); + fprintf (dump_file, "-------------------------\n"); if (ifc_bbs) { free (ifc_bbs); -- cgit v1.2.1 From dd3354aa6d89f71b01b8ea6c95e59b8ec5511083 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 26 May 2010 16:45:56 +0000 Subject: Make tree_if_conversion not return a bool. 2010-05-26 Sebastian Pop * tree-if-conv.c (tree_if_conversion): Do not return a bool. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159881 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 127b5e36b59..ba3b7c6848a 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1004,10 +1004,10 @@ combine_blocks (struct loop *loop) merge_blocks (loop->header, exit_bb); } -/* Main entry point: return true when LOOP is if-converted, otherwise - the loop remains unchanged. */ +/* If-convert LOOP when it is legal. For the moment this pass has no + profitability analysis. */ -static bool +static void tree_if_conversion (struct loop *loop) { gimple_stmt_iterator itr; @@ -1027,7 +1027,7 @@ tree_if_conversion (struct loop *loop) ifc_bbs = NULL; } free_dominance_info (CDI_POST_DOMINATORS); - return false; + return; } for (i = 0; i < loop->num_nodes; i++) @@ -1071,8 +1071,6 @@ tree_if_conversion (struct loop *loop) clean_predicate_lists (loop); free (ifc_bbs); ifc_bbs = NULL; - - return true; } /* Tree if-conversion pass management. */ -- cgit v1.2.1 From cd40b2d311ead6ed28393516fc04711c5861fd80 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 26 May 2010 16:46:12 +0000 Subject: Do not compute/free CDI_POST_DOMINATORS. 2010-05-26 Sebastian Pop * tree-if-conv.c (if_convertible_loop_p): Do not compute/free CDI_POST_DOMINATORS. (tree_if_conversion): Same. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159882 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index ba3b7c6848a..23d71a044cf 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -624,7 +624,6 @@ if_convertible_loop_p (struct loop *loop) } calculate_dominance_info (CDI_DOMINATORS); - calculate_dominance_info (CDI_POST_DOMINATORS); /* Allow statements that can be handled during if-conversion. */ ifc_bbs = get_loop_body_in_if_conv_order (loop); @@ -632,7 +631,6 @@ if_convertible_loop_p (struct loop *loop) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Irreducible loop\n"); - free_dominance_info (CDI_POST_DOMINATORS); return false; } @@ -664,7 +662,6 @@ if_convertible_loop_p (struct loop *loop) if (dump_file) fprintf (dump_file, "Applying if-conversion\n"); - free_dominance_info (CDI_POST_DOMINATORS); return true; } @@ -1026,7 +1023,6 @@ tree_if_conversion (struct loop *loop) free (ifc_bbs); ifc_bbs = NULL; } - free_dominance_info (CDI_POST_DOMINATORS); return; } -- cgit v1.2.1 From fa6e55f9f5e5f21ac53fcac10bd69218b73961c7 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 26 May 2010 16:46:25 +0000 Subject: Avoid if-conversion of loops in which the data dependence analysis fails. 2010-05-26 Sebastian Pop * tree-if-conv.c (if_convertible_loop_p): Avoid if-conversion of loops in which the data dependence analysis fails. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159883 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 23d71a044cf..f5247a35ee7 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -623,6 +623,20 @@ if_convertible_loop_p (struct loop *loop) return false; } + /* Don't if-convert the loop when the data dependences cannot be + computed: the loop won't be vectorized in that case. */ + { + VEC (data_reference_p, heap) *refs = VEC_alloc (data_reference_p, heap, 5); + VEC (ddr_p, heap) *ddrs = VEC_alloc (ddr_p, heap, 25); + bool res = compute_data_dependences_for_loop (loop, true, &refs, &ddrs); + + free_data_refs (refs); + free_dependence_relations (ddrs); + + if (!res) + return false; + } + calculate_dominance_info (CDI_DOMINATORS); /* Allow statements that can be handled during if-conversion. */ -- cgit v1.2.1 From cedd9a279aaa2b3c54dc83f5ddce499a547c4631 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 26 May 2010 16:46:39 +0000 Subject: Don't handle BBs with more than 2 preds or succs. 2010-05-26 Sebastian Pop * tree-if-conv.c (if_convertible_bb_p): Don't handle BBs with more than 2 predecessors or more than 2 successors. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159884 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index f5247a35ee7..0c2e96fe71a 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -460,6 +460,10 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "----------[%d]-------------\n", bb->index); + if (EDGE_COUNT (bb->preds) > 2 + || EDGE_COUNT (bb->succs) > 2) + return false; + if (exit_bb) { if (bb != loop->latch) -- cgit v1.2.1 From 01c40c0ba32353e9954a265254ce3f67d91cb977 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 26 May 2010 16:46:49 +0000 Subject: Remove conditions in the code generation of if-conversion. 2010-05-26 Sebastian Pop * tree-if-conv.c (tree_if_convert_cond_stmt): Do not remove statements in the analysis part. (tree_if_convert_stmt): Update comment. (remove_conditions_and_labels): New. (combine_blocks): Call remove_conditions_and_labels. (tree_if_conversion): Update comment. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159885 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 66 +++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 0c2e96fe71a..60033e25fc6 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -207,7 +207,6 @@ bb_with_exit_edge_p (struct loop *loop, basic_block bb) } /* STMT is a GIMPLE_COND. Update two destination's predicate list. - Remove COND_EXPR, if it is not the exit condition of LOOP. Otherwise update the exit condition of LOOP appropriately. GSI points to the statement STMT. */ @@ -232,24 +231,12 @@ tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, /* If C is false, then FALSE_EDGE is taken. */ c2 = invert_truthvalue_loc (loc, unshare_expr (c)); add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi); - - /* Now this conditional statement is redundant. Remove it. But, do - not remove the exit condition! Update the exit condition using - the new condition. */ - if (!bb_with_exit_edge_p (loop, gimple_bb (stmt))) - { - gsi_remove (gsi, true); - cond = NULL_TREE; - } } /* If-convert stmt T which is part of LOOP. - If T is a GIMPLE_ASSIGN then it is converted into a conditional - modify expression using COND. For conditional expressions, add - a condition in the destination basic block's predicate list and - remove the conditional expression itself. GSI points to the - statement T. */ + For conditional expressions, add a condition in the destination + basic block's predicate list. GSI points to the statement T. */ static tree tree_if_convert_stmt (struct loop *loop, gimple t, tree cond, @@ -286,8 +273,6 @@ tree_if_convert_stmt (struct loop *loop, gimple t, tree cond, break; case GIMPLE_COND: - /* Update destination blocks' predicate list and remove this - condition expression. */ tree_if_convert_cond_stmt (loop, t, cond, gsi); cond = NULL_TREE; break; @@ -911,6 +896,32 @@ process_phi_nodes (struct loop *loop) } } +/* Remove all GIMPLE_CONDs and GIMPLE_LABELs of all the basic blocks + other than the exit and latch of the LOOP. */ + +static void +remove_conditions_and_labels (loop_p loop) +{ + gimple_stmt_iterator gsi; + unsigned int i; + + for (i = 0; i < loop->num_nodes; i++) + { + basic_block bb = ifc_bbs [i]; + + if (bb_with_exit_edge_p (loop, bb) + || bb == loop->latch) + continue; + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) + if (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND + || gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL) + gsi_remove (&gsi, true); + else + gsi_next (&gsi); + } +} + /* Combine all the basic blocks from LOOP into one or two super basic blocks. Replace PHI nodes with conditional modify expressions. */ @@ -923,6 +934,8 @@ combine_blocks (struct loop *loop) edge e; edge_iterator ei; + remove_conditions_and_labels (loop); + /* Process phi nodes to prepare blocks for merge. */ process_phi_nodes (loop); @@ -988,17 +1001,9 @@ combine_blocks (struct loop *loop) if (bb == exit_bb || bb == loop->latch) continue; - /* Remove labels and make stmts member of loop->header. */ - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) - { - if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL) - gsi_remove (&gsi, true); - else - { - gimple_set_bb (gsi_stmt (gsi), merge_target_bb); - gsi_next (&gsi); - } - } + /* Make stmts member of loop->header. */ + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + gimple_set_bb (gsi_stmt (gsi), merge_target_bb); /* Update stmt list. */ last = gsi_last_bb (merge_target_bb); @@ -1049,9 +1054,8 @@ tree_if_conversion (struct loop *loop) basic_block bb = ifc_bbs [i]; tree cond = (tree) bb->aux; - /* Process all the statements in this basic block. - Remove conditional expression, if any, and annotate - destination basic block(s) appropriately. */ + /* Predicate basic block(s) with the condition expressions + leading to their execution. */ for (itr = gsi_start_bb (bb); !gsi_end_p (itr); /* empty */) { gimple t = gsi_stmt (itr); -- cgit v1.2.1 From 60e0f7c43c3e98797fd79d7b706d7a68794507d3 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 26 May 2010 16:46:59 +0000 Subject: Reorganize the analysis of basic block predication. 2010-05-26 Sebastian Pop * tree-if-conv.c (add_to_dst_predicate_list): Do not pass a statemet iterator in parameter. Do not generate code during the analysis. (tree_if_convert_cond_stmt): Removed. (tree_if_convert_stmt): Removed. (predicate_bbs): New. (if_convertible_loop_p): Call predicate_bbs. (tree_if_conversion): Simplify the top-level logic as predicate_bbs now contains all the analysis part. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159886 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 313 +++++++++++++++++++++++++---------------------------- 1 file changed, 150 insertions(+), 163 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 60033e25fc6..da6b1cde27a 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -147,15 +147,13 @@ add_to_predicate_list (basic_block bb, tree new_cond) bb->aux = cond; } -/* Add the condition COND to the previous condition PREV_COND, and add this - to the predicate list of the destination of edge E. GSI is the - place where the gimplification of the resulting condition should - output code. LOOP is the loop to be if-converted. */ +/* Add the condition COND to the previous condition PREV_COND, and add + this to the predicate list of the destination of edge E. LOOP is + the loop to be if-converted. */ static tree add_to_dst_predicate_list (struct loop *loop, edge e, - tree prev_cond, tree cond, - gimple_stmt_iterator *gsi) + tree prev_cond, tree cond) { tree new_cond = NULL_TREE; @@ -166,25 +164,13 @@ add_to_dst_predicate_list (struct loop *loop, edge e, new_cond = unshare_expr (cond); else { - tree tmp; - gimple tmp_stmt = NULL; - - prev_cond = force_gimple_operand_gsi (gsi, unshare_expr (prev_cond), - true, NULL, true, GSI_SAME_STMT); - - cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), - true, NULL, true, GSI_SAME_STMT); - /* Add the condition COND to the e->aux field. In case the edge destination is a PHI node, this condition will be added to the block predicate to construct a complete condition. */ e->aux = cond; - tmp = build2 (TRUTH_AND_EXPR, boolean_type_node, - unshare_expr (prev_cond), cond); - tmp_stmt = ifc_temp_var (boolean_type_node, tmp); - gsi_insert_before (gsi, tmp_stmt, GSI_SAME_STMT); - new_cond = gimple_assign_lhs (tmp_stmt); + new_cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, + unshare_expr (prev_cond), cond); } add_to_predicate_list (e->dest, new_cond); @@ -206,84 +192,6 @@ bb_with_exit_edge_p (struct loop *loop, basic_block bb) return false; } -/* STMT is a GIMPLE_COND. Update two destination's predicate list. - Otherwise update the exit condition of LOOP appropriately. GSI - points to the statement STMT. */ - -static void -tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond, - gimple_stmt_iterator *gsi) -{ - tree c2; - edge true_edge, false_edge; - location_t loc = gimple_location (stmt); - tree c = fold_build2_loc (loc, gimple_cond_code (stmt), boolean_type_node, - gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); - - extract_true_false_edges_from_block (gimple_bb (stmt), - &true_edge, &false_edge); - - /* Add new condition into destination's predicate list. */ - - /* If C is true, then TRUE_EDGE is taken. */ - add_to_dst_predicate_list (loop, true_edge, cond, c, gsi); - - /* If C is false, then FALSE_EDGE is taken. */ - c2 = invert_truthvalue_loc (loc, unshare_expr (c)); - add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi); -} - -/* If-convert stmt T which is part of LOOP. - - For conditional expressions, add a condition in the destination - basic block's predicate list. GSI points to the statement T. */ - -static tree -tree_if_convert_stmt (struct loop *loop, gimple t, tree cond, - gimple_stmt_iterator *gsi) -{ - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "------if-convert stmt\n"); - print_gimple_stmt (dump_file, t, 0, TDF_SLIM); - print_generic_stmt (dump_file, cond, TDF_SLIM); - } - - switch (gimple_code (t)) - { - /* Labels are harmless here. */ - case GIMPLE_LABEL: - break; - - case GIMPLE_DEBUG: - /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */ - if (gimple_debug_bind_p (gsi_stmt (*gsi))) - { - gimple_debug_bind_reset_value (gsi_stmt (*gsi)); - update_stmt (gsi_stmt (*gsi)); - } - break; - - case GIMPLE_ASSIGN: - /* This GIMPLE_ASSIGN is killing previous value of LHS. Appropriate - value will be selected by PHI node based on condition. It is possible - that before this transformation, PHI nodes was selecting default - value and now it will use this new value. This is OK because it does - not change the validity of the program. */ - break; - - case GIMPLE_COND: - tree_if_convert_cond_stmt (loop, t, cond, gsi); - cond = NULL_TREE; - break; - - default: - gcc_unreachable (); - } - - return cond; -} - /* Return true when PHI is if-convertible. PHI is part of loop LOOP and it belongs to basic block BB. @@ -560,6 +468,126 @@ get_loop_body_in_if_conv_order (const struct loop *loop) return blocks; } +/* Returns true when the analysis of the predicates for all the basic + blocks in LOOP succeeded. + + predicate_bbs first clears the ->aux fields of the edges and basic + blocks. These fields are then initialized with the tree + expressions representing the predicates under which a basic block + is executed in the LOOP. As the loop->header is executed at each + iteration, it has the "true" predicate. Other statements executed + under a condition are predicated with that condition, for example + + | if (x) + | S1; + | else + | S2; + + S1 will be predicated with "x", and S2 will be predicated with + "!x". */ + +static bool +predicate_bbs (loop_p loop) +{ + unsigned int i; + + for (i = 0; i < loop->num_nodes; i++) + { + edge e; + edge_iterator ei; + basic_block bb = ifc_bbs [i]; + gimple_stmt_iterator itr = gsi_start_phis (bb); + + if (!gsi_end_p (itr)) + FOR_EACH_EDGE (e, ei, bb->preds) + e->aux = NULL; + + bb->aux = NULL; + } + + for (i = 0; i < loop->num_nodes; i++) + { + basic_block bb = ifc_bbs [i]; + tree cond = (tree) bb->aux; + gimple_stmt_iterator itr; + + for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr)) + { + gimple stmt = gsi_stmt (itr); + + switch (gimple_code (stmt)) + { + case GIMPLE_LABEL: + case GIMPLE_ASSIGN: + case GIMPLE_CALL: + break; + + case GIMPLE_DEBUG: + /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */ + if (gimple_debug_bind_p (gsi_stmt (itr))) + { + gimple_debug_bind_reset_value (gsi_stmt (itr)); + update_stmt (gsi_stmt (itr)); + } + break; + + case GIMPLE_COND: + { + tree c2; + edge true_edge, false_edge; + location_t loc = gimple_location (stmt); + tree c = fold_build2_loc (loc, gimple_cond_code (stmt), + boolean_type_node, + gimple_cond_lhs (stmt), + gimple_cond_rhs (stmt)); + + extract_true_false_edges_from_block (gimple_bb (stmt), + &true_edge, &false_edge); + + /* Add new condition into destination's predicate list. */ + + /* If C is true, then TRUE_EDGE is taken. */ + add_to_dst_predicate_list (loop, true_edge, cond, c); + + /* If C is false, then FALSE_EDGE is taken. */ + c2 = invert_truthvalue_loc (loc, unshare_expr (c)); + add_to_dst_predicate_list (loop, false_edge, cond, c2); + + cond = NULL_TREE; + break; + } + + case GIMPLE_SWITCH: + /* Not handled yet in if-conversion. */ + return false; + + default: + gcc_unreachable (); + } + } + + /* If current bb has only one successor, then consider it as an + unconditional goto. */ + if (single_succ_p (bb)) + { + basic_block bb_n = single_succ (bb); + + /* The successor bb inherits the predicate of its + predecessor. If there is no predicate in the predecessor + bb, then consider the successor bb as always executed. */ + if (cond == NULL_TREE) + cond = boolean_true_node; + + add_to_predicate_list (bb_n, cond); + } + } + + /* The loop header is always executed. */ + loop->header->aux = boolean_true_node; + + return true; +} + /* Return true when LOOP is if-convertible. LOOP is if-convertible if: - it is innermost, @@ -571,8 +599,6 @@ get_loop_body_in_if_conv_order (const struct loop *loop) static bool if_convertible_loop_p (struct loop *loop) { - basic_block bb; - gimple_stmt_iterator itr; unsigned int i; edge e; edge_iterator ei; @@ -639,27 +665,30 @@ if_convertible_loop_p (struct loop *loop) for (i = 0; i < loop->num_nodes; i++) { - bb = ifc_bbs[i]; + basic_block bb = ifc_bbs[i]; if (!if_convertible_bb_p (loop, bb, exit_bb)) return false; + if (bb_with_exit_edge_p (loop, bb)) + exit_bb = bb; + } + + if (!predicate_bbs (loop)) + return false; + + for (i = 0; i < loop->num_nodes; i++) + { + basic_block bb = ifc_bbs[i]; + gimple_stmt_iterator itr; + for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr)) if (!if_convertible_stmt_p (loop, bb, gsi_stmt (itr))) return false; - itr = gsi_start_phis (bb); - - if (!gsi_end_p (itr)) - FOR_EACH_EDGE (e, ei, bb->preds) - e->aux = NULL; - - for (; !gsi_end_p (itr); gsi_next (&itr)) + for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr)) if (!if_convertible_phi_p (loop, bb, gsi_stmt (itr))) return false; - - if (bb_with_exit_edge_p (loop, bb)) - exit_bb = bb; } if (dump_file) @@ -1030,65 +1059,23 @@ combine_blocks (struct loop *loop) static void tree_if_conversion (struct loop *loop) { - gimple_stmt_iterator itr; - unsigned int i; - ifc_bbs = NULL; - /* If-conversion is not appropriate for all loops. First, check if - the loop is if-convertible. */ if (!if_convertible_loop_p (loop)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "-------------------------\n"); - if (ifc_bbs) - { - free (ifc_bbs); - ifc_bbs = NULL; - } - return; - } - - for (i = 0; i < loop->num_nodes; i++) - { - basic_block bb = ifc_bbs [i]; - tree cond = (tree) bb->aux; - - /* Predicate basic block(s) with the condition expressions - leading to their execution. */ - for (itr = gsi_start_bb (bb); !gsi_end_p (itr); /* empty */) - { - gimple t = gsi_stmt (itr); - cond = tree_if_convert_stmt (loop, t, cond, &itr); - if (!gsi_end_p (itr)) - gsi_next (&itr); - } - - /* If current bb has only one successor, then consider it as an - unconditional goto. */ - if (single_succ_p (bb)) - { - basic_block bb_n = single_succ (bb); - - /* The successor bb inherits the predicate of its - predecessor. If there is no predicate in the predecessor - bb, then consider the successor bb as always executed. */ - if (cond == NULL_TREE) - cond = boolean_true_node; + goto cleanup; - add_to_predicate_list (bb_n, cond); - } - } - - /* Now, all statements are if-converted and basic blocks are - annotated appropriately. Combine all the basic blocks into one - huge basic block. */ + /* Now all statements are if-convertible. Combine all the basic + blocks into one huge basic block doing the if-conversion + on-the-fly. */ combine_blocks (loop); - /* clean up */ + cleanup: clean_predicate_lists (loop); - free (ifc_bbs); - ifc_bbs = NULL; + if (ifc_bbs) + { + free (ifc_bbs); + ifc_bbs = NULL; + } } /* Tree if-conversion pass management. */ -- cgit v1.2.1 From 12ec13dfcbd60f62bb1d2b157384107198f9a8d6 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 26 May 2010 16:47:08 +0000 Subject: Do not check the if-convertibility of statements that are not predicated. 2010-05-26 Sebastian Pop * tree-if-conv.c (if_convertible_gimple_assign_stmt_p): Do not special case loop->header. (is_predicated): New. (if_convertible_loop_p): Call it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159887 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index da6b1cde27a..8dc1de682be 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -274,9 +274,7 @@ if_convertible_gimple_assign_stmt_p (struct loop *loop, basic_block bb, return false; } - /* See if it needs speculative loading or not. */ - if (bb != loop->header - && gimple_assign_rhs_could_trap_p (stmt)) + if (gimple_assign_rhs_could_trap_p (stmt)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "tree could trap...\n"); @@ -588,6 +586,19 @@ predicate_bbs (loop_p loop) return true; } +/* Returns true when BB has a predicate that is not trivial: true or + NULL_TREE. */ + +static bool +is_predicated (basic_block bb) +{ + tree cond = (tree) bb->aux; + + return (cond != NULL_TREE + && cond != boolean_true_node + && !integer_onep (cond)); +} + /* Return true when LOOP is if-convertible. LOOP is if-convertible if: - it is innermost, @@ -682,6 +693,10 @@ if_convertible_loop_p (struct loop *loop) basic_block bb = ifc_bbs[i]; gimple_stmt_iterator itr; + /* For non predicated BBs, don't check their statements. */ + if (!is_predicated (bb)) + continue; + for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr)) if (!if_convertible_stmt_p (loop, bb, gsi_stmt (itr))) return false; -- cgit v1.2.1 From 7f6dfba24116c147149176350a08d74389e85de2 Mon Sep 17 00:00:00 2001 From: spop Date: Fri, 28 May 2010 18:38:06 +0000 Subject: Check the if-convertibility of phi nodes in non predicated BBs. 2010-05-28 Sebastian Pop PR middle-end/44293 * tree-if-conv.c (if_convertible_loop_p): Check the if-convertibility of phi nodes in non predicated BBs. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159990 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 8dc1de682be..c338ecbe6f0 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -693,6 +693,10 @@ if_convertible_loop_p (struct loop *loop) basic_block bb = ifc_bbs[i]; gimple_stmt_iterator itr; + for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr)) + if (!if_convertible_phi_p (loop, bb, gsi_stmt (itr))) + return false; + /* For non predicated BBs, don't check their statements. */ if (!is_predicated (bb)) continue; @@ -700,10 +704,6 @@ if_convertible_loop_p (struct loop *loop) for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr)) if (!if_convertible_stmt_p (loop, bb, gsi_stmt (itr))) return false; - - for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr)) - if (!if_convertible_phi_p (loop, bb, gsi_stmt (itr))) - return false; } if (dump_file) -- cgit v1.2.1 From 9fc1b63766a4be0cffd236a2c7ce7e4e2af5d8a7 Mon Sep 17 00:00:00 2001 From: spop Date: Fri, 28 May 2010 18:42:06 +0000 Subject: Don't generate COND_EXPRs for degenerate_phi_result. 2010-05-28 Sebastian Pop * tree-if-conv.c (replace_phi_with_cond_gimple_assign_stmt): Don't generate COND_EXPRs for degenerate_phi_result. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159991 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index c338ecbe6f0..2729bf3cf15 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -864,31 +864,37 @@ replace_phi_with_cond_gimple_assign_stmt (gimple phi, tree cond, gimple new_stmt; basic_block bb; tree rhs; - tree arg_0, arg_1; + tree arg; gcc_assert (gimple_code (phi) == GIMPLE_PHI && gimple_phi_num_args (phi) == 2); bb = gimple_bb (phi); - /* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */ - if (EDGE_PRED (bb, 1)->src == true_bb) - { - arg_0 = gimple_phi_arg_def (phi, 1); - arg_1 = gimple_phi_arg_def (phi, 0); - } + arg = degenerate_phi_result (phi); + if (arg) + rhs = arg; else { - arg_0 = gimple_phi_arg_def (phi, 0); - arg_1 = gimple_phi_arg_def (phi, 1); - } + tree arg_0, arg_1; + /* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */ + if (EDGE_PRED (bb, 1)->src == true_bb) + { + arg_0 = gimple_phi_arg_def (phi, 1); + arg_1 = gimple_phi_arg_def (phi, 0); + } + else + { + arg_0 = gimple_phi_arg_def (phi, 0); + arg_1 = gimple_phi_arg_def (phi, 1); + } - /* Build new RHS using selected condition and arguments. */ - rhs = build3 (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)), - unshare_expr (cond), unshare_expr (arg_0), - unshare_expr (arg_1)); + /* Build new RHS using selected condition and arguments. */ + rhs = build3 (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)), + unshare_expr (cond), arg_0, arg_1); + } - new_stmt = gimple_build_assign (unshare_expr (PHI_RESULT (phi)), rhs); + new_stmt = gimple_build_assign (PHI_RESULT (phi), rhs); SSA_NAME_DEF_STMT (gimple_phi_result (phi)) = new_stmt; gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); update_stmt (new_stmt); -- cgit v1.2.1 From c814c39ca0056e6c646aac87b829bb6e0a46a13e Mon Sep 17 00:00:00 2001 From: spop Date: Sat, 29 May 2010 17:14:17 +0000 Subject: Do not use annotations on edges in if-conversion. 2010-05-29 Sebastian Pop * tree-if-conv.c (add_to_dst_predicate_list): Do not use the ->aux field on edges. (predicate_bbs): Same. (clean_predicate_lists): Same. (find_phi_replacement_condition): Do not AND the predicate from edge->aux. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160030 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 70 ++++++++++++------------------------------------------ 1 file changed, 15 insertions(+), 55 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 2729bf3cf15..45ce388891d 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -163,15 +163,8 @@ add_to_dst_predicate_list (struct loop *loop, edge e, if (prev_cond == boolean_true_node || !prev_cond) new_cond = unshare_expr (cond); else - { - /* Add the condition COND to the e->aux field. In case the edge - destination is a PHI node, this condition will be added to - the block predicate to construct a complete condition. */ - e->aux = cond; - - new_cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, - unshare_expr (prev_cond), cond); - } + new_cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, + unshare_expr (prev_cond), cond); add_to_predicate_list (e->dest, new_cond); return new_cond; @@ -469,12 +462,12 @@ get_loop_body_in_if_conv_order (const struct loop *loop) /* Returns true when the analysis of the predicates for all the basic blocks in LOOP succeeded. - predicate_bbs first clears the ->aux fields of the edges and basic - blocks. These fields are then initialized with the tree - expressions representing the predicates under which a basic block - is executed in the LOOP. As the loop->header is executed at each - iteration, it has the "true" predicate. Other statements executed - under a condition are predicated with that condition, for example + predicate_bbs first clears the ->aux fields of the basic blocks. + These fields are then initialized with the tree expressions + representing the predicates under which a basic block is executed + in the LOOP. As the loop->header is executed at each iteration, it + has the "true" predicate. Other statements executed under a + condition are predicated with that condition, for example | if (x) | S1; @@ -490,18 +483,7 @@ predicate_bbs (loop_p loop) unsigned int i; for (i = 0; i < loop->num_nodes; i++) - { - edge e; - edge_iterator ei; - basic_block bb = ifc_bbs [i]; - gimple_stmt_iterator itr = gsi_start_phis (bb); - - if (!gsi_end_p (itr)) - FOR_EACH_EDGE (e, ei, bb->preds) - e->aux = NULL; - - bb->aux = NULL; - } + ifc_bbs[i]->aux = NULL; for (i = 0; i < loop->num_nodes; i++) { @@ -714,26 +696,18 @@ if_convertible_loop_p (struct loop *loop) /* During if-conversion, the bb->aux field is used to hold a predicate list. This function cleans for all the basic blocks in the given - LOOP their predicate list. It also cleans up the e->aux field of - all the successor edges: e->aux is used to hold the true and false - conditions for conditional expressions. */ + LOOP their predicate list. */ static void clean_predicate_lists (struct loop *loop) { - basic_block *bb; unsigned int i; - edge e; - edge_iterator ei; + basic_block *bbs = get_loop_body (loop); - bb = get_loop_body (loop); for (i = 0; i < loop->num_nodes; i++) - { - bb[i]->aux = NULL; - FOR_EACH_EDGE (e, ei, bb[i]->succs) - e->aux = NULL; - } - free (bb); + bbs[i]->aux = NULL; + + free (bbs); } /* Basic block BB has two predecessors. Using predecessor's bb->aux @@ -799,12 +773,6 @@ find_phi_replacement_condition (struct loop *loop, { *cond = (tree) (second_edge->src)->aux; - /* If there is a condition on an incoming edge, add it to the - incoming bb predicate. */ - if (second_edge->aux) - *cond = build2 (TRUTH_AND_EXPR, boolean_type_node, - *cond, (tree) second_edge->aux); - if (TREE_CODE (*cond) == TRUTH_NOT_EXPR) *cond = invert_truthvalue (*cond); else @@ -812,15 +780,7 @@ find_phi_replacement_condition (struct loop *loop, first_edge = second_edge; } else - { - *cond = (tree) (first_edge->src)->aux; - - /* If there is a condition on an incoming edge, add it to the - incoming bb predicate. */ - if (first_edge->aux) - *cond = build2 (TRUTH_AND_EXPR, boolean_type_node, - *cond, (tree) first_edge->aux); - } + *cond = (tree) (first_edge->src)->aux; /* Gimplify the condition: the vectorizer prefers to have gimple values as conditions. Various targets use different means to -- cgit v1.2.1 From 16d6ea49020b60c7a978b4dd4bd5fe53a695e31d Mon Sep 17 00:00:00 2001 From: spop Date: Sat, 29 May 2010 17:14:31 +0000 Subject: Don't use unshare_expr when not necessary. 2010-05-29 Sebastian Pop PR middle-end/44306 * gcc.dg/tree-ssa/pr44306.c: New. * tree-if-conv.c (is_true_predicate): New. (is_predicated): Use is_true_predicate. (add_to_predicate_list): Same. Do not use unshare_expr. (add_to_dst_predicate_list): Same. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160031 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 63 ++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 45ce388891d..268c171baa6 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -130,44 +130,54 @@ ifc_temp_var (tree type, tree exp) return stmt; } +/* Return true when COND is a true predicate. */ + +static inline bool +is_true_predicate (tree cond) +{ + return (cond == NULL_TREE + || cond == boolean_true_node + || integer_onep (cond)); +} + +/* Returns true when BB has a predicate that is not trivial: true or + NULL_TREE. */ + +static inline bool +is_predicated (basic_block bb) +{ + return !is_true_predicate ((tree) bb->aux); +} + /* Add condition NEW_COND to the predicate list of basic block BB. */ -static void +static inline void add_to_predicate_list (basic_block bb, tree new_cond) { tree cond = (tree) bb->aux; - if (cond) - cond = fold_build2_loc (EXPR_LOCATION (cond), - TRUTH_OR_EXPR, boolean_type_node, - unshare_expr (cond), new_cond); - else - cond = new_cond; - - bb->aux = cond; + bb->aux = is_true_predicate (cond) ? new_cond : + fold_build2_loc (EXPR_LOCATION (cond), + TRUTH_OR_EXPR, boolean_type_node, + cond, new_cond); } /* Add the condition COND to the previous condition PREV_COND, and add this to the predicate list of the destination of edge E. LOOP is the loop to be if-converted. */ -static tree +static void add_to_dst_predicate_list (struct loop *loop, edge e, tree prev_cond, tree cond) { - tree new_cond = NULL_TREE; - if (!flow_bb_inside_loop_p (loop, e->dest)) - return NULL_TREE; + return; - if (prev_cond == boolean_true_node || !prev_cond) - new_cond = unshare_expr (cond); - else - new_cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, - unshare_expr (prev_cond), cond); + if (!is_true_predicate (prev_cond)) + cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, + prev_cond, cond); - add_to_predicate_list (e->dest, new_cond); - return new_cond; + add_to_predicate_list (e->dest, cond); } /* Return true if one of the successor edges of BB exits LOOP. */ @@ -568,19 +578,6 @@ predicate_bbs (loop_p loop) return true; } -/* Returns true when BB has a predicate that is not trivial: true or - NULL_TREE. */ - -static bool -is_predicated (basic_block bb) -{ - tree cond = (tree) bb->aux; - - return (cond != NULL_TREE - && cond != boolean_true_node - && !integer_onep (cond)); -} - /* Return true when LOOP is if-convertible. LOOP is if-convertible if: - it is innermost, -- cgit v1.2.1 From 8e3cb73bc66100e137b20bcd98316bc415b6e53c Mon Sep 17 00:00:00 2001 From: steven Date: Tue, 1 Jun 2010 22:00:56 +0000 Subject: * gimplify.c: Do not include except.h and optabs.h. (gimplify_body): Do not initialize RTL profiling. * gimple-low.c: Do not include rtl.h, diagnostic.h, langhooks.h, langhooks-def.h, timevar.h, except.h, hashtab.h, and expr.h. * gimple-fold.c: Do not include rtl.h, tm_p.h, ggc.h, basic-block.h, output.h, expr.h, diagnostic.h, timevar.h, value-prof.h, and langhooks.h. * tree-pretty-print.h: Include pretty-print.h. * gimple-pretty-print.h: Include pretty-print.h. * tree-pretty-print.c: Do not include diagnostic.h. * tree-vrp.c: Likewise. * tree-tailcall.c: Likewise * tree-scalar-evolution.c: Likewise * tree-ssa-dse.c: Likewise * tree-chrec.c: Likewise * tree-ssa-sccvn.c: Likewise * tree-ssa-copyrename.c: Likewise * tree-nomudflap.c: Likewise * tree-call-cdce.c: Likewise * tree-stdarg.c: Likewise * tree-ssa-math-opts.c: Likewise * tree-nrv.c: Likewise * tree-ssa-sink.c: Likewise * tree-browser.c: Likewise * tree-ssa-loop-ivcanon.c: Likewise * tree-ssa-loop.c: Likewise * tree-parloops.c: Likewise * tree-ssa-address.c: Likewise * tree-ssa-ifcombine.c: Likewise * tree-if-conv.c: Likewise * tree-data-ref.c: Likewise * tree-affine.c: Likewise * tree-ssa-phiopt.c: Likewise * tree-ssa-coalesce.c: Likewise * tree-ssa-pre.c: Likewise * tree-ssa-live.c: Likewise * tree-predcom.c: Likewise * tree-ssa-forwprop.c: Likewise * tree-ssa-dce.c: Likewise * tree-ssa-ter.c: Likewise * tree-ssa-loop-prefetch.c: Likewise * tree-optimize.c: Likewise * tree-ssa-phiprop.c: Likewise * tree-object-size.c: Likewise * tree-outof-ssa.c: Likewise * tree-ssa-structalias.c: Likewise * tree-switch-conversion.c: Likewise * tree-ssa-reassoc.c: Likewise * tree-ssa-operands.c: Likewise * tree-vectorizer.c: Likewise * tree-vect-data-refs.c: Likewise * tree-vect-generic.c: Likewise * tree-vect-stmts.c: Likewise * tree-vect-patterns.c: Likewise * tree-vect-slp.c: Likewise * tree-vect-loop.c: Likewise * tree-ssa-loop-ivopts.c: Likewise * tree-ssa-loop-im.c: Likewise * tree-ssa-loop-niter.c: Likewise * tree-ssa-loop-unswitch.c: Likewise * tree-ssa-loop-manip.c: Likewise * tree-ssa-loop-ch.c: Likewise * tree-dump.c: Likewise * tree-complex.c: Likewise * tree-into-ssa.c: Do not include diagnostic.h and expr.h. * tree-ssa-uninit.c: Likewise * tree-ssa-threadupdate.c: Likewise * tree-ssa-uncprop.c: Likewise * tree-ssa-ccp.c: Likewise * tree-ssa-dom.c: Likewise * tree-ssa-propagate.c: Likewise * tree-ssa-alias.c: Likewise * tree-dfa.c: Likewise * tree-cfgcleanup.c: Likewise * tree-sra.c: Likewise * tree-ssa-copy.c: Likewise * tree-ssa.c: Likewise * tree-profile.c: Likewise * tree-cfg.c: Likewise * tree-ssa-threadedge.c: Likewise * tree-vect-loop-manip.c: Likewise * tree-inline.c: Do not include diagnostic.h and expr.h. Include rtl.h. (copy_decl_for_dup_finish): Do not use NULL_RTX. * tree-loop-linear.c: Do not include diagnostic.h, expr.h, and optabs.h. * tree-loop-distribution.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160125 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 1 - 1 file changed, 1 deletion(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 268c171baa6..f64623dae7d 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -89,7 +89,6 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "timevar.h" #include "basic-block.h" -#include "diagnostic.h" #include "tree-pretty-print.h" #include "gimple-pretty-print.h" #include "tree-flow.h" -- cgit v1.2.1 From 5f7a9884300c48797d4b913ac94f846e69017d59 Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 2 Jun 2010 16:39:26 +0000 Subject: Fix PR44363: don't abort when the ifcvt analysis fails to recognize a Gimple stmt. 2010-06-02 Sebastian Pop PR middle-end/44363 * tree-if-conv.c (predicate_bbs): Do not call gcc_unreachable, return false instead. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160163 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index f64623dae7d..f6e8c969dc1 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -483,8 +483,8 @@ get_loop_body_in_if_conv_order (const struct loop *loop) | else | S2; - S1 will be predicated with "x", and S2 will be predicated with - "!x". */ + S1 will be predicated with "x", and + S2 will be predicated with "!x". */ static bool predicate_bbs (loop_p loop) @@ -546,12 +546,9 @@ predicate_bbs (loop_p loop) break; } - case GIMPLE_SWITCH: + default: /* Not handled yet in if-conversion. */ return false; - - default: - gcc_unreachable (); } } -- cgit v1.2.1 From 0812914835fc52792631d284676a263031c04a4d Mon Sep 17 00:00:00 2001 From: spop Date: Wed, 2 Jun 2010 16:39:37 +0000 Subject: Only reset the GIMPLE_DEBUG information in the code gen of if-conversion. 2010-06-02 Sebastian Pop * tree-if-conv.c (predicate_bbs): Do not reset the GIMPLE_DEBUG information. (remove_conditions_and_labels): Reset the GIMPLE_DEBUG information. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160164 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index f6e8c969dc1..25cb9183739 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -509,15 +509,7 @@ predicate_bbs (loop_p loop) case GIMPLE_LABEL: case GIMPLE_ASSIGN: case GIMPLE_CALL: - break; - case GIMPLE_DEBUG: - /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */ - if (gimple_debug_bind_p (gsi_stmt (itr))) - { - gimple_debug_bind_reset_value (gsi_stmt (itr)); - update_stmt (gsi_stmt (itr)); - } break; case GIMPLE_COND: @@ -900,7 +892,8 @@ process_phi_nodes (struct loop *loop) } /* Remove all GIMPLE_CONDs and GIMPLE_LABELs of all the basic blocks - other than the exit and latch of the LOOP. */ + other than the exit and latch of the LOOP. Also resets the + GIMPLE_DEBUG information. */ static void remove_conditions_and_labels (loop_p loop) @@ -917,11 +910,26 @@ remove_conditions_and_labels (loop_p loop) continue; for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) - if (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND - || gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL) - gsi_remove (&gsi, true); - else - gsi_next (&gsi); + switch (gimple_code (gsi_stmt (gsi))) + { + case GIMPLE_COND: + case GIMPLE_LABEL: + gsi_remove (&gsi, true); + break; + + case GIMPLE_DEBUG: + /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */ + if (gimple_debug_bind_p (gsi_stmt (gsi))) + { + gimple_debug_bind_reset_value (gsi_stmt (gsi)); + update_stmt (gsi_stmt (gsi)); + } + gsi_next (&gsi); + break; + + default: + gsi_next (&gsi); + } } } -- cgit v1.2.1 From fa683b760a396a8b6c03304f009306eb48da1b70 Mon Sep 17 00:00:00 2001 From: spop Date: Fri, 11 Jun 2010 18:28:17 +0000 Subject: Fix PR44483: incrementally gimplify BB predicates to avoid redundant computations. 2010-06-11 Sebastian Pop PR middle-end/44483 * tree-if-conv.c (bb_predicate_s): New struct. (bb_predicate_p): New. (bb_has_predicate): New. (bb_predicate): New. (set_bb_predicate): New. (bb_predicate_gimplified_stmts): New. (set_bb_predicate_gimplified_stmts): New. (add_bb_predicate_gimplified_stmts): New. (init_bb_predicate): New. (free_bb_predicate): New. (is_predicated): Use bb_predicate. (add_to_predicate_list): Use bb_predicate and set_bb_predicate. (predicate_bbs): Same. Gimplify the condition of the basic blocks before processing their successors. (clean_predicate_lists): Removed. (find_phi_replacement_condition): Use bb_predicate. (process_phi_nodes): Renamed ifconvert_phi_nodes. Avoid useless computations. (insert_gimplified_predicates): New. (combine_blocks): Call insert_gimplified_predicates. (tree_if_conversion): Call free_bb_predicate instead of clean_predicate_lists. * gcc.dg/tree-ssa/pr44483.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160625 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 235 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 187 insertions(+), 48 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 25cb9183739..16864734a24 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -102,6 +102,106 @@ along with GCC; see the file COPYING3. If not see /* List of basic blocks in if-conversion-suitable order. */ static basic_block *ifc_bbs; +/* Structure used to predicate basic blocks. This is attached to the + ->aux field of the BBs in the loop to be if-converted. */ +typedef struct bb_predicate_s { + + /* The condition under which this basic block is executed. */ + tree predicate; + + /* PREDICATE is gimplified, and the sequence of statements is + recorded here, in order to avoid the duplication of computations + that occur in previous conditions. See PR44483. */ + gimple_seq predicate_gimplified_stmts; +} *bb_predicate_p; + +/* Returns true when the basic block BB has a predicate. */ + +static inline bool +bb_has_predicate (basic_block bb) +{ + return bb->aux != NULL; +} + +/* Returns the gimplified predicate for basic block BB. */ + +static inline tree +bb_predicate (basic_block bb) +{ + return ((bb_predicate_p) bb->aux)->predicate; +} + +/* Sets the gimplified predicate COND for basic block BB. */ + +static inline void +set_bb_predicate (basic_block bb, tree cond) +{ + ((bb_predicate_p) bb->aux)->predicate = cond; +} + +/* Returns the sequence of statements of the gimplification of the + predicate for basic block BB. */ + +static inline gimple_seq +bb_predicate_gimplified_stmts (basic_block bb) +{ + return ((bb_predicate_p) bb->aux)->predicate_gimplified_stmts; +} + +/* Sets the sequence of statements STMTS of the gimplification of the + predicate for basic block BB. */ + +static inline void +set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts) +{ + ((bb_predicate_p) bb->aux)->predicate_gimplified_stmts = stmts; +} + +/* Adds the sequence of statements STMTS to the sequence of statements + of the predicate for basic block BB. */ + +static inline void +add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts) +{ + gimple_seq_add_seq + (&(((bb_predicate_p) bb->aux)->predicate_gimplified_stmts), stmts); +} + +/* Initializes to TRUE the predicate of basic block BB. */ + +static inline void +init_bb_predicate (basic_block bb) +{ + bb->aux = XNEW (struct bb_predicate_s); + set_bb_predicate_gimplified_stmts (bb, NULL); + set_bb_predicate (bb, NULL_TREE); +} + +/* Free the predicate of basic block BB. */ + +static inline void +free_bb_predicate (basic_block bb) +{ + gimple_seq stmts; + + if (!bb_has_predicate (bb)) + return; + + /* Release the SSA_NAMEs created for the gimplification of the + predicate. */ + stmts = bb_predicate_gimplified_stmts (bb); + if (stmts) + { + gimple_stmt_iterator i; + + for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i)) + free_stmt_operands (gsi_stmt (i)); + } + + free (bb->aux); + bb->aux = NULL; +} + /* Create a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP to the new variable. */ @@ -145,7 +245,7 @@ is_true_predicate (tree cond) static inline bool is_predicated (basic_block bb) { - return !is_true_predicate ((tree) bb->aux); + return !is_true_predicate (bb_predicate (bb)); } /* Add condition NEW_COND to the predicate list of basic block BB. */ @@ -153,12 +253,12 @@ is_predicated (basic_block bb) static inline void add_to_predicate_list (basic_block bb, tree new_cond) { - tree cond = (tree) bb->aux; + tree cond = bb_predicate (bb); - bb->aux = is_true_predicate (cond) ? new_cond : - fold_build2_loc (EXPR_LOCATION (cond), - TRUTH_OR_EXPR, boolean_type_node, - cond, new_cond); + set_bb_predicate (bb, is_true_predicate (cond) ? new_cond : + fold_build2_loc (EXPR_LOCATION (cond), + TRUTH_OR_EXPR, boolean_type_node, + cond, new_cond)); } /* Add the condition COND to the previous condition PREV_COND, and add @@ -471,7 +571,7 @@ get_loop_body_in_if_conv_order (const struct loop *loop) /* Returns true when the analysis of the predicates for all the basic blocks in LOOP succeeded. - predicate_bbs first clears the ->aux fields of the basic blocks. + predicate_bbs first allocates the predicates of the basic blocks. These fields are then initialized with the tree expressions representing the predicates under which a basic block is executed in the LOOP. As the loop->header is executed at each iteration, it @@ -492,14 +592,33 @@ predicate_bbs (loop_p loop) unsigned int i; for (i = 0; i < loop->num_nodes; i++) - ifc_bbs[i]->aux = NULL; + init_bb_predicate (ifc_bbs[i]); for (i = 0; i < loop->num_nodes; i++) { - basic_block bb = ifc_bbs [i]; - tree cond = (tree) bb->aux; + basic_block bb = ifc_bbs[i]; + tree cond; gimple_stmt_iterator itr; + /* The loop latch is always executed and has no extra conditions + to be processed: skip it. */ + if (bb == loop->latch) + { + set_bb_predicate (loop->latch, boolean_true_node); + set_bb_predicate_gimplified_stmts (loop->latch, NULL); + continue; + } + + cond = bb_predicate (bb); + if (cond + && bb != loop->header) + { + gimple_seq stmts; + + cond = force_gimple_operand (cond, &stmts, true, NULL_TREE); + add_bb_predicate_gimplified_stmts (bb, stmts); + } + for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr)) { gimple stmt = gsi_stmt (itr); @@ -522,11 +641,10 @@ predicate_bbs (loop_p loop) gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); + /* Add new condition into destination's predicate list. */ extract_true_false_edges_from_block (gimple_bb (stmt), &true_edge, &false_edge); - /* Add new condition into destination's predicate list. */ - /* If C is true, then TRUE_EDGE is taken. */ add_to_dst_predicate_list (loop, true_edge, cond, c); @@ -561,7 +679,9 @@ predicate_bbs (loop_p loop) } /* The loop header is always executed. */ - loop->header->aux = boolean_true_node; + set_bb_predicate (loop->header, boolean_true_node); + gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL + && bb_predicate_gimplified_stmts (loop->latch) == NULL); return true; } @@ -679,27 +799,12 @@ if_convertible_loop_p (struct loop *loop) return true; } -/* During if-conversion, the bb->aux field is used to hold a predicate - list. This function cleans for all the basic blocks in the given - LOOP their predicate list. */ - -static void -clean_predicate_lists (struct loop *loop) -{ - unsigned int i; - basic_block *bbs = get_loop_body (loop); - - for (i = 0; i < loop->num_nodes; i++) - bbs[i]->aux = NULL; - - free (bbs); -} - -/* Basic block BB has two predecessors. Using predecessor's bb->aux - field, set appropriate condition COND for the PHI node replacement. - Return true block whose phi arguments are selected when cond is - true. LOOP is the loop containing the if-converted region, GSI is - the place to insert the code for the if-conversion. */ +/* Basic block BB has two predecessors. Using predecessor's bb + predicate, set an appropriate condition COND for the PHI node + replacement. Return the true block whose phi arguments are + selected when cond is true. LOOP is the loop containing the + if-converted region, GSI is the place to insert the code for the + if-conversion. */ static basic_block find_phi_replacement_condition (struct loop *loop, @@ -738,7 +843,7 @@ find_phi_replacement_condition (struct loop *loop, See PR23115. */ /* Select condition that is not TRUTH_NOT_EXPR. */ - tmp_cond = (tree) (first_edge->src)->aux; + tmp_cond = bb_predicate (first_edge->src); gcc_assert (tmp_cond); if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR) @@ -756,7 +861,7 @@ find_phi_replacement_condition (struct loop *loop, || dominated_by_p (CDI_DOMINATORS, second_edge->src, first_edge->src)) { - *cond = (tree) (second_edge->src)->aux; + *cond = bb_predicate (second_edge->src); if (TREE_CODE (*cond) == TRUTH_NOT_EXPR) *cond = invert_truthvalue (*cond); @@ -765,7 +870,7 @@ find_phi_replacement_condition (struct loop *loop, first_edge = second_edge; } else - *cond = (tree) (first_edge->src)->aux; + *cond = bb_predicate (first_edge->src); /* Gimplify the condition: the vectorizer prefers to have gimple values as conditions. Various targets use different means to @@ -851,11 +956,11 @@ replace_phi_with_cond_gimple_assign_stmt (gimple phi, tree cond, } } -/* Process phi nodes for the given LOOP. Replace phi nodes with - conditional modify expressions. */ +/* Replaces in LOOP all the phi nodes other than those in the + LOOP->header block with conditional modify expressions. */ static void -process_phi_nodes (struct loop *loop) +ifconvert_phi_nodes (struct loop *loop) { basic_block bb; unsigned int orig_loop_num_nodes = loop->num_nodes; @@ -873,12 +978,13 @@ process_phi_nodes (struct loop *loop) continue; phi_gsi = gsi_start_phis (bb); - gsi = gsi_after_labels (bb); + if (gsi_end_p (phi_gsi)) + continue; /* BB has two predecessors. Using predecessor's aux field, set appropriate condition for the PHI node replacement. */ - if (!gsi_end_p (phi_gsi)) - true_bb = find_phi_replacement_condition (loop, bb, &cond, &gsi); + gsi = gsi_after_labels (bb); + true_bb = find_phi_replacement_condition (loop, bb, &cond, &gsi); while (!gsi_end_p (phi_gsi)) { @@ -887,10 +993,40 @@ process_phi_nodes (struct loop *loop) release_phi_node (phi); gsi_next (&phi_gsi); } + set_phi_nodes (bb, NULL); } } +/* Insert in each basic block of LOOP the statements produced by the + gimplification of the predicates. */ + +static void +insert_gimplified_predicates (loop_p loop) +{ + unsigned int i; + + for (i = 0; i < loop->num_nodes; i++) + { + basic_block bb = ifc_bbs[i]; + gimple_seq stmts = bb_predicate_gimplified_stmts (bb); + + if (stmts) + { + gimple_stmt_iterator gsi = gsi_last_bb (bb); + + if (gsi_end_p (gsi) + || gimple_code (gsi_stmt (gsi)) == GIMPLE_COND) + gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT); + else + gsi_insert_seq_after (&gsi, stmts, GSI_SAME_STMT); + + /* Once the sequence is code generated, set it to NULL. */ + set_bb_predicate_gimplified_stmts (bb, NULL); + } + } +} + /* Remove all GIMPLE_CONDs and GIMPLE_LABELs of all the basic blocks other than the exit and latch of the LOOP. Also resets the GIMPLE_DEBUG information. */ @@ -903,7 +1039,7 @@ remove_conditions_and_labels (loop_p loop) for (i = 0; i < loop->num_nodes; i++) { - basic_block bb = ifc_bbs [i]; + basic_block bb = ifc_bbs[i]; if (bb_with_exit_edge_p (loop, bb) || bb == loop->latch) @@ -946,9 +1082,8 @@ combine_blocks (struct loop *loop) edge_iterator ei; remove_conditions_and_labels (loop); - - /* Process phi nodes to prepare blocks for merge. */ - process_phi_nodes (loop); + insert_gimplified_predicates (loop); + ifconvert_phi_nodes (loop); /* Merge basic blocks: first remove all the edges in the loop, except for those from the exit block. */ @@ -1052,9 +1187,13 @@ tree_if_conversion (struct loop *loop) combine_blocks (loop); cleanup: - clean_predicate_lists (loop); if (ifc_bbs) { + unsigned int i; + + for (i = 0; i < loop->num_nodes; i++) + free_bb_predicate (ifc_bbs[i]); + free (ifc_bbs); ifc_bbs = NULL; } -- cgit v1.2.1 From 4bd0f929cfa5fcd5b8fac9eebbf027809b70f656 Mon Sep 17 00:00:00 2001 From: spop Date: Fri, 25 Jun 2010 18:37:50 +0000 Subject: Add a debug counter for the tree-ssa level if-conversion. 2010-06-25 Sebastian Pop * Makefile.in (tree-if-conv.o): Depends on DBGCNT_H. * dbgcnt.def (if_conversion_tree): New DEBUG_COUNTER. * tree-if-conv.c: Include dbgcnt.h. (tree_if_conversion): Use if_conversion_tree to count the number of if-convertible loops. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161395 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 16864734a24..b7fe749c419 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -98,6 +98,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-data-ref.h" #include "tree-scalar-evolution.h" #include "tree-pass.h" +#include "dbgcnt.h" /* List of basic blocks in if-conversion-suitable order. */ static basic_block *ifc_bbs; @@ -1178,7 +1179,8 @@ tree_if_conversion (struct loop *loop) { ifc_bbs = NULL; - if (!if_convertible_loop_p (loop)) + if (!if_convertible_loop_p (loop) + || !dbg_cnt (if_conversion_tree)) goto cleanup; /* Now all statements are if-convertible. Combine all the basic -- cgit v1.2.1 From b519e9db13f7ccb059444df2395c0f3614c427e5 Mon Sep 17 00:00:00 2001 From: spop Date: Fri, 25 Jun 2010 18:38:04 +0000 Subject: Call cleanup_tree_cfg after if-conversion. 2010-06-25 Sebastian Pop * tree-if-conv.c (combine_blocks): Remove FIXME comment. (tree_if_conversion): Returns true when something has been changed. (main_tree_if_conversion): Return TODO_cleanup_cfg when if-conversion changed something. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161396 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index b7fe749c419..f200d480b59 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1162,9 +1162,7 @@ combine_blocks (struct loop *loop) /* If possible, merge loop header to the block with the exit edge. This reduces the number of basic blocks to two, to please the - vectorizer that handles only loops with two nodes. - - FIXME: Call cleanup_tree_cfg. */ + vectorizer that handles only loops with two nodes. */ if (exit_bb && exit_bb != loop->header && can_merge_blocks_p (loop->header, exit_bb)) @@ -1172,11 +1170,12 @@ combine_blocks (struct loop *loop) } /* If-convert LOOP when it is legal. For the moment this pass has no - profitability analysis. */ + profitability analysis. Returns true when something changed. */ -static void +static bool tree_if_conversion (struct loop *loop) { + bool changed = false; ifc_bbs = NULL; if (!if_convertible_loop_p (loop) @@ -1187,6 +1186,7 @@ tree_if_conversion (struct loop *loop) blocks into one huge basic block doing the if-conversion on-the-fly. */ combine_blocks (loop); + changed = true; cleanup: if (ifc_bbs) @@ -1199,6 +1199,8 @@ tree_if_conversion (struct loop *loop) free (ifc_bbs); ifc_bbs = NULL; } + + return changed; } /* Tree if-conversion pass management. */ @@ -1208,14 +1210,15 @@ main_tree_if_conversion (void) { loop_iterator li; struct loop *loop; + bool changed = false; if (number_of_loops () <= 1) return 0; FOR_EACH_LOOP (li, loop, 0) - tree_if_conversion (loop); + changed |= tree_if_conversion (loop); - return 0; + return changed ? TODO_cleanup_cfg : 0; } static bool -- cgit v1.2.1 From 48c9b1fe3b1a2ad5a4adbebb37640be8af8b1d0f Mon Sep 17 00:00:00 2001 From: spop Date: Fri, 25 Jun 2010 18:38:14 +0000 Subject: Use reset_bb_predicate whenever the predicate of a BB should be reset to true. 2010-06-25 Sebastian Pop * tree-if-conv.c (init_bb_predicate): Initialize the predicate to boolean_true_node. (reset_bb_predicate): New. (predicate_bbs): Call reset_bb_predicate. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161397 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index f200d480b59..80a53a807bb 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -175,7 +175,7 @@ init_bb_predicate (basic_block bb) { bb->aux = XNEW (struct bb_predicate_s); set_bb_predicate_gimplified_stmts (bb, NULL); - set_bb_predicate (bb, NULL_TREE); + set_bb_predicate (bb, boolean_true_node); } /* Free the predicate of basic block BB. */ @@ -203,6 +203,16 @@ free_bb_predicate (basic_block bb) bb->aux = NULL; } +/* Free the predicate of BB and reinitialize it with the true + predicate. */ + +static inline void +reset_bb_predicate (basic_block bb) +{ + free_bb_predicate (bb); + init_bb_predicate (bb); +} + /* Create a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP to the new variable. */ @@ -605,8 +615,7 @@ predicate_bbs (loop_p loop) to be processed: skip it. */ if (bb == loop->latch) { - set_bb_predicate (loop->latch, boolean_true_node); - set_bb_predicate_gimplified_stmts (loop->latch, NULL); + reset_bb_predicate (loop->latch); continue; } @@ -680,7 +689,7 @@ predicate_bbs (loop_p loop) } /* The loop header is always executed. */ - set_bb_predicate (loop->header, boolean_true_node); + reset_bb_predicate (loop->header); gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL && bb_predicate_gimplified_stmts (loop->latch) == NULL); -- cgit v1.2.1 From a560ff2b0ff9a04508e51c4119863006fc8203da Mon Sep 17 00:00:00 2001 From: spop Date: Fri, 25 Jun 2010 18:38:25 +0000 Subject: Do not insert statements computing the true predicate. 2010-06-25 Sebastian Pop * tree-if-conv.c (insert_gimplified_predicates): Do not insert statements computing the true predicate. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161398 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 80a53a807bb..8d5d2268ec5 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1021,6 +1021,15 @@ insert_gimplified_predicates (loop_p loop) basic_block bb = ifc_bbs[i]; gimple_seq stmts = bb_predicate_gimplified_stmts (bb); + if (!is_predicated (bb)) + { + /* Do not insert statements for a basic block that is not + predicated. Also make sure that the predicate of the + basic block is set to true. */ + reset_bb_predicate (bb); + continue; + } + if (stmts) { gimple_stmt_iterator gsi = gsi_last_bb (bb); -- cgit v1.2.1 From 0cb1935db968b200bd25627bdc7a630294007731 Mon Sep 17 00:00:00 2001 From: spop Date: Thu, 8 Jul 2010 16:37:49 +0000 Subject: Add the -ftree-loop-if-convert flag. 2010-07-08 Sebastian Pop * common.opt (ftree-loop-if-convert): New flag. * doc/invoke.texi (ftree-loop-if-convert): Documented. * tree-if-conv.c (gate_tree_if_conversion): Enable if-conversion when flag_tree_loop_if_convert is set. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161963 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 8d5d2268ec5..2dd8aa1edd3 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1239,10 +1239,13 @@ main_tree_if_conversion (void) return changed ? TODO_cleanup_cfg : 0; } +/* Returns true when the if-conversion pass is enabled. */ + static bool gate_tree_if_conversion (void) { - return flag_tree_vectorize != 0; + return ((flag_tree_vectorize && flag_tree_loop_if_convert != 0) + || flag_tree_loop_if_convert == 1); } struct gimple_opt_pass pass_if_conversion = -- cgit v1.2.1 From 74a43fe9018ceb9c32ad2b6fb1958bed53471994 Mon Sep 17 00:00:00 2001 From: spop Date: Thu, 8 Jul 2010 16:38:00 +0000 Subject: Call maybe_fold_or_comparisons to fold OR-ed predicates. 2010-07-08 Sebastian Pop PR tree-optimization/44710 * tree-if-conv.c (parse_predicate): New. (add_to_predicate_list): Call it, call maybe_fold_or_comparisons. Make sure that the predicates are either SSA_NAMEs or gimple_condexpr. * gcc.dg/tree-ssa/ifc-6.c: New. * gcc.dg/tree-ssa/ifc-pr44710.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161964 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 7 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 2dd8aa1edd3..7058ee4c274 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -259,17 +259,93 @@ is_predicated (basic_block bb) return !is_true_predicate (bb_predicate (bb)); } -/* Add condition NEW_COND to the predicate list of basic block BB. */ +/* Parses the predicate COND and returns its comparison code and + operands OP0 and OP1. */ + +static enum tree_code +parse_predicate (tree cond, tree *op0, tree *op1) +{ + gimple s; + + if (TREE_CODE (cond) == SSA_NAME + && is_gimple_assign (s = SSA_NAME_DEF_STMT (cond))) + { + if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison) + { + *op0 = gimple_assign_rhs1 (s); + *op1 = gimple_assign_rhs2 (s); + return gimple_assign_rhs_code (s); + } + + else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR) + { + tree op = gimple_assign_rhs1 (s); + tree type = TREE_TYPE (op); + enum tree_code code = parse_predicate (op, op0, op1); + + return code == ERROR_MARK ? ERROR_MARK + : invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (type))); + } + + return ERROR_MARK; + } + + if (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison) + { + *op0 = TREE_OPERAND (cond, 0); + *op1 = TREE_OPERAND (cond, 1); + return TREE_CODE (cond); + } + + return ERROR_MARK; +} + +/* Add condition NC to the predicate list of basic block BB. */ static inline void -add_to_predicate_list (basic_block bb, tree new_cond) +add_to_predicate_list (basic_block bb, tree nc) { - tree cond = bb_predicate (bb); + tree bc; + + if (is_true_predicate (nc)) + return; + + if (!is_predicated (bb)) + bc = nc; + else + { + enum tree_code code1, code2; + tree op1a, op1b, op2a, op2b; + + bc = bb_predicate (bb); + code1 = parse_predicate (bc, &op1a, &op1b); + code2 = parse_predicate (nc, &op2a, &op2b); + + if (code1 != ERROR_MARK && code2 != ERROR_MARK) + { + tree t = maybe_fold_or_comparisons (code1, op1a, op1b, + code2, op2a, op2b); + if (!t) + t = fold_build2_loc (EXPR_LOCATION (bc), TRUTH_OR_EXPR, + boolean_type_node, bc, nc); + bc = t; + } + else + bc = fold_build2_loc (EXPR_LOCATION (bc), TRUTH_OR_EXPR, + boolean_type_node, bc, nc); + } - set_bb_predicate (bb, is_true_predicate (cond) ? new_cond : - fold_build2_loc (EXPR_LOCATION (cond), - TRUTH_OR_EXPR, boolean_type_node, - cond, new_cond)); + if (!is_gimple_condexpr (bc)) + { + gimple_seq stmts; + bc = force_gimple_operand (bc, &stmts, true, NULL_TREE); + add_bb_predicate_gimplified_stmts (bb, stmts); + } + + if (is_true_predicate (bc)) + reset_bb_predicate (bb); + else + set_bb_predicate (bb, bc); } /* Add the condition COND to the previous condition PREV_COND, and add -- cgit v1.2.1 From 4be7307ce1e74282de71f3806026c59177aacc25 Mon Sep 17 00:00:00 2001 From: spop Date: Fri, 9 Jul 2010 18:58:20 +0000 Subject: Outline fold_or_predicates from add_to_predicate_list. 2010-07-09 Sebastian Pop * tree-if-conv.c (fold_or_predicates): New. (add_to_predicate_list): Call it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162007 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/tree-if-conv.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'gcc/tree-if-conv.c') diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 7058ee4c274..0f1caaa3dbc 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -300,6 +300,26 @@ parse_predicate (tree cond, tree *op0, tree *op1) return ERROR_MARK; } +/* Returns the fold of predicate C1 OR C2 at location LOC. */ + +static tree +fold_or_predicates (location_t loc, tree c1, tree c2) +{ + tree op1a, op1b, op2a, op2b; + enum tree_code code1 = parse_predicate (c1, &op1a, &op1b); + enum tree_code code2 = parse_predicate (c2, &op2a, &op2b); + + if (code1 != ERROR_MARK && code2 != ERROR_MARK) + { + tree t = maybe_fold_or_comparisons (code1, op1a, op1b, + code2, op2a, op2b); + if (t) + return t; + } + + return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2); +} + /* Add condition NC to the predicate list of basic block BB. */ static inline void @@ -314,25 +334,8 @@ add_to_predicate_list (basic_block bb, tree nc) bc = nc; else { - enum tree_code code1, code2; - tree op1a, op1b, op2a, op2b; - bc = bb_predicate (bb); - code1 = parse_predicate (bc, &op1a, &op1b); - code2 = parse_predicate (nc, &op2a, &op2b); - - if (code1 != ERROR_MARK && code2 != ERROR_MARK) - { - tree t = maybe_fold_or_comparisons (code1, op1a, op1b, - code2, op2a, op2b); - if (!t) - t = fold_build2_loc (EXPR_LOCATION (bc), TRUTH_OR_EXPR, - boolean_type_node, bc, nc); - bc = t; - } - else - bc = fold_build2_loc (EXPR_LOCATION (bc), TRUTH_OR_EXPR, - boolean_type_node, bc, nc); + bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc); } if (!is_gimple_condexpr (bc)) -- cgit v1.2.1