summaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-03 07:15:51 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-09-03 07:15:51 +0000
commit43ee3f43c8355e623faca36246804e55a784b985 (patch)
treebe310b3c549e4a26b6cc910f7f7dc8dcbd09a174 /gcc/emit-rtl.c
parentc5f9099f3c8c8e7e3a89952504f01eec289117bd (diff)
downloadgcc-43ee3f43c8355e623faca36246804e55a784b985.tar.gz
2009-09-03 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 151367 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@151369 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r--gcc/emit-rtl.c391
1 files changed, 376 insertions, 15 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 21d8434d457..65022fc65e3 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "tree-pass.h"
#include "df.h"
+#include "params.h"
/* Commonly used modes. */
@@ -175,6 +176,7 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
#define first_insn (crtl->emit.x_first_insn)
#define last_insn (crtl->emit.x_last_insn)
#define cur_insn_uid (crtl->emit.x_cur_insn_uid)
+#define cur_debug_insn_uid (crtl->emit.x_cur_debug_insn_uid)
#define last_location (crtl->emit.x_last_location)
#define first_label_num (crtl->emit.x_first_label_num)
@@ -2268,8 +2270,31 @@ set_new_first_and_last_insn (rtx first, rtx last)
last_insn = last;
cur_insn_uid = 0;
- for (insn = first; insn; insn = NEXT_INSN (insn))
- cur_insn_uid = MAX (cur_insn_uid, INSN_UID (insn));
+ if (MIN_NONDEBUG_INSN_UID || MAY_HAVE_DEBUG_INSNS)
+ {
+ int debug_count = 0;
+
+ cur_insn_uid = MIN_NONDEBUG_INSN_UID - 1;
+ cur_debug_insn_uid = 0;
+
+ for (insn = first; insn; insn = NEXT_INSN (insn))
+ if (INSN_UID (insn) < MIN_NONDEBUG_INSN_UID)
+ cur_debug_insn_uid = MAX (cur_debug_insn_uid, INSN_UID (insn));
+ else
+ {
+ cur_insn_uid = MAX (cur_insn_uid, INSN_UID (insn));
+ if (DEBUG_INSN_P (insn))
+ debug_count++;
+ }
+
+ if (debug_count)
+ cur_debug_insn_uid = MIN_NONDEBUG_INSN_UID + debug_count;
+ else
+ cur_debug_insn_uid++;
+ }
+ else
+ for (insn = first; insn; insn = NEXT_INSN (insn))
+ cur_insn_uid = MAX (cur_insn_uid, INSN_UID (insn));
cur_insn_uid++;
}
@@ -2592,6 +2617,7 @@ repeat:
return;
break;
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -2698,6 +2724,7 @@ repeat:
case CC0:
return;
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -2768,6 +2795,7 @@ set_used_flags (rtx x)
case CC0:
return;
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -2947,6 +2975,27 @@ get_max_uid (void)
{
return cur_insn_uid;
}
+
+/* Return the number of actual (non-debug) insns emitted in this
+ function. */
+
+int
+get_max_insn_count (void)
+{
+ int n = cur_insn_uid;
+
+ /* The table size must be stable across -g, to avoid codegen
+ differences due to debug insns, and not be affected by
+ -fmin-insn-uid, to avoid excessive table size and to simplify
+ debugging of -fcompare-debug failures. */
+ if (cur_debug_insn_uid > MIN_NONDEBUG_INSN_UID)
+ n -= cur_debug_insn_uid;
+ else
+ n -= MIN_NONDEBUG_INSN_UID;
+
+ return n;
+}
+
/* Return the next insn. If it is a SEQUENCE, return the first insn
of the sequence. */
@@ -3033,6 +3082,57 @@ prev_nonnote_insn (rtx insn)
return insn;
}
+/* Return the previous insn before INSN that is not a NOTE, but stop
+ the search before we enter another basic block. This routine does
+ not look inside SEQUENCEs. */
+
+rtx
+prev_nonnote_insn_bb (rtx insn)
+{
+ while (insn)
+ {
+ insn = PREV_INSN (insn);
+ if (insn == 0 || !NOTE_P (insn))
+ break;
+ if (NOTE_INSN_BASIC_BLOCK_P (insn))
+ return NULL_RTX;
+ }
+
+ return insn;
+}
+
+/* Return the next insn after INSN that is not a DEBUG_INSN. This
+ routine does not look inside SEQUENCEs. */
+
+rtx
+next_nondebug_insn (rtx insn)
+{
+ while (insn)
+ {
+ insn = NEXT_INSN (insn);
+ if (insn == 0 || !DEBUG_INSN_P (insn))
+ break;
+ }
+
+ return insn;
+}
+
+/* Return the previous insn before INSN that is not a DEBUG_INSN.
+ This routine does not look inside SEQUENCEs. */
+
+rtx
+prev_nondebug_insn (rtx insn)
+{
+ while (insn)
+ {
+ insn = PREV_INSN (insn);
+ if (insn == 0 || !DEBUG_INSN_P (insn))
+ break;
+ }
+
+ return insn;
+}
+
/* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;
or 0, if there is none. This routine does not look inside
SEQUENCEs. */
@@ -3504,6 +3604,27 @@ make_insn_raw (rtx pattern)
return insn;
}
+/* Like `make_insn_raw' but make a DEBUG_INSN instead of an insn. */
+
+rtx
+make_debug_insn_raw (rtx pattern)
+{
+ rtx insn;
+
+ insn = rtx_alloc (DEBUG_INSN);
+ INSN_UID (insn) = cur_debug_insn_uid++;
+ if (cur_debug_insn_uid > MIN_NONDEBUG_INSN_UID)
+ INSN_UID (insn) = cur_insn_uid++;
+
+ PATTERN (insn) = pattern;
+ INSN_CODE (insn) = -1;
+ REG_NOTES (insn) = NULL;
+ INSN_LOCATOR (insn) = curr_insn_locator ();
+ BLOCK_FOR_INSN (insn) = NULL;
+
+ return insn;
+}
+
/* Like `make_insn_raw' but make a JUMP_INSN instead of an insn. */
rtx
@@ -3917,6 +4038,7 @@ emit_insn_before_noloc (rtx x, rtx before, basic_block bb)
switch (GET_CODE (x))
{
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -3960,6 +4082,7 @@ emit_jump_insn_before_noloc (rtx x, rtx before)
switch (GET_CODE (x))
{
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -4003,6 +4126,7 @@ emit_call_insn_before_noloc (rtx x, rtx before)
switch (GET_CODE (x))
{
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -4034,6 +4158,50 @@ emit_call_insn_before_noloc (rtx x, rtx before)
return last;
}
+/* Make an instruction with body X and code DEBUG_INSN
+ and output it before the instruction BEFORE. */
+
+rtx
+emit_debug_insn_before_noloc (rtx x, rtx before)
+{
+ rtx last = NULL_RTX, insn;
+
+ gcc_assert (before);
+
+ switch (GET_CODE (x))
+ {
+ case DEBUG_INSN:
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ insn = x;
+ while (insn)
+ {
+ rtx next = NEXT_INSN (insn);
+ add_insn_before (insn, before, NULL);
+ last = insn;
+ insn = next;
+ }
+ break;
+
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ gcc_unreachable ();
+ break;
+#endif
+
+ default:
+ last = make_debug_insn_raw (x);
+ add_insn_before (last, before, NULL);
+ break;
+ }
+
+ return last;
+}
+
/* Make an insn of code BARRIER
and output it before the insn BEFORE. */
@@ -4140,6 +4308,7 @@ emit_insn_after_noloc (rtx x, rtx after, basic_block bb)
switch (GET_CODE (x))
{
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -4177,6 +4346,7 @@ emit_jump_insn_after_noloc (rtx x, rtx after)
switch (GET_CODE (x))
{
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -4213,6 +4383,7 @@ emit_call_insn_after_noloc (rtx x, rtx after)
switch (GET_CODE (x))
{
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -4237,6 +4408,43 @@ emit_call_insn_after_noloc (rtx x, rtx after)
return last;
}
+/* Make an instruction with body X and code CALL_INSN
+ and output it after the instruction AFTER. */
+
+rtx
+emit_debug_insn_after_noloc (rtx x, rtx after)
+{
+ rtx last;
+
+ gcc_assert (after);
+
+ switch (GET_CODE (x))
+ {
+ case DEBUG_INSN:
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ last = emit_insn_after_1 (x, after, NULL);
+ break;
+
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ gcc_unreachable ();
+ break;
+#endif
+
+ default:
+ last = make_debug_insn_raw (x);
+ add_insn_after (last, after, NULL);
+ break;
+ }
+
+ return last;
+}
+
/* Make an insn of code BARRIER
and output it after the insn AFTER. */
@@ -4307,8 +4515,13 @@ emit_insn_after_setloc (rtx pattern, rtx after, int loc)
rtx
emit_insn_after (rtx pattern, rtx after)
{
- if (INSN_P (after))
- return emit_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
+ rtx prev = after;
+
+ while (DEBUG_INSN_P (prev))
+ prev = PREV_INSN (prev);
+
+ if (INSN_P (prev))
+ return emit_insn_after_setloc (pattern, after, INSN_LOCATOR (prev));
else
return emit_insn_after_noloc (pattern, after, NULL);
}
@@ -4338,8 +4551,13 @@ emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
rtx
emit_jump_insn_after (rtx pattern, rtx after)
{
- if (INSN_P (after))
- return emit_jump_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
+ rtx prev = after;
+
+ while (DEBUG_INSN_P (prev))
+ prev = PREV_INSN (prev);
+
+ if (INSN_P (prev))
+ return emit_jump_insn_after_setloc (pattern, after, INSN_LOCATOR (prev));
else
return emit_jump_insn_after_noloc (pattern, after);
}
@@ -4369,12 +4587,48 @@ emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
rtx
emit_call_insn_after (rtx pattern, rtx after)
{
- if (INSN_P (after))
- return emit_call_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
+ rtx prev = after;
+
+ while (DEBUG_INSN_P (prev))
+ prev = PREV_INSN (prev);
+
+ if (INSN_P (prev))
+ return emit_call_insn_after_setloc (pattern, after, INSN_LOCATOR (prev));
else
return emit_call_insn_after_noloc (pattern, after);
}
+/* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according to SCOPE. */
+rtx
+emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
+{
+ rtx last = emit_debug_insn_after_noloc (pattern, after);
+
+ if (pattern == NULL_RTX || !loc)
+ return last;
+
+ after = NEXT_INSN (after);
+ while (1)
+ {
+ if (active_insn_p (after) && !INSN_LOCATOR (after))
+ INSN_LOCATOR (after) = loc;
+ if (after == last)
+ break;
+ after = NEXT_INSN (after);
+ }
+ return last;
+}
+
+/* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according to AFTER. */
+rtx
+emit_debug_insn_after (rtx pattern, rtx after)
+{
+ if (INSN_P (after))
+ return emit_debug_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
+ else
+ return emit_debug_insn_after_noloc (pattern, after);
+}
+
/* Like emit_insn_before_noloc, but set INSN_LOCATOR according to SCOPE. */
rtx
emit_insn_before_setloc (rtx pattern, rtx before, int loc)
@@ -4404,8 +4658,13 @@ emit_insn_before_setloc (rtx pattern, rtx before, int loc)
rtx
emit_insn_before (rtx pattern, rtx before)
{
- if (INSN_P (before))
- return emit_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
+ rtx next = before;
+
+ while (DEBUG_INSN_P (next))
+ next = PREV_INSN (next);
+
+ if (INSN_P (next))
+ return emit_insn_before_setloc (pattern, before, INSN_LOCATOR (next));
else
return emit_insn_before_noloc (pattern, before, NULL);
}
@@ -4436,8 +4695,13 @@ emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
rtx
emit_jump_insn_before (rtx pattern, rtx before)
{
- if (INSN_P (before))
- return emit_jump_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
+ rtx next = before;
+
+ while (DEBUG_INSN_P (next))
+ next = PREV_INSN (next);
+
+ if (INSN_P (next))
+ return emit_jump_insn_before_setloc (pattern, before, INSN_LOCATOR (next));
else
return emit_jump_insn_before_noloc (pattern, before);
}
@@ -4469,11 +4733,49 @@ emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
rtx
emit_call_insn_before (rtx pattern, rtx before)
{
- if (INSN_P (before))
- return emit_call_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
+ rtx next = before;
+
+ while (DEBUG_INSN_P (next))
+ next = PREV_INSN (next);
+
+ if (INSN_P (next))
+ return emit_call_insn_before_setloc (pattern, before, INSN_LOCATOR (next));
else
return emit_call_insn_before_noloc (pattern, before);
}
+
+/* like emit_insn_before_noloc, but set insn_locator according to scope. */
+rtx
+emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
+{
+ rtx first = PREV_INSN (before);
+ rtx last = emit_debug_insn_before_noloc (pattern, before);
+
+ if (pattern == NULL_RTX)
+ return last;
+
+ first = NEXT_INSN (first);
+ while (1)
+ {
+ if (active_insn_p (first) && !INSN_LOCATOR (first))
+ INSN_LOCATOR (first) = loc;
+ if (first == last)
+ break;
+ first = NEXT_INSN (first);
+ }
+ return last;
+}
+
+/* like emit_debug_insn_before_noloc,
+ but set insn_locator according to before. */
+rtx
+emit_debug_insn_before (rtx pattern, rtx before)
+{
+ if (INSN_P (before))
+ return emit_debug_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
+ else
+ return emit_debug_insn_before_noloc (pattern, before);
+}
/* Take X and emit it at the end of the doubly-linked
INSN list.
@@ -4491,6 +4793,7 @@ emit_insn (rtx x)
switch (GET_CODE (x))
{
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -4522,6 +4825,52 @@ emit_insn (rtx x)
return last;
}
+/* Make an insn of code DEBUG_INSN with pattern X
+ and add it to the end of the doubly-linked list. */
+
+rtx
+emit_debug_insn (rtx x)
+{
+ rtx last = last_insn;
+ rtx insn;
+
+ if (x == NULL_RTX)
+ return last;
+
+ switch (GET_CODE (x))
+ {
+ case DEBUG_INSN:
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case CODE_LABEL:
+ case BARRIER:
+ case NOTE:
+ insn = x;
+ while (insn)
+ {
+ rtx next = NEXT_INSN (insn);
+ add_insn (insn);
+ last = insn;
+ insn = next;
+ }
+ break;
+
+#ifdef ENABLE_RTL_CHECKING
+ case SEQUENCE:
+ gcc_unreachable ();
+ break;
+#endif
+
+ default:
+ last = make_debug_insn_raw (x);
+ add_insn (last);
+ break;
+ }
+
+ return last;
+}
+
/* Make an insn of code JUMP_INSN with pattern X
and add it to the end of the doubly-linked list. */
@@ -4532,6 +4881,7 @@ emit_jump_insn (rtx x)
switch (GET_CODE (x))
{
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -4573,6 +4923,7 @@ emit_call_insn (rtx x)
switch (GET_CODE (x))
{
+ case DEBUG_INSN:
case INSN:
case JUMP_INSN:
case CALL_INSN:
@@ -4844,6 +5195,8 @@ emit (rtx x)
}
case CALL_INSN:
return emit_call_insn (x);
+ case DEBUG_INSN:
+ return emit_debug_insn (x);
default:
gcc_unreachable ();
}
@@ -5168,7 +5521,11 @@ init_emit (void)
{
first_insn = NULL;
last_insn = NULL;
- cur_insn_uid = 1;
+ if (MIN_NONDEBUG_INSN_UID)
+ cur_insn_uid = MIN_NONDEBUG_INSN_UID;
+ else
+ cur_insn_uid = 1;
+ cur_debug_insn_uid = 1;
reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
last_location = UNKNOWN_LOCATION;
first_label_num = label_num;
@@ -5625,6 +5982,10 @@ emit_copy_of_insn_after (rtx insn, rtx after)
new_rtx = emit_jump_insn_after (copy_insn (PATTERN (insn)), after);
break;
+ case DEBUG_INSN:
+ new_rtx = emit_debug_insn_after (copy_insn (PATTERN (insn)), after);
+ break;
+
case CALL_INSN:
new_rtx = emit_call_insn_after (copy_insn (PATTERN (insn)), after);
if (CALL_INSN_FUNCTION_USAGE (insn))