CALL_INSNs and LIBCALLs
Richard Kenner
kenner@vlsi1.ultra.nyu.edu
Fri Apr 14 15:06:00 GMT 2000
Some CALL_INSNs end a basic block, but they must not do so if they are
in a LIBCALL. This fixes that.
Fri Apr 14 18:07:30 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* flow.c (count_basic_blocks): Remove unused var PREV_CALL.
Never have a LIBCALL end a basic block.
(find_basic_blocks_1): Likewise.
Reorganize CALL_INSN cases.
*** flow.c 2000/04/12 01:38:15 1.251
--- flow.c 2000/04/14 17:01:38
*************** count_basic_blocks (f)
*** 463,467 ****
int eh_region = 0;
int call_had_abnormal_edge = 0;
! rtx prev_call = NULL_RTX;
prev_code = JUMP_INSN;
--- 463,467 ----
int eh_region = 0;
int call_had_abnormal_edge = 0;
! int in_libcall = 0;
prev_code = JUMP_INSN;
*************** count_basic_blocks (f)
*** 474,481 ****
&& (prev_code == JUMP_INSN
|| prev_code == BARRIER
! || (prev_code == CALL_INSN && call_had_abnormal_edge))))
! {
! count++;
! }
/* Record whether this call created an edge. */
--- 474,487 ----
&& (prev_code == JUMP_INSN
|| prev_code == BARRIER
! || (prev_code == CALL_INSN
! && call_had_abnormal_edge && in_libcall == 0))))
! count++;
!
! /* Track whether or not we are in a LIBCALL block. These must
! all be within the same basic block. */
! if (find_reg_note (insn, REG_LIBCALL, NULL_RTX) != 0)
! in_libcall++;
! else if (find_reg_note (insn, REG_RETVAL, NULL_RTX) != 0)
! in_libcall--;
/* Record whether this call created an edge. */
*************** count_basic_blocks (f)
*** 484,488 ****
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
int region = (note ? INTVAL (XEXP (note, 0)) : 1);
! prev_call = insn;
call_had_abnormal_edge = 0;
--- 490,494 ----
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
int region = (note ? INTVAL (XEXP (note, 0)) : 1);
!
call_had_abnormal_edge = 0;
*************** count_basic_blocks (f)
*** 491,505 ****
|| find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
call_had_abnormal_edge = 1;
! else
! {
! /* If there is a nonlocal goto label and the specified
! region number isn't -1, we have an edge. (0 means
! no throw, but might have a nonlocal goto). */
! if (nonlocal_goto_handler_labels && region >= 0)
! call_had_abnormal_edge = 1;
! }
}
- else if (code != NOTE)
- prev_call = NULL_RTX;
if (code != NOTE)
--- 497,506 ----
|| find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
call_had_abnormal_edge = 1;
! else if (nonlocal_goto_handler_labels && region >= 0)
! /* If there is a nonlocal goto label and the specified
! region number isn't -1, we have an edge. (0 means
! no throw, but might have a nonlocal goto). */
! call_had_abnormal_edge = 1;
}
if (code != NOTE)
*************** count_basic_blocks (f)
*** 509,513 ****
else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
--eh_region;
-
}
--- 510,513 ----
*************** find_basic_blocks_1 (f)
*** 533,537 ****
{
register rtx insn, next;
- int call_has_abnormal_edge = 0;
int i = 0;
rtx bb_note = NULL_RTX;
--- 533,536 ----
*************** find_basic_blocks_1 (f)
*** 540,543 ****
--- 539,543 ----
rtx head = NULL_RTX;
rtx end = NULL_RTX;
+ int in_libcall = 0;
/* We process the instructions in a slightly different way than we did
*************** find_basic_blocks_1 (f)
*** 553,577 ****
next = NEXT_INSN (insn);
- if (code == CALL_INSN)
- {
- /* Record whether this call created an edge. */
- rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- int region = (note ? INTVAL (XEXP (note, 0)) : 1);
- call_has_abnormal_edge = 0;
-
- /* If there is an EH region or rethrow, we have an edge. */
- if ((eh_list && region > 0)
- || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
- call_has_abnormal_edge = 1;
- else
- {
- /* If there is a nonlocal goto label and the specified
- region number isn't -1, we have an edge. (0 means
- no throw, but might have a nonlocal goto). */
- if (nonlocal_goto_handler_labels && region >= 0)
- call_has_abnormal_edge = 1;
- }
- }
-
switch (code)
{
--- 553,556 ----
*************** find_basic_blocks_1 (f)
*** 586,589 ****
--- 565,569 ----
{
rtx t = eh_list;
+
eh_list = XEXP (eh_list, 1);
free_INSN_LIST_node (t);
*************** find_basic_blocks_1 (f)
*** 598,604 ****
if (bb_note == NULL_RTX)
bb_note = insn;
next = flow_delete_insn (insn);
}
-
break;
}
--- 578,584 ----
if (bb_note == NULL_RTX)
bb_note = insn;
+
next = flow_delete_insn (insn);
}
break;
}
*************** find_basic_blocks_1 (f)
*** 614,619 ****
everything can be updated. So continue to emit a noop at
the end of such a block. */
! if (GET_CODE (end) == CALL_INSN
! && ! SIBLING_CALL_P (end))
{
rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
--- 594,598 ----
everything can be updated. So continue to emit a noop at
the end of such a block. */
! if (GET_CODE (end) == CALL_INSN && ! SIBLING_CALL_P (end))
{
rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
*************** find_basic_blocks_1 (f)
*** 624,627 ****
--- 603,607 ----
bb_note = NULL_RTX;
}
+
head = end = insn;
break;
*************** find_basic_blocks_1 (f)
*** 667,672 ****
be updated. So continue to emit a noop at the end of such a
block. */
! if (GET_CODE (end) == CALL_INSN
! && ! SIBLING_CALL_P (end))
{
rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
--- 647,651 ----
be updated. So continue to emit a noop at the end of such a
block. */
! if (GET_CODE (end) == CALL_INSN && ! SIBLING_CALL_P (end))
{
rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
*************** find_basic_blocks_1 (f)
*** 676,693 ****
case CALL_INSN:
! /* A basic block ends at a call that can either throw or
! do a non-local goto. */
! if (call_has_abnormal_edge)
! {
! new_bb_inclusive:
! if (head == NULL_RTX)
! head = insn;
! end = insn;
! new_bb_exclusive:
! create_basic_block (i++, head, end, bb_note);
! head = end = NULL_RTX;
! bb_note = NULL_RTX;
! break;
}
/* FALLTHRU */
--- 655,690 ----
case CALL_INSN:
! {
! /* Record whether this call created an edge. */
! rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
! int region = (note ? INTVAL (XEXP (note, 0)) : 1);
! int call_has_abnormal_edge = 0;
!
! /* If there is an EH region or rethrow, we have an edge. */
! if ((eh_list && region > 0)
! || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
! call_has_abnormal_edge = 1;
! else if (nonlocal_goto_handler_labels && region >= 0)
! /* If there is a nonlocal goto label and the specified
! region number isn't -1, we have an edge. (0 means
! no throw, but might have a nonlocal goto). */
! call_has_abnormal_edge = 1;
! /* A basic block ends at a call that can either throw or
! do a non-local goto. LIBCALLs must reside totally in one
! basic block, so don't end a block after them. */
! if (call_has_abnormal_edge && in_libcall == 0)
! {
! new_bb_inclusive:
! if (head == NULL_RTX)
! head = insn;
! end = insn;
!
! new_bb_exclusive:
! create_basic_block (i++, head, end, bb_note);
! head = end = NULL_RTX;
! bb_note = NULL_RTX;
! break;
! }
}
/* FALLTHRU */
*************** find_basic_blocks_1 (f)
*** 717,735 ****
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
! if (REG_NOTE_KIND (note) == REG_LABEL)
! {
! rtx lab = XEXP (note, 0), next;
! if (lab == eh_return_stub_label)
! ;
! else if ((next = next_nonnote_insn (lab)) != NULL
! && GET_CODE (next) == JUMP_INSN
! && (GET_CODE (PATTERN (next)) == ADDR_VEC
! || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
! ;
! else
! label_value_list
! = alloc_EXPR_LIST (0, XEXP (note, 0), label_value_list);
! }
}
}
--- 714,738 ----
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
! {
! if (REG_NOTE_KIND (note) == REG_LABEL)
! {
! rtx lab = XEXP (note, 0), next;
! if (lab == eh_return_stub_label)
! ;
! else if ((next = next_nonnote_insn (lab)) != NULL
! && GET_CODE (next) == JUMP_INSN
! && (GET_CODE (PATTERN (next)) == ADDR_VEC
! || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
! ;
! else
! label_value_list
! = alloc_EXPR_LIST (0, XEXP (note, 0), label_value_list);
! }
! else if (REG_NOTE_KIND (note) == REG_LIBCALL)
! in_libcall++;
! else if (REG_NOTE_KIND (note) == REG_RETVAL)
! in_libcall--;
! }
}
}
More information about the Gcc-patches
mailing list