diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-10-15 07:41:28 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-10-15 07:41:28 +0000 |
commit | 16bf64db09c393f14dd07753360279d943b3498b (patch) | |
tree | 1c783187427863f2b594e432c0a46863b7bdb374 /gcc/dse.c | |
parent | e2d9473df995c429354a369fa5071f5e041d1d89 (diff) | |
download | gcc-16bf64db09c393f14dd07753360279d943b3498b.tar.gz |
* dse.c (struct insn_info): Add 'frame_read' field.
(scan_insn): For the call to a const function, set frame_read if
reload has been run.
If the insn reads the frame, kill the frame related stores.
(scan_reads_nospill): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129312 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/dse.c')
-rw-r--r-- | gcc/dse.c | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/gcc/dse.c b/gcc/dse.c index a5244e11414..764c3359d1b 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -286,8 +286,26 @@ struct insn_info /* This field is only used for the processing of const functions. These functions cannot read memory, but they can read the stack - because that is where they may get their parms. It is set to - true if the insn may contain a stack pointer based store. */ + because that is where they may get their parms. We need to be + this conservative because, like the store motion pass, we don't + consider CALL_INSN_FUNCTION_USAGE when processing call insns. + Moreover, we need to distinguish two cases: + 1. Before reload (register elimination), the stores related to + outgoing arguments are stack pointer based and thus deemed + of non-constant base in this pass. This requires special + handling but also means that the frame pointer based stores + need not be killed upon encountering a const function call. + 2. After reload, the stores related to outgoing arguments can be + either stack pointer or hard frame pointer based. This means + that we have no other choice than also killing all the frame + pointer based stores upon encountering a const function call. + This field is set after reload for const function calls. Having + this set is less severe than a wild read, it just means that all + the frame related stores are killed rather than all the stores. */ + bool frame_read; + + /* This field is only used for the processing of const functions. + It is set if the insn may contain a stack pointer based store. */ bool stack_pointer_based; /* This is true if any of the sets within the store contains a @@ -1967,10 +1985,36 @@ scan_insn (bb_info_t bb_info, rtx insn) if (dump_file) fprintf (dump_file, "const call %d\n", INSN_UID (insn)); + /* See the head comment of the frame_read field. */ + if (reload_completed) + insn_info->frame_read = true; + + /* Loop over the active stores and remove those which are + killed by the const function call. */ while (i_ptr) { - /* Remove the stack pointer based stores. */ + bool remove_store = false; + + /* The stack pointer based stores are always killed. */ if (i_ptr->stack_pointer_based) + remove_store = true; + + /* If the frame is read, the frame related stores are killed. */ + else if (insn_info->frame_read) + { + store_info_t store_info = i_ptr->store_rec; + + /* Skip the clobbers. */ + while (!store_info->is_set) + store_info = store_info->next; + + if (store_info->group_id >= 0 + && VEC_index (group_info_t, rtx_group_vec, + store_info->group_id)->frame_related) + remove_store = true; + } + + if (remove_store) { if (dump_file) dump_insn_info ("removing from active", i_ptr); @@ -1982,6 +2026,7 @@ scan_insn (bb_info_t bb_info, rtx insn) } else last = i_ptr; + i_ptr = i_ptr->next_local_store; } } @@ -2491,6 +2536,18 @@ scan_reads_nospill (insn_info_t insn_info, bitmap gen, bitmap kill) int i; group_info_t group; + /* If this insn reads the frame, kill all the frame related stores. */ + if (insn_info->frame_read) + { + for (i = 0; VEC_iterate (group_info_t, rtx_group_vec, i, group); i++) + if (group->process_globally && group->frame_related) + { + if (kill) + bitmap_ior_into (kill, group->group_kill); + bitmap_and_compl_into (gen, group->group_kill); + } + } + while (read_info) { for (i = 0; VEC_iterate (group_info_t, rtx_group_vec, i, group); i++) |