summaryrefslogtreecommitdiff
path: root/gcc/profile.c
diff options
context:
space:
mode:
authorwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>1998-04-23 19:10:52 +0000
committerwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>1998-04-23 19:10:52 +0000
commitc3b641a26b32ca0831b6c55ae4954fcaa2e29265 (patch)
treec7752a4e5b4c384f8e7906d09434bc29071647e9 /gcc/profile.c
parent45590189f09127f6243b340e6feb5a84299a6142 (diff)
downloadgcc-c3b641a26b32ca0831b6c55ae4954fcaa2e29265.tar.gz
Fix gcov mips switch table interaction bug reported to bug-gcc.
* profile.c (tablejump_entry_p): New function. (branch_prob): Add code to recognize MIPS tablejump entry branch. Use tablejump_entry_p in MIPS and HPPA tablejump checking code. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@19388 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/profile.c')
-rw-r--r--gcc/profile.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/gcc/profile.c b/gcc/profile.c
index bec6ca36d6a..8b6fff5be98 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -413,6 +413,25 @@ output_gcov_string (string, delimiter)
__write_long (delimiter, bb_file, 4);
}
+/* Return TRUE if this insn must be a tablejump entry insn. This works for
+ the MIPS port, but may give false negatives for some targets. */
+
+int
+tablejump_entry_p (insn, label)
+ rtx insn, label;
+{
+ rtx next = next_active_insn (insn);
+ enum rtx_code code = GET_CODE (PATTERN (next));
+
+ if (code != ADDR_DIFF_VEC && code != ADDR_VEC)
+ return 0;
+
+ if (PREV_INSN (next) == XEXP (label, 0))
+ return 1;
+
+ return 0;
+}
+
/* Instrument and/or analyze program behavior based on program flow graph.
In either case, this function builds a flow graph for the function being
compiled. The flow graph is stored in BB_GRAPH.
@@ -711,10 +730,22 @@ branch_prob (f, dump_file)
We have to handle tablejumps and returns specially anyways, so
we don't check the JUMP_LABEL at all here. */
+ /* ??? This code should be rewritten. We need a more elegant way
+ to find the LABEL_REF. We need a more elegant way to
+ differentiate tablejump entries from computed gotos.
+ We should perhaps reuse code from flow to compute the CFG
+ instead of trying to compute it here.
+
+ We can't use current_function_has_computed_jump, because that
+ is calculated later by flow. We can't use computed_jump_p,
+ because that returns true for tablejump entry insns for some
+ targets, e.g. HPPA and MIPS. */
+
if (GET_CODE (pattern) == PARALLEL)
{
- /* This assumes that PARALLEL jumps are tablejump entry
- jumps. */
+ /* This assumes that PARALLEL jumps with a USE are
+ tablejump entry jumps. The same assumption can be found
+ in computed_jump_p. */
/* Make an arc from this jump to the label of the
jump table. This will instrument the number of
times the switch statement is executed. */
@@ -755,7 +786,14 @@ branch_prob (f, dump_file)
&& GET_CODE (XEXP (tem, 0)) == MEM
&& GET_CODE (XEXP (XEXP (tem, 0), 0)) == PLUS
&& GET_CODE (XEXP (XEXP (XEXP (tem, 0), 0), 0)) == PC
- && GET_CODE (XEXP (tem, 1)) == LABEL_REF)
+ && GET_CODE (XEXP (tem, 1)) == LABEL_REF
+ && tablejump_entry_p (insn, XEXP (tem, 1)))
+ dest = label_to_bb[CODE_LABEL_NUMBER (XEXP (XEXP (tem, 1), 0))];
+ /* Recognize the MIPS table jump entry. */
+ else if (GET_CODE (tem) == PLUS
+ && GET_CODE (XEXP (tem, 0)) == REG
+ && GET_CODE (XEXP (tem, 1)) == LABEL_REF
+ && tablejump_entry_p (insn, XEXP (tem, 1)))
dest = label_to_bb[CODE_LABEL_NUMBER (XEXP (XEXP (tem, 1), 0))];
else
{