diff options
-rw-r--r-- | gcc/ChangeLog | 36 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 32 | ||||
-rw-r--r-- | gcc/except.c | 300 | ||||
-rw-r--r-- | gcc/function.h | 2 | ||||
-rw-r--r-- | gcc/opts.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-prof/partition1.C | 53 |
8 files changed, 377 insertions, 79 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 75129f68720..1a76d9acef6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,39 @@ +2009-08-07 Jakub Jelinek <jakub@redhat.com> + + * dwarf2out.c (output_fde): When doing hot/cold partitioning, use + fde->dw_fde_begin as begin label instead of hot/cold label. + Use LLSDAC label instead of LLSDA for second section lsda. + (dwarf2out_do_cfi_startproc): Add SECOND argument. Use LLSDAC + label instead of LLSDA if it is true. + (dwarf2out_begin_prologue, dwarf2out_switch_text_section): Adjust + callers. + * except.c (add_call_site, dw2_size_of_call_site_table): Add + SECTION argument. Use it as index into crtl->eh.call_site_record + array. + (dw2_output_call_site_table): Likewise. Add CS_FORMAT argument, + use it to determine how to print table entries instead of using + #ifdef HAVE_AS_LEB128. For SECTION > 0 use hot resp. cold + label instead of normal begin label as base. + (sjlj_assign_call_site_values): Adjust add_call_site caller. + (convert_to_eh_region_ranges): When doing hot/cold partitioning, + ensure no EH range spans between sections and that landing pads + are always in the corresponding section. + (sjlj_size_of_call_site_table, sjlj_output_call_site_table): Adjust + for crtl->eh.call_site_record being an array rather than scalar. + (output_one_function_exception_table): New function, copied + from output_function_exception_table. Adjust + dw2_size_of_call_site_table, dw2_output_call_site_table + callers. For SECOND section use *C suffixed labels. + (output_function_exception_table): Call + output_one_function_exception_table and, when doing hot/cold + partitioning, also another time for the second section. + * opts.c: Include except.h. + (decode_options): Allow -freorder-blocks-and-partition with + exceptions, unless SJLJ or TARGET_UNWIND_INFO. + * Makefile.in (opts.o): Depend on $(EXCEPT_H). + * function.h (struct rtl_eh): Change call_site_record from + scalar into array of 2 elements. + 2009-08-07 Martin Jambor <mjambor@suse.cz> * ipa-prop.c (count_formal_params_1): New function. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index dd52a037cb5..7951d29492f 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2595,7 +2595,7 @@ opts.o : opts.c opts.h options.h $(TOPLEV_H) $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(EXPR_H) $(RTL_H) \ output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ $(FLAGS_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H) debug.h varray.h \ - $(PLUGIN_H) + $(PLUGIN_H) $(EXCEPT_H) opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \ coretypes.h intl.h targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index fe7b72de7a0..af97bb0fee7 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -3429,15 +3429,22 @@ output_fde (dw_fde_ref fde, bool for_eh, bool second, begin = fde->dw_fde_begin; end = fde->dw_fde_end; } - else if (second ^ fde->dw_fde_switched_cold_to_hot) - { - begin = fde->dw_fde_unlikely_section_label; - end = fde->dw_fde_unlikely_section_end_label; - } else { - begin = fde->dw_fde_hot_section_label; - end = fde->dw_fde_hot_section_end_label; + /* For the first section, prefer dw_fde_begin over + dw_fde_{hot,cold}_section_label, as the latter + might be separated from the real start of the + function by alignment padding. */ + if (!second) + begin = fde->dw_fde_begin; + else if (fde->dw_fde_switched_cold_to_hot) + begin = fde->dw_fde_hot_section_label; + else + begin = fde->dw_fde_unlikely_section_label; + if (second ^ fde->dw_fde_switched_cold_to_hot) + end = fde->dw_fde_unlikely_section_end_label; + else + end = fde->dw_fde_hot_section_end_label; } if (for_eh) @@ -3477,7 +3484,8 @@ output_fde (dw_fde_ref fde, bool for_eh, bool second, if (fde->uses_eh_lsda) { - ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA", fde->funcdef_number); + ASM_GENERATE_INTERNAL_LABEL (l1, second ? "LLSDAC" : "LLSDA", + fde->funcdef_number); dw2_asm_output_encoded_addr_rtx (lsda_encoding, gen_rtx_SYMBOL_REF (Pmode, l1), false, @@ -3781,7 +3789,7 @@ output_call_frame_info (int for_eh) /* Emit .cfi_startproc and .cfi_personality/.cfi_lsda if needed. */ static void -dwarf2out_do_cfi_startproc (void) +dwarf2out_do_cfi_startproc (bool second) { int enc; rtx ref; @@ -3810,7 +3818,7 @@ dwarf2out_do_cfi_startproc (void) char lab[20]; enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0); - ASM_GENERATE_INTERNAL_LABEL (lab, "LLSDA", + ASM_GENERATE_INTERNAL_LABEL (lab, second ? "LLSDAC" : "LLSDA", current_function_funcdef_no); ref = gen_rtx_SYMBOL_REF (Pmode, lab); SYMBOL_REF_FLAGS (ref) = SYMBOL_FLAG_LOCAL; @@ -3929,7 +3937,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, #endif if (dwarf2out_do_cfi_asm ()) - dwarf2out_do_cfi_startproc (); + dwarf2out_do_cfi_startproc (false); } /* Output a marker (i.e. a label) for the absolute end of the generated code @@ -4038,7 +4046,7 @@ dwarf2out_switch_text_section (void) if (dwarf2out_do_cfi_asm ()) { - dwarf2out_do_cfi_startproc (); + dwarf2out_do_cfi_startproc (true); /* As this is a different FDE, insert all current CFI instructions again. */ output_cfis (fde->dw_fde_cfi, true, fde, true); diff --git a/gcc/except.c b/gcc/except.c index 06e5529dddc..d72029cf94f 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -169,7 +169,7 @@ static int action_record_eq (const void *, const void *); static hashval_t action_record_hash (const void *); static int add_action_record (htab_t, int, int); static int collect_one_action_chain (htab_t, struct eh_region_d *); -static int add_call_site (rtx, int); +static int add_call_site (rtx, int, int); static void push_uleb128 (varray_type *, unsigned int); static void push_sleb128 (varray_type *, int); @@ -177,7 +177,7 @@ static void push_sleb128 (varray_type *, int); static int dw2_size_of_call_site_table (void); static int sjlj_size_of_call_site_table (void); #endif -static void dw2_output_call_site_table (void); +static void dw2_output_call_site_table (int, int); static void sjlj_output_call_site_table (void); @@ -2337,7 +2337,8 @@ sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info) index = -1; /* Otherwise, look it up in the table. */ else - index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action); + index = add_call_site (GEN_INT (lp_info[i].dispatch_index), + action, 0); lp_info[i].call_site_index = index; } @@ -3784,7 +3785,7 @@ collect_one_action_chain (htab_t ar_hash, struct eh_region_d *region) } static int -add_call_site (rtx landing_pad, int action) +add_call_site (rtx landing_pad, int action, int section) { call_site_record record; @@ -3792,9 +3793,11 @@ add_call_site (rtx landing_pad, int action) record->landing_pad = landing_pad; record->action = action; - VEC_safe_push (call_site_record, gc, crtl->eh.call_site_record, record); + VEC_safe_push (call_site_record, gc, + crtl->eh.call_site_record[section], record); - return call_site_base + VEC_length (call_site_record, crtl->eh.call_site_record) - 1; + return call_site_base + VEC_length (call_site_record, + crtl->eh.call_site_record[section]) - 1; } /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes. @@ -3811,6 +3814,14 @@ convert_to_eh_region_ranges (void) rtx last_landing_pad = NULL_RTX; rtx first_no_action_insn = NULL_RTX; int call_site = 0; + int cur_sec = 0; + rtx section_switch_note = NULL_RTX; + rtx first_no_action_insn_before_switch = NULL_RTX; + rtx last_no_action_insn_before_switch = NULL_RTX; + rtx *pad_map = NULL; + sbitmap pad_loc = NULL; + int min_labelno = 0, max_labelno = 0; + int saved_call_site_base = call_site_base; if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL) return 0; @@ -3885,9 +3896,27 @@ convert_to_eh_region_ranges (void) if (last_action >= -1) { /* If we delayed the creation of the begin, do it now. */ + if (first_no_action_insn_before_switch) + { + call_site = add_call_site (NULL_RTX, 0, 0); + note + = emit_note_before (NOTE_INSN_EH_REGION_BEG, + first_no_action_insn_before_switch); + NOTE_EH_HANDLER (note) = call_site; + if (first_no_action_insn) + { + note + = emit_note_after (NOTE_INSN_EH_REGION_END, + last_no_action_insn_before_switch); + NOTE_EH_HANDLER (note) = call_site; + } + else + gcc_assert (last_action_insn + == last_no_action_insn_before_switch); + } if (first_no_action_insn) { - call_site = add_call_site (NULL_RTX, 0); + call_site = add_call_site (NULL_RTX, 0, cur_sec); note = emit_note_before (NOTE_INSN_EH_REGION_BEG, first_no_action_insn); NOTE_EH_HANDLER (note) = call_site; @@ -3904,7 +3933,8 @@ convert_to_eh_region_ranges (void) if (this_action >= -1) { call_site = add_call_site (this_landing_pad, - this_action < 0 ? 0 : this_action); + this_action < 0 ? 0 : this_action, + cur_sec); note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter); NOTE_EH_HANDLER (note) = call_site; } @@ -3914,6 +3944,37 @@ convert_to_eh_region_ranges (void) } last_action_insn = iter; } + else if (NOTE_P (iter) + && NOTE_KIND (iter) == NOTE_INSN_SWITCH_TEXT_SECTIONS) + { + gcc_assert (section_switch_note == NULL_RTX); + gcc_assert (flag_reorder_blocks_and_partition); + section_switch_note = iter; + if (first_no_action_insn) + { + first_no_action_insn_before_switch = first_no_action_insn; + last_no_action_insn_before_switch = last_action_insn; + first_no_action_insn = NULL_RTX; + gcc_assert (last_action == -1); + last_action = -3; + } + /* Force closing of current EH region before section switch and + opening a new one afterwards. */ + else if (last_action != -3) + last_landing_pad = pc_rtx; + call_site_base += VEC_length (call_site_record, + crtl->eh.call_site_record[cur_sec]); + cur_sec++; + gcc_assert (crtl->eh.call_site_record[cur_sec] == NULL); + crtl->eh.call_site_record[cur_sec] + = VEC_alloc (call_site_record, gc, 10); + max_labelno = max_label_num (); + min_labelno = get_first_label_num (); + pad_map = XCNEWVEC (rtx, max_labelno - min_labelno + 1); + pad_loc = sbitmap_alloc (max_labelno - min_labelno + 1); + } + else if (LABEL_P (iter) && pad_map) + SET_BIT (pad_loc, CODE_LABEL_NUMBER (iter) - min_labelno); if (last_action >= -1 && ! first_no_action_insn) { @@ -3921,6 +3982,105 @@ convert_to_eh_region_ranges (void) NOTE_EH_HANDLER (note) = call_site; } + call_site_base = saved_call_site_base; + + if (pad_map) + { + /* When doing hot/cold partitioning, ensure landing pads are + always in the same section as the EH region, .gcc_except_table + can't express it otherwise. */ + for (cur_sec = 0; cur_sec < 2; cur_sec++) + { + int i, idx; + int n = VEC_length (call_site_record, + crtl->eh.call_site_record[cur_sec]); + basic_block prev_bb = NULL, padbb; + + for (i = 0; i < n; ++i) + { + struct call_site_record_d *cs = + VEC_index (call_site_record, + crtl->eh.call_site_record[cur_sec], i); + rtx jump, note; + + if (cs->landing_pad == NULL_RTX) + continue; + idx = CODE_LABEL_NUMBER (cs->landing_pad) - min_labelno; + /* If the landing pad is in the correct section, nothing + is needed. */ + if (TEST_BIT (pad_loc, idx) ^ (cur_sec == 0)) + continue; + /* Otherwise, if we haven't seen this pad yet, we need to + add a new label and jump to the correct section. */ + if (pad_map[idx] == NULL_RTX) + { + pad_map[idx] = gen_label_rtx (); + if (prev_bb == NULL) + for (iter = section_switch_note; + iter; iter = PREV_INSN (iter)) + if (NOTE_INSN_BASIC_BLOCK_P (iter)) + { + prev_bb = NOTE_BASIC_BLOCK (iter); + break; + } + if (cur_sec == 0) + { + note = emit_label_before (pad_map[idx], + section_switch_note); + jump = emit_jump_insn_before (gen_jump (cs->landing_pad), + section_switch_note); + } + else + { + jump = emit_jump_insn_after (gen_jump (cs->landing_pad), + section_switch_note); + note = emit_label_after (pad_map[idx], + section_switch_note); + } + JUMP_LABEL (jump) = cs->landing_pad; + add_reg_note (jump, REG_CROSSING_JUMP, NULL_RTX); + iter = NEXT_INSN (cs->landing_pad); + if (iter && NOTE_INSN_BASIC_BLOCK_P (iter)) + padbb = NOTE_BASIC_BLOCK (iter); + else + padbb = NULL; + if (padbb && prev_bb + && BB_PARTITION (padbb) != BB_UNPARTITIONED) + { + basic_block bb; + int part + = BB_PARTITION (padbb) == BB_COLD_PARTITION + ? BB_HOT_PARTITION : BB_COLD_PARTITION; + edge_iterator ei; + edge e; + + bb = create_basic_block (note, jump, prev_bb); + make_single_succ_edge (bb, padbb, EDGE_CROSSING); + BB_SET_PARTITION (bb, part); + for (ei = ei_start (padbb->preds); + (e = ei_safe_edge (ei)); ) + { + if ((e->flags & (EDGE_EH|EDGE_CROSSING)) + == (EDGE_EH|EDGE_CROSSING)) + { + redirect_edge_succ (e, bb); + e->flags &= ~EDGE_CROSSING; + } + else + ei_next (&ei); + } + if (cur_sec == 0) + prev_bb = bb; + } + } + cs->landing_pad = pad_map[idx]; + } + } + + sbitmap_free (pad_loc); + XDELETEVEC (pad_map); + } + htab_delete (ar_hash); return 0; } @@ -3981,16 +4141,16 @@ push_sleb128 (varray_type *data_area, int value) #ifndef HAVE_AS_LEB128 static int -dw2_size_of_call_site_table (void) +dw2_size_of_call_site_table (int section) { - int n = VEC_length (call_site_record, crtl->eh.call_site_record); + int n = VEC_length (call_site_record, crtl->eh.call_site_record[section]); int size = n * (4 + 4 + 4); int i; for (i = 0; i < n; ++i) { struct call_site_record_d *cs = - VEC_index (call_site_record, crtl->eh.call_site_record, i); + VEC_index (call_site_record, crtl->eh.call_site_record[section], i); size += size_of_uleb128 (cs->action); } @@ -4000,14 +4160,14 @@ dw2_size_of_call_site_table (void) static int sjlj_size_of_call_site_table (void) { - int n = VEC_length (call_site_record, crtl->eh.call_site_record); + int n = VEC_length (call_site_record, crtl->eh.call_site_record[0]); int size = 0; int i; for (i = 0; i < n; ++i) { struct call_site_record_d *cs = - VEC_index (call_site_record, crtl->eh.call_site_record, i); + VEC_index (call_site_record, crtl->eh.call_site_record[0], i); size += size_of_uleb128 (INTVAL (cs->landing_pad)); size += size_of_uleb128 (cs->action); } @@ -4017,15 +4177,23 @@ sjlj_size_of_call_site_table (void) #endif static void -dw2_output_call_site_table (void) +dw2_output_call_site_table (int cs_format, int section) { - int n = VEC_length (call_site_record, crtl->eh.call_site_record); + int n = VEC_length (call_site_record, crtl->eh.call_site_record[section]); int i; + const char *begin; + + if (section == 0) + begin = current_function_func_begin_label; + else if (first_function_block_is_cold) + begin = crtl->subsections.hot_section_label; + else + begin = crtl->subsections.cold_section_label; for (i = 0; i < n; ++i) { struct call_site_record_d *cs = - VEC_index (call_site_record, crtl->eh.call_site_record, i); + VEC_index (call_site_record, crtl->eh.call_site_record[section], i); char reg_start_lab[32]; char reg_end_lab[32]; char landing_pad_lab[32]; @@ -4041,30 +4209,29 @@ dw2_output_call_site_table (void) generic arithmetic. */ /* ??? Perhaps use attr_length to choose data1 or data2 instead of data4 if the function is small enough. */ -#ifdef HAVE_AS_LEB128 - dw2_asm_output_delta_uleb128 (reg_start_lab, - current_function_func_begin_label, - "region %d start", i); - dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab, - "length"); - if (cs->landing_pad) - dw2_asm_output_delta_uleb128 (landing_pad_lab, - current_function_func_begin_label, - "landing pad"); - else - dw2_asm_output_data_uleb128 (0, "landing pad"); -#else - dw2_asm_output_delta (4, reg_start_lab, - current_function_func_begin_label, - "region %d start", i); - dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length"); - if (cs->landing_pad) - dw2_asm_output_delta (4, landing_pad_lab, - current_function_func_begin_label, - "landing pad"); + if (cs_format == DW_EH_PE_uleb128) + { + dw2_asm_output_delta_uleb128 (reg_start_lab, begin, + "region %d start", i); + dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab, + "length"); + if (cs->landing_pad) + dw2_asm_output_delta_uleb128 (landing_pad_lab, begin, + "landing pad"); + else + dw2_asm_output_data_uleb128 (0, "landing pad"); + } else - dw2_asm_output_data (4, 0, "landing pad"); -#endif + { + dw2_asm_output_delta (4, reg_start_lab, begin, + "region %d start", i); + dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length"); + if (cs->landing_pad) + dw2_asm_output_delta (4, landing_pad_lab, begin, + "landing pad"); + else + dw2_asm_output_data (4, 0, "landing pad"); + } dw2_asm_output_data_uleb128 (cs->action, "action"); } @@ -4074,13 +4241,13 @@ dw2_output_call_site_table (void) static void sjlj_output_call_site_table (void) { - int n = VEC_length (call_site_record, crtl->eh.call_site_record); + int n = VEC_length (call_site_record, crtl->eh.call_site_record[0]); int i; for (i = 0; i < n; ++i) { struct call_site_record_d *cs = - VEC_index (call_site_record, crtl->eh.call_site_record, i); + VEC_index (call_site_record, crtl->eh.call_site_record[0], i); dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad), "region %d landing pad", i); @@ -4192,8 +4359,9 @@ output_ttype (tree type, int tt_format, int tt_format_size) dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL); } -void -output_function_exception_table (const char * ARG_UNUSED (fnname)) +static void +output_one_function_exception_table (const char * ARG_UNUSED (fnname), + int section) { int tt_format, cs_format, lp_format, i, n; #ifdef HAVE_AS_LEB128 @@ -4206,13 +4374,6 @@ output_function_exception_table (const char * ARG_UNUSED (fnname)) int have_tt_data; int tt_format_size = 0; - /* Not all functions need anything. */ - if (! crtl->uses_eh_lsda) - return; - - if (eh_personality_libfunc) - assemble_external_libcall (eh_personality_libfunc); - #ifdef TARGET_UNWIND_INFO /* TODO: Move this into target file. */ fputs ("\t.personality\t", asm_out_file); @@ -4237,7 +4398,8 @@ output_function_exception_table (const char * ARG_UNUSED (fnname)) { tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1); #ifdef HAVE_AS_LEB128 - ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT", + ASM_GENERATE_INTERNAL_LABEL (ttype_label, + section ? "LLSDATTC" : "LLSDATT", current_function_funcdef_no); #endif tt_format_size = size_of_encoded_value (tt_format); @@ -4245,8 +4407,8 @@ output_function_exception_table (const char * ARG_UNUSED (fnname)) assemble_align (tt_format_size * BITS_PER_UNIT); } - targetm.asm_out.internal_label (asm_out_file, "LLSDA", - current_function_funcdef_no); + targetm.asm_out.internal_label (asm_out_file, section ? "LLSDAC" : "LLSDA", + current_function_funcdef_no); /* The LSDA header. */ @@ -4269,7 +4431,7 @@ output_function_exception_table (const char * ARG_UNUSED (fnname)) if (USING_SJLJ_EXCEPTIONS) call_site_len = sjlj_size_of_call_site_table (); else - call_site_len = dw2_size_of_call_site_table (); + call_site_len = dw2_size_of_call_site_table (section); #endif /* A pc-relative 4-byte displacement to the @TType data. */ @@ -4277,7 +4439,8 @@ output_function_exception_table (const char * ARG_UNUSED (fnname)) { #ifdef HAVE_AS_LEB128 char ttype_after_disp_label[32]; - ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD", + ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, + section ? "LLSDATTDC" : "LLSDATTD", current_function_funcdef_no); dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label, "@TType base offset"); @@ -4323,9 +4486,11 @@ output_function_exception_table (const char * ARG_UNUSED (fnname)) eh_data_format_name (cs_format)); #ifdef HAVE_AS_LEB128 - ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB", + ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, + section ? "LLSDACSBC" : "LLSDACSB", current_function_funcdef_no); - ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE", + ASM_GENERATE_INTERNAL_LABEL (cs_end_label, + section ? "LLSDACSEC" : "LLSDACSE", current_function_funcdef_no); dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label, "Call-site table length"); @@ -4333,14 +4498,14 @@ output_function_exception_table (const char * ARG_UNUSED (fnname)) if (USING_SJLJ_EXCEPTIONS) sjlj_output_call_site_table (); else - dw2_output_call_site_table (); + dw2_output_call_site_table (cs_format, section); ASM_OUTPUT_LABEL (asm_out_file, cs_end_label); #else - dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length"); + dw2_asm_output_data_uleb128 (call_site_len, "Call-site table length"); if (USING_SJLJ_EXCEPTIONS) sjlj_output_call_site_table (); else - dw2_output_call_site_table (); + dw2_output_call_site_table (cs_format, section); #endif /* ??? Decode and interpret the data for flag_debug_asm. */ @@ -4377,6 +4542,21 @@ output_function_exception_table (const char * ARG_UNUSED (fnname)) dw2_asm_output_data (1, VARRAY_UCHAR (crtl->eh.ehspec_data, i), (i ? NULL : "Exception specification table")); } +} + +void +output_function_exception_table (const char * ARG_UNUSED (fnname)) +{ + /* Not all functions need anything. */ + if (! crtl->uses_eh_lsda) + return; + + if (eh_personality_libfunc) + assemble_external_libcall (eh_personality_libfunc); + + output_one_function_exception_table (fnname, 0); + if (crtl->eh.call_site_record[1] != NULL) + output_one_function_exception_table (fnname, 1); switch_to_section (current_function_section ()); } diff --git a/gcc/function.h b/gcc/function.h index 8f69429d150..ac3a1749549 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -156,7 +156,7 @@ struct GTY(()) rtl_eh { varray_type ehspec_data; varray_type action_record_data; - VEC(call_site_record,gc) *call_site_record; + VEC(call_site_record,gc) *call_site_record[2]; }; #define pending_stack_adjust (crtl->expr.x_pending_stack_adjust) diff --git a/gcc/opts.c b/gcc/opts.c index 33635dd979d..59c24b67db1 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "dbgcnt.h" #include "debug.h" #include "plugin.h" +#include "except.h" /* Value of the -G xx switch, and whether it was passed or not. */ unsigned HOST_WIDE_INT g_switch_value; @@ -1036,10 +1037,15 @@ decode_options (unsigned int argc, const char **argv) generating unwind info. If flag_exceptions is turned on we need to turn off the partitioning optimization. */ - if (flag_exceptions && flag_reorder_blocks_and_partition) + if (flag_exceptions && flag_reorder_blocks_and_partition + && (USING_SJLJ_EXCEPTIONS +#ifdef TARGET_UNWIND_INFO + || 1 +#endif + )) { inform (input_location, - "-freorder-blocks-and-partition does not work with exceptions"); + "-freorder-blocks-and-partition does not work with exceptions on this architecture"); flag_reorder_blocks_and_partition = 0; flag_reorder_blocks = 1; } @@ -1048,9 +1054,15 @@ decode_options (unsigned int argc, const char **argv) optimization. */ if (flag_unwind_tables && ! targetm.unwind_tables_default - && flag_reorder_blocks_and_partition) + && flag_reorder_blocks_and_partition + && (USING_SJLJ_EXCEPTIONS +#ifdef TARGET_UNWIND_INFO + || 1 +#endif + )) { - inform (input_location, "-freorder-blocks-and-partition does not support unwind info"); + inform (input_location, + "-freorder-blocks-and-partition does not support unwind info on this architecture"); flag_reorder_blocks_and_partition = 0; flag_reorder_blocks = 1; } @@ -1061,7 +1073,12 @@ decode_options (unsigned int argc, const char **argv) if (flag_reorder_blocks_and_partition && (!targetm.have_named_sections - || (flag_unwind_tables && targetm.unwind_tables_default))) + || (flag_unwind_tables && targetm.unwind_tables_default + && (USING_SJLJ_EXCEPTIONS +#ifdef TARGET_UNWIND_INFO + || 1 +#endif + )))) { inform (input_location, "-freorder-blocks-and-partition does not work on this architecture"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0dc1b9dc543..4d3f9b0077a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-08-07 Jakub Jelinek <jakub@redhat.com> + + * g++.dg/tree-prof/partition1.C: New test. + 2009-08-06 Richard Earnshaw <rearnsha@arm.com> * gcc.target/arm/abitest.h: Allow the test function to have a PCS diff --git a/gcc/testsuite/g++.dg/tree-prof/partition1.C b/gcc/testsuite/g++.dg/tree-prof/partition1.C new file mode 100644 index 00000000000..d0dcbc4524b --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-prof/partition1.C @@ -0,0 +1,53 @@ +/* { dg-require-effective-target freorder } */ +/* { dg-options "-O2 -freorder-blocks-and-partition" } */ + +struct A { A () __attribute__((noinline)); ~A () __attribute__((noinline)); }; +A::A () { asm volatile ("" : : : "memory"); } +A::~A () { asm volatile ("" : : : "memory"); } + +int bar () __attribute__((noinline)); +void foo () __attribute__((noinline)); + +volatile int k, l; + +int bar (int i) +{ + void *p = __builtin_alloca (i); + asm volatile ("" : : "r" (i), "r" (p) : "memory"); + if (k) throw 6; + return ++l; +} + +void foo () +{ + A a; + try { + A b; + int i = bar (5); + try { throw 6; } catch (int) {} + if (__builtin_expect (i < 4500, 0)) { + bar (7); + try { bar (8); } catch (long) {} + bar (10); + if (__builtin_expect (i < 0, 0)) { + try { bar (12); } catch (...) {} + bar (16); + bar (122); + } else { + try { bar (bar (7)); } catch (int) {} + } + } else { + try { bar (bar (bar (9))); } catch (...) {} + bar (5); + } + } catch (...) { + } +} + +int +main () +{ + int i; + for (i = 0; i < 10000; i++) + foo (); +} |