comparison gcc/except.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Implements exception handling. 1 /* Implements exception handling.
2 Copyright (C) 1989-2017 Free Software Foundation, Inc. 2 Copyright (C) 1989-2018 Free Software Foundation, Inc.
3 Contributed by Mike Stump <mrs@cygnus.com>. 3 Contributed by Mike Stump <mrs@cygnus.com>.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
945 945
946 /* A subroutine of dw2_build_landing_pads, also used for edge splitting 946 /* A subroutine of dw2_build_landing_pads, also used for edge splitting
947 at the rtl level. Emit the code required by the target at a landing 947 at the rtl level. Emit the code required by the target at a landing
948 pad for the given region. */ 948 pad for the given region. */
949 949
950 void 950 static void
951 expand_dw2_landing_pad_for_region (eh_region region) 951 expand_dw2_landing_pad_for_region (eh_region region)
952 { 952 {
953 if (targetm.have_exception_receiver ()) 953 if (targetm.have_exception_receiver ())
954 emit_insn (targetm.gen_exception_receiver ()); 954 emit_insn (targetm.gen_exception_receiver ());
955 else if (targetm.have_nonlocal_goto_receiver ()) 955 else if (targetm.have_nonlocal_goto_receiver ())
1001 seq = get_insns (); 1001 seq = get_insns ();
1002 end_sequence (); 1002 end_sequence ();
1003 1003
1004 bb = emit_to_new_bb_before (seq, label_rtx (lp->post_landing_pad)); 1004 bb = emit_to_new_bb_before (seq, label_rtx (lp->post_landing_pad));
1005 bb->count = bb->next_bb->count; 1005 bb->count = bb->next_bb->count;
1006 bb->frequency = bb->next_bb->frequency;
1007 make_single_succ_edge (bb, bb->next_bb, e_flags); 1006 make_single_succ_edge (bb, bb->next_bb, e_flags);
1008 if (current_loops) 1007 if (current_loops)
1009 { 1008 {
1010 struct loop *loop = bb->next_bb->loop_father; 1009 struct loop *loop = bb->next_bb->loop_father;
1011 /* If we created a pre-header block, add the new block to the 1010 /* If we created a pre-header block, add the new block to the
1509 /* Construct the landing pads. */ 1508 /* Construct the landing pads. */
1510 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) 1509 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
1511 sjlj_build_landing_pads (); 1510 sjlj_build_landing_pads ();
1512 else 1511 else
1513 dw2_build_landing_pads (); 1512 dw2_build_landing_pads ();
1513
1514 break_superblocks (); 1514 break_superblocks ();
1515
1516 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ
1517 /* Kludge for Alpha (see alpha_gp_save_rtx). */
1518 || single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->insns.r)
1519 commit_edge_insertions ();
1520 1515
1521 /* Redirect all EH edges from the post_landing_pad to the landing pad. */ 1516 /* Redirect all EH edges from the post_landing_pad to the landing pad. */
1522 FOR_EACH_BB_FN (bb, cfun) 1517 FOR_EACH_BB_FN (bb, cfun)
1523 { 1518 {
1524 eh_landing_pad lp; 1519 eh_landing_pad lp;
1545 e->flags |= (CALL_P (BB_END (bb)) 1540 e->flags |= (CALL_P (BB_END (bb))
1546 ? EDGE_ABNORMAL | EDGE_ABNORMAL_CALL 1541 ? EDGE_ABNORMAL | EDGE_ABNORMAL_CALL
1547 : EDGE_ABNORMAL); 1542 : EDGE_ABNORMAL);
1548 } 1543 }
1549 } 1544 }
1545
1546 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ
1547 /* Kludge for Alpha (see alpha_gp_save_rtx). */
1548 || single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->insns.r)
1549 commit_edge_insertions ();
1550 } 1550 }
1551 1551
1552 /* This section handles removing dead code for flow. */ 1552 /* This section handles removing dead code for flow. */
1553 1553
1554 void 1554 void
2464 } 2464 }
2465 2465
2466 static rtx_note * 2466 static rtx_note *
2467 emit_note_eh_region_end (rtx_insn *insn) 2467 emit_note_eh_region_end (rtx_insn *insn)
2468 { 2468 {
2469 rtx_insn *next = NEXT_INSN (insn);
2470
2471 /* Make sure we do not split a call and its corresponding
2472 CALL_ARG_LOCATION note. */
2473 if (next && NOTE_P (next)
2474 && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
2475 insn = next;
2476
2477 return emit_note_after (NOTE_INSN_EH_REGION_END, insn); 2469 return emit_note_after (NOTE_INSN_EH_REGION_END, insn);
2478 } 2470 }
2479 2471
2480 /* Add NOP after NOTE_INSN_SWITCH_TEXT_SECTIONS when the cold section starts 2472 /* Add NOP after NOTE_INSN_SWITCH_TEXT_SECTIONS when the cold section starts
2481 with landing pad. 2473 with landing pad.
2946 } 2938 }
2947 2939
2948 switch_to_section (s); 2940 switch_to_section (s);
2949 } 2941 }
2950 2942
2951
2952 /* Output a reference from an exception table to the type_info object TYPE. 2943 /* Output a reference from an exception table to the type_info object TYPE.
2953 TT_FORMAT and TT_FORMAT_SIZE describe the DWARF encoding method used for 2944 TT_FORMAT and TT_FORMAT_SIZE describe the DWARF encoding method used for
2954 the value. */ 2945 the value. */
2955 2946
2956 static void 2947 static void
2996 tt_format_size * BITS_PER_UNIT, 1); 2987 tt_format_size * BITS_PER_UNIT, 1);
2997 else 2988 else
2998 dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL); 2989 dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL);
2999 } 2990 }
3000 2991
2992 /* Output an exception table for the current function according to SECTION.
2993
2994 If the function has been partitioned into hot and cold parts, value 0 for
2995 SECTION refers to the table associated with the hot part while value 1
2996 refers to the table associated with the cold part. If the function has
2997 not been partitioned, value 0 refers to the single exception table. */
2998
3001 static void 2999 static void
3002 output_one_function_exception_table (int section) 3000 output_one_function_exception_table (int section)
3003 { 3001 {
3004 int tt_format, cs_format, lp_format, i; 3002 int tt_format, cs_format, lp_format, i;
3005 char ttype_label[32]; 3003 char ttype_label[32];
3174 dw2_asm_output_data (1, uc, 3172 dw2_asm_output_data (1, uc,
3175 i ? NULL : "Exception specification table"); 3173 i ? NULL : "Exception specification table");
3176 } 3174 }
3177 } 3175 }
3178 3176
3177 /* Output an exception table for the current function according to SECTION,
3178 switching back and forth from the function section appropriately.
3179
3180 If the function has been partitioned into hot and cold parts, value 0 for
3181 SECTION refers to the table associated with the hot part while value 1
3182 refers to the table associated with the cold part. If the function has
3183 not been partitioned, value 0 refers to the single exception table. */
3184
3179 void 3185 void
3180 output_function_exception_table (const char *fnname) 3186 output_function_exception_table (int section)
3181 { 3187 {
3188 const char *fnname = get_fnname_from_decl (current_function_decl);
3182 rtx personality = get_personality_function (current_function_decl); 3189 rtx personality = get_personality_function (current_function_decl);
3183 3190
3184 /* Not all functions need anything. */ 3191 /* Not all functions need anything. */
3185 if (! crtl->uses_eh_lsda) 3192 if (!crtl->uses_eh_lsda
3193 || targetm_common.except_unwind_info (&global_options) == UI_NONE)
3194 return;
3195
3196 /* No need to emit any boilerplate stuff for the cold part. */
3197 if (section == 1 && !crtl->eh.call_site_record_v[1])
3186 return; 3198 return;
3187 3199
3188 if (personality) 3200 if (personality)
3189 { 3201 {
3190 assemble_external_libcall (personality); 3202 assemble_external_libcall (personality);
3196 switch_to_exception_section (fnname); 3208 switch_to_exception_section (fnname);
3197 3209
3198 /* If the target wants a label to begin the table, emit it here. */ 3210 /* If the target wants a label to begin the table, emit it here. */
3199 targetm.asm_out.emit_except_table_label (asm_out_file); 3211 targetm.asm_out.emit_except_table_label (asm_out_file);
3200 3212
3201 output_one_function_exception_table (0); 3213 /* Do the real work. */
3202 if (crtl->eh.call_site_record_v[1]) 3214 output_one_function_exception_table (section);
3203 output_one_function_exception_table (1);
3204 3215
3205 switch_to_section (current_function_section ()); 3216 switch_to_section (current_function_section ());
3206 } 3217 }
3207 3218
3208 void 3219 void