1999-03-10 21:14:05 +01:00
|
|
|
|
/* Global common subexpression elimination/Partial redundancy elimination
|
1998-05-20 02:24:32 +02:00
|
|
|
|
and global constant/copy propagation for GNU compiler.
|
2001-01-02 01:58:27 +01:00
|
|
|
|
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
This file is part of GNU CC.
|
|
|
|
|
|
|
|
|
|
GNU CC is free software; you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
|
|
GNU CC is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with GNU CC; see the file COPYING. If not, write to
|
|
|
|
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
|
|
|
Boston, MA 02111-1307, USA. */
|
|
|
|
|
|
|
|
|
|
/* TODO
|
|
|
|
|
- reordering of memory allocation and freeing to be more space efficient
|
|
|
|
|
- do rough calc of how many regs are needed in each block, and a rough
|
|
|
|
|
calc of how many regs are available in each class and use that to
|
|
|
|
|
throttle back the code in cases where RTX_COST is minimal.
|
1999-03-10 21:14:05 +01:00
|
|
|
|
- dead store elimination
|
|
|
|
|
- a store to the same address as a load does not kill the load if the
|
|
|
|
|
source of the store is also the destination of the load. Handling this
|
|
|
|
|
allows more load motion, particularly out of loops.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
- ability to realloc sbitmap vectors would allow one initial computation
|
|
|
|
|
of reg_set_in_block with only subsequent additions, rather than
|
|
|
|
|
recomputing it for each pass
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* References searched while implementing this.
|
|
|
|
|
|
|
|
|
|
Compilers Principles, Techniques and Tools
|
|
|
|
|
Aho, Sethi, Ullman
|
|
|
|
|
Addison-Wesley, 1988
|
|
|
|
|
|
|
|
|
|
Global Optimization by Suppression of Partial Redundancies
|
|
|
|
|
E. Morel, C. Renvoise
|
|
|
|
|
communications of the acm, Vol. 22, Num. 2, Feb. 1979
|
|
|
|
|
|
|
|
|
|
A Portable Machine-Independent Global Optimizer - Design and Measurements
|
|
|
|
|
Frederick Chow
|
|
|
|
|
Stanford Ph.D. thesis, Dec. 1983
|
|
|
|
|
|
|
|
|
|
A Fast Algorithm for Code Movement Optimization
|
|
|
|
|
D.M. Dhamdhere
|
|
|
|
|
SIGPLAN Notices, Vol. 23, Num. 10, Oct. 1988
|
|
|
|
|
|
|
|
|
|
A Solution to a Problem with Morel and Renvoise's
|
|
|
|
|
Global Optimization by Suppression of Partial Redundancies
|
|
|
|
|
K-H Drechsler, M.P. Stadel
|
|
|
|
|
ACM TOPLAS, Vol. 10, Num. 4, Oct. 1988
|
|
|
|
|
|
|
|
|
|
Practical Adaptation of the Global Optimization
|
|
|
|
|
Algorithm of Morel and Renvoise
|
|
|
|
|
D.M. Dhamdhere
|
|
|
|
|
ACM TOPLAS, Vol. 13, Num. 2. Apr. 1991
|
|
|
|
|
|
|
|
|
|
Efficiently Computing Static Single Assignment Form and the Control
|
|
|
|
|
Dependence Graph
|
|
|
|
|
R. Cytron, J. Ferrante, B.K. Rosen, M.N. Wegman, and F.K. Zadeck
|
|
|
|
|
ACM TOPLAS, Vol. 13, Num. 4, Oct. 1991
|
|
|
|
|
|
|
|
|
|
Lazy Code Motion
|
|
|
|
|
J. Knoop, O. Ruthing, B. Steffen
|
|
|
|
|
ACM SIGPLAN Notices Vol. 27, Num. 7, Jul. 1992, '92 Conference on PLDI
|
|
|
|
|
|
|
|
|
|
What's In a Region? Or Computing Control Dependence Regions in Near-Linear
|
|
|
|
|
Time for Reducible Flow Control
|
|
|
|
|
Thomas Ball
|
|
|
|
|
ACM Letters on Programming Languages and Systems,
|
|
|
|
|
Vol. 2, Num. 1-4, Mar-Dec 1993
|
|
|
|
|
|
|
|
|
|
An Efficient Representation for Sparse Sets
|
|
|
|
|
Preston Briggs, Linda Torczon
|
|
|
|
|
ACM Letters on Programming Languages and Systems,
|
|
|
|
|
Vol. 2, Num. 1-4, Mar-Dec 1993
|
|
|
|
|
|
|
|
|
|
A Variation of Knoop, Ruthing, and Steffen's Lazy Code Motion
|
|
|
|
|
K-H Drechsler, M.P. Stadel
|
|
|
|
|
ACM SIGPLAN Notices, Vol. 28, Num. 5, May 1993
|
|
|
|
|
|
|
|
|
|
Partial Dead Code Elimination
|
|
|
|
|
J. Knoop, O. Ruthing, B. Steffen
|
|
|
|
|
ACM SIGPLAN Notices, Vol. 29, Num. 6, Jun. 1994
|
|
|
|
|
|
|
|
|
|
Effective Partial Redundancy Elimination
|
|
|
|
|
P. Briggs, K.D. Cooper
|
|
|
|
|
ACM SIGPLAN Notices, Vol. 29, Num. 6, Jun. 1994
|
|
|
|
|
|
|
|
|
|
The Program Structure Tree: Computing Control Regions in Linear Time
|
|
|
|
|
R. Johnson, D. Pearson, K. Pingali
|
|
|
|
|
ACM SIGPLAN Notices, Vol. 29, Num. 6, Jun. 1994
|
|
|
|
|
|
|
|
|
|
Optimal Code Motion: Theory and Practice
|
|
|
|
|
J. Knoop, O. Ruthing, B. Steffen
|
|
|
|
|
ACM TOPLAS, Vol. 16, Num. 4, Jul. 1994
|
|
|
|
|
|
|
|
|
|
The power of assignment motion
|
|
|
|
|
J. Knoop, O. Ruthing, B. Steffen
|
|
|
|
|
ACM SIGPLAN Notices Vol. 30, Num. 6, Jun. 1995, '95 Conference on PLDI
|
|
|
|
|
|
|
|
|
|
Global code motion / global value numbering
|
|
|
|
|
C. Click
|
|
|
|
|
ACM SIGPLAN Notices Vol. 30, Num. 6, Jun. 1995, '95 Conference on PLDI
|
|
|
|
|
|
|
|
|
|
Value Driven Redundancy Elimination
|
|
|
|
|
L.T. Simpson
|
|
|
|
|
Rice University Ph.D. thesis, Apr. 1996
|
|
|
|
|
|
|
|
|
|
Value Numbering
|
|
|
|
|
L.T. Simpson
|
|
|
|
|
Massively Scalar Compiler Project, Rice University, Sep. 1996
|
|
|
|
|
|
|
|
|
|
High Performance Compilers for Parallel Computing
|
|
|
|
|
Michael Wolfe
|
|
|
|
|
Addison-Wesley, 1996
|
|
|
|
|
|
1999-03-10 21:14:05 +01:00
|
|
|
|
Advanced Compiler Design and Implementation
|
|
|
|
|
Steven Muchnick
|
|
|
|
|
Morgan Kaufmann, 1997
|
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
Building an Optimizing Compiler
|
|
|
|
|
Robert Morgan
|
|
|
|
|
Digital Press, 1998
|
|
|
|
|
|
1999-03-10 21:14:05 +01:00
|
|
|
|
People wishing to speed up the code here should read:
|
|
|
|
|
Elimination Algorithms for Data Flow Analysis
|
|
|
|
|
B.G. Ryder, M.C. Paull
|
|
|
|
|
ACM Computing Surveys, Vol. 18, Num. 3, Sep. 1986
|
|
|
|
|
|
|
|
|
|
How to Analyze Large Programs Efficiently and Informatively
|
|
|
|
|
D.M. Dhamdhere, B.K. Rosen, F.K. Zadeck
|
|
|
|
|
ACM SIGPLAN Notices Vol. 27, Num. 7, Jul. 1992, '92 Conference on PLDI
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
People wishing to do something different can find various possibilities
|
|
|
|
|
in the above papers and elsewhere.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "config.h"
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
#include "system.h"
|
c-aux-info.c, [...]: Include toplev.h for real declaration of trim_filename.
1999-04-17 20:11 -0400 Zack Weinberg <zack@rabi.columbia.edu>
* c-aux-info.c, emit-rtl.c, explow.c, expmed.c, gcse.c,
haifa-sched.c, optabs.c, reorg.c, resource.c, sched.c: Include
toplev.h for real declaration of trim_filename.
* Makefile.in: Update dependencies.
From-SVN: r26523
1999-04-17 19:14:58 +02:00
|
|
|
|
#include "toplev.h"
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
#include "rtl.h"
|
1999-09-20 12:00:03 +02:00
|
|
|
|
#include "tm_p.h"
|
1998-05-20 02:24:32 +02:00
|
|
|
|
#include "regs.h"
|
|
|
|
|
#include "hard-reg-set.h"
|
|
|
|
|
#include "flags.h"
|
|
|
|
|
#include "real.h"
|
|
|
|
|
#include "insn-config.h"
|
|
|
|
|
#include "recog.h"
|
|
|
|
|
#include "basic-block.h"
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
#include "output.h"
|
1999-08-09 16:00:21 +02:00
|
|
|
|
#include "function.h"
|
1998-12-17 14:54:39 +01:00
|
|
|
|
#include "expr.h"
|
2001-02-19 00:56:34 +01:00
|
|
|
|
#include "ggc.h"
|
2001-04-11 20:22:46 +02:00
|
|
|
|
#include "params.h"
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
#include "obstack.h"
|
|
|
|
|
#define obstack_chunk_alloc gmalloc
|
|
|
|
|
#define obstack_chunk_free free
|
|
|
|
|
|
|
|
|
|
/* Maximum number of passes to perform. */
|
|
|
|
|
#define MAX_PASSES 1
|
|
|
|
|
|
|
|
|
|
/* Propagate flow information through back edges and thus enable PRE's
|
|
|
|
|
moving loop invariant calculations out of loops.
|
|
|
|
|
|
|
|
|
|
Originally this tended to create worse overall code, but several
|
|
|
|
|
improvements during the development of PRE seem to have made following
|
|
|
|
|
back edges generally a win.
|
|
|
|
|
|
|
|
|
|
Note much of the loop invariant code motion done here would normally
|
|
|
|
|
be done by loop.c, which has more heuristics for when to move invariants
|
|
|
|
|
out of loops. At some point we might need to move some of those
|
|
|
|
|
heuristics into gcse.c. */
|
|
|
|
|
#define FOLLOW_BACK_EDGES 1
|
|
|
|
|
|
1999-03-10 21:14:05 +01:00
|
|
|
|
/* We support GCSE via Partial Redundancy Elimination. PRE optimizations
|
|
|
|
|
are a superset of those done by GCSE.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-03-10 21:14:05 +01:00
|
|
|
|
We perform the following steps:
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
1) Compute basic block information.
|
|
|
|
|
|
|
|
|
|
2) Compute table of places where registers are set.
|
|
|
|
|
|
|
|
|
|
3) Perform copy/constant propagation.
|
|
|
|
|
|
|
|
|
|
4) Perform global cse.
|
|
|
|
|
|
1999-03-10 20:45:18 +01:00
|
|
|
|
5) Perform another pass of copy/constant propagation.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
Two passes of copy/constant propagation are done because the first one
|
|
|
|
|
enables more GCSE and the second one helps to clean up the copies that
|
|
|
|
|
GCSE creates. This is needed more for PRE than for Classic because Classic
|
|
|
|
|
GCSE will try to use an existing register containing the common
|
|
|
|
|
subexpression rather than create a new one. This is harder to do for PRE
|
|
|
|
|
because of the code motion (which Classic GCSE doesn't do).
|
|
|
|
|
|
|
|
|
|
Expressions we are interested in GCSE-ing are of the form
|
|
|
|
|
(set (pseudo-reg) (expression)).
|
|
|
|
|
Function want_to_gcse_p says what these are.
|
|
|
|
|
|
|
|
|
|
PRE handles moving invariant expressions out of loops (by treating them as
|
1999-03-10 21:14:05 +01:00
|
|
|
|
partially redundant).
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
Eventually it would be nice to replace cse.c/gcse.c with SSA (static single
|
|
|
|
|
assignment) based GVN (global value numbering). L. T. Simpson's paper
|
|
|
|
|
(Rice University) on value numbering is a useful reference for this.
|
|
|
|
|
|
|
|
|
|
**********************
|
|
|
|
|
|
|
|
|
|
We used to support multiple passes but there are diminishing returns in
|
|
|
|
|
doing so. The first pass usually makes 90% of the changes that are doable.
|
|
|
|
|
A second pass can make a few more changes made possible by the first pass.
|
|
|
|
|
Experiments show any further passes don't make enough changes to justify
|
|
|
|
|
the expense.
|
|
|
|
|
|
|
|
|
|
A study of spec92 using an unlimited number of passes:
|
|
|
|
|
[1 pass] = 1208 substitutions, [2] = 577, [3] = 202, [4] = 192, [5] = 83,
|
|
|
|
|
[6] = 34, [7] = 17, [8] = 9, [9] = 4, [10] = 4, [11] = 2,
|
|
|
|
|
[12] = 2, [13] = 1, [15] = 1, [16] = 2, [41] = 1
|
|
|
|
|
|
|
|
|
|
It was found doing copy propagation between each pass enables further
|
|
|
|
|
substitutions.
|
|
|
|
|
|
|
|
|
|
PRE is quite expensive in complicated functions because the DFA can take
|
|
|
|
|
awhile to converge. Hence we only perform one pass. Macro MAX_PASSES can
|
|
|
|
|
be modified if one wants to experiment.
|
|
|
|
|
|
|
|
|
|
**********************
|
|
|
|
|
|
|
|
|
|
The steps for PRE are:
|
|
|
|
|
|
|
|
|
|
1) Build the hash table of expressions we wish to GCSE (expr_hash_table).
|
|
|
|
|
|
|
|
|
|
2) Perform the data flow analysis for PRE.
|
|
|
|
|
|
|
|
|
|
3) Delete the redundant instructions
|
|
|
|
|
|
|
|
|
|
4) Insert the required copies [if any] that make the partially
|
|
|
|
|
redundant instructions fully redundant.
|
|
|
|
|
|
|
|
|
|
5) For other reaching expressions, insert an instruction to copy the value
|
|
|
|
|
to a newly created pseudo that will reach the redundant instruction.
|
|
|
|
|
|
|
|
|
|
The deletion is done first so that when we do insertions we
|
|
|
|
|
know which pseudo reg to use.
|
|
|
|
|
|
|
|
|
|
Various papers have argued that PRE DFA is expensive (O(n^2)) and others
|
|
|
|
|
argue it is not. The number of iterations for the algorithm to converge
|
|
|
|
|
is typically 2-4 so I don't view it as that expensive (relatively speaking).
|
|
|
|
|
|
1999-03-10 21:14:05 +01:00
|
|
|
|
PRE GCSE depends heavily on the second CSE pass to clean up the copies
|
1998-05-20 02:24:32 +02:00
|
|
|
|
we create. To make an expression reach the place where it's redundant,
|
|
|
|
|
the result of the expression is copied to a new register, and the redundant
|
|
|
|
|
expression is deleted by replacing it with this new register. Classic GCSE
|
|
|
|
|
doesn't have this problem as much as it computes the reaching defs of
|
|
|
|
|
each register in each block and thus can try to use an existing register.
|
|
|
|
|
|
|
|
|
|
**********************
|
|
|
|
|
|
|
|
|
|
A fair bit of simplicity is created by creating small functions for simple
|
|
|
|
|
tasks, even when the function is only called in one place. This may
|
|
|
|
|
measurably slow things down [or may not] by creating more function call
|
|
|
|
|
overhead than is necessary. The source is laid out so that it's trivial
|
|
|
|
|
to make the affected functions inline so that one can measure what speed
|
|
|
|
|
up, if any, can be achieved, and maybe later when things settle things can
|
|
|
|
|
be rearranged.
|
|
|
|
|
|
|
|
|
|
Help stamp out big monolithic functions! */
|
|
|
|
|
|
|
|
|
|
/* GCSE global vars. */
|
|
|
|
|
|
|
|
|
|
/* -dG dump file. */
|
|
|
|
|
static FILE *gcse_file;
|
|
|
|
|
|
1999-03-10 21:14:05 +01:00
|
|
|
|
/* Note whether or not we should run jump optimization after gcse. We
|
|
|
|
|
want to do this for two cases.
|
|
|
|
|
|
|
|
|
|
* If we changed any jumps via cprop.
|
|
|
|
|
|
|
|
|
|
* If we added any labels via edge splitting. */
|
|
|
|
|
|
|
|
|
|
static int run_jump_opt_after_gcse;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Bitmaps are normally not included in debugging dumps.
|
|
|
|
|
However it's useful to be able to print them from GDB.
|
|
|
|
|
We could create special functions for this, but it's simpler to
|
|
|
|
|
just allow passing stderr to the dump_foo fns. Since stderr can
|
|
|
|
|
be a macro, we store a copy here. */
|
|
|
|
|
static FILE *debug_stderr;
|
|
|
|
|
|
|
|
|
|
/* An obstack for our working variables. */
|
|
|
|
|
static struct obstack gcse_obstack;
|
|
|
|
|
|
|
|
|
|
/* Non-zero for each mode that supports (set (reg) (reg)).
|
|
|
|
|
This is trivially true for integer and floating point values.
|
|
|
|
|
It may or may not be true for condition codes. */
|
|
|
|
|
static char can_copy_p[(int) NUM_MACHINE_MODES];
|
|
|
|
|
|
|
|
|
|
/* Non-zero if can_copy_p has been initialized. */
|
|
|
|
|
static int can_copy_init_p;
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct reg_use {rtx reg_rtx; };
|
1999-08-25 05:30:45 +02:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Hash table of expressions. */
|
|
|
|
|
|
|
|
|
|
struct expr
|
|
|
|
|
{
|
|
|
|
|
/* The expression (SET_SRC for expressions, PATTERN for assignments). */
|
|
|
|
|
rtx expr;
|
|
|
|
|
/* Index in the available expression bitmaps. */
|
|
|
|
|
int bitmap_index;
|
|
|
|
|
/* Next entry with the same hash. */
|
|
|
|
|
struct expr *next_same_hash;
|
|
|
|
|
/* List of anticipatable occurrences in basic blocks in the function.
|
|
|
|
|
An "anticipatable occurrence" is one that is the first occurrence in the
|
1999-03-10 21:14:05 +01:00
|
|
|
|
basic block, the operands are not modified in the basic block prior
|
|
|
|
|
to the occurrence and the output is not used between the start of
|
|
|
|
|
the block and the occurrence. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
struct occr *antic_occr;
|
|
|
|
|
/* List of available occurrence in basic blocks in the function.
|
|
|
|
|
An "available occurrence" is one that is the last occurrence in the
|
|
|
|
|
basic block and the operands are not modified by following statements in
|
|
|
|
|
the basic block [including this insn]. */
|
|
|
|
|
struct occr *avail_occr;
|
|
|
|
|
/* Non-null if the computation is PRE redundant.
|
|
|
|
|
The value is the newly created pseudo-reg to record a copy of the
|
|
|
|
|
expression in all the places that reach the redundant copy. */
|
|
|
|
|
rtx reaching_reg;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Occurrence of an expression.
|
|
|
|
|
There is one per basic block. If a pattern appears more than once the
|
|
|
|
|
last appearance is used [or first for anticipatable expressions]. */
|
|
|
|
|
|
|
|
|
|
struct occr
|
|
|
|
|
{
|
|
|
|
|
/* Next occurrence of this expression. */
|
|
|
|
|
struct occr *next;
|
|
|
|
|
/* The insn that computes the expression. */
|
|
|
|
|
rtx insn;
|
|
|
|
|
/* Non-zero if this [anticipatable] occurrence has been deleted. */
|
|
|
|
|
char deleted_p;
|
|
|
|
|
/* Non-zero if this [available] occurrence has been copied to
|
|
|
|
|
reaching_reg. */
|
|
|
|
|
/* ??? This is mutually exclusive with deleted_p, so they could share
|
|
|
|
|
the same byte. */
|
|
|
|
|
char copied_p;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Expression and copy propagation hash tables.
|
|
|
|
|
Each hash table is an array of buckets.
|
|
|
|
|
??? It is known that if it were an array of entries, structure elements
|
|
|
|
|
`next_same_hash' and `bitmap_index' wouldn't be necessary. However, it is
|
|
|
|
|
not clear whether in the final analysis a sufficient amount of memory would
|
|
|
|
|
be saved as the size of the available expression bitmaps would be larger
|
|
|
|
|
[one could build a mapping table without holes afterwards though].
|
2000-02-29 21:08:52 +01:00
|
|
|
|
Someday I'll perform the computation and figure it out. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Total size of the expression hash table, in elements. */
|
2000-04-10 13:33:18 +02:00
|
|
|
|
static unsigned int expr_hash_table_size;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* The table itself.
|
|
|
|
|
This is an array of `expr_hash_table_size' elements. */
|
|
|
|
|
static struct expr **expr_hash_table;
|
|
|
|
|
|
|
|
|
|
/* Total size of the copy propagation hash table, in elements. */
|
2000-10-20 21:17:41 +02:00
|
|
|
|
static unsigned int set_hash_table_size;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* The table itself.
|
|
|
|
|
This is an array of `set_hash_table_size' elements. */
|
|
|
|
|
static struct expr **set_hash_table;
|
|
|
|
|
|
|
|
|
|
/* Mapping of uids to cuids.
|
|
|
|
|
Only real insns get cuids. */
|
|
|
|
|
static int *uid_cuid;
|
|
|
|
|
|
|
|
|
|
/* Highest UID in UID_CUID. */
|
|
|
|
|
static int max_uid;
|
|
|
|
|
|
|
|
|
|
/* Get the cuid of an insn. */
|
2000-07-19 19:22:01 +02:00
|
|
|
|
#ifdef ENABLE_CHECKING
|
|
|
|
|
#define INSN_CUID(INSN) (INSN_UID (INSN) > max_uid ? (abort (), 0) : uid_cuid[INSN_UID (INSN)])
|
|
|
|
|
#else
|
1998-05-20 02:24:32 +02:00
|
|
|
|
#define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
|
2000-07-19 19:22:01 +02:00
|
|
|
|
#endif
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Number of cuids. */
|
|
|
|
|
static int max_cuid;
|
|
|
|
|
|
|
|
|
|
/* Mapping of cuids to insns. */
|
|
|
|
|
static rtx *cuid_insn;
|
|
|
|
|
|
|
|
|
|
/* Get insn from cuid. */
|
|
|
|
|
#define CUID_INSN(CUID) (cuid_insn[CUID])
|
|
|
|
|
|
|
|
|
|
/* Maximum register number in function prior to doing gcse + 1.
|
|
|
|
|
Registers created during this pass have regno >= max_gcse_regno.
|
|
|
|
|
This is named with "gcse" to not collide with global of same name. */
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
static unsigned int max_gcse_regno;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Maximum number of cse-able expressions found. */
|
|
|
|
|
static int n_exprs;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Maximum number of assignments for copy propagation found. */
|
|
|
|
|
static int n_sets;
|
|
|
|
|
|
|
|
|
|
/* Table of registers that are modified.
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
For each register, each element is a list of places where the pseudo-reg
|
|
|
|
|
is set.
|
|
|
|
|
|
|
|
|
|
For simplicity, GCSE is done on sets of pseudo-regs only. PRE GCSE only
|
|
|
|
|
requires knowledge of which blocks kill which regs [and thus could use
|
1999-03-10 21:14:05 +01:00
|
|
|
|
a bitmap instead of the lists `reg_set_table' uses].
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
`reg_set_table' and could be turned into an array of bitmaps (num-bbs x
|
|
|
|
|
num-regs) [however perhaps it may be useful to keep the data as is]. One
|
|
|
|
|
advantage of recording things this way is that `reg_set_table' is fairly
|
|
|
|
|
sparse with respect to pseudo regs but for hard regs could be fairly dense
|
|
|
|
|
[relatively speaking]. And recording sets of pseudo-regs in lists speeds
|
1998-05-20 02:24:32 +02:00
|
|
|
|
up functions like compute_transp since in the case of pseudo-regs we only
|
|
|
|
|
need to iterate over the number of times a pseudo-reg is set, not over the
|
|
|
|
|
number of basic blocks [clearly there is a bit of a slow down in the cases
|
|
|
|
|
where a pseudo is set more than once in a block, however it is believed
|
|
|
|
|
that the net effect is to speed things up]. This isn't done for hard-regs
|
|
|
|
|
because recording call-clobbered hard-regs in `reg_set_table' at each
|
2000-02-29 21:08:52 +01:00
|
|
|
|
function call can consume a fair bit of memory, and iterating over
|
|
|
|
|
hard-regs stored this way in compute_transp will be more expensive. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
typedef struct reg_set
|
|
|
|
|
{
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* The next setting of this register. */
|
|
|
|
|
struct reg_set *next;
|
|
|
|
|
/* The insn where it was set. */
|
|
|
|
|
rtx insn;
|
|
|
|
|
} reg_set;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
static reg_set **reg_set_table;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Size of `reg_set_table'.
|
|
|
|
|
The table starts out at max_gcse_regno + slop, and is enlarged as
|
|
|
|
|
necessary. */
|
|
|
|
|
static int reg_set_table_size;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Amount to grow `reg_set_table' by when it's full. */
|
|
|
|
|
#define REG_SET_TABLE_SLOP 100
|
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* This is a list of expressions which are MEMs and will be used by load
|
|
|
|
|
or store motion.
|
|
|
|
|
Load motion tracks MEMs which aren't killed by
|
|
|
|
|
anything except itself. (ie, loads and stores to a single location).
|
|
|
|
|
We can then allow movement of these MEM refs with a little special
|
|
|
|
|
allowance. (all stores copy the same value to the reaching reg used
|
|
|
|
|
for the loads). This means all values used to store into memory must have
|
|
|
|
|
no side effects so we can re-issue the setter value.
|
|
|
|
|
Store Motion uses this structure as an expression table to track stores
|
|
|
|
|
which look interesting, and might be moveable towards the exit block. */
|
|
|
|
|
|
|
|
|
|
struct ls_expr
|
|
|
|
|
{
|
|
|
|
|
struct expr * expr; /* Gcse expression reference for LM. */
|
|
|
|
|
rtx pattern; /* Pattern of this mem. */
|
|
|
|
|
rtx loads; /* INSN list of loads seen. */
|
|
|
|
|
rtx stores; /* INSN list of stores seen. */
|
|
|
|
|
struct ls_expr * next; /* Next in the list. */
|
|
|
|
|
int invalid; /* Invalid for some reason. */
|
|
|
|
|
int index; /* If it maps to a bitmap index. */
|
|
|
|
|
int hash_index; /* Index when in a hash table. */
|
|
|
|
|
rtx reaching_reg; /* Register to use when re-writing. */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Head of the list of load/store memory refs. */
|
|
|
|
|
static struct ls_expr * pre_ldst_mems = NULL;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Bitmap containing one bit for each register in the program.
|
|
|
|
|
Used when performing GCSE to track which registers have been set since
|
|
|
|
|
the start of the basic block. */
|
|
|
|
|
static sbitmap reg_set_bitmap;
|
|
|
|
|
|
|
|
|
|
/* For each block, a bitmap of registers set in the block.
|
|
|
|
|
This is used by expr_killed_p and compute_transp.
|
|
|
|
|
It is computed during hash table computation and not by compute_sets
|
|
|
|
|
as it includes registers added since the last pass (or between cprop and
|
|
|
|
|
gcse) and it's currently not easy to realloc sbitmap vectors. */
|
|
|
|
|
static sbitmap *reg_set_in_block;
|
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* Array, indexed by basic block number for a list of insns which modify
|
|
|
|
|
memory within that block. */
|
|
|
|
|
static rtx * modify_mem_list;
|
|
|
|
|
|
|
|
|
|
/* This array parallels modify_mem_list, but is kept canonicalized. */
|
|
|
|
|
static rtx * canon_modify_mem_list;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* For each block, non-zero if memory is set in that block.
|
|
|
|
|
This is computed during hash table computation and is used by
|
|
|
|
|
expr_killed_p and compute_transp.
|
|
|
|
|
??? Handling of memory is very simple, we don't make any attempt
|
|
|
|
|
to optimize things (later).
|
|
|
|
|
??? This can be computed by compute_sets since the information
|
|
|
|
|
doesn't change. */
|
|
|
|
|
static char *mem_set_in_block;
|
|
|
|
|
|
|
|
|
|
/* Various variables for statistics gathering. */
|
|
|
|
|
|
|
|
|
|
/* Memory used in a pass.
|
|
|
|
|
This isn't intended to be absolutely precise. Its intent is only
|
|
|
|
|
to keep an eye on memory usage. */
|
|
|
|
|
static int bytes_used;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* GCSE substitutions made. */
|
|
|
|
|
static int gcse_subst_count;
|
|
|
|
|
/* Number of copy instructions created. */
|
|
|
|
|
static int gcse_create_count;
|
|
|
|
|
/* Number of constants propagated. */
|
|
|
|
|
static int const_prop_count;
|
|
|
|
|
/* Number of copys propagated. */
|
|
|
|
|
static int copy_prop_count;
|
|
|
|
|
|
|
|
|
|
/* These variables are used by classic GCSE.
|
|
|
|
|
Normally they'd be defined a bit later, but `rd_gen' needs to
|
|
|
|
|
be declared sooner. */
|
|
|
|
|
|
|
|
|
|
/* Each block has a bitmap of each type.
|
|
|
|
|
The length of each blocks bitmap is:
|
|
|
|
|
|
|
|
|
|
max_cuid - for reaching definitions
|
|
|
|
|
n_exprs - for available expressions
|
|
|
|
|
|
|
|
|
|
Thus we view the bitmaps as 2 dimensional arrays. i.e.
|
|
|
|
|
rd_kill[block_num][cuid_num]
|
2000-02-29 21:08:52 +01:00
|
|
|
|
ae_kill[block_num][expr_num] */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* For reaching defs */
|
|
|
|
|
static sbitmap *rd_kill, *rd_gen, *reaching_defs, *rd_out;
|
|
|
|
|
|
|
|
|
|
/* for available exprs */
|
|
|
|
|
static sbitmap *ae_kill, *ae_gen, *ae_in, *ae_out;
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
1999-11-03 23:45:45 +01:00
|
|
|
|
/* Objects of this type are passed around by the null-pointer check
|
|
|
|
|
removal routines. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct null_pointer_info
|
|
|
|
|
{
|
1999-11-03 23:45:45 +01:00
|
|
|
|
/* The basic block being processed. */
|
|
|
|
|
int current_block;
|
|
|
|
|
/* The first register to be handled in this pass. */
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int min_reg;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
/* One greater than the last register to be handled in this pass. */
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int max_reg;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
sbitmap *nonnull_local;
|
|
|
|
|
sbitmap *nonnull_killed;
|
|
|
|
|
};
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void compute_can_copy PARAMS ((void));
|
|
|
|
|
static char *gmalloc PARAMS ((unsigned int));
|
|
|
|
|
static char *grealloc PARAMS ((char *, unsigned int));
|
|
|
|
|
static char *gcse_alloc PARAMS ((unsigned long));
|
|
|
|
|
static void alloc_gcse_mem PARAMS ((rtx));
|
|
|
|
|
static void free_gcse_mem PARAMS ((void));
|
|
|
|
|
static void alloc_reg_set_mem PARAMS ((int));
|
|
|
|
|
static void free_reg_set_mem PARAMS ((void));
|
|
|
|
|
static int get_bitmap_width PARAMS ((int, int, int));
|
|
|
|
|
static void record_one_set PARAMS ((int, rtx));
|
|
|
|
|
static void record_set_info PARAMS ((rtx, rtx, void *));
|
|
|
|
|
static void compute_sets PARAMS ((rtx));
|
|
|
|
|
static void hash_scan_insn PARAMS ((rtx, int, int));
|
|
|
|
|
static void hash_scan_set PARAMS ((rtx, rtx, int));
|
|
|
|
|
static void hash_scan_clobber PARAMS ((rtx, rtx));
|
|
|
|
|
static void hash_scan_call PARAMS ((rtx, rtx));
|
|
|
|
|
static int want_to_gcse_p PARAMS ((rtx));
|
|
|
|
|
static int oprs_unchanged_p PARAMS ((rtx, rtx, int));
|
|
|
|
|
static int oprs_anticipatable_p PARAMS ((rtx, rtx));
|
|
|
|
|
static int oprs_available_p PARAMS ((rtx, rtx));
|
|
|
|
|
static void insert_expr_in_table PARAMS ((rtx, enum machine_mode, rtx,
|
|
|
|
|
int, int));
|
|
|
|
|
static void insert_set_in_table PARAMS ((rtx, rtx));
|
|
|
|
|
static unsigned int hash_expr PARAMS ((rtx, enum machine_mode, int *, int));
|
|
|
|
|
static unsigned int hash_expr_1 PARAMS ((rtx, enum machine_mode, int *));
|
2000-09-05 08:04:09 +02:00
|
|
|
|
static unsigned int hash_string_1 PARAMS ((const char *));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static unsigned int hash_set PARAMS ((int, int));
|
|
|
|
|
static int expr_equiv_p PARAMS ((rtx, rtx));
|
|
|
|
|
static void record_last_reg_set_info PARAMS ((rtx, int));
|
|
|
|
|
static void record_last_mem_set_info PARAMS ((rtx));
|
|
|
|
|
static void record_last_set_info PARAMS ((rtx, rtx, void *));
|
2000-01-14 18:14:43 +01:00
|
|
|
|
static void compute_hash_table PARAMS ((int));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void alloc_set_hash_table PARAMS ((int));
|
|
|
|
|
static void free_set_hash_table PARAMS ((void));
|
|
|
|
|
static void compute_set_hash_table PARAMS ((void));
|
2000-04-10 13:33:18 +02:00
|
|
|
|
static void alloc_expr_hash_table PARAMS ((unsigned int));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void free_expr_hash_table PARAMS ((void));
|
|
|
|
|
static void compute_expr_hash_table PARAMS ((void));
|
|
|
|
|
static void dump_hash_table PARAMS ((FILE *, const char *, struct expr **,
|
|
|
|
|
int, int));
|
|
|
|
|
static struct expr *lookup_expr PARAMS ((rtx));
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
static struct expr *lookup_set PARAMS ((unsigned int, rtx));
|
|
|
|
|
static struct expr *next_set PARAMS ((unsigned int, struct expr *));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void reset_opr_set_tables PARAMS ((void));
|
|
|
|
|
static int oprs_not_set_p PARAMS ((rtx, rtx));
|
|
|
|
|
static void mark_call PARAMS ((rtx));
|
|
|
|
|
static void mark_set PARAMS ((rtx, rtx));
|
|
|
|
|
static void mark_clobber PARAMS ((rtx, rtx));
|
|
|
|
|
static void mark_oprs_set PARAMS ((rtx));
|
|
|
|
|
static void alloc_cprop_mem PARAMS ((int, int));
|
|
|
|
|
static void free_cprop_mem PARAMS ((void));
|
|
|
|
|
static void compute_transp PARAMS ((rtx, int, sbitmap *, int));
|
|
|
|
|
static void compute_transpout PARAMS ((void));
|
|
|
|
|
static void compute_local_properties PARAMS ((sbitmap *, sbitmap *, sbitmap *,
|
|
|
|
|
int));
|
2000-01-14 18:14:43 +01:00
|
|
|
|
static void compute_cprop_data PARAMS ((void));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void find_used_regs PARAMS ((rtx));
|
|
|
|
|
static int try_replace_reg PARAMS ((rtx, rtx, rtx));
|
|
|
|
|
static struct expr *find_avail_set PARAMS ((int, rtx));
|
2001-02-16 20:29:49 +01:00
|
|
|
|
static int cprop_jump PARAMS ((rtx, rtx, rtx));
|
1999-09-02 19:29:25 +02:00
|
|
|
|
#ifdef HAVE_cc0
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static int cprop_cc0_jump PARAMS ((rtx, struct reg_use *, rtx));
|
1999-09-02 19:29:25 +02:00
|
|
|
|
#endif
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int));
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
static void canon_list_insert PARAMS ((rtx, rtx, void *));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static int cprop_insn PARAMS ((rtx, int));
|
|
|
|
|
static int cprop PARAMS ((int));
|
|
|
|
|
static int one_cprop_pass PARAMS ((int, int));
|
|
|
|
|
static void alloc_pre_mem PARAMS ((int, int));
|
|
|
|
|
static void free_pre_mem PARAMS ((void));
|
|
|
|
|
static void compute_pre_data PARAMS ((void));
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
static int pre_expr_reaches_here_p PARAMS ((basic_block, struct expr *,
|
|
|
|
|
basic_block));
|
|
|
|
|
static void insert_insn_end_bb PARAMS ((struct expr *, basic_block, int));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void pre_insert_copy_insn PARAMS ((struct expr *, rtx));
|
|
|
|
|
static void pre_insert_copies PARAMS ((void));
|
|
|
|
|
static int pre_delete PARAMS ((void));
|
|
|
|
|
static int pre_gcse PARAMS ((void));
|
|
|
|
|
static int one_pre_gcse_pass PARAMS ((int));
|
|
|
|
|
static void add_label_notes PARAMS ((rtx, rtx));
|
|
|
|
|
static void alloc_code_hoist_mem PARAMS ((int, int));
|
|
|
|
|
static void free_code_hoist_mem PARAMS ((void));
|
2000-01-14 18:14:43 +01:00
|
|
|
|
static void compute_code_hoist_vbeinout PARAMS ((void));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void compute_code_hoist_data PARAMS ((void));
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
static int hoist_expr_reaches_here_p PARAMS ((basic_block, int, basic_block,
|
|
|
|
|
char *));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void hoist_code PARAMS ((void));
|
|
|
|
|
static int one_code_hoisting_pass PARAMS ((void));
|
|
|
|
|
static void alloc_rd_mem PARAMS ((int, int));
|
|
|
|
|
static void free_rd_mem PARAMS ((void));
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
static void handle_rd_kill_set PARAMS ((rtx, int, basic_block));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void compute_kill_rd PARAMS ((void));
|
2000-01-14 18:14:43 +01:00
|
|
|
|
static void compute_rd PARAMS ((void));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void alloc_avail_expr_mem PARAMS ((int, int));
|
|
|
|
|
static void free_avail_expr_mem PARAMS ((void));
|
|
|
|
|
static void compute_ae_gen PARAMS ((void));
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
static int expr_killed_p PARAMS ((rtx, basic_block));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static void compute_ae_kill PARAMS ((sbitmap *, sbitmap *));
|
2000-01-14 18:14:43 +01:00
|
|
|
|
static int expr_reaches_here_p PARAMS ((struct occr *, struct expr *,
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block, int));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static rtx computing_insn PARAMS ((struct expr *, rtx));
|
|
|
|
|
static int def_reaches_here_p PARAMS ((rtx, rtx));
|
|
|
|
|
static int can_disregard_other_sets PARAMS ((struct reg_set **, rtx, int));
|
|
|
|
|
static int handle_avail_expr PARAMS ((rtx, struct expr *));
|
|
|
|
|
static int classic_gcse PARAMS ((void));
|
|
|
|
|
static int one_classic_gcse_pass PARAMS ((int));
|
|
|
|
|
static void invalidate_nonnull_info PARAMS ((rtx, rtx, void *));
|
2001-04-04 22:19:23 +02:00
|
|
|
|
static void delete_null_pointer_checks_1 PARAMS ((varray_type *, unsigned int *,
|
|
|
|
|
sbitmap *, sbitmap *,
|
2000-01-14 18:14:43 +01:00
|
|
|
|
struct null_pointer_info *));
|
|
|
|
|
static rtx process_insert_insn PARAMS ((struct expr *));
|
|
|
|
|
static int pre_edge_insert PARAMS ((struct edge_list *, struct expr **));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
static int expr_reaches_here_p_work PARAMS ((struct occr *, struct expr *,
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block, int, char *));
|
|
|
|
|
static int pre_expr_reaches_here_p_work PARAMS ((basic_block, struct expr *,
|
|
|
|
|
basic_block, char *));
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
static struct ls_expr * ldst_entry PARAMS ((rtx));
|
|
|
|
|
static void free_ldst_entry PARAMS ((struct ls_expr *));
|
|
|
|
|
static void free_ldst_mems PARAMS ((void));
|
|
|
|
|
static void print_ldst_list PARAMS ((FILE *));
|
|
|
|
|
static struct ls_expr * find_rtx_in_ldst PARAMS ((rtx));
|
|
|
|
|
static int enumerate_ldsts PARAMS ((void));
|
|
|
|
|
static inline struct ls_expr * first_ls_expr PARAMS ((void));
|
|
|
|
|
static inline struct ls_expr * next_ls_expr PARAMS ((struct ls_expr *));
|
|
|
|
|
static int simple_mem PARAMS ((rtx));
|
|
|
|
|
static void invalidate_any_buried_refs PARAMS ((rtx));
|
|
|
|
|
static void compute_ld_motion_mems PARAMS ((void));
|
|
|
|
|
static void trim_ld_motion_mems PARAMS ((void));
|
|
|
|
|
static void update_ld_motion_stores PARAMS ((struct expr *));
|
|
|
|
|
static void reg_set_info PARAMS ((rtx, rtx, void *));
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
static int store_ops_ok PARAMS ((rtx, basic_block));
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
static void find_moveable_store PARAMS ((rtx));
|
|
|
|
|
static int compute_store_table PARAMS ((void));
|
|
|
|
|
static int load_kills_store PARAMS ((rtx, rtx));
|
|
|
|
|
static int find_loads PARAMS ((rtx, rtx));
|
|
|
|
|
static int store_killed_in_insn PARAMS ((rtx, rtx));
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
static int store_killed_after PARAMS ((rtx, rtx, basic_block));
|
|
|
|
|
static int store_killed_before PARAMS ((rtx, rtx, basic_block));
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
static void build_store_vectors PARAMS ((void));
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
static void insert_insn_start_bb PARAMS ((rtx, basic_block));
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
static int insert_store PARAMS ((struct ls_expr *, edge));
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
static void replace_store_insn PARAMS ((rtx, rtx, basic_block));
|
|
|
|
|
static void delete_store PARAMS ((struct ls_expr *,
|
|
|
|
|
basic_block));
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
static void free_store_memory PARAMS ((void));
|
|
|
|
|
static void store_motion PARAMS ((void));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Entry point for global common subexpression elimination.
|
|
|
|
|
F is the first instruction in the function. */
|
|
|
|
|
|
1999-03-10 20:45:18 +01:00
|
|
|
|
int
|
1998-05-20 02:24:32 +02:00
|
|
|
|
gcse_main (f, file)
|
|
|
|
|
rtx f;
|
|
|
|
|
FILE *file;
|
|
|
|
|
{
|
|
|
|
|
int changed, pass;
|
|
|
|
|
/* Bytes used at start of pass. */
|
|
|
|
|
int initial_bytes_used;
|
|
|
|
|
/* Maximum number of bytes used by a pass. */
|
|
|
|
|
int max_pass_bytes;
|
|
|
|
|
/* Point to release obstack data from for each pass. */
|
|
|
|
|
char *gcse_obstack_bottom;
|
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* Insertion of instructions on edges can create new basic blocks; we
|
|
|
|
|
need the original basic block count so that we can properly deallocate
|
|
|
|
|
arrays sized on the number of basic blocks originally in the cfg. */
|
|
|
|
|
int orig_bb_count;
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
/* We do not construct an accurate cfg in functions which call
|
|
|
|
|
setjmp, so just punt to be safe. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (current_function_calls_setjmp)
|
1999-03-10 20:45:18 +01:00
|
|
|
|
return 0;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
/* Assume that we do not need to run jump optimizations after gcse. */
|
|
|
|
|
run_jump_opt_after_gcse = 0;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* For calling dump_foo fns from gdb. */
|
|
|
|
|
debug_stderr = stderr;
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
gcse_file = file;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
/* Identify the basic block information for this function, including
|
|
|
|
|
successors and predecessors. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
max_gcse_regno = max_reg_num ();
|
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
if (file)
|
|
|
|
|
dump_flow_info (file);
|
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
orig_bb_count = n_basic_blocks;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Return if there's nothing to do. */
|
|
|
|
|
if (n_basic_blocks <= 1)
|
2000-04-07 11:23:29 +02:00
|
|
|
|
return 0;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-10-10 07:30:28 +02:00
|
|
|
|
/* Trying to perform global optimizations on flow graphs which have
|
|
|
|
|
a high connectivity will take a long time and is unlikely to be
|
|
|
|
|
particularly useful.
|
|
|
|
|
|
|
|
|
|
In normal circumstances a cfg should have about twice has many edges
|
|
|
|
|
as blocks. But we do not want to punish small functions which have
|
|
|
|
|
a couple switch statements. So we require a relatively large number
|
|
|
|
|
of basic blocks and the ratio of edges to blocks to be high. */
|
|
|
|
|
if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
|
2000-09-22 09:22:07 +02:00
|
|
|
|
{
|
|
|
|
|
if (warn_disabled_optimization)
|
|
|
|
|
warning ("GCSE disabled: %d > 1000 basic blocks and %d >= 20 edges/basic block",
|
|
|
|
|
n_basic_blocks, n_edges / n_basic_blocks);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1999-10-10 07:30:28 +02:00
|
|
|
|
|
2001-04-11 20:22:46 +02:00
|
|
|
|
/* If allocating memory for the cprop bitmap would take up too much
|
|
|
|
|
storage it's better just to disable the optimization. */
|
|
|
|
|
if ((n_basic_blocks
|
|
|
|
|
* SBITMAP_SET_SIZE (max_gcse_regno)
|
|
|
|
|
* sizeof (SBITMAP_ELT_TYPE)) > MAX_GCSE_MEMORY)
|
|
|
|
|
{
|
|
|
|
|
if (warn_disabled_optimization)
|
|
|
|
|
warning ("GCSE disabled: %d basic blocks and %d registers",
|
|
|
|
|
n_basic_blocks, max_gcse_regno);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* See what modes support reg/reg copy operations. */
|
|
|
|
|
if (! can_copy_init_p)
|
|
|
|
|
{
|
|
|
|
|
compute_can_copy ();
|
|
|
|
|
can_copy_init_p = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gcc_obstack_init (&gcse_obstack);
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
bytes_used = 0;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* We need alias. */
|
|
|
|
|
init_alias_analysis ();
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Record where pseudo-registers are set. This data is kept accurate
|
|
|
|
|
during each pass. ??? We could also record hard-reg information here
|
|
|
|
|
[since it's unchanging], however it is currently done during hash table
|
|
|
|
|
computation.
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
It may be tempting to compute MEM set information here too, but MEM sets
|
|
|
|
|
will be subject to code motion one day and thus we need to compute
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
information about memory sets when we build the hash tables. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
alloc_reg_set_mem (max_gcse_regno);
|
|
|
|
|
compute_sets (f);
|
|
|
|
|
|
|
|
|
|
pass = 0;
|
|
|
|
|
initial_bytes_used = bytes_used;
|
|
|
|
|
max_pass_bytes = 0;
|
|
|
|
|
gcse_obstack_bottom = gcse_alloc (1);
|
|
|
|
|
changed = 1;
|
|
|
|
|
while (changed && pass < MAX_PASSES)
|
|
|
|
|
{
|
|
|
|
|
changed = 0;
|
|
|
|
|
if (file)
|
|
|
|
|
fprintf (file, "GCSE pass %d\n\n", pass + 1);
|
|
|
|
|
|
|
|
|
|
/* Initialize bytes_used to the space for the pred/succ lists,
|
|
|
|
|
and the reg_set_table data. */
|
|
|
|
|
bytes_used = initial_bytes_used;
|
|
|
|
|
|
|
|
|
|
/* Each pass may create new registers, so recalculate each time. */
|
|
|
|
|
max_gcse_regno = max_reg_num ();
|
|
|
|
|
|
|
|
|
|
alloc_gcse_mem (f);
|
|
|
|
|
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
/* Don't allow constant propagation to modify jumps
|
|
|
|
|
during this pass. */
|
|
|
|
|
changed = one_cprop_pass (pass + 1, 0);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (optimize_size)
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
changed |= one_classic_gcse_pass (pass + 1);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
{
|
|
|
|
|
changed |= one_pre_gcse_pass (pass + 1);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* We may have just created new basic blocks. Release and
|
|
|
|
|
recompute various things which are sized on the number of
|
|
|
|
|
basic blocks. */
|
|
|
|
|
if (changed)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < orig_bb_count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (modify_mem_list[i])
|
|
|
|
|
free_INSN_LIST_list (modify_mem_list + i);
|
|
|
|
|
if (canon_modify_mem_list[i])
|
|
|
|
|
free_INSN_LIST_list (canon_modify_mem_list + i);
|
|
|
|
|
}
|
|
|
|
|
modify_mem_list
|
|
|
|
|
= (rtx *) gmalloc (n_basic_blocks * sizeof (rtx *));
|
|
|
|
|
canon_modify_mem_list
|
|
|
|
|
= (rtx *) gmalloc (n_basic_blocks * sizeof (rtx *));
|
|
|
|
|
memset ((char *) modify_mem_list, 0, n_basic_blocks * sizeof (rtx *));
|
|
|
|
|
memset ((char *) canon_modify_mem_list, 0, n_basic_blocks * sizeof (rtx *));
|
|
|
|
|
orig_bb_count = n_basic_blocks;
|
|
|
|
|
}
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
free_reg_set_mem ();
|
|
|
|
|
alloc_reg_set_mem (max_reg_num ());
|
|
|
|
|
compute_sets (f);
|
|
|
|
|
run_jump_opt_after_gcse = 1;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (max_pass_bytes < bytes_used)
|
|
|
|
|
max_pass_bytes = bytes_used;
|
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
/* Free up memory, then reallocate for code hoisting. We can
|
|
|
|
|
not re-use the existing allocated memory because the tables
|
|
|
|
|
will not have info for the insns or registers created by
|
|
|
|
|
partial redundancy elimination. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
free_gcse_mem ();
|
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
/* It does not make sense to run code hoisting unless we optimizing
|
|
|
|
|
for code size -- it rarely makes programs faster, and can make
|
|
|
|
|
them bigger if we did partial redundancy elimination (when optimizing
|
|
|
|
|
for space, we use a classic gcse algorithm instead of partial
|
|
|
|
|
redundancy algorithms). */
|
|
|
|
|
if (optimize_size)
|
|
|
|
|
{
|
|
|
|
|
max_gcse_regno = max_reg_num ();
|
|
|
|
|
alloc_gcse_mem (f);
|
|
|
|
|
changed |= one_code_hoisting_pass ();
|
|
|
|
|
free_gcse_mem ();
|
|
|
|
|
|
|
|
|
|
if (max_pass_bytes < bytes_used)
|
|
|
|
|
max_pass_bytes = bytes_used;
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (file, "\n");
|
|
|
|
|
fflush (file);
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
obstack_free (&gcse_obstack, gcse_obstack_bottom);
|
|
|
|
|
pass++;
|
|
|
|
|
}
|
|
|
|
|
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
/* Do one last pass of copy propagation, including cprop into
|
|
|
|
|
conditional jumps. */
|
|
|
|
|
|
|
|
|
|
max_gcse_regno = max_reg_num ();
|
|
|
|
|
alloc_gcse_mem (f);
|
|
|
|
|
/* This time, go ahead and allow cprop to alter jumps. */
|
|
|
|
|
one_cprop_pass (pass + 1, 1);
|
|
|
|
|
free_gcse_mem ();
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (file, "GCSE of %s: %d basic blocks, ",
|
|
|
|
|
current_function_name, n_basic_blocks);
|
|
|
|
|
fprintf (file, "%d pass%s, %d bytes\n\n",
|
|
|
|
|
pass, pass > 1 ? "es" : "", max_pass_bytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
obstack_free (&gcse_obstack, NULL_PTR);
|
|
|
|
|
free_reg_set_mem ();
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* We are finished with alias. */
|
|
|
|
|
end_alias_analysis ();
|
|
|
|
|
allocate_reg_info (max_reg_num (), FALSE, FALSE);
|
|
|
|
|
|
|
|
|
|
if (!optimize_size && flag_gcse_sm)
|
|
|
|
|
store_motion ();
|
|
|
|
|
/* Record where pseudo-registers are set. */
|
1999-03-10 20:45:18 +01:00
|
|
|
|
return run_jump_opt_after_gcse;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Misc. utilities. */
|
|
|
|
|
|
|
|
|
|
/* Compute which modes support reg/reg copy operations. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_can_copy ()
|
|
|
|
|
{
|
|
|
|
|
int i;
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
#ifndef AVOID_CCMODE_COPIES
|
1998-05-20 02:24:32 +02:00
|
|
|
|
rtx reg,insn;
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
#endif
|
alias.c [...] (init_alias_analysis, [...]): Use memset () instead of bzero ().
* alias.c (init_alias_analysis), calls.c (expand_call,
emit_library_call_value_1), combine.c (init_reg_last_arrays),
cse.c (new_basic_block), dbxout.c (dbxout_type), diagnostic.c
(init_output_buffer, set_diagnostic_context), dwarf2out.c
(equate_decl_number_to_die, build_abbrev_table), emit-rtl.c
(init_emit_once), fold-const.c (mul_double, div_and_round_double),
function.c (assign_parms), gcse.c (compute_can_copy,
alloc_gcse_mem, alloc_reg_set_mem, record_one_set,
compute_hash_table, compute_set_hash_table,
compute_expr_hash_table), genattrtab.c (optimize_attrs), global.c
(global_alloc, global_conflicts), haifa-sched.c (compute_trg_info,
clear_units, schedule_block), integrate.c (initialize_for_inline,
expand_inline_function), jump.c (thread_jumps), local-alloc.c
(local_alloc), loop.c (combine_movables, count_loop_regs_set,
load_mems_and_recount_loop_regs_set), print-tree.c (debug_tree),
regclass.c (init_reg_sets, init_reg_sets_1, regclass,
record_reg_classes, allocate_reg_info), reload.c
(get_secondary_mem, remove_address_replacements, find_reloads),
reload1.c (reload, set_initial_label_offsets, finish_spills,
reload_as_needed, choose_reload_regs_init,
reload_cse_simplify_operands), reorg.c (dbr_schedule), sbitmap.c
(sbitmap_zero), simplify-rtx.c (simplify_plus_minus), ssa.c
(rename_registers), stmt.c (expand_end_case), unroll.c
(unroll_loop), varray.c (varray_grow), objc/objc-act.c: Use memset
() instead of bzero ().
ch:
* actions.c (check_missing_cases), typeck.c (build_chill_slice,
build_chill_cast): Use memset () instead of bzero ().
cp:
* class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
(push_binding_level), error.c (cp_tree_printer), pt.c
(process_partial_specialization, tsubst_template_arg_vector),
search.c (lookup_member): Use memset () instead of bzero ().
java:
* expr.c (note_instructions), jcf-io.c (find_class), jcf-parse.c
(init_outgoing_cpool), lex.c (java_init_lex): Use memset ()
instead of bzero ().
From-SVN: r37303
2000-11-07 23:50:06 +01:00
|
|
|
|
memset (can_copy_p, 0, NUM_MACHINE_MODES);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
start_sequence ();
|
|
|
|
|
for (i = 0; i < NUM_MACHINE_MODES; i++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (GET_MODE_CLASS (i) == MODE_CC)
|
|
|
|
|
{
|
1998-05-20 02:24:32 +02:00
|
|
|
|
#ifdef AVOID_CCMODE_COPIES
|
2000-02-29 21:08:52 +01:00
|
|
|
|
can_copy_p[i] = 0;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
#else
|
2000-02-29 21:08:52 +01:00
|
|
|
|
reg = gen_rtx_REG ((enum machine_mode) i, LAST_VIRTUAL_REGISTER + 1);
|
|
|
|
|
insn = emit_insn (gen_rtx_SET (VOIDmode, reg, reg));
|
|
|
|
|
if (recog (PATTERN (insn), insn, NULL_PTR) >= 0)
|
|
|
|
|
can_copy_p[i] = 1;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
#endif
|
2000-02-29 21:08:52 +01:00
|
|
|
|
}
|
2000-03-07 04:43:03 +01:00
|
|
|
|
else
|
|
|
|
|
can_copy_p[i] = 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
end_sequence ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Cover function to xmalloc to record bytes allocated. */
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
gmalloc (size)
|
|
|
|
|
unsigned int size;
|
|
|
|
|
{
|
|
|
|
|
bytes_used += size;
|
|
|
|
|
return xmalloc (size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Cover function to xrealloc.
|
|
|
|
|
We don't record the additional size since we don't know it.
|
|
|
|
|
It won't affect memory usage stats much anyway. */
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
grealloc (ptr, size)
|
|
|
|
|
char *ptr;
|
|
|
|
|
unsigned int size;
|
|
|
|
|
{
|
|
|
|
|
return xrealloc (ptr, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Cover function to obstack_alloc.
|
|
|
|
|
We don't need to record the bytes allocated here since
|
|
|
|
|
obstack_chunk_alloc is set to gmalloc. */
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
gcse_alloc (size)
|
|
|
|
|
unsigned long size;
|
|
|
|
|
{
|
|
|
|
|
return (char *) obstack_alloc (&gcse_obstack, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Allocate memory for the cuid mapping array,
|
|
|
|
|
and reg/memory set tracking tables.
|
|
|
|
|
|
|
|
|
|
This is called at the start of each pass. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
alloc_gcse_mem (f)
|
|
|
|
|
rtx f;
|
|
|
|
|
{
|
|
|
|
|
int i,n;
|
|
|
|
|
rtx insn;
|
|
|
|
|
|
|
|
|
|
/* Find the largest UID and create a mapping from UIDs to CUIDs.
|
|
|
|
|
CUIDs are like UIDs except they increase monotonically, have no gaps,
|
|
|
|
|
and only apply to real insns. */
|
|
|
|
|
|
|
|
|
|
max_uid = get_max_uid ();
|
|
|
|
|
n = (max_uid + 1) * sizeof (int);
|
|
|
|
|
uid_cuid = (int *) gmalloc (n);
|
alias.c [...] (init_alias_analysis, [...]): Use memset () instead of bzero ().
* alias.c (init_alias_analysis), calls.c (expand_call,
emit_library_call_value_1), combine.c (init_reg_last_arrays),
cse.c (new_basic_block), dbxout.c (dbxout_type), diagnostic.c
(init_output_buffer, set_diagnostic_context), dwarf2out.c
(equate_decl_number_to_die, build_abbrev_table), emit-rtl.c
(init_emit_once), fold-const.c (mul_double, div_and_round_double),
function.c (assign_parms), gcse.c (compute_can_copy,
alloc_gcse_mem, alloc_reg_set_mem, record_one_set,
compute_hash_table, compute_set_hash_table,
compute_expr_hash_table), genattrtab.c (optimize_attrs), global.c
(global_alloc, global_conflicts), haifa-sched.c (compute_trg_info,
clear_units, schedule_block), integrate.c (initialize_for_inline,
expand_inline_function), jump.c (thread_jumps), local-alloc.c
(local_alloc), loop.c (combine_movables, count_loop_regs_set,
load_mems_and_recount_loop_regs_set), print-tree.c (debug_tree),
regclass.c (init_reg_sets, init_reg_sets_1, regclass,
record_reg_classes, allocate_reg_info), reload.c
(get_secondary_mem, remove_address_replacements, find_reloads),
reload1.c (reload, set_initial_label_offsets, finish_spills,
reload_as_needed, choose_reload_regs_init,
reload_cse_simplify_operands), reorg.c (dbr_schedule), sbitmap.c
(sbitmap_zero), simplify-rtx.c (simplify_plus_minus), ssa.c
(rename_registers), stmt.c (expand_end_case), unroll.c
(unroll_loop), varray.c (varray_grow), objc/objc-act.c: Use memset
() instead of bzero ().
ch:
* actions.c (check_missing_cases), typeck.c (build_chill_slice,
build_chill_cast): Use memset () instead of bzero ().
cp:
* class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
(push_binding_level), error.c (cp_tree_printer), pt.c
(process_partial_specialization, tsubst_template_arg_vector),
search.c (lookup_member): Use memset () instead of bzero ().
java:
* expr.c (note_instructions), jcf-io.c (find_class), jcf-parse.c
(init_outgoing_cpool), lex.c (java_init_lex): Use memset ()
instead of bzero ().
From-SVN: r37303
2000-11-07 23:50:06 +01:00
|
|
|
|
memset ((char *) uid_cuid, 0, n);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
|
|
|
|
|
{
|
2000-08-04 22:28:08 +02:00
|
|
|
|
if (INSN_P (insn))
|
2000-07-19 19:22:01 +02:00
|
|
|
|
uid_cuid[INSN_UID (insn)] = i++;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
2000-07-19 19:22:01 +02:00
|
|
|
|
uid_cuid[INSN_UID (insn)] = i;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create a table mapping cuids to insns. */
|
|
|
|
|
|
|
|
|
|
max_cuid = i;
|
|
|
|
|
n = (max_cuid + 1) * sizeof (rtx);
|
|
|
|
|
cuid_insn = (rtx *) gmalloc (n);
|
alias.c [...] (init_alias_analysis, [...]): Use memset () instead of bzero ().
* alias.c (init_alias_analysis), calls.c (expand_call,
emit_library_call_value_1), combine.c (init_reg_last_arrays),
cse.c (new_basic_block), dbxout.c (dbxout_type), diagnostic.c
(init_output_buffer, set_diagnostic_context), dwarf2out.c
(equate_decl_number_to_die, build_abbrev_table), emit-rtl.c
(init_emit_once), fold-const.c (mul_double, div_and_round_double),
function.c (assign_parms), gcse.c (compute_can_copy,
alloc_gcse_mem, alloc_reg_set_mem, record_one_set,
compute_hash_table, compute_set_hash_table,
compute_expr_hash_table), genattrtab.c (optimize_attrs), global.c
(global_alloc, global_conflicts), haifa-sched.c (compute_trg_info,
clear_units, schedule_block), integrate.c (initialize_for_inline,
expand_inline_function), jump.c (thread_jumps), local-alloc.c
(local_alloc), loop.c (combine_movables, count_loop_regs_set,
load_mems_and_recount_loop_regs_set), print-tree.c (debug_tree),
regclass.c (init_reg_sets, init_reg_sets_1, regclass,
record_reg_classes, allocate_reg_info), reload.c
(get_secondary_mem, remove_address_replacements, find_reloads),
reload1.c (reload, set_initial_label_offsets, finish_spills,
reload_as_needed, choose_reload_regs_init,
reload_cse_simplify_operands), reorg.c (dbr_schedule), sbitmap.c
(sbitmap_zero), simplify-rtx.c (simplify_plus_minus), ssa.c
(rename_registers), stmt.c (expand_end_case), unroll.c
(unroll_loop), varray.c (varray_grow), objc/objc-act.c: Use memset
() instead of bzero ().
ch:
* actions.c (check_missing_cases), typeck.c (build_chill_slice,
build_chill_cast): Use memset () instead of bzero ().
cp:
* class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
(push_binding_level), error.c (cp_tree_printer), pt.c
(process_partial_specialization, tsubst_template_arg_vector),
search.c (lookup_member): Use memset () instead of bzero ().
java:
* expr.c (note_instructions), jcf-io.c (find_class), jcf-parse.c
(init_outgoing_cpool), lex.c (java_init_lex): Use memset ()
instead of bzero ().
From-SVN: r37303
2000-11-07 23:50:06 +01:00
|
|
|
|
memset ((char *) cuid_insn, 0, n);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
|
2000-08-04 22:28:08 +02:00
|
|
|
|
if (INSN_P (insn))
|
2000-02-29 21:08:52 +01:00
|
|
|
|
CUID_INSN (i++) = insn;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Allocate vars to track sets of regs. */
|
|
|
|
|
reg_set_bitmap = (sbitmap) sbitmap_alloc (max_gcse_regno);
|
|
|
|
|
|
|
|
|
|
/* Allocate vars to track sets of regs, memory per block. */
|
|
|
|
|
reg_set_in_block = (sbitmap *) sbitmap_vector_alloc (n_basic_blocks,
|
|
|
|
|
max_gcse_regno);
|
|
|
|
|
mem_set_in_block = (char *) gmalloc (n_basic_blocks);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* Allocate array to keep a list of insns which modify memory in each
|
|
|
|
|
basic block. */
|
|
|
|
|
modify_mem_list = (rtx *) gmalloc (n_basic_blocks * sizeof (rtx *));
|
|
|
|
|
canon_modify_mem_list = (rtx *) gmalloc (n_basic_blocks * sizeof (rtx *));
|
|
|
|
|
memset ((char *) modify_mem_list, 0, n_basic_blocks * sizeof (rtx *));
|
|
|
|
|
memset ((char *) canon_modify_mem_list, 0, n_basic_blocks * sizeof (rtx *));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free memory allocated by alloc_gcse_mem. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_gcse_mem ()
|
|
|
|
|
{
|
|
|
|
|
free (uid_cuid);
|
|
|
|
|
free (cuid_insn);
|
|
|
|
|
|
|
|
|
|
free (reg_set_bitmap);
|
|
|
|
|
|
|
|
|
|
free (reg_set_in_block);
|
|
|
|
|
free (mem_set_in_block);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* re-Cache any INSN_LIST nodes we have allocated. */
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < n_basic_blocks; i++)
|
|
|
|
|
{
|
|
|
|
|
if (modify_mem_list[i])
|
|
|
|
|
free_INSN_LIST_list (modify_mem_list + i);
|
|
|
|
|
if (canon_modify_mem_list[i])
|
|
|
|
|
free_INSN_LIST_list (canon_modify_mem_list + i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free (modify_mem_list);
|
|
|
|
|
free (canon_modify_mem_list);
|
|
|
|
|
modify_mem_list = 0;
|
|
|
|
|
canon_modify_mem_list = 0;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-11-03 23:45:45 +01:00
|
|
|
|
/* Many of the global optimization algorithms work by solving dataflow
|
|
|
|
|
equations for various expressions. Initially, some local value is
|
2000-02-29 21:08:52 +01:00
|
|
|
|
computed for each expression in each block. Then, the values across the
|
|
|
|
|
various blocks are combined (by following flow graph edges) to arrive at
|
|
|
|
|
global values. Conceptually, each set of equations is independent. We
|
|
|
|
|
may therefore solve all the equations in parallel, solve them one at a
|
|
|
|
|
time, or pick any intermediate approach.
|
|
|
|
|
|
|
|
|
|
When you're going to need N two-dimensional bitmaps, each X (say, the
|
|
|
|
|
number of blocks) by Y (say, the number of expressions), call this
|
|
|
|
|
function. It's not important what X and Y represent; only that Y
|
|
|
|
|
correspond to the things that can be done in parallel. This function will
|
|
|
|
|
return an appropriate chunking factor C; you should solve C sets of
|
|
|
|
|
equations in parallel. By going through this function, we can easily
|
|
|
|
|
trade space against time; by solving fewer equations in parallel we use
|
|
|
|
|
less space. */
|
1999-11-03 23:45:45 +01:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
get_bitmap_width (n, x, y)
|
|
|
|
|
int n;
|
|
|
|
|
int x;
|
|
|
|
|
int y;
|
|
|
|
|
{
|
|
|
|
|
/* It's not really worth figuring out *exactly* how much memory will
|
|
|
|
|
be used by a particular choice. The important thing is to get
|
|
|
|
|
something approximately right. */
|
|
|
|
|
size_t max_bitmap_memory = 10 * 1024 * 1024;
|
|
|
|
|
|
|
|
|
|
/* The number of bytes we'd use for a single column of minimum
|
|
|
|
|
width. */
|
|
|
|
|
size_t column_size = n * x * sizeof (SBITMAP_ELT_TYPE);
|
|
|
|
|
|
|
|
|
|
/* Often, it's reasonable just to solve all the equations in
|
|
|
|
|
parallel. */
|
|
|
|
|
if (column_size * SBITMAP_SET_SIZE (y) <= max_bitmap_memory)
|
|
|
|
|
return y;
|
|
|
|
|
|
|
|
|
|
/* Otherwise, pick the largest width we can, without going over the
|
|
|
|
|
limit. */
|
|
|
|
|
return SBITMAP_ELT_BITS * ((max_bitmap_memory + column_size - 1)
|
|
|
|
|
/ column_size);
|
|
|
|
|
}
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
|
|
|
|
/* Compute the local properties of each recorded expression.
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
Local properties are those that are defined by the block, irrespective of
|
|
|
|
|
other blocks.
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
|
|
|
|
An expression is transparent in a block if its operands are not modified
|
|
|
|
|
in the block.
|
|
|
|
|
|
|
|
|
|
An expression is computed (locally available) in a block if it is computed
|
|
|
|
|
at least once and expression would contain the same value if the
|
|
|
|
|
computation was moved to the end of the block.
|
|
|
|
|
|
|
|
|
|
An expression is locally anticipatable in a block if it is computed at
|
|
|
|
|
least once and expression would contain the same value if the computation
|
|
|
|
|
was moved to the beginning of the block.
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
We call this routine for cprop, pre and code hoisting. They all compute
|
|
|
|
|
basically the same information and thus can easily share this code.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
TRANSP, COMP, and ANTLOC are destination sbitmaps for recording local
|
|
|
|
|
properties. If NULL, then it is not necessary to compute or record that
|
|
|
|
|
particular property.
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
SETP controls which hash table to look at. If zero, this routine looks at
|
|
|
|
|
the expr hash table; if nonzero this routine looks at the set hash table.
|
|
|
|
|
Additionally, TRANSP is computed as ~TRANSP, since this is really cprop's
|
|
|
|
|
ABSALTERED. */
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_local_properties (transp, comp, antloc, setp)
|
|
|
|
|
sbitmap *transp;
|
|
|
|
|
sbitmap *comp;
|
|
|
|
|
sbitmap *antloc;
|
|
|
|
|
int setp;
|
|
|
|
|
{
|
2000-04-10 13:33:18 +02:00
|
|
|
|
unsigned int i, hash_table_size;
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
struct expr **hash_table;
|
|
|
|
|
|
|
|
|
|
/* Initialize any bitmaps that were passed in. */
|
|
|
|
|
if (transp)
|
1999-04-17 23:33:24 +02:00
|
|
|
|
{
|
|
|
|
|
if (setp)
|
|
|
|
|
sbitmap_vector_zero (transp, n_basic_blocks);
|
|
|
|
|
else
|
|
|
|
|
sbitmap_vector_ones (transp, n_basic_blocks);
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
if (comp)
|
|
|
|
|
sbitmap_vector_zero (comp, n_basic_blocks);
|
|
|
|
|
if (antloc)
|
|
|
|
|
sbitmap_vector_zero (antloc, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
/* We use the same code for cprop, pre and hoisting. For cprop
|
|
|
|
|
we care about the set hash table, for pre and hoisting we
|
|
|
|
|
care about the expr hash table. */
|
|
|
|
|
hash_table_size = setp ? set_hash_table_size : expr_hash_table_size;
|
|
|
|
|
hash_table = setp ? set_hash_table : expr_hash_table;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < hash_table_size; i++)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
struct expr *expr;
|
|
|
|
|
|
|
|
|
|
for (expr = hash_table[i]; expr != NULL; expr = expr->next_same_hash)
|
|
|
|
|
{
|
|
|
|
|
int indx = expr->bitmap_index;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct occr *occr;
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
|
|
|
|
/* The expression is transparent in this block if it is not killed.
|
|
|
|
|
We start by assuming all are transparent [none are killed], and
|
|
|
|
|
then reset the bits for those that are. */
|
|
|
|
|
if (transp)
|
|
|
|
|
compute_transp (expr->expr, indx, transp, setp);
|
|
|
|
|
|
|
|
|
|
/* The occurrences recorded in antic_occr are exactly those that
|
|
|
|
|
we want to set to non-zero in ANTLOC. */
|
|
|
|
|
if (antloc)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
|
|
|
|
|
{
|
|
|
|
|
SET_BIT (antloc[BLOCK_NUM (occr->insn)], indx);
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* While we're scanning the table, this is a good place to
|
|
|
|
|
initialize this. */
|
|
|
|
|
occr->deleted_p = 0;
|
|
|
|
|
}
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
|
|
|
|
/* The occurrences recorded in avail_occr are exactly those that
|
|
|
|
|
we want to set to non-zero in COMP. */
|
|
|
|
|
if (comp)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
|
|
|
|
|
{
|
|
|
|
|
SET_BIT (comp[BLOCK_NUM (occr->insn)], indx);
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* While we're scanning the table, this is a good place to
|
|
|
|
|
initialize this. */
|
|
|
|
|
occr->copied_p = 0;
|
|
|
|
|
}
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
|
|
|
|
/* While we're scanning the table, this is a good place to
|
|
|
|
|
initialize this. */
|
|
|
|
|
expr->reaching_reg = 0;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Register set information.
|
|
|
|
|
|
|
|
|
|
`reg_set_table' records where each register is set or otherwise
|
|
|
|
|
modified. */
|
|
|
|
|
|
|
|
|
|
static struct obstack reg_set_obstack;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
alloc_reg_set_mem (n_regs)
|
|
|
|
|
int n_regs;
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
unsigned int n;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
reg_set_table_size = n_regs + REG_SET_TABLE_SLOP;
|
|
|
|
|
n = reg_set_table_size * sizeof (struct reg_set *);
|
|
|
|
|
reg_set_table = (struct reg_set **) gmalloc (n);
|
alias.c [...] (init_alias_analysis, [...]): Use memset () instead of bzero ().
* alias.c (init_alias_analysis), calls.c (expand_call,
emit_library_call_value_1), combine.c (init_reg_last_arrays),
cse.c (new_basic_block), dbxout.c (dbxout_type), diagnostic.c
(init_output_buffer, set_diagnostic_context), dwarf2out.c
(equate_decl_number_to_die, build_abbrev_table), emit-rtl.c
(init_emit_once), fold-const.c (mul_double, div_and_round_double),
function.c (assign_parms), gcse.c (compute_can_copy,
alloc_gcse_mem, alloc_reg_set_mem, record_one_set,
compute_hash_table, compute_set_hash_table,
compute_expr_hash_table), genattrtab.c (optimize_attrs), global.c
(global_alloc, global_conflicts), haifa-sched.c (compute_trg_info,
clear_units, schedule_block), integrate.c (initialize_for_inline,
expand_inline_function), jump.c (thread_jumps), local-alloc.c
(local_alloc), loop.c (combine_movables, count_loop_regs_set,
load_mems_and_recount_loop_regs_set), print-tree.c (debug_tree),
regclass.c (init_reg_sets, init_reg_sets_1, regclass,
record_reg_classes, allocate_reg_info), reload.c
(get_secondary_mem, remove_address_replacements, find_reloads),
reload1.c (reload, set_initial_label_offsets, finish_spills,
reload_as_needed, choose_reload_regs_init,
reload_cse_simplify_operands), reorg.c (dbr_schedule), sbitmap.c
(sbitmap_zero), simplify-rtx.c (simplify_plus_minus), ssa.c
(rename_registers), stmt.c (expand_end_case), unroll.c
(unroll_loop), varray.c (varray_grow), objc/objc-act.c: Use memset
() instead of bzero ().
ch:
* actions.c (check_missing_cases), typeck.c (build_chill_slice,
build_chill_cast): Use memset () instead of bzero ().
cp:
* class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
(push_binding_level), error.c (cp_tree_printer), pt.c
(process_partial_specialization, tsubst_template_arg_vector),
search.c (lookup_member): Use memset () instead of bzero ().
java:
* expr.c (note_instructions), jcf-io.c (find_class), jcf-parse.c
(init_outgoing_cpool), lex.c (java_init_lex): Use memset ()
instead of bzero ().
From-SVN: r37303
2000-11-07 23:50:06 +01:00
|
|
|
|
memset ((char *) reg_set_table, 0, n);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
gcc_obstack_init (®_set_obstack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_reg_set_mem ()
|
|
|
|
|
{
|
|
|
|
|
free (reg_set_table);
|
|
|
|
|
obstack_free (®_set_obstack, NULL_PTR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Record REGNO in the reg_set table. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
record_one_set (regno, insn)
|
|
|
|
|
int regno;
|
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* Allocate a new reg_set element and link it onto the list. */
|
2000-07-28 18:08:54 +02:00
|
|
|
|
struct reg_set *new_reg_info;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* If the table isn't big enough, enlarge it. */
|
|
|
|
|
if (regno >= reg_set_table_size)
|
|
|
|
|
{
|
|
|
|
|
int new_size = regno + REG_SET_TABLE_SLOP;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
reg_set_table
|
|
|
|
|
= (struct reg_set **) grealloc ((char *) reg_set_table,
|
|
|
|
|
new_size * sizeof (struct reg_set *));
|
alias.c [...] (init_alias_analysis, [...]): Use memset () instead of bzero ().
* alias.c (init_alias_analysis), calls.c (expand_call,
emit_library_call_value_1), combine.c (init_reg_last_arrays),
cse.c (new_basic_block), dbxout.c (dbxout_type), diagnostic.c
(init_output_buffer, set_diagnostic_context), dwarf2out.c
(equate_decl_number_to_die, build_abbrev_table), emit-rtl.c
(init_emit_once), fold-const.c (mul_double, div_and_round_double),
function.c (assign_parms), gcse.c (compute_can_copy,
alloc_gcse_mem, alloc_reg_set_mem, record_one_set,
compute_hash_table, compute_set_hash_table,
compute_expr_hash_table), genattrtab.c (optimize_attrs), global.c
(global_alloc, global_conflicts), haifa-sched.c (compute_trg_info,
clear_units, schedule_block), integrate.c (initialize_for_inline,
expand_inline_function), jump.c (thread_jumps), local-alloc.c
(local_alloc), loop.c (combine_movables, count_loop_regs_set,
load_mems_and_recount_loop_regs_set), print-tree.c (debug_tree),
regclass.c (init_reg_sets, init_reg_sets_1, regclass,
record_reg_classes, allocate_reg_info), reload.c
(get_secondary_mem, remove_address_replacements, find_reloads),
reload1.c (reload, set_initial_label_offsets, finish_spills,
reload_as_needed, choose_reload_regs_init,
reload_cse_simplify_operands), reorg.c (dbr_schedule), sbitmap.c
(sbitmap_zero), simplify-rtx.c (simplify_plus_minus), ssa.c
(rename_registers), stmt.c (expand_end_case), unroll.c
(unroll_loop), varray.c (varray_grow), objc/objc-act.c: Use memset
() instead of bzero ().
ch:
* actions.c (check_missing_cases), typeck.c (build_chill_slice,
build_chill_cast): Use memset () instead of bzero ().
cp:
* class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
(push_binding_level), error.c (cp_tree_printer), pt.c
(process_partial_specialization, tsubst_template_arg_vector),
search.c (lookup_member): Use memset () instead of bzero ().
java:
* expr.c (note_instructions), jcf-io.c (find_class), jcf-parse.c
(init_outgoing_cpool), lex.c (java_init_lex): Use memset ()
instead of bzero ().
From-SVN: r37303
2000-11-07 23:50:06 +01:00
|
|
|
|
memset ((char *) (reg_set_table + reg_set_table_size), 0,
|
1998-05-20 02:24:32 +02:00
|
|
|
|
(new_size - reg_set_table_size) * sizeof (struct reg_set *));
|
|
|
|
|
reg_set_table_size = new_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
new_reg_info = (struct reg_set *) obstack_alloc (®_set_obstack,
|
|
|
|
|
sizeof (struct reg_set));
|
|
|
|
|
bytes_used += sizeof (struct reg_set);
|
|
|
|
|
new_reg_info->insn = insn;
|
2000-07-21 02:07:33 +02:00
|
|
|
|
new_reg_info->next = reg_set_table[regno];
|
|
|
|
|
reg_set_table[regno] = new_reg_info;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Called from compute_sets via note_stores to handle one SET or CLOBBER in
|
|
|
|
|
an insn. The DATA is really the instruction in which the SET is
|
|
|
|
|
occurring. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
1999-10-27 21:27:41 +02:00
|
|
|
|
record_set_info (dest, setter, data)
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
rtx dest, setter ATTRIBUTE_UNUSED;
|
1999-10-27 21:27:41 +02:00
|
|
|
|
void *data;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
1999-10-27 21:27:41 +02:00
|
|
|
|
rtx record_set_insn = (rtx) data;
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (GET_CODE (dest) == REG && REGNO (dest) >= FIRST_PSEUDO_REGISTER)
|
|
|
|
|
record_one_set (REGNO (dest), record_set_insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Scan the function and record each set of each pseudo-register.
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
This is called once, at the start of the gcse pass. See the comments for
|
|
|
|
|
`reg_set_table' for further documenation. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_sets (f)
|
|
|
|
|
rtx f;
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
rtx insn;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (insn = f; insn != 0; insn = NEXT_INSN (insn))
|
2000-08-04 22:28:08 +02:00
|
|
|
|
if (INSN_P (insn))
|
2000-02-29 21:08:52 +01:00
|
|
|
|
note_stores (PATTERN (insn), record_set_info, insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Hash table support. */
|
|
|
|
|
|
|
|
|
|
/* For each register, the cuid of the first/last insn in the block to set it,
|
1998-09-16 01:43:50 +02:00
|
|
|
|
or -1 if not set. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
#define NEVER_SET -1
|
1998-05-20 02:24:32 +02:00
|
|
|
|
static int *reg_first_set;
|
|
|
|
|
static int *reg_last_set;
|
|
|
|
|
|
|
|
|
|
/* While computing "first/last set" info, this is the CUID of first/last insn
|
1998-09-16 01:43:50 +02:00
|
|
|
|
to set memory or -1 if not set. `mem_last_set' is also used when
|
1998-05-20 02:24:32 +02:00
|
|
|
|
performing GCSE to record whether memory has been set since the beginning
|
|
|
|
|
of the block.
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
Note that handling of memory is very simple, we don't make any attempt
|
|
|
|
|
to optimize things (later). */
|
|
|
|
|
static int mem_first_set;
|
|
|
|
|
static int mem_last_set;
|
|
|
|
|
|
2001-02-19 00:56:34 +01:00
|
|
|
|
/* See whether X, the source of a set, is something we want to consider for
|
|
|
|
|
GCSE. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
want_to_gcse_p (x)
|
|
|
|
|
rtx x;
|
|
|
|
|
{
|
2001-02-19 00:56:34 +01:00
|
|
|
|
static rtx test_insn = 0;
|
|
|
|
|
int num_clobbers = 0;
|
|
|
|
|
int icode;
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
switch (GET_CODE (x))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
case REG:
|
|
|
|
|
case SUBREG:
|
|
|
|
|
case CONST_INT:
|
|
|
|
|
case CONST_DOUBLE:
|
|
|
|
|
case CALL:
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-19 00:56:34 +01:00
|
|
|
|
/* If this is a valid operand, we are OK. If it's VOIDmode, we aren't. */
|
|
|
|
|
if (general_operand (x, GET_MODE (x)))
|
|
|
|
|
return 1;
|
|
|
|
|
else if (GET_MODE (x) == VOIDmode)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* Otherwise, check if we can make a valid insn from it. First initialize
|
|
|
|
|
our test insn if we haven't already. */
|
|
|
|
|
if (test_insn == 0)
|
|
|
|
|
{
|
|
|
|
|
test_insn
|
|
|
|
|
= make_insn_raw (gen_rtx_SET (VOIDmode,
|
|
|
|
|
gen_rtx_REG (word_mode,
|
|
|
|
|
FIRST_PSEUDO_REGISTER * 2),
|
|
|
|
|
const0_rtx));
|
|
|
|
|
NEXT_INSN (test_insn) = PREV_INSN (test_insn) = 0;
|
|
|
|
|
ggc_add_rtx_root (&test_insn, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now make an insn like the one we would make when GCSE'ing and see if
|
|
|
|
|
valid. */
|
|
|
|
|
PUT_MODE (SET_DEST (PATTERN (test_insn)), GET_MODE (x));
|
|
|
|
|
SET_SRC (PATTERN (test_insn)) = x;
|
|
|
|
|
return ((icode = recog (PATTERN (test_insn), test_insn, &num_clobbers)) >= 0
|
|
|
|
|
&& (num_clobbers == 0 || ! added_clobbers_hard_reg_p (icode)));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return non-zero if the operands of expression X are unchanged from the
|
|
|
|
|
start of INSN's basic block up to but not including INSN (if AVAIL_P == 0),
|
|
|
|
|
or from INSN to the end of INSN's basic block (if AVAIL_P != 0). */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
oprs_unchanged_p (x, insn, avail_p)
|
|
|
|
|
rtx x, insn;
|
|
|
|
|
int avail_p;
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int i, j;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
enum rtx_code code;
|
rtl.h (rtx_format): Constify a char*.
* rtl.h (rtx_format): Constify a char*.
* rtl.c (rtx_format): Likewise.
(copy_rtx, copy_most_rtx, read_rtx): Likewise.
(init_rtl): Use accessor macro, not `rtx_format'.
* alias.c (rtx_equal_for_memref_p, find_symbolic_term): Constify a
char*.
* caller-save.c (mark_referenced_regs): Likewise.
* combine.c (subst, make_compound_operation, known_cond,
gen_rtx_combine, update_table_tick, get_last_value_validate,
use_crosses_set_p, mark_used_regs_combine, move_deaths): Likewise.
* cse.c (rtx_cost, mention_regs, canon_hash, exp_equiv_p,
refers_to_p, canon_reg, fold_rtx, cse_process_notes,
count_reg_usage): Likewise.
* emit-rtl.c (gen_rtx, copy_rtx_if_shared, reset_used_flags):
Likewise.
* final.c (leaf_renumber_regs_insn): Likewise.
* flow.c (mark_used_regs, find_use_as_address, dump_flow_info,
dump_edge_info, count_reg_references): Likewise.
* function.c (fixup_var_refs_1, walk_fixup_memory_subreg,
fixup_stack_1, purge_addressof_1, instantiate_virtual_regs_1):
Likewise.
* gcse.c (oprs_unchanged_p, hash_expr_1, expr_equiv_p,
oprs_not_set_p, expr_killed_p, compute_transp, find_used_regs,
add_label_notes): Likewise.
* genattrtab.c (attr_rtx, attr_copy_rtx, encode_units_mask,
clear_struct_flag, count_sub_rtxs, count_alternatives,
compares_alternatives_p, contained_in_p, walk_attr_value,
write_expr_attr_cache): Likewise.
* genconfig.c (walk_insn_part): Likewise.
* genemit.c (max_operand_1, gen_exp): Likewise.
* genextract.c (walk_rtx): Likewise.
* genflags.c (num_operands): Likewise.
* genoutput.c (scan_operands): Likewise.
* genpeep.c (match_rtx): Likewise.
* genrecog.c (add_to_sequence): Likewise.
* haifa-sched.c (may_trap_exp, sched_analyze_2, attach_deaths):
Likewise.
* integrate.c (save_constants, copy_for_inline,
copy_rtx_and_substitute, subst_constants, restore_constants):
Likewise.
* jump.c (mark_jump_label, invert_exp, redirect_exp,
rtx_renumbered_equal_p, rtx_equal_for_thread_p): Likewise.
* local-alloc.c (contains_replace_regs, memref_referenced_p):
Likewise.
* loop.c (record_excess_regs, rtx_equal_for_loop_p,
add_label_notes, replace_call_address, count_nonfixed_reads,
invariant_p, find_single_use_in_loop, find_mem_givs,
find_life_end, maybe_eliminate_biv_1, update_reg_last_use):
Likewise.
* print-rtl.c (reg_names, print_rtx): Likewise.
* recog.c (validate_replace_rtx_1, find_single_use_1): Likewise.
* reg-stack.c (stack_regs_mentioned_p, record_label_references,
record_reg_life_pat, swap_rtx_condition, goto_block_pat,
print_blocks): Likewise.
* regclass.c (fix_register, record_address_regs,
reg_scan_mark_refs): Likewise.
* regmove.c (stable_but_for_p): Likewise.
* reload.c (loc_mentioned_in_p, operands_match_p,
find_reloads_toplevsubst_reg_equivs, find_reloads_address_1,
copy_replacements, refers_to_regno_for_reload_p,
refers_to_mem_for_reload_p, find_inc_amount, regno_clobbered_p,
reload_when_needed_name, reg_class_names, debug_reload_to_stream):
Likewise.
* reload1.c (eliminate_regs, scan_paradoxical_subregs,
delete_address_reloads_1, count_occurrences,
reload_cse_mem_conflict_p, reload_combine_note_use,
add_auto_inc_notes): Likewise.
* resource.c (mark_referenced_resources, mark_set_resources):
Likewise.
* rtlanal.c (rtx_unstable_p, rtx_varies_p, rtx_addr_varies_p,
reg_mentioned_p, regs_set_between_p, modified_between_p,
modified_in_p, refers_to_regno_p, reg_overlap_mentioned_p,
rtx_equal_p, volatile_insn_p, volatile_refs_p, side_effects_p,
may_trap_p, inequality_comparisons_p, replace_rtx, replace_regs,
jmp_uses_reg_or_mem, for_each_rtx, regno_use_in): Likewise.
* sched.c (sched_analyze_2, attach_deaths): Likewise.
* stupid.c (stupid_mark_refs): Likewise.
* unroll.c (remap_split_bivs): Likewise.
* varasm.c (mark_constants): Likewise.
* a29k/a29k.c (uses_local_reg_p): Likewise.
* alpha/alpha.c (summarize_insn): Likewise.
* arm/arm.c (symbol_mentioned_p, label_mentioned_p,
eliminate_lr2ip): Likewise.
* arm/thumb.c (symbol_mentioned_p, label_mentioned_p): Likewise.
* i386/i386.c (symbolic_reference_mentioned_p, copy_all_rtx,
reg_mentioned_in_mem): Likewise.
* ns32k/ns32k.c (global_symbolic_reference_mentioned_p,
symbolic_reference_mentioned_p): Likewise.
* romp/romp.c (unsigned_comparisons_p, hash_rtx): Likewise.
* sh/sh.c (regs_used, mark_use): Likewise.
* vax/vax.c (vax_rtx_cost): Likewise.
From-SVN: r28784
1999-08-21 01:05:25 +02:00
|
|
|
|
const char *fmt;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (x == 0)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
code = GET_CODE (x);
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case REG:
|
|
|
|
|
if (avail_p)
|
1998-09-16 01:32:22 +02:00
|
|
|
|
return (reg_last_set[REGNO (x)] == NEVER_SET
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|| reg_last_set[REGNO (x)] < INSN_CUID (insn));
|
|
|
|
|
else
|
1998-09-16 01:32:22 +02:00
|
|
|
|
return (reg_first_set[REGNO (x)] == NEVER_SET
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|| reg_first_set[REGNO (x)] >= INSN_CUID (insn));
|
|
|
|
|
|
|
|
|
|
case MEM:
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (load_killed_in_block_p (BLOCK_FOR_INSN (insn), INSN_CUID (insn),
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
x, avail_p))
|
|
|
|
|
return 0;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (avail_p && mem_last_set != NEVER_SET
|
|
|
|
|
&& mem_last_set >= INSN_CUID (insn))
|
|
|
|
|
return 0;
|
|
|
|
|
else if (! avail_p && mem_first_set != NEVER_SET
|
|
|
|
|
&& mem_first_set < INSN_CUID (insn))
|
|
|
|
|
return 0;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
2000-02-29 21:08:52 +01:00
|
|
|
|
return oprs_unchanged_p (XEXP (x, 0), insn, avail_p);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
case PRE_DEC:
|
|
|
|
|
case PRE_INC:
|
|
|
|
|
case POST_DEC:
|
|
|
|
|
case POST_INC:
|
2000-07-28 19:46:18 +02:00
|
|
|
|
case PRE_MODIFY:
|
|
|
|
|
case POST_MODIFY:
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case PC:
|
|
|
|
|
case CC0: /*FIXME*/
|
|
|
|
|
case CONST:
|
|
|
|
|
case CONST_INT:
|
|
|
|
|
case CONST_DOUBLE:
|
|
|
|
|
case SYMBOL_REF:
|
|
|
|
|
case LABEL_REF:
|
|
|
|
|
case ADDR_VEC:
|
|
|
|
|
case ADDR_DIFF_VEC:
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* If we are about to do the last recursive call needed at this
|
|
|
|
|
level, change it into iteration. This function is called enough
|
|
|
|
|
to be worth it. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (i == 0)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
return oprs_unchanged_p (XEXP (x, i), insn, avail_p);
|
|
|
|
|
|
|
|
|
|
else if (! oprs_unchanged_p (XEXP (x, i), insn, avail_p))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if (fmt[i] == 'E')
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (j = 0; j < XVECLEN (x, i); j++)
|
|
|
|
|
if (! oprs_unchanged_p (XVECEXP (x, i, j), insn, avail_p))
|
|
|
|
|
return 0;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* Used for communication between mems_conflict_for_gcse_p and
|
|
|
|
|
load_killed_in_block_p. Nonzero if mems_conflict_for_gcse_p finds a
|
|
|
|
|
conflict between two memory references. */
|
|
|
|
|
static int gcse_mems_conflict_p;
|
|
|
|
|
|
|
|
|
|
/* Used for communication between mems_conflict_for_gcse_p and
|
|
|
|
|
load_killed_in_block_p. A memory reference for a load instruction,
|
|
|
|
|
mems_conflict_for_gcse_p will see if a memory store conflicts with
|
|
|
|
|
this memory load. */
|
|
|
|
|
static rtx gcse_mem_operand;
|
|
|
|
|
|
|
|
|
|
/* DEST is the output of an instruction. If it is a memory reference, and
|
|
|
|
|
possibly conflicts with the load found in gcse_mem_operand, then set
|
|
|
|
|
gcse_mems_conflict_p to a nonzero value. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mems_conflict_for_gcse_p (dest, setter, data)
|
|
|
|
|
rtx dest, setter ATTRIBUTE_UNUSED;
|
|
|
|
|
void *data ATTRIBUTE_UNUSED;
|
|
|
|
|
{
|
|
|
|
|
while (GET_CODE (dest) == SUBREG
|
|
|
|
|
|| GET_CODE (dest) == ZERO_EXTRACT
|
|
|
|
|
|| GET_CODE (dest) == SIGN_EXTRACT
|
|
|
|
|
|| GET_CODE (dest) == STRICT_LOW_PART)
|
|
|
|
|
dest = XEXP (dest, 0);
|
|
|
|
|
|
|
|
|
|
/* If DEST is not a MEM, then it will not conflict with the load. Note
|
|
|
|
|
that function calls are assumed to clobber memory, but are handled
|
|
|
|
|
elsewhere. */
|
|
|
|
|
if (GET_CODE (dest) != MEM)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* If we are setting a MEM in our list of specially recognized MEMs,
|
|
|
|
|
don't mark as killed this time. */
|
|
|
|
|
|
|
|
|
|
if (dest == gcse_mem_operand && pre_ldst_mems != NULL)
|
|
|
|
|
{
|
|
|
|
|
if (!find_rtx_in_ldst (dest))
|
|
|
|
|
gcse_mems_conflict_p = 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (true_dependence (dest, GET_MODE (dest), gcse_mem_operand,
|
|
|
|
|
rtx_addr_varies_p))
|
|
|
|
|
gcse_mems_conflict_p = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return nonzero if the expression in X (a memory reference) is killed
|
|
|
|
|
in block BB before or after the insn with the CUID in UID_LIMIT.
|
|
|
|
|
AVAIL_P is nonzero for kills after UID_LIMIT, and zero for kills
|
|
|
|
|
before UID_LIMIT.
|
|
|
|
|
|
|
|
|
|
To check the entire block, set UID_LIMIT to max_uid + 1 and
|
|
|
|
|
AVAIL_P to 0. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
load_killed_in_block_p (bb, uid_limit, x, avail_p)
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
int uid_limit;
|
|
|
|
|
rtx x;
|
|
|
|
|
int avail_p;
|
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
rtx list_entry = modify_mem_list[bb->index];
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
while (list_entry)
|
|
|
|
|
{
|
|
|
|
|
rtx setter;
|
|
|
|
|
/* Ignore entries in the list that do not apply. */
|
|
|
|
|
if ((avail_p
|
|
|
|
|
&& INSN_CUID (XEXP (list_entry, 0)) < uid_limit)
|
|
|
|
|
|| (! avail_p
|
|
|
|
|
&& INSN_CUID (XEXP (list_entry, 0)) > uid_limit))
|
|
|
|
|
{
|
|
|
|
|
list_entry = XEXP (list_entry, 1);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setter = XEXP (list_entry, 0);
|
|
|
|
|
|
|
|
|
|
/* If SETTER is a call everything is clobbered. Note that calls
|
|
|
|
|
to pure functions are never put on the list, so we need not
|
|
|
|
|
worry about them. */
|
|
|
|
|
if (GET_CODE (setter) == CALL_INSN)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
/* SETTER must be an INSN of some kind that sets memory. Call
|
|
|
|
|
note_stores to examine each hunk of memory that is modified.
|
|
|
|
|
|
|
|
|
|
The note_stores interface is pretty limited, so we have to
|
|
|
|
|
communicate via global variables. Yuk. */
|
|
|
|
|
gcse_mem_operand = x;
|
|
|
|
|
gcse_mems_conflict_p = 0;
|
|
|
|
|
note_stores (PATTERN (setter), mems_conflict_for_gcse_p, NULL);
|
|
|
|
|
if (gcse_mems_conflict_p)
|
|
|
|
|
return 1;
|
|
|
|
|
list_entry = XEXP (list_entry, 1);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Return non-zero if the operands of expression X are unchanged from
|
|
|
|
|
the start of INSN's basic block up to but not including INSN. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
oprs_anticipatable_p (x, insn)
|
|
|
|
|
rtx x, insn;
|
|
|
|
|
{
|
|
|
|
|
return oprs_unchanged_p (x, insn, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return non-zero if the operands of expression X are unchanged from
|
|
|
|
|
INSN to the end of INSN's basic block. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
oprs_available_p (x, insn)
|
|
|
|
|
rtx x, insn;
|
|
|
|
|
{
|
|
|
|
|
return oprs_unchanged_p (x, insn, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Hash expression X.
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
MODE is only used if X is a CONST_INT. DO_NOT_RECORD_P is a boolean
|
|
|
|
|
indicating if a volatile operand is found or if the expression contains
|
|
|
|
|
something we don't want to insert in the table.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
??? One might want to merge this with canon_hash. Later. */
|
|
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
hash_expr (x, mode, do_not_record_p, hash_table_size)
|
|
|
|
|
rtx x;
|
|
|
|
|
enum machine_mode mode;
|
|
|
|
|
int *do_not_record_p;
|
|
|
|
|
int hash_table_size;
|
|
|
|
|
{
|
|
|
|
|
unsigned int hash;
|
|
|
|
|
|
|
|
|
|
*do_not_record_p = 0;
|
|
|
|
|
|
|
|
|
|
hash = hash_expr_1 (x, mode, do_not_record_p);
|
|
|
|
|
return hash % hash_table_size;
|
|
|
|
|
}
|
2001-02-16 20:29:49 +01:00
|
|
|
|
|
2000-09-02 04:54:55 +02:00
|
|
|
|
/* Hash a string. Just add its bytes up. */
|
2001-02-16 20:29:49 +01:00
|
|
|
|
|
2000-09-02 04:54:55 +02:00
|
|
|
|
static inline unsigned
|
|
|
|
|
hash_string_1 (ps)
|
|
|
|
|
const char *ps;
|
|
|
|
|
{
|
|
|
|
|
unsigned hash = 0;
|
|
|
|
|
const unsigned char *p = (const unsigned char *)ps;
|
|
|
|
|
|
|
|
|
|
if (p)
|
|
|
|
|
while (*p)
|
|
|
|
|
hash += *p++;
|
|
|
|
|
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Subroutine of hash_expr to do the actual work. */
|
|
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
hash_expr_1 (x, mode, do_not_record_p)
|
|
|
|
|
rtx x;
|
|
|
|
|
enum machine_mode mode;
|
|
|
|
|
int *do_not_record_p;
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
unsigned hash = 0;
|
|
|
|
|
enum rtx_code code;
|
rtl.h (rtx_format): Constify a char*.
* rtl.h (rtx_format): Constify a char*.
* rtl.c (rtx_format): Likewise.
(copy_rtx, copy_most_rtx, read_rtx): Likewise.
(init_rtl): Use accessor macro, not `rtx_format'.
* alias.c (rtx_equal_for_memref_p, find_symbolic_term): Constify a
char*.
* caller-save.c (mark_referenced_regs): Likewise.
* combine.c (subst, make_compound_operation, known_cond,
gen_rtx_combine, update_table_tick, get_last_value_validate,
use_crosses_set_p, mark_used_regs_combine, move_deaths): Likewise.
* cse.c (rtx_cost, mention_regs, canon_hash, exp_equiv_p,
refers_to_p, canon_reg, fold_rtx, cse_process_notes,
count_reg_usage): Likewise.
* emit-rtl.c (gen_rtx, copy_rtx_if_shared, reset_used_flags):
Likewise.
* final.c (leaf_renumber_regs_insn): Likewise.
* flow.c (mark_used_regs, find_use_as_address, dump_flow_info,
dump_edge_info, count_reg_references): Likewise.
* function.c (fixup_var_refs_1, walk_fixup_memory_subreg,
fixup_stack_1, purge_addressof_1, instantiate_virtual_regs_1):
Likewise.
* gcse.c (oprs_unchanged_p, hash_expr_1, expr_equiv_p,
oprs_not_set_p, expr_killed_p, compute_transp, find_used_regs,
add_label_notes): Likewise.
* genattrtab.c (attr_rtx, attr_copy_rtx, encode_units_mask,
clear_struct_flag, count_sub_rtxs, count_alternatives,
compares_alternatives_p, contained_in_p, walk_attr_value,
write_expr_attr_cache): Likewise.
* genconfig.c (walk_insn_part): Likewise.
* genemit.c (max_operand_1, gen_exp): Likewise.
* genextract.c (walk_rtx): Likewise.
* genflags.c (num_operands): Likewise.
* genoutput.c (scan_operands): Likewise.
* genpeep.c (match_rtx): Likewise.
* genrecog.c (add_to_sequence): Likewise.
* haifa-sched.c (may_trap_exp, sched_analyze_2, attach_deaths):
Likewise.
* integrate.c (save_constants, copy_for_inline,
copy_rtx_and_substitute, subst_constants, restore_constants):
Likewise.
* jump.c (mark_jump_label, invert_exp, redirect_exp,
rtx_renumbered_equal_p, rtx_equal_for_thread_p): Likewise.
* local-alloc.c (contains_replace_regs, memref_referenced_p):
Likewise.
* loop.c (record_excess_regs, rtx_equal_for_loop_p,
add_label_notes, replace_call_address, count_nonfixed_reads,
invariant_p, find_single_use_in_loop, find_mem_givs,
find_life_end, maybe_eliminate_biv_1, update_reg_last_use):
Likewise.
* print-rtl.c (reg_names, print_rtx): Likewise.
* recog.c (validate_replace_rtx_1, find_single_use_1): Likewise.
* reg-stack.c (stack_regs_mentioned_p, record_label_references,
record_reg_life_pat, swap_rtx_condition, goto_block_pat,
print_blocks): Likewise.
* regclass.c (fix_register, record_address_regs,
reg_scan_mark_refs): Likewise.
* regmove.c (stable_but_for_p): Likewise.
* reload.c (loc_mentioned_in_p, operands_match_p,
find_reloads_toplevsubst_reg_equivs, find_reloads_address_1,
copy_replacements, refers_to_regno_for_reload_p,
refers_to_mem_for_reload_p, find_inc_amount, regno_clobbered_p,
reload_when_needed_name, reg_class_names, debug_reload_to_stream):
Likewise.
* reload1.c (eliminate_regs, scan_paradoxical_subregs,
delete_address_reloads_1, count_occurrences,
reload_cse_mem_conflict_p, reload_combine_note_use,
add_auto_inc_notes): Likewise.
* resource.c (mark_referenced_resources, mark_set_resources):
Likewise.
* rtlanal.c (rtx_unstable_p, rtx_varies_p, rtx_addr_varies_p,
reg_mentioned_p, regs_set_between_p, modified_between_p,
modified_in_p, refers_to_regno_p, reg_overlap_mentioned_p,
rtx_equal_p, volatile_insn_p, volatile_refs_p, side_effects_p,
may_trap_p, inequality_comparisons_p, replace_rtx, replace_regs,
jmp_uses_reg_or_mem, for_each_rtx, regno_use_in): Likewise.
* sched.c (sched_analyze_2, attach_deaths): Likewise.
* stupid.c (stupid_mark_refs): Likewise.
* unroll.c (remap_split_bivs): Likewise.
* varasm.c (mark_constants): Likewise.
* a29k/a29k.c (uses_local_reg_p): Likewise.
* alpha/alpha.c (summarize_insn): Likewise.
* arm/arm.c (symbol_mentioned_p, label_mentioned_p,
eliminate_lr2ip): Likewise.
* arm/thumb.c (symbol_mentioned_p, label_mentioned_p): Likewise.
* i386/i386.c (symbolic_reference_mentioned_p, copy_all_rtx,
reg_mentioned_in_mem): Likewise.
* ns32k/ns32k.c (global_symbolic_reference_mentioned_p,
symbolic_reference_mentioned_p): Likewise.
* romp/romp.c (unsigned_comparisons_p, hash_rtx): Likewise.
* sh/sh.c (regs_used, mark_use): Likewise.
* vax/vax.c (vax_rtx_cost): Likewise.
From-SVN: r28784
1999-08-21 01:05:25 +02:00
|
|
|
|
const char *fmt;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Used to turn recursion into iteration. We can't rely on GCC's
|
|
|
|
|
tail-recursion eliminatio since we need to keep accumulating values
|
|
|
|
|
in HASH. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (x == 0)
|
|
|
|
|
return hash;
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
repeat:
|
1998-05-20 02:24:32 +02:00
|
|
|
|
code = GET_CODE (x);
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case REG:
|
2000-02-29 21:08:52 +01:00
|
|
|
|
hash += ((unsigned int) REG << 7) + REGNO (x);
|
|
|
|
|
return hash;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
case CONST_INT:
|
2000-02-29 21:08:52 +01:00
|
|
|
|
hash += (((unsigned int) CONST_INT << 7) + (unsigned int) mode
|
|
|
|
|
+ (unsigned int) INTVAL (x));
|
|
|
|
|
return hash;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
case CONST_DOUBLE:
|
|
|
|
|
/* This is like the general case, except that it only counts
|
|
|
|
|
the integers representing the constant. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
hash += (unsigned int) code + (unsigned int) GET_MODE (x);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (GET_MODE (x) != VOIDmode)
|
|
|
|
|
for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
hash += (unsigned int) XWINT (x, i);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
2000-02-29 21:08:52 +01:00
|
|
|
|
hash += ((unsigned int) CONST_DOUBLE_LOW (x)
|
|
|
|
|
+ (unsigned int) CONST_DOUBLE_HIGH (x));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return hash;
|
|
|
|
|
|
|
|
|
|
/* Assume there is only one rtx object for any given label. */
|
|
|
|
|
case LABEL_REF:
|
|
|
|
|
/* We don't hash on the address of the CODE_LABEL to avoid bootstrap
|
|
|
|
|
differences and differences between each stage's debugging dumps. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
hash += (((unsigned int) LABEL_REF << 7)
|
|
|
|
|
+ CODE_LABEL_NUMBER (XEXP (x, 0)));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return hash;
|
|
|
|
|
|
|
|
|
|
case SYMBOL_REF:
|
|
|
|
|
{
|
|
|
|
|
/* Don't hash on the symbol's address to avoid bootstrap differences.
|
|
|
|
|
Different hash values may cause expressions to be recorded in
|
|
|
|
|
different orders and thus different registers to be used in the
|
|
|
|
|
final assembler. This also avoids differences in the dump files
|
|
|
|
|
between various stages. */
|
|
|
|
|
unsigned int h = 0;
|
rtl.h (rtunion_def): Constify member `rtstr'.
* rtl.h (rtunion_def): Constify member `rtstr'.
(emit_line_note_after, emit_line_note, emit_line_note_force,
emit_note, decode_asm_operands): Constify.
* cse.c (canon_hash): Likewise.
* dbxout.c (dbxout_block): Likewise.
* diagnostic.c (file_and_line_for_asm, v_error_for_asm,
v_warning_for_asm): Likewise.
* dwarfout.c (function_start_label): Likewise.
* emit-rtl.c (emit_line_note_after, emit_line_note, emit_note,
emit_line_note_force): Likewise.
* final.c (last_filename, asm_insn_count, final_scan_insn,
output_source_line): Likewise.
* function.h (struct emit_status): Likewise.
* gcse.c (hash_expr_1): Likewise.
* genattr.c (gen_attr, main): Likewise.
* genattrtab.c (struct function_unit, current_alternative_string,
write_attr_valueq, n_comma_elts, next_comma_elt, attr_eq,
attr_numeral, check_attr_test, check_attr_value,
convert_set_attr_alternative, convert_set_attr,
compute_alternative_mask, simplify_by_exploding, gen_attr,
gen_unit): Likewise.
* genflags.c (gen_insn): Likewise.
* gengenrtl.c (type_from_format): Likewise.
* genopinit.c (gen_insn): Likewise.
* genoutput.c (n_occurrences, process_template, process_template):
Likewise.
* ggc-page.c (ggc_set_mark, ggc_mark_if_gcable, ggc_get_size):
Likewise.
* ggc-simple.c (ggc_set_mark, ggc_mark_if_gcable, ggc_get_size):
Likewise.
* ggc.h (ggc_mark_string, ggc_mark, ggc_mark_if_gcable,
ggc_set_mark, ggc_get_size): Likewise.
* objc/objc-act.c (build_module_descriptor, finish_objc): Likewise.
* optabs.c (init_one_libfunc): Likewise.
* output.h (assemble_start_function): Likewise.
* recog.c (decode_asm_operands): Likewise.
* toplev.c (rest_of_compilation): Likewise.
* tree.h (emit_line_note_after, emit_line_note,
emit_line_note_force): Likewise.
* varasm.c (asm_output_bss, asm_output_aligned_bss,
asm_emit_uninitialised, assemble_start_function,
assemble_variable, const_hash, compare_constant_1,
find_pool_constant, mark_constant_pool, assemble_alias): Likewise.
* xcoffout.h (DBX_FINISH_SYMBOL): Likewise.
* alpha/alpha.md (call_vms, call_value_vms): Likewise.
* arm/aof.h (ASM_OUTPUT_ASCII): Likewise.
* arm/aout.h (ASM_OUTPUT_ASCII): Likewise.
* arm/arm-protos.h (output_ascii_pseudo_op, arm_dllexport_name_p,
arm_dllimport_name_p): Likewise.
* arm/arm.c (arm_encode_call_attribute, output_ascii_pseudo_op):
Likewise.
* arm/arm.h (ASM_OUTPUT_MI_THUNK): Likewise.
* arm/elf.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* arm/pe.c (arm_dllexport_name_p, arm_dllimport_name_p,
arm_mark_dllexport, arm_mark_dllimport,
arm_pe_encode_section_info): Likewise.
* arm/telf.h (ASM_OUTPUT_DEF_FROM_DECLS,
ASM_FINISH_DECLARE_OBJECT): Likewise.
* arm/thumb.c (thumb_function_prologue): Likewise.
* arm/thumb.h (ASM_OUTPUT_ASCII): Likewise.
* avr/avr.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* clipper/clix.h (ASM_OUTPUT_ASCII): Likewise.
* fx80/fx80.h (ASM_OUTPUT_ASCII): Likewise.
* i386/cygwin.h (ASM_OUTPUT_SECTION_NAME): Likewise.
* i386/freebsd.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* i386/i386-interix.h (ASM_OUTPUT_LIMITED_STRING,
ASM_OUTPUT_ASCII, ASM_OUTPUT_SECTION_NAME): Likewise.
* i386/i386-protos.h (asm_output_function_prefix): Likewise.
* i386/i386.c (asm_output_function_prefix): Likewise.
* i386/i386elf.h (ASM_OUTPUT_ASCII): Likewise.
* i386/osfrose.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* i386/ptx4-i.h (ASM_OUTPUT_ASCII): Likewise.
* i386/sco5.h (ASM_FINISH_DECLARE_OBJECT,
ASM_OUTPUT_LIMITED_STRING, ASM_OUTPUT_ASCII,
ASM_OUTPUT_SECTION_NAME): Likewise.
* i386/sysv4.h (ASM_OUTPUT_ASCII): Likewise.
* i860/paragon.h (ASM_OUTPUT_ASCII): Likewise.
* i860/sysv3.h (ASM_OUTPUT_ASCII): Likewise.
* m32r/m32r.c (m32r_encode_section_info): Likewise.
* mcore-elf.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* mcore/mcore.c (mcore_encode_section_info): Likewise.
* mips/elf.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* mips/elf64.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* mips/iris6.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* mips/mips.h (ASM_OUTPUT_IDENT): Likewise.
* mips/mips.md (movdi, movsi): Likewise.
* mips/netbsd.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* netbsd.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* openbsd.h (ASM_FINISH_DECLARE_OBJECT): Likewise.
* ptx4.h (ASM_FINISH_DECLARE_OBJECT, ASM_OUTPUT_LIMITED_STRING,
ASM_OUTPUT_ASCII): Likewise.
* rs6000/rs6000.c (rs6000_allocate_stack_space, output_epilog,
output_mi_thunk, output_toc): Likewise.
* rs6000/rs6000.md (movsi): Likewise.
* rs6000/sysv4.h (ASM_OUTPUT_INT, ASM_OUTPUT_SECTION_NAME): Likewise.
* tahoe/harris.h (ASM_OUTPUT_ASCII): Likewise.
* v850/v850.c (print_operand, print_operand_address,
v850_encode_data_area): Likewise.
ch:
* grant.c (globalize_decl): Constify a char*.
cp:
* decl2.c (finish_objects): Constify a char*.
* method.c (emit_thunk): Likewise.
From-SVN: r32388
2000-03-07 21:39:10 +01:00
|
|
|
|
const unsigned char *p = (const unsigned char *) XSTR (x, 0);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
while (*p)
|
|
|
|
|
h += (h << 7) + *p++; /* ??? revisit */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
hash += ((unsigned int) SYMBOL_REF << 7) + h;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case MEM:
|
|
|
|
|
if (MEM_VOLATILE_P (x))
|
|
|
|
|
{
|
|
|
|
|
*do_not_record_p = 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
hash += (unsigned int) MEM;
|
1999-10-16 09:08:27 +02:00
|
|
|
|
hash += MEM_ALIAS_SET (x);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
x = XEXP (x, 0);
|
|
|
|
|
goto repeat;
|
|
|
|
|
|
|
|
|
|
case PRE_DEC:
|
|
|
|
|
case PRE_INC:
|
|
|
|
|
case POST_DEC:
|
|
|
|
|
case POST_INC:
|
|
|
|
|
case PC:
|
|
|
|
|
case CC0:
|
|
|
|
|
case CALL:
|
|
|
|
|
case UNSPEC_VOLATILE:
|
|
|
|
|
*do_not_record_p = 1;
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case ASM_OPERANDS:
|
|
|
|
|
if (MEM_VOLATILE_P (x))
|
|
|
|
|
{
|
|
|
|
|
*do_not_record_p = 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2000-09-02 04:54:55 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* We don't want to take the filename and line into account. */
|
|
|
|
|
hash += (unsigned) code + (unsigned) GET_MODE (x)
|
|
|
|
|
+ hash_string_1 (ASM_OPERANDS_TEMPLATE (x))
|
|
|
|
|
+ hash_string_1 (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
|
|
|
|
|
+ (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
|
|
|
|
|
|
|
|
|
|
if (ASM_OPERANDS_INPUT_LENGTH (x))
|
|
|
|
|
{
|
|
|
|
|
for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
|
|
|
|
|
{
|
|
|
|
|
hash += (hash_expr_1 (ASM_OPERANDS_INPUT (x, i),
|
|
|
|
|
GET_MODE (ASM_OPERANDS_INPUT (x, i)),
|
|
|
|
|
do_not_record_p)
|
|
|
|
|
+ hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT
|
|
|
|
|
(x, i)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hash += hash_string_1 (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
|
|
|
|
|
x = ASM_OPERANDS_INPUT (x, 0);
|
|
|
|
|
mode = GET_MODE (x);
|
|
|
|
|
goto repeat;
|
|
|
|
|
}
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hash += (unsigned) code + (unsigned) GET_MODE (x);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
{
|
|
|
|
|
/* If we are about to do the last recursive call
|
|
|
|
|
needed at this level, change it into iteration.
|
|
|
|
|
This function is called enough to be worth it. */
|
|
|
|
|
if (i == 0)
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
x = XEXP (x, i);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
goto repeat;
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
hash += hash_expr_1 (XEXP (x, i), 0, do_not_record_p);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (*do_not_record_p)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else if (fmt[i] == 'E')
|
|
|
|
|
for (j = 0; j < XVECLEN (x, i); j++)
|
|
|
|
|
{
|
|
|
|
|
hash += hash_expr_1 (XVECEXP (x, i, j), 0, do_not_record_p);
|
|
|
|
|
if (*do_not_record_p)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else if (fmt[i] == 's')
|
2000-09-02 04:54:55 +02:00
|
|
|
|
hash += hash_string_1 (XSTR (x, i));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else if (fmt[i] == 'i')
|
2000-02-29 21:08:52 +01:00
|
|
|
|
hash += (unsigned int) XINT (x, i);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Hash a set of register REGNO.
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
Sets are hashed on the register that is set. This simplifies the PRE copy
|
|
|
|
|
propagation code.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
??? May need to make things more elaborate. Later, as necessary. */
|
|
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
hash_set (regno, hash_table_size)
|
|
|
|
|
int regno;
|
|
|
|
|
int hash_table_size;
|
|
|
|
|
{
|
|
|
|
|
unsigned int hash;
|
|
|
|
|
|
|
|
|
|
hash = regno;
|
|
|
|
|
return hash % hash_table_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return non-zero if exp1 is equivalent to exp2.
|
|
|
|
|
??? Borrowed from cse.c. Might want to remerge with cse.c. Later. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
expr_equiv_p (x, y)
|
|
|
|
|
rtx x, y;
|
|
|
|
|
{
|
|
|
|
|
register int i, j;
|
|
|
|
|
register enum rtx_code code;
|
rtl.h (rtx_format): Constify a char*.
* rtl.h (rtx_format): Constify a char*.
* rtl.c (rtx_format): Likewise.
(copy_rtx, copy_most_rtx, read_rtx): Likewise.
(init_rtl): Use accessor macro, not `rtx_format'.
* alias.c (rtx_equal_for_memref_p, find_symbolic_term): Constify a
char*.
* caller-save.c (mark_referenced_regs): Likewise.
* combine.c (subst, make_compound_operation, known_cond,
gen_rtx_combine, update_table_tick, get_last_value_validate,
use_crosses_set_p, mark_used_regs_combine, move_deaths): Likewise.
* cse.c (rtx_cost, mention_regs, canon_hash, exp_equiv_p,
refers_to_p, canon_reg, fold_rtx, cse_process_notes,
count_reg_usage): Likewise.
* emit-rtl.c (gen_rtx, copy_rtx_if_shared, reset_used_flags):
Likewise.
* final.c (leaf_renumber_regs_insn): Likewise.
* flow.c (mark_used_regs, find_use_as_address, dump_flow_info,
dump_edge_info, count_reg_references): Likewise.
* function.c (fixup_var_refs_1, walk_fixup_memory_subreg,
fixup_stack_1, purge_addressof_1, instantiate_virtual_regs_1):
Likewise.
* gcse.c (oprs_unchanged_p, hash_expr_1, expr_equiv_p,
oprs_not_set_p, expr_killed_p, compute_transp, find_used_regs,
add_label_notes): Likewise.
* genattrtab.c (attr_rtx, attr_copy_rtx, encode_units_mask,
clear_struct_flag, count_sub_rtxs, count_alternatives,
compares_alternatives_p, contained_in_p, walk_attr_value,
write_expr_attr_cache): Likewise.
* genconfig.c (walk_insn_part): Likewise.
* genemit.c (max_operand_1, gen_exp): Likewise.
* genextract.c (walk_rtx): Likewise.
* genflags.c (num_operands): Likewise.
* genoutput.c (scan_operands): Likewise.
* genpeep.c (match_rtx): Likewise.
* genrecog.c (add_to_sequence): Likewise.
* haifa-sched.c (may_trap_exp, sched_analyze_2, attach_deaths):
Likewise.
* integrate.c (save_constants, copy_for_inline,
copy_rtx_and_substitute, subst_constants, restore_constants):
Likewise.
* jump.c (mark_jump_label, invert_exp, redirect_exp,
rtx_renumbered_equal_p, rtx_equal_for_thread_p): Likewise.
* local-alloc.c (contains_replace_regs, memref_referenced_p):
Likewise.
* loop.c (record_excess_regs, rtx_equal_for_loop_p,
add_label_notes, replace_call_address, count_nonfixed_reads,
invariant_p, find_single_use_in_loop, find_mem_givs,
find_life_end, maybe_eliminate_biv_1, update_reg_last_use):
Likewise.
* print-rtl.c (reg_names, print_rtx): Likewise.
* recog.c (validate_replace_rtx_1, find_single_use_1): Likewise.
* reg-stack.c (stack_regs_mentioned_p, record_label_references,
record_reg_life_pat, swap_rtx_condition, goto_block_pat,
print_blocks): Likewise.
* regclass.c (fix_register, record_address_regs,
reg_scan_mark_refs): Likewise.
* regmove.c (stable_but_for_p): Likewise.
* reload.c (loc_mentioned_in_p, operands_match_p,
find_reloads_toplevsubst_reg_equivs, find_reloads_address_1,
copy_replacements, refers_to_regno_for_reload_p,
refers_to_mem_for_reload_p, find_inc_amount, regno_clobbered_p,
reload_when_needed_name, reg_class_names, debug_reload_to_stream):
Likewise.
* reload1.c (eliminate_regs, scan_paradoxical_subregs,
delete_address_reloads_1, count_occurrences,
reload_cse_mem_conflict_p, reload_combine_note_use,
add_auto_inc_notes): Likewise.
* resource.c (mark_referenced_resources, mark_set_resources):
Likewise.
* rtlanal.c (rtx_unstable_p, rtx_varies_p, rtx_addr_varies_p,
reg_mentioned_p, regs_set_between_p, modified_between_p,
modified_in_p, refers_to_regno_p, reg_overlap_mentioned_p,
rtx_equal_p, volatile_insn_p, volatile_refs_p, side_effects_p,
may_trap_p, inequality_comparisons_p, replace_rtx, replace_regs,
jmp_uses_reg_or_mem, for_each_rtx, regno_use_in): Likewise.
* sched.c (sched_analyze_2, attach_deaths): Likewise.
* stupid.c (stupid_mark_refs): Likewise.
* unroll.c (remap_split_bivs): Likewise.
* varasm.c (mark_constants): Likewise.
* a29k/a29k.c (uses_local_reg_p): Likewise.
* alpha/alpha.c (summarize_insn): Likewise.
* arm/arm.c (symbol_mentioned_p, label_mentioned_p,
eliminate_lr2ip): Likewise.
* arm/thumb.c (symbol_mentioned_p, label_mentioned_p): Likewise.
* i386/i386.c (symbolic_reference_mentioned_p, copy_all_rtx,
reg_mentioned_in_mem): Likewise.
* ns32k/ns32k.c (global_symbolic_reference_mentioned_p,
symbolic_reference_mentioned_p): Likewise.
* romp/romp.c (unsigned_comparisons_p, hash_rtx): Likewise.
* sh/sh.c (regs_used, mark_use): Likewise.
* vax/vax.c (vax_rtx_cost): Likewise.
From-SVN: r28784
1999-08-21 01:05:25 +02:00
|
|
|
|
register const char *fmt;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (x == y)
|
|
|
|
|
return 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (x == 0 || y == 0)
|
|
|
|
|
return x == y;
|
|
|
|
|
|
|
|
|
|
code = GET_CODE (x);
|
|
|
|
|
if (code != GET_CODE (y))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
|
|
|
|
|
if (GET_MODE (x) != GET_MODE (y))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case PC:
|
|
|
|
|
case CC0:
|
|
|
|
|
return x == y;
|
|
|
|
|
|
|
|
|
|
case CONST_INT:
|
|
|
|
|
return INTVAL (x) == INTVAL (y);
|
|
|
|
|
|
|
|
|
|
case LABEL_REF:
|
|
|
|
|
return XEXP (x, 0) == XEXP (y, 0);
|
|
|
|
|
|
|
|
|
|
case SYMBOL_REF:
|
|
|
|
|
return XSTR (x, 0) == XSTR (y, 0);
|
|
|
|
|
|
|
|
|
|
case REG:
|
|
|
|
|
return REGNO (x) == REGNO (y);
|
|
|
|
|
|
1999-10-16 09:08:27 +02:00
|
|
|
|
case MEM:
|
|
|
|
|
/* Can't merge two expressions in different alias sets, since we can
|
|
|
|
|
decide that the expression is transparent in a block when it isn't,
|
|
|
|
|
due to it being set with the different alias set. */
|
|
|
|
|
if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
|
|
|
|
|
return 0;
|
|
|
|
|
break;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* For commutative operations, check both orders. */
|
|
|
|
|
case PLUS:
|
|
|
|
|
case MULT:
|
|
|
|
|
case AND:
|
|
|
|
|
case IOR:
|
|
|
|
|
case XOR:
|
|
|
|
|
case NE:
|
|
|
|
|
case EQ:
|
|
|
|
|
return ((expr_equiv_p (XEXP (x, 0), XEXP (y, 0))
|
|
|
|
|
&& expr_equiv_p (XEXP (x, 1), XEXP (y, 1)))
|
|
|
|
|
|| (expr_equiv_p (XEXP (x, 0), XEXP (y, 1))
|
|
|
|
|
&& expr_equiv_p (XEXP (x, 1), XEXP (y, 0))));
|
|
|
|
|
|
2000-09-02 04:54:55 +02:00
|
|
|
|
case ASM_OPERANDS:
|
|
|
|
|
/* We don't use the generic code below because we want to
|
|
|
|
|
disregard filename and line numbers. */
|
|
|
|
|
|
|
|
|
|
/* A volatile asm isn't equivalent to any other. */
|
|
|
|
|
if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (GET_MODE (x) != GET_MODE (y)
|
|
|
|
|
|| strcmp (ASM_OPERANDS_TEMPLATE (x), ASM_OPERANDS_TEMPLATE (y))
|
|
|
|
|
|| strcmp (ASM_OPERANDS_OUTPUT_CONSTRAINT (x),
|
|
|
|
|
ASM_OPERANDS_OUTPUT_CONSTRAINT (y))
|
|
|
|
|
|| ASM_OPERANDS_OUTPUT_IDX (x) != ASM_OPERANDS_OUTPUT_IDX (y)
|
|
|
|
|
|| ASM_OPERANDS_INPUT_LENGTH (x) != ASM_OPERANDS_INPUT_LENGTH (y))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (ASM_OPERANDS_INPUT_LENGTH (x))
|
|
|
|
|
{
|
|
|
|
|
for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
|
|
|
|
|
if (! expr_equiv_p (ASM_OPERANDS_INPUT (x, i),
|
|
|
|
|
ASM_OPERANDS_INPUT (y, i))
|
|
|
|
|
|| strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
|
|
|
|
|
ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compare the elements. If any pair of corresponding elements
|
|
|
|
|
fail to match, return 0 for the whole thing. */
|
|
|
|
|
|
|
|
|
|
fmt = GET_RTX_FORMAT (code);
|
|
|
|
|
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
switch (fmt[i])
|
|
|
|
|
{
|
|
|
|
|
case 'e':
|
|
|
|
|
if (! expr_equiv_p (XEXP (x, i), XEXP (y, i)))
|
|
|
|
|
return 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'E':
|
|
|
|
|
if (XVECLEN (x, i) != XVECLEN (y, i))
|
|
|
|
|
return 0;
|
|
|
|
|
for (j = 0; j < XVECLEN (x, i); j++)
|
|
|
|
|
if (! expr_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
|
|
|
|
|
return 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 's':
|
|
|
|
|
if (strcmp (XSTR (x, i), XSTR (y, i)))
|
|
|
|
|
return 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'i':
|
|
|
|
|
if (XINT (x, i) != XINT (y, i))
|
|
|
|
|
return 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'w':
|
|
|
|
|
if (XWINT (x, i) != XWINT (y, i))
|
|
|
|
|
return 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case '0':
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Insert expression X in INSN in the hash table.
|
|
|
|
|
If it is already present, record it as the last occurrence in INSN's
|
|
|
|
|
basic block.
|
|
|
|
|
|
|
|
|
|
MODE is the mode of the value X is being stored into.
|
|
|
|
|
It is only used if X is a CONST_INT.
|
|
|
|
|
|
|
|
|
|
ANTIC_P is non-zero if X is an anticipatable expression.
|
|
|
|
|
AVAIL_P is non-zero if X is an available expression. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
insert_expr_in_table (x, mode, insn, antic_p, avail_p)
|
|
|
|
|
rtx x;
|
|
|
|
|
enum machine_mode mode;
|
|
|
|
|
rtx insn;
|
|
|
|
|
int antic_p, avail_p;
|
|
|
|
|
{
|
|
|
|
|
int found, do_not_record_p;
|
|
|
|
|
unsigned int hash;
|
|
|
|
|
struct expr *cur_expr, *last_expr = NULL;
|
|
|
|
|
struct occr *antic_occr, *avail_occr;
|
|
|
|
|
struct occr *last_occr = NULL;
|
|
|
|
|
|
|
|
|
|
hash = hash_expr (x, mode, &do_not_record_p, expr_hash_table_size);
|
|
|
|
|
|
|
|
|
|
/* Do not insert expression in table if it contains volatile operands,
|
|
|
|
|
or if hash_expr determines the expression is something we don't want
|
|
|
|
|
to or can't handle. */
|
|
|
|
|
if (do_not_record_p)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
cur_expr = expr_hash_table[hash];
|
|
|
|
|
found = 0;
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
while (cur_expr && 0 == (found = expr_equiv_p (cur_expr->expr, x)))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* If the expression isn't found, save a pointer to the end of
|
|
|
|
|
the list. */
|
|
|
|
|
last_expr = cur_expr;
|
|
|
|
|
cur_expr = cur_expr->next_same_hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! found)
|
|
|
|
|
{
|
|
|
|
|
cur_expr = (struct expr *) gcse_alloc (sizeof (struct expr));
|
|
|
|
|
bytes_used += sizeof (struct expr);
|
|
|
|
|
if (expr_hash_table[hash] == NULL)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* This is the first pattern that hashed to this index. */
|
|
|
|
|
expr_hash_table[hash] = cur_expr;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Add EXPR to end of this hash chain. */
|
|
|
|
|
last_expr->next_same_hash = cur_expr;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Set the fields of the expr element. */
|
|
|
|
|
cur_expr->expr = x;
|
|
|
|
|
cur_expr->bitmap_index = n_exprs++;
|
|
|
|
|
cur_expr->next_same_hash = NULL;
|
|
|
|
|
cur_expr->antic_occr = NULL;
|
|
|
|
|
cur_expr->avail_occr = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now record the occurrence(s). */
|
|
|
|
|
if (antic_p)
|
|
|
|
|
{
|
|
|
|
|
antic_occr = cur_expr->antic_occr;
|
|
|
|
|
|
|
|
|
|
/* Search for another occurrence in the same basic block. */
|
|
|
|
|
while (antic_occr && BLOCK_NUM (antic_occr->insn) != BLOCK_NUM (insn))
|
|
|
|
|
{
|
|
|
|
|
/* If an occurrence isn't found, save a pointer to the end of
|
|
|
|
|
the list. */
|
|
|
|
|
last_occr = antic_occr;
|
|
|
|
|
antic_occr = antic_occr->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (antic_occr)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Found another instance of the expression in the same basic block.
|
|
|
|
|
Prefer the currently recorded one. We want the first one in the
|
|
|
|
|
block and the block is scanned from start to end. */
|
|
|
|
|
; /* nothing to do */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* First occurrence of this expression in this basic block. */
|
|
|
|
|
antic_occr = (struct occr *) gcse_alloc (sizeof (struct occr));
|
|
|
|
|
bytes_used += sizeof (struct occr);
|
|
|
|
|
/* First occurrence of this expression in any block? */
|
|
|
|
|
if (cur_expr->antic_occr == NULL)
|
|
|
|
|
cur_expr->antic_occr = antic_occr;
|
|
|
|
|
else
|
|
|
|
|
last_occr->next = antic_occr;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
antic_occr->insn = insn;
|
|
|
|
|
antic_occr->next = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (avail_p)
|
|
|
|
|
{
|
|
|
|
|
avail_occr = cur_expr->avail_occr;
|
|
|
|
|
|
|
|
|
|
/* Search for another occurrence in the same basic block. */
|
|
|
|
|
while (avail_occr && BLOCK_NUM (avail_occr->insn) != BLOCK_NUM (insn))
|
|
|
|
|
{
|
|
|
|
|
/* If an occurrence isn't found, save a pointer to the end of
|
|
|
|
|
the list. */
|
|
|
|
|
last_occr = avail_occr;
|
|
|
|
|
avail_occr = avail_occr->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (avail_occr)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Found another instance of the expression in the same basic block.
|
|
|
|
|
Prefer this occurrence to the currently recorded one. We want
|
|
|
|
|
the last one in the block and the block is scanned from start
|
|
|
|
|
to end. */
|
|
|
|
|
avail_occr->insn = insn;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* First occurrence of this expression in this basic block. */
|
|
|
|
|
avail_occr = (struct occr *) gcse_alloc (sizeof (struct occr));
|
|
|
|
|
bytes_used += sizeof (struct occr);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* First occurrence of this expression in any block? */
|
|
|
|
|
if (cur_expr->avail_occr == NULL)
|
|
|
|
|
cur_expr->avail_occr = avail_occr;
|
|
|
|
|
else
|
|
|
|
|
last_occr->next = avail_occr;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
avail_occr->insn = insn;
|
|
|
|
|
avail_occr->next = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Insert pattern X in INSN in the hash table.
|
|
|
|
|
X is a SET of a reg to either another reg or a constant.
|
|
|
|
|
If it is already present, record it as the last occurrence in INSN's
|
|
|
|
|
basic block. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
insert_set_in_table (x, insn)
|
|
|
|
|
rtx x;
|
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
|
|
|
|
int found;
|
|
|
|
|
unsigned int hash;
|
|
|
|
|
struct expr *cur_expr, *last_expr = NULL;
|
|
|
|
|
struct occr *cur_occr, *last_occr = NULL;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (x) != SET
|
|
|
|
|
|| GET_CODE (SET_DEST (x)) != REG)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
hash = hash_set (REGNO (SET_DEST (x)), set_hash_table_size);
|
|
|
|
|
|
|
|
|
|
cur_expr = set_hash_table[hash];
|
|
|
|
|
found = 0;
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
while (cur_expr && 0 == (found = expr_equiv_p (cur_expr->expr, x)))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* If the expression isn't found, save a pointer to the end of
|
|
|
|
|
the list. */
|
|
|
|
|
last_expr = cur_expr;
|
|
|
|
|
cur_expr = cur_expr->next_same_hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! found)
|
|
|
|
|
{
|
|
|
|
|
cur_expr = (struct expr *) gcse_alloc (sizeof (struct expr));
|
|
|
|
|
bytes_used += sizeof (struct expr);
|
|
|
|
|
if (set_hash_table[hash] == NULL)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* This is the first pattern that hashed to this index. */
|
|
|
|
|
set_hash_table[hash] = cur_expr;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Add EXPR to end of this hash chain. */
|
|
|
|
|
last_expr->next_same_hash = cur_expr;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Set the fields of the expr element.
|
|
|
|
|
We must copy X because it can be modified when copy propagation is
|
|
|
|
|
performed on its operands. */
|
|
|
|
|
cur_expr->expr = copy_rtx (x);
|
|
|
|
|
cur_expr->bitmap_index = n_sets++;
|
|
|
|
|
cur_expr->next_same_hash = NULL;
|
|
|
|
|
cur_expr->antic_occr = NULL;
|
|
|
|
|
cur_expr->avail_occr = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now record the occurrence. */
|
|
|
|
|
cur_occr = cur_expr->avail_occr;
|
|
|
|
|
|
|
|
|
|
/* Search for another occurrence in the same basic block. */
|
|
|
|
|
while (cur_occr && BLOCK_NUM (cur_occr->insn) != BLOCK_NUM (insn))
|
|
|
|
|
{
|
|
|
|
|
/* If an occurrence isn't found, save a pointer to the end of
|
|
|
|
|
the list. */
|
|
|
|
|
last_occr = cur_occr;
|
|
|
|
|
cur_occr = cur_occr->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cur_occr)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Found another instance of the expression in the same basic block.
|
|
|
|
|
Prefer this occurrence to the currently recorded one. We want the
|
|
|
|
|
last one in the block and the block is scanned from start to end. */
|
|
|
|
|
cur_occr->insn = insn;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* First occurrence of this expression in this basic block. */
|
|
|
|
|
cur_occr = (struct occr *) gcse_alloc (sizeof (struct occr));
|
|
|
|
|
bytes_used += sizeof (struct occr);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* First occurrence of this expression in any block? */
|
|
|
|
|
if (cur_expr->avail_occr == NULL)
|
|
|
|
|
cur_expr->avail_occr = cur_occr;
|
|
|
|
|
else
|
|
|
|
|
last_occr->next = cur_occr;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
cur_occr->insn = insn;
|
|
|
|
|
cur_occr->next = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Scan pattern PAT of INSN and add an entry to the hash table. If SET_P is
|
|
|
|
|
non-zero, this is for the assignment hash table, otherwise it is for the
|
|
|
|
|
expression hash table. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
hash_scan_set (pat, insn, set_p)
|
|
|
|
|
rtx pat, insn;
|
|
|
|
|
int set_p;
|
|
|
|
|
{
|
|
|
|
|
rtx src = SET_SRC (pat);
|
|
|
|
|
rtx dest = SET_DEST (pat);
|
2001-02-16 20:29:49 +01:00
|
|
|
|
rtx note;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (GET_CODE (src) == CALL)
|
|
|
|
|
hash_scan_call (src, insn);
|
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
else if (GET_CODE (dest) == REG)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
2001-02-16 20:29:49 +01:00
|
|
|
|
unsigned int regno = REGNO (dest);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
rtx tmp;
|
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* If this is a single set and we are doing constant propagation,
|
|
|
|
|
see if a REG_NOTE shows this equivalent to a constant. */
|
|
|
|
|
if (set_p && (note = find_reg_equal_equiv_note (insn)) != 0
|
|
|
|
|
&& CONSTANT_P (XEXP (note, 0)))
|
|
|
|
|
src = XEXP (note, 0), pat = gen_rtx_SET (VOIDmode, dest, src);
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Only record sets of pseudo-regs in the hash table. */
|
|
|
|
|
if (! set_p
|
|
|
|
|
&& regno >= FIRST_PSEUDO_REGISTER
|
|
|
|
|
/* Don't GCSE something if we can't do a reg/reg copy. */
|
|
|
|
|
&& can_copy_p [GET_MODE (dest)]
|
|
|
|
|
/* Is SET_SRC something we want to gcse? */
|
2001-02-16 20:29:49 +01:00
|
|
|
|
&& want_to_gcse_p (src)
|
|
|
|
|
/* Don't CSE a nop. */
|
2001-04-04 07:03:29 +02:00
|
|
|
|
&& ! set_noop_p (pat))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* An expression is not anticipatable if its operands are
|
2001-03-22 01:21:16 +01:00
|
|
|
|
modified before this insn or if this is not the only SET in
|
|
|
|
|
this insn. */
|
|
|
|
|
int antic_p = oprs_anticipatable_p (src, insn) && single_set (insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* An expression is not available if its operands are
|
|
|
|
|
subsequently modified, including this insn. */
|
|
|
|
|
int avail_p = oprs_available_p (src, insn);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
insert_expr_in_table (src, GET_MODE (dest), insn, antic_p, avail_p);
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Record sets for constant/copy propagation. */
|
|
|
|
|
else if (set_p
|
|
|
|
|
&& regno >= FIRST_PSEUDO_REGISTER
|
|
|
|
|
&& ((GET_CODE (src) == REG
|
|
|
|
|
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
|
2001-02-16 20:29:49 +01:00
|
|
|
|
&& can_copy_p [GET_MODE (dest)]
|
|
|
|
|
&& REGNO (src) != regno)
|
1999-03-10 20:45:18 +01:00
|
|
|
|
|| GET_CODE (src) == CONST_INT
|
1999-08-07 10:13:28 +02:00
|
|
|
|
|| GET_CODE (src) == SYMBOL_REF
|
1999-03-10 20:45:18 +01:00
|
|
|
|
|| GET_CODE (src) == CONST_DOUBLE)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* A copy is not available if its src or dest is subsequently
|
|
|
|
|
modified. Here we want to search from INSN+1 on, but
|
|
|
|
|
oprs_available_p searches from INSN on. */
|
|
|
|
|
&& (insn == BLOCK_END (BLOCK_NUM (insn))
|
|
|
|
|
|| ((tmp = next_nonnote_insn (insn)) != NULL_RTX
|
|
|
|
|
&& oprs_available_p (pat, tmp))))
|
|
|
|
|
insert_set_in_table (pat, insn);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
hash_scan_clobber (x, insn)
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
rtx x ATTRIBUTE_UNUSED, insn ATTRIBUTE_UNUSED;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* Currently nothing to do. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
hash_scan_call (x, insn)
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
rtx x ATTRIBUTE_UNUSED, insn ATTRIBUTE_UNUSED;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* Currently nothing to do. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Process INSN and add hash table entries as appropriate.
|
|
|
|
|
|
|
|
|
|
Only available expressions that set a single pseudo-reg are recorded.
|
|
|
|
|
|
|
|
|
|
Single sets in a PARALLEL could be handled, but it's an extra complication
|
|
|
|
|
that isn't dealt with right now. The trick is handling the CLOBBERs that
|
|
|
|
|
are also in the PARALLEL. Later.
|
|
|
|
|
|
|
|
|
|
If SET_P is non-zero, this is for the assignment hash table,
|
1998-07-06 23:50:50 +02:00
|
|
|
|
otherwise it is for the expression hash table.
|
|
|
|
|
If IN_LIBCALL_BLOCK nonzero, we are in a libcall block, and should
|
|
|
|
|
not record any expressions. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
1998-07-06 23:50:50 +02:00
|
|
|
|
hash_scan_insn (insn, set_p, in_libcall_block)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
rtx insn;
|
|
|
|
|
int set_p;
|
1998-07-14 00:09:21 +02:00
|
|
|
|
int in_libcall_block;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
rtx pat = PATTERN (insn);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int i;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
if (in_libcall_block)
|
|
|
|
|
return;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Pick out the sets of INSN and for other forms of instructions record
|
|
|
|
|
what's been modified. */
|
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
if (GET_CODE (pat) == SET)
|
|
|
|
|
hash_scan_set (pat, insn, set_p);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
else if (GET_CODE (pat) == PARALLEL)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = 0; i < XVECLEN (pat, 0); i++)
|
|
|
|
|
{
|
|
|
|
|
rtx x = XVECEXP (pat, 0, i);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (GET_CODE (x) == SET)
|
2001-02-16 20:29:49 +01:00
|
|
|
|
hash_scan_set (x, insn, set_p);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
else if (GET_CODE (x) == CLOBBER)
|
|
|
|
|
hash_scan_clobber (x, insn);
|
|
|
|
|
else if (GET_CODE (x) == CALL)
|
|
|
|
|
hash_scan_call (x, insn);
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
else if (GET_CODE (pat) == CLOBBER)
|
|
|
|
|
hash_scan_clobber (pat, insn);
|
|
|
|
|
else if (GET_CODE (pat) == CALL)
|
|
|
|
|
hash_scan_call (pat, insn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dump_hash_table (file, name, table, table_size, total_size)
|
|
|
|
|
FILE *file;
|
c-aux-info.c (data_type, [...]): Qualify a char* with the `const' keyword.
* c-aux-info.c (data_type, affix_data_type, gen_decl,
gen_formal_list_for_type, gen_formal_list_for_func_def, gen_type):
Qualify a char* with the `const' keyword.
* c-common.c (declare_hidden_char_array, add_attribute, if_elt,
declare_function_name, decl_attributes, format_char_info,
check_format_info, binary_op_error): Likewise.
* cexp.y (yyerror, error, pedwarn, warning, token): Likewise.
* gcse.c (dump_hash_table): Likewise.
* integrate.c (function_cannot_inline_p): Likewise
* optabs.c: Include insn-config.h earlier.
(init_libfuncs, init_integral_libfuncs, init_floating_libfuncs):
Qualify a char* with the `const' keyword.
* real.c (asctoe24, asctoe53, asctoe64, asctoe113, asctoe,
asctoeg, mtherr, ereal_atof): Likewise.
* real.h (ereal_atof): Likewise.
* sbitmap.c (dump_sbitmap_vector): Likewise.
* sbitmap.h (dump_sbitmap_vector): Likewise.
* stmt.c (nesting, n_occurrences, expand_start_case): Likewise.
* toplev.c (rest_of_compilation): Likewise.
* tree.h (function_cannot_inline_p, expand_start_case): Likewise.
From-SVN: r25614
1999-03-06 06:34:26 +01:00
|
|
|
|
const char *name;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
struct expr **table;
|
|
|
|
|
int table_size, total_size;
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
/* Flattened out table, so it's printed in proper order. */
|
1999-11-08 05:56:18 +01:00
|
|
|
|
struct expr **flat_table;
|
|
|
|
|
unsigned int *hash_val;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct expr *expr;
|
1999-11-08 05:56:18 +01:00
|
|
|
|
|
|
|
|
|
flat_table
|
|
|
|
|
= (struct expr **) xcalloc (total_size, sizeof (struct expr *));
|
|
|
|
|
hash_val = (unsigned int *) xmalloc (total_size * sizeof (unsigned int));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < table_size; i++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (expr = table[i]; expr != NULL; expr = expr->next_same_hash)
|
|
|
|
|
{
|
|
|
|
|
flat_table[expr->bitmap_index] = expr;
|
|
|
|
|
hash_val[expr->bitmap_index] = i;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
fprintf (file, "%s hash table (%d buckets, %d entries)\n",
|
|
|
|
|
name, table_size, total_size);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < total_size; i++)
|
2000-03-02 19:29:56 +01:00
|
|
|
|
if (flat_table[i] != 0)
|
|
|
|
|
{
|
2000-03-03 09:28:43 +01:00
|
|
|
|
expr = flat_table[i];
|
2000-03-02 19:29:56 +01:00
|
|
|
|
fprintf (file, "Index %d (hash value %d)\n ",
|
|
|
|
|
expr->bitmap_index, hash_val[i]);
|
2000-03-03 09:28:43 +01:00
|
|
|
|
print_rtl (file, expr->expr);
|
2000-03-02 19:29:56 +01:00
|
|
|
|
fprintf (file, "\n");
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
fprintf (file, "\n");
|
1999-11-08 05:56:18 +01:00
|
|
|
|
|
|
|
|
|
free (flat_table);
|
|
|
|
|
free (hash_val);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Record register first/last/block set information for REGNO in INSN.
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
reg_first_set records the first place in the block where the register
|
|
|
|
|
is set and is used to compute "anticipatability".
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
reg_last_set records the last place in the block where the register
|
|
|
|
|
is set and is used to compute "availability".
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
reg_set_in_block records whether the register is set in the block
|
|
|
|
|
and is used to compute "transparency". */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
record_last_reg_set_info (insn, regno)
|
|
|
|
|
rtx insn;
|
|
|
|
|
int regno;
|
|
|
|
|
{
|
1998-09-16 01:32:22 +02:00
|
|
|
|
if (reg_first_set[regno] == NEVER_SET)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
reg_first_set[regno] = INSN_CUID (insn);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
reg_last_set[regno] = INSN_CUID (insn);
|
|
|
|
|
SET_BIT (reg_set_in_block[BLOCK_NUM (insn)], regno);
|
|
|
|
|
}
|
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
/* Record all of the canonicalized MEMs of record_last_mem_set_info's insn.
|
|
|
|
|
Note we store a pair of elements in the list, so they have to be
|
|
|
|
|
taken off pairwise. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
canon_list_insert (dest, unused1, v_insn)
|
|
|
|
|
rtx dest ATTRIBUTE_UNUSED;
|
|
|
|
|
rtx unused1 ATTRIBUTE_UNUSED;
|
|
|
|
|
void * v_insn;
|
|
|
|
|
{
|
|
|
|
|
rtx dest_addr, insn;
|
|
|
|
|
|
|
|
|
|
while (GET_CODE (dest) == SUBREG
|
|
|
|
|
|| GET_CODE (dest) == ZERO_EXTRACT
|
|
|
|
|
|| GET_CODE (dest) == SIGN_EXTRACT
|
|
|
|
|
|| GET_CODE (dest) == STRICT_LOW_PART)
|
|
|
|
|
dest = XEXP (dest, 0);
|
|
|
|
|
|
|
|
|
|
/* If DEST is not a MEM, then it will not conflict with a load. Note
|
|
|
|
|
that function calls are assumed to clobber memory, but are handled
|
|
|
|
|
elsewhere. */
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (dest) != MEM)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
dest_addr = get_addr (XEXP (dest, 0));
|
|
|
|
|
dest_addr = canon_rtx (dest_addr);
|
|
|
|
|
insn = (rtx) v_insn;
|
|
|
|
|
|
|
|
|
|
canon_modify_mem_list[BLOCK_NUM (insn)] =
|
|
|
|
|
alloc_INSN_LIST (dest_addr, canon_modify_mem_list[BLOCK_NUM (insn)]);
|
|
|
|
|
canon_modify_mem_list[BLOCK_NUM (insn)] =
|
|
|
|
|
alloc_INSN_LIST (dest, canon_modify_mem_list[BLOCK_NUM (insn)]);
|
|
|
|
|
}
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Record memory first/last/block set information for INSN. */
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* Record memory modification information for INSN. We do not actually care
|
|
|
|
|
about the memory location(s) that are set, or even how they are set (consider
|
|
|
|
|
a CALL_INSN). We merely need to record which insns modify memory. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
record_last_mem_set_info (insn)
|
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
1998-09-16 01:32:22 +02:00
|
|
|
|
if (mem_first_set == NEVER_SET)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
mem_first_set = INSN_CUID (insn);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
mem_last_set = INSN_CUID (insn);
|
|
|
|
|
mem_set_in_block[BLOCK_NUM (insn)] = 1;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
modify_mem_list[BLOCK_NUM (insn)] =
|
|
|
|
|
alloc_INSN_LIST (insn, modify_mem_list[BLOCK_NUM (insn)]);
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (insn) == CALL_INSN)
|
|
|
|
|
{
|
|
|
|
|
/* Note that traversals of this loop (other than for free-ing)
|
|
|
|
|
will break after encountering a CALL_INSN. So, there's no
|
|
|
|
|
need to insert a pair of items, as canon_list_insert does. */
|
|
|
|
|
canon_modify_mem_list[BLOCK_NUM (insn)] =
|
|
|
|
|
alloc_INSN_LIST (insn, canon_modify_mem_list[BLOCK_NUM (insn)]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
note_stores (PATTERN (insn), canon_list_insert, (void*)insn );
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Called from compute_hash_table via note_stores to handle one
|
1999-10-27 21:27:41 +02:00
|
|
|
|
SET or CLOBBER in an insn. DATA is really the instruction in which
|
|
|
|
|
the SET is taking place. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
1999-10-27 21:27:41 +02:00
|
|
|
|
record_last_set_info (dest, setter, data)
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
rtx dest, setter ATTRIBUTE_UNUSED;
|
1999-10-27 21:27:41 +02:00
|
|
|
|
void *data;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
1999-10-27 21:27:41 +02:00
|
|
|
|
rtx last_set_insn = (rtx) data;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (GET_CODE (dest) == SUBREG)
|
|
|
|
|
dest = SUBREG_REG (dest);
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (dest) == REG)
|
|
|
|
|
record_last_reg_set_info (last_set_insn, REGNO (dest));
|
|
|
|
|
else if (GET_CODE (dest) == MEM
|
|
|
|
|
/* Ignore pushes, they clobber nothing. */
|
|
|
|
|
&& ! push_operand (dest, GET_MODE (dest)))
|
|
|
|
|
record_last_mem_set_info (last_set_insn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Top level function to create an expression or assignment hash table.
|
|
|
|
|
|
|
|
|
|
Expression entries are placed in the hash table if
|
|
|
|
|
- they are of the form (set (pseudo-reg) src),
|
|
|
|
|
- src is something we want to perform GCSE on,
|
|
|
|
|
- none of the operands are subsequently modified in the block
|
|
|
|
|
|
|
|
|
|
Assignment entries are placed in the hash table if
|
|
|
|
|
- they are of the form (set (pseudo-reg) src),
|
|
|
|
|
- src is something we want to perform const/copy propagation on,
|
|
|
|
|
- none of the operands or target are subsequently modified in the block
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
Currently src must be a pseudo-reg or a const_int.
|
|
|
|
|
|
|
|
|
|
F is the first insn.
|
|
|
|
|
SET_P is non-zero for computing the assignment hash table. */
|
|
|
|
|
|
|
|
|
|
static void
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
compute_hash_table (set_p)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
int set_p;
|
|
|
|
|
{
|
|
|
|
|
int bb;
|
|
|
|
|
|
|
|
|
|
/* While we compute the hash table we also compute a bit array of which
|
|
|
|
|
registers are set in which blocks.
|
|
|
|
|
We also compute which blocks set memory, in the absence of aliasing
|
|
|
|
|
support [which is TODO].
|
|
|
|
|
??? This isn't needed during const/copy propagation, but it's cheap to
|
|
|
|
|
compute. Later. */
|
|
|
|
|
sbitmap_vector_zero (reg_set_in_block, n_basic_blocks);
|
alias.c [...] (init_alias_analysis, [...]): Use memset () instead of bzero ().
* alias.c (init_alias_analysis), calls.c (expand_call,
emit_library_call_value_1), combine.c (init_reg_last_arrays),
cse.c (new_basic_block), dbxout.c (dbxout_type), diagnostic.c
(init_output_buffer, set_diagnostic_context), dwarf2out.c
(equate_decl_number_to_die, build_abbrev_table), emit-rtl.c
(init_emit_once), fold-const.c (mul_double, div_and_round_double),
function.c (assign_parms), gcse.c (compute_can_copy,
alloc_gcse_mem, alloc_reg_set_mem, record_one_set,
compute_hash_table, compute_set_hash_table,
compute_expr_hash_table), genattrtab.c (optimize_attrs), global.c
(global_alloc, global_conflicts), haifa-sched.c (compute_trg_info,
clear_units, schedule_block), integrate.c (initialize_for_inline,
expand_inline_function), jump.c (thread_jumps), local-alloc.c
(local_alloc), loop.c (combine_movables, count_loop_regs_set,
load_mems_and_recount_loop_regs_set), print-tree.c (debug_tree),
regclass.c (init_reg_sets, init_reg_sets_1, regclass,
record_reg_classes, allocate_reg_info), reload.c
(get_secondary_mem, remove_address_replacements, find_reloads),
reload1.c (reload, set_initial_label_offsets, finish_spills,
reload_as_needed, choose_reload_regs_init,
reload_cse_simplify_operands), reorg.c (dbr_schedule), sbitmap.c
(sbitmap_zero), simplify-rtx.c (simplify_plus_minus), ssa.c
(rename_registers), stmt.c (expand_end_case), unroll.c
(unroll_loop), varray.c (varray_grow), objc/objc-act.c: Use memset
() instead of bzero ().
ch:
* actions.c (check_missing_cases), typeck.c (build_chill_slice,
build_chill_cast): Use memset () instead of bzero ().
cp:
* class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
(push_binding_level), error.c (cp_tree_printer), pt.c
(process_partial_specialization, tsubst_template_arg_vector),
search.c (lookup_member): Use memset () instead of bzero ().
java:
* expr.c (note_instructions), jcf-io.c (find_class), jcf-parse.c
(init_outgoing_cpool), lex.c (java_init_lex): Use memset ()
instead of bzero ().
From-SVN: r37303
2000-11-07 23:50:06 +01:00
|
|
|
|
memset ((char *) mem_set_in_block, 0, n_basic_blocks);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
/* re-Cache any INSN_LIST nodes we have allocated. */
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < n_basic_blocks; i++)
|
|
|
|
|
{
|
|
|
|
|
if (modify_mem_list[i])
|
|
|
|
|
free_INSN_LIST_list (modify_mem_list + i);
|
|
|
|
|
if (canon_modify_mem_list[i])
|
|
|
|
|
free_INSN_LIST_list (canon_modify_mem_list + i);
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Some working arrays used to track first and last set in each block. */
|
|
|
|
|
/* ??? One could use alloca here, but at some size a threshold is crossed
|
|
|
|
|
beyond which one should use malloc. Are we at that threshold here? */
|
|
|
|
|
reg_first_set = (int *) gmalloc (max_gcse_regno * sizeof (int));
|
|
|
|
|
reg_last_set = (int *) gmalloc (max_gcse_regno * sizeof (int));
|
|
|
|
|
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
{
|
|
|
|
|
rtx insn;
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int regno;
|
1998-07-06 23:50:50 +02:00
|
|
|
|
int in_libcall_block;
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int i;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* First pass over the instructions records information used to
|
|
|
|
|
determine when registers and memory are first and last set.
|
|
|
|
|
??? The mem_set_in_block and hard-reg reg_set_in_block computation
|
|
|
|
|
could be moved to compute_sets since they currently don't change. */
|
|
|
|
|
|
1998-09-16 01:32:22 +02:00
|
|
|
|
for (i = 0; i < max_gcse_regno; i++)
|
|
|
|
|
reg_first_set[i] = reg_last_set[i] = NEVER_SET;
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
|
1998-09-16 01:32:22 +02:00
|
|
|
|
mem_first_set = NEVER_SET;
|
|
|
|
|
mem_last_set = NEVER_SET;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
basic-block.h (basic_block_head): Rename to x_basic_block_head.
* basic-block.h (basic_block_head): Rename to x_basic_block_head.
(basic_block_end): Rename to x_basic_block_end.
(BLOCK_HEAD, BLOCK_END): Update.
* caller-save.c: Change basic_block_head/end references to
BLOCK_HEAD/END.
* combine.c, flow.c, function.c, gcse.c, global.c: Likewise.
* graph.c, haifa-sched.c, local-alloc.c, regclass.c: Likewise.
* regmove.c, reload1.c, reorg.c, sched.c: Likewise.
From-SVN: r24622
1999-01-11 23:37:20 +01:00
|
|
|
|
for (insn = BLOCK_HEAD (bb);
|
|
|
|
|
insn && insn != NEXT_INSN (BLOCK_END (bb));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
insn = NEXT_INSN (insn))
|
|
|
|
|
{
|
|
|
|
|
#ifdef NON_SAVING_SETJMP
|
|
|
|
|
if (NON_SAVING_SETJMP && GET_CODE (insn) == NOTE
|
|
|
|
|
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
|
|
|
|
|
{
|
|
|
|
|
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
|
|
|
|
record_last_reg_set_info (insn, regno);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-08-04 22:28:08 +02:00
|
|
|
|
if (! INSN_P (insn))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (insn) == CALL_INSN)
|
|
|
|
|
{
|
|
|
|
|
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
1998-10-20 01:17:48 +02:00
|
|
|
|
if ((call_used_regs[regno]
|
|
|
|
|
&& regno != STACK_POINTER_REGNUM
|
|
|
|
|
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
|
|
|
|
&& regno != HARD_FRAME_POINTER_REGNUM
|
|
|
|
|
#endif
|
|
|
|
|
#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
|
|
|
|
&& ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
|
|
|
|
|
#endif
|
2001-02-13 21:17:45 +01:00
|
|
|
|
#if !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
|
1998-10-20 01:17:48 +02:00
|
|
|
|
&& ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
&& regno != FRAME_POINTER_REGNUM)
|
|
|
|
|
|| global_regs[regno])
|
1998-05-20 02:24:32 +02:00
|
|
|
|
record_last_reg_set_info (insn, regno);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (! CONST_CALL_P (insn))
|
|
|
|
|
record_last_mem_set_info (insn);
|
|
|
|
|
}
|
|
|
|
|
|
1999-10-27 21:27:41 +02:00
|
|
|
|
note_stores (PATTERN (insn), record_last_set_info, insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The next pass builds the hash table. */
|
|
|
|
|
|
basic-block.h (basic_block_head): Rename to x_basic_block_head.
* basic-block.h (basic_block_head): Rename to x_basic_block_head.
(basic_block_end): Rename to x_basic_block_end.
(BLOCK_HEAD, BLOCK_END): Update.
* caller-save.c: Change basic_block_head/end references to
BLOCK_HEAD/END.
* combine.c, flow.c, function.c, gcse.c, global.c: Likewise.
* graph.c, haifa-sched.c, local-alloc.c, regclass.c: Likewise.
* regmove.c, reload1.c, reorg.c, sched.c: Likewise.
From-SVN: r24622
1999-01-11 23:37:20 +01:00
|
|
|
|
for (insn = BLOCK_HEAD (bb), in_libcall_block = 0;
|
|
|
|
|
insn && insn != NEXT_INSN (BLOCK_END (bb));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
insn = NEXT_INSN (insn))
|
2000-08-04 22:28:08 +02:00
|
|
|
|
if (INSN_P (insn))
|
2000-02-29 21:08:52 +01:00
|
|
|
|
{
|
|
|
|
|
if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
|
|
|
|
|
in_libcall_block = 1;
|
|
|
|
|
else if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
|
|
|
|
|
in_libcall_block = 0;
|
|
|
|
|
hash_scan_insn (insn, set_p, in_libcall_block);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free (reg_first_set);
|
|
|
|
|
free (reg_last_set);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Catch bugs early. */
|
|
|
|
|
reg_first_set = reg_last_set = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Allocate space for the set hash table.
|
|
|
|
|
N_INSNS is the number of instructions in the function.
|
|
|
|
|
It is used to determine the number of buckets to use. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
alloc_set_hash_table (n_insns)
|
|
|
|
|
int n_insns;
|
|
|
|
|
{
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
set_hash_table_size = n_insns / 4;
|
|
|
|
|
if (set_hash_table_size < 11)
|
|
|
|
|
set_hash_table_size = 11;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Attempt to maintain efficient use of hash table.
|
|
|
|
|
Making it an odd number is simplest for now.
|
|
|
|
|
??? Later take some measurements. */
|
|
|
|
|
set_hash_table_size |= 1;
|
|
|
|
|
n = set_hash_table_size * sizeof (struct expr *);
|
|
|
|
|
set_hash_table = (struct expr **) gmalloc (n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free things allocated by alloc_set_hash_table. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_set_hash_table ()
|
|
|
|
|
{
|
|
|
|
|
free (set_hash_table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute the hash table for doing copy/const propagation. */
|
|
|
|
|
|
|
|
|
|
static void
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
compute_set_hash_table ()
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* Initialize count of number of entries in hash table. */
|
|
|
|
|
n_sets = 0;
|
alias.c [...] (init_alias_analysis, [...]): Use memset () instead of bzero ().
* alias.c (init_alias_analysis), calls.c (expand_call,
emit_library_call_value_1), combine.c (init_reg_last_arrays),
cse.c (new_basic_block), dbxout.c (dbxout_type), diagnostic.c
(init_output_buffer, set_diagnostic_context), dwarf2out.c
(equate_decl_number_to_die, build_abbrev_table), emit-rtl.c
(init_emit_once), fold-const.c (mul_double, div_and_round_double),
function.c (assign_parms), gcse.c (compute_can_copy,
alloc_gcse_mem, alloc_reg_set_mem, record_one_set,
compute_hash_table, compute_set_hash_table,
compute_expr_hash_table), genattrtab.c (optimize_attrs), global.c
(global_alloc, global_conflicts), haifa-sched.c (compute_trg_info,
clear_units, schedule_block), integrate.c (initialize_for_inline,
expand_inline_function), jump.c (thread_jumps), local-alloc.c
(local_alloc), loop.c (combine_movables, count_loop_regs_set,
load_mems_and_recount_loop_regs_set), print-tree.c (debug_tree),
regclass.c (init_reg_sets, init_reg_sets_1, regclass,
record_reg_classes, allocate_reg_info), reload.c
(get_secondary_mem, remove_address_replacements, find_reloads),
reload1.c (reload, set_initial_label_offsets, finish_spills,
reload_as_needed, choose_reload_regs_init,
reload_cse_simplify_operands), reorg.c (dbr_schedule), sbitmap.c
(sbitmap_zero), simplify-rtx.c (simplify_plus_minus), ssa.c
(rename_registers), stmt.c (expand_end_case), unroll.c
(unroll_loop), varray.c (varray_grow), objc/objc-act.c: Use memset
() instead of bzero ().
ch:
* actions.c (check_missing_cases), typeck.c (build_chill_slice,
build_chill_cast): Use memset () instead of bzero ().
cp:
* class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
(push_binding_level), error.c (cp_tree_printer), pt.c
(process_partial_specialization, tsubst_template_arg_vector),
search.c (lookup_member): Use memset () instead of bzero ().
java:
* expr.c (note_instructions), jcf-io.c (find_class), jcf-parse.c
(init_outgoing_cpool), lex.c (java_init_lex): Use memset ()
instead of bzero ().
From-SVN: r37303
2000-11-07 23:50:06 +01:00
|
|
|
|
memset ((char *) set_hash_table, 0,
|
2000-02-29 21:08:52 +01:00
|
|
|
|
set_hash_table_size * sizeof (struct expr *));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
compute_hash_table (1);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Allocate space for the expression hash table.
|
|
|
|
|
N_INSNS is the number of instructions in the function.
|
|
|
|
|
It is used to determine the number of buckets to use. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
alloc_expr_hash_table (n_insns)
|
2000-04-10 13:33:18 +02:00
|
|
|
|
unsigned int n_insns;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
expr_hash_table_size = n_insns / 2;
|
|
|
|
|
/* Make sure the amount is usable. */
|
|
|
|
|
if (expr_hash_table_size < 11)
|
|
|
|
|
expr_hash_table_size = 11;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Attempt to maintain efficient use of hash table.
|
|
|
|
|
Making it an odd number is simplest for now.
|
|
|
|
|
??? Later take some measurements. */
|
|
|
|
|
expr_hash_table_size |= 1;
|
|
|
|
|
n = expr_hash_table_size * sizeof (struct expr *);
|
|
|
|
|
expr_hash_table = (struct expr **) gmalloc (n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free things allocated by alloc_expr_hash_table. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_expr_hash_table ()
|
|
|
|
|
{
|
|
|
|
|
free (expr_hash_table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute the hash table for doing GCSE. */
|
|
|
|
|
|
|
|
|
|
static void
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
compute_expr_hash_table ()
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* Initialize count of number of entries in hash table. */
|
|
|
|
|
n_exprs = 0;
|
alias.c [...] (init_alias_analysis, [...]): Use memset () instead of bzero ().
* alias.c (init_alias_analysis), calls.c (expand_call,
emit_library_call_value_1), combine.c (init_reg_last_arrays),
cse.c (new_basic_block), dbxout.c (dbxout_type), diagnostic.c
(init_output_buffer, set_diagnostic_context), dwarf2out.c
(equate_decl_number_to_die, build_abbrev_table), emit-rtl.c
(init_emit_once), fold-const.c (mul_double, div_and_round_double),
function.c (assign_parms), gcse.c (compute_can_copy,
alloc_gcse_mem, alloc_reg_set_mem, record_one_set,
compute_hash_table, compute_set_hash_table,
compute_expr_hash_table), genattrtab.c (optimize_attrs), global.c
(global_alloc, global_conflicts), haifa-sched.c (compute_trg_info,
clear_units, schedule_block), integrate.c (initialize_for_inline,
expand_inline_function), jump.c (thread_jumps), local-alloc.c
(local_alloc), loop.c (combine_movables, count_loop_regs_set,
load_mems_and_recount_loop_regs_set), print-tree.c (debug_tree),
regclass.c (init_reg_sets, init_reg_sets_1, regclass,
record_reg_classes, allocate_reg_info), reload.c
(get_secondary_mem, remove_address_replacements, find_reloads),
reload1.c (reload, set_initial_label_offsets, finish_spills,
reload_as_needed, choose_reload_regs_init,
reload_cse_simplify_operands), reorg.c (dbr_schedule), sbitmap.c
(sbitmap_zero), simplify-rtx.c (simplify_plus_minus), ssa.c
(rename_registers), stmt.c (expand_end_case), unroll.c
(unroll_loop), varray.c (varray_grow), objc/objc-act.c: Use memset
() instead of bzero ().
ch:
* actions.c (check_missing_cases), typeck.c (build_chill_slice,
build_chill_cast): Use memset () instead of bzero ().
cp:
* class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
(push_binding_level), error.c (cp_tree_printer), pt.c
(process_partial_specialization, tsubst_template_arg_vector),
search.c (lookup_member): Use memset () instead of bzero ().
java:
* expr.c (note_instructions), jcf-io.c (find_class), jcf-parse.c
(init_outgoing_cpool), lex.c (java_init_lex): Use memset ()
instead of bzero ().
From-SVN: r37303
2000-11-07 23:50:06 +01:00
|
|
|
|
memset ((char *) expr_hash_table, 0,
|
2000-02-29 21:08:52 +01:00
|
|
|
|
expr_hash_table_size * sizeof (struct expr *));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
compute_hash_table (0);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Expression tracking support. */
|
|
|
|
|
|
|
|
|
|
/* Lookup pattern PAT in the expression table.
|
|
|
|
|
The result is a pointer to the table entry, or NULL if not found. */
|
|
|
|
|
|
|
|
|
|
static struct expr *
|
|
|
|
|
lookup_expr (pat)
|
|
|
|
|
rtx pat;
|
|
|
|
|
{
|
|
|
|
|
int do_not_record_p;
|
|
|
|
|
unsigned int hash = hash_expr (pat, GET_MODE (pat), &do_not_record_p,
|
|
|
|
|
expr_hash_table_size);
|
|
|
|
|
struct expr *expr;
|
|
|
|
|
|
|
|
|
|
if (do_not_record_p)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
expr = expr_hash_table[hash];
|
|
|
|
|
|
|
|
|
|
while (expr && ! expr_equiv_p (expr->expr, pat))
|
|
|
|
|
expr = expr->next_same_hash;
|
|
|
|
|
|
|
|
|
|
return expr;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Lookup REGNO in the set table. If PAT is non-NULL look for the entry that
|
|
|
|
|
matches it, otherwise return the first entry for REGNO. The result is a
|
|
|
|
|
pointer to the table entry, or NULL if not found. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static struct expr *
|
|
|
|
|
lookup_set (regno, pat)
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int regno;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
rtx pat;
|
|
|
|
|
{
|
|
|
|
|
unsigned int hash = hash_set (regno, set_hash_table_size);
|
|
|
|
|
struct expr *expr;
|
|
|
|
|
|
|
|
|
|
expr = set_hash_table[hash];
|
|
|
|
|
|
|
|
|
|
if (pat)
|
|
|
|
|
{
|
|
|
|
|
while (expr && ! expr_equiv_p (expr->expr, pat))
|
|
|
|
|
expr = expr->next_same_hash;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
while (expr && REGNO (SET_DEST (expr->expr)) != regno)
|
|
|
|
|
expr = expr->next_same_hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return expr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the next entry for REGNO in list EXPR. */
|
|
|
|
|
|
|
|
|
|
static struct expr *
|
|
|
|
|
next_set (regno, expr)
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int regno;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
struct expr *expr;
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
expr = expr->next_same_hash;
|
|
|
|
|
while (expr && REGNO (SET_DEST (expr->expr)) != regno);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return expr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Reset tables used to keep track of what's still available [since the
|
|
|
|
|
start of the block]. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
reset_opr_set_tables ()
|
|
|
|
|
{
|
|
|
|
|
/* Maintain a bitmap of which regs have been set since beginning of
|
|
|
|
|
the block. */
|
|
|
|
|
sbitmap_zero (reg_set_bitmap);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Also keep a record of the last instruction to modify memory.
|
|
|
|
|
For now this is very trivial, we only record whether any memory
|
|
|
|
|
location has been modified. */
|
|
|
|
|
mem_last_set = 0;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* re-Cache any INSN_LIST nodes we have allocated. */
|
|
|
|
|
for (i = 0; i < n_basic_blocks; i++)
|
|
|
|
|
{
|
|
|
|
|
if (modify_mem_list[i])
|
|
|
|
|
free_INSN_LIST_list (modify_mem_list + i);
|
|
|
|
|
if (canon_modify_mem_list[i])
|
|
|
|
|
free_INSN_LIST_list (canon_modify_mem_list + i);
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return non-zero if the operands of X are not set before INSN in
|
|
|
|
|
INSN's basic block. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
oprs_not_set_p (x, insn)
|
|
|
|
|
rtx x, insn;
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int i, j;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
enum rtx_code code;
|
rtl.h (rtx_format): Constify a char*.
* rtl.h (rtx_format): Constify a char*.
* rtl.c (rtx_format): Likewise.
(copy_rtx, copy_most_rtx, read_rtx): Likewise.
(init_rtl): Use accessor macro, not `rtx_format'.
* alias.c (rtx_equal_for_memref_p, find_symbolic_term): Constify a
char*.
* caller-save.c (mark_referenced_regs): Likewise.
* combine.c (subst, make_compound_operation, known_cond,
gen_rtx_combine, update_table_tick, get_last_value_validate,
use_crosses_set_p, mark_used_regs_combine, move_deaths): Likewise.
* cse.c (rtx_cost, mention_regs, canon_hash, exp_equiv_p,
refers_to_p, canon_reg, fold_rtx, cse_process_notes,
count_reg_usage): Likewise.
* emit-rtl.c (gen_rtx, copy_rtx_if_shared, reset_used_flags):
Likewise.
* final.c (leaf_renumber_regs_insn): Likewise.
* flow.c (mark_used_regs, find_use_as_address, dump_flow_info,
dump_edge_info, count_reg_references): Likewise.
* function.c (fixup_var_refs_1, walk_fixup_memory_subreg,
fixup_stack_1, purge_addressof_1, instantiate_virtual_regs_1):
Likewise.
* gcse.c (oprs_unchanged_p, hash_expr_1, expr_equiv_p,
oprs_not_set_p, expr_killed_p, compute_transp, find_used_regs,
add_label_notes): Likewise.
* genattrtab.c (attr_rtx, attr_copy_rtx, encode_units_mask,
clear_struct_flag, count_sub_rtxs, count_alternatives,
compares_alternatives_p, contained_in_p, walk_attr_value,
write_expr_attr_cache): Likewise.
* genconfig.c (walk_insn_part): Likewise.
* genemit.c (max_operand_1, gen_exp): Likewise.
* genextract.c (walk_rtx): Likewise.
* genflags.c (num_operands): Likewise.
* genoutput.c (scan_operands): Likewise.
* genpeep.c (match_rtx): Likewise.
* genrecog.c (add_to_sequence): Likewise.
* haifa-sched.c (may_trap_exp, sched_analyze_2, attach_deaths):
Likewise.
* integrate.c (save_constants, copy_for_inline,
copy_rtx_and_substitute, subst_constants, restore_constants):
Likewise.
* jump.c (mark_jump_label, invert_exp, redirect_exp,
rtx_renumbered_equal_p, rtx_equal_for_thread_p): Likewise.
* local-alloc.c (contains_replace_regs, memref_referenced_p):
Likewise.
* loop.c (record_excess_regs, rtx_equal_for_loop_p,
add_label_notes, replace_call_address, count_nonfixed_reads,
invariant_p, find_single_use_in_loop, find_mem_givs,
find_life_end, maybe_eliminate_biv_1, update_reg_last_use):
Likewise.
* print-rtl.c (reg_names, print_rtx): Likewise.
* recog.c (validate_replace_rtx_1, find_single_use_1): Likewise.
* reg-stack.c (stack_regs_mentioned_p, record_label_references,
record_reg_life_pat, swap_rtx_condition, goto_block_pat,
print_blocks): Likewise.
* regclass.c (fix_register, record_address_regs,
reg_scan_mark_refs): Likewise.
* regmove.c (stable_but_for_p): Likewise.
* reload.c (loc_mentioned_in_p, operands_match_p,
find_reloads_toplevsubst_reg_equivs, find_reloads_address_1,
copy_replacements, refers_to_regno_for_reload_p,
refers_to_mem_for_reload_p, find_inc_amount, regno_clobbered_p,
reload_when_needed_name, reg_class_names, debug_reload_to_stream):
Likewise.
* reload1.c (eliminate_regs, scan_paradoxical_subregs,
delete_address_reloads_1, count_occurrences,
reload_cse_mem_conflict_p, reload_combine_note_use,
add_auto_inc_notes): Likewise.
* resource.c (mark_referenced_resources, mark_set_resources):
Likewise.
* rtlanal.c (rtx_unstable_p, rtx_varies_p, rtx_addr_varies_p,
reg_mentioned_p, regs_set_between_p, modified_between_p,
modified_in_p, refers_to_regno_p, reg_overlap_mentioned_p,
rtx_equal_p, volatile_insn_p, volatile_refs_p, side_effects_p,
may_trap_p, inequality_comparisons_p, replace_rtx, replace_regs,
jmp_uses_reg_or_mem, for_each_rtx, regno_use_in): Likewise.
* sched.c (sched_analyze_2, attach_deaths): Likewise.
* stupid.c (stupid_mark_refs): Likewise.
* unroll.c (remap_split_bivs): Likewise.
* varasm.c (mark_constants): Likewise.
* a29k/a29k.c (uses_local_reg_p): Likewise.
* alpha/alpha.c (summarize_insn): Likewise.
* arm/arm.c (symbol_mentioned_p, label_mentioned_p,
eliminate_lr2ip): Likewise.
* arm/thumb.c (symbol_mentioned_p, label_mentioned_p): Likewise.
* i386/i386.c (symbolic_reference_mentioned_p, copy_all_rtx,
reg_mentioned_in_mem): Likewise.
* ns32k/ns32k.c (global_symbolic_reference_mentioned_p,
symbolic_reference_mentioned_p): Likewise.
* romp/romp.c (unsigned_comparisons_p, hash_rtx): Likewise.
* sh/sh.c (regs_used, mark_use): Likewise.
* vax/vax.c (vax_rtx_cost): Likewise.
From-SVN: r28784
1999-08-21 01:05:25 +02:00
|
|
|
|
const char *fmt;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (x == 0)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
code = GET_CODE (x);
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case PC:
|
|
|
|
|
case CC0:
|
|
|
|
|
case CONST:
|
|
|
|
|
case CONST_INT:
|
|
|
|
|
case CONST_DOUBLE:
|
|
|
|
|
case SYMBOL_REF:
|
|
|
|
|
case LABEL_REF:
|
|
|
|
|
case ADDR_VEC:
|
|
|
|
|
case ADDR_DIFF_VEC:
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
case MEM:
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (load_killed_in_block_p (BLOCK_FOR_INSN (insn),
|
|
|
|
|
INSN_CUID (insn), x, 0))
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
return 0;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (mem_last_set != 0)
|
|
|
|
|
return 0;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
else
|
|
|
|
|
return oprs_not_set_p (XEXP (x, 0), insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
case REG:
|
|
|
|
|
return ! TEST_BIT (reg_set_bitmap, REGNO (x));
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
{
|
|
|
|
|
/* If we are about to do the last recursive call
|
|
|
|
|
needed at this level, change it into iteration.
|
|
|
|
|
This function is called enough to be worth it. */
|
|
|
|
|
if (i == 0)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
return oprs_not_set_p (XEXP (x, i), insn);
|
|
|
|
|
|
|
|
|
|
if (! oprs_not_set_p (XEXP (x, i), insn))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if (fmt[i] == 'E')
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (j = 0; j < XVECLEN (x, i); j++)
|
|
|
|
|
if (! oprs_not_set_p (XVECEXP (x, i, j), insn))
|
|
|
|
|
return 0;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Mark things set by a CALL. */
|
|
|
|
|
|
|
|
|
|
static void
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
mark_call (insn)
|
|
|
|
|
rtx insn;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
mem_last_set = INSN_CUID (insn);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
if (! CONST_CALL_P (insn))
|
|
|
|
|
record_last_mem_set_info (insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Mark things set by a SET. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mark_set (pat, insn)
|
|
|
|
|
rtx pat, insn;
|
|
|
|
|
{
|
|
|
|
|
rtx dest = SET_DEST (pat);
|
|
|
|
|
|
|
|
|
|
while (GET_CODE (dest) == SUBREG
|
|
|
|
|
|| GET_CODE (dest) == ZERO_EXTRACT
|
|
|
|
|
|| GET_CODE (dest) == SIGN_EXTRACT
|
|
|
|
|
|| GET_CODE (dest) == STRICT_LOW_PART)
|
|
|
|
|
dest = XEXP (dest, 0);
|
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
if (GET_CODE (dest) == REG)
|
|
|
|
|
SET_BIT (reg_set_bitmap, REGNO (dest));
|
|
|
|
|
else if (GET_CODE (dest) == MEM)
|
|
|
|
|
record_last_mem_set_info (insn);
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (GET_CODE (dest) == REG)
|
|
|
|
|
SET_BIT (reg_set_bitmap, REGNO (dest));
|
|
|
|
|
else if (GET_CODE (dest) == MEM)
|
|
|
|
|
mem_last_set = INSN_CUID (insn);
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (SET_SRC (pat)) == CALL)
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
mark_call (insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Record things set by a CLOBBER. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mark_clobber (pat, insn)
|
|
|
|
|
rtx pat, insn;
|
|
|
|
|
{
|
|
|
|
|
rtx clob = XEXP (pat, 0);
|
|
|
|
|
|
|
|
|
|
while (GET_CODE (clob) == SUBREG || GET_CODE (clob) == STRICT_LOW_PART)
|
|
|
|
|
clob = XEXP (clob, 0);
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (clob) == REG)
|
|
|
|
|
SET_BIT (reg_set_bitmap, REGNO (clob));
|
|
|
|
|
else
|
|
|
|
|
mem_last_set = INSN_CUID (insn);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
if (GET_CODE (clob) == REG)
|
|
|
|
|
SET_BIT (reg_set_bitmap, REGNO (clob));
|
|
|
|
|
else
|
|
|
|
|
record_last_mem_set_info (insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Record things set by INSN.
|
|
|
|
|
This data is used by oprs_not_set_p. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mark_oprs_set (insn)
|
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
|
|
|
|
rtx pat = PATTERN (insn);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int i;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (GET_CODE (pat) == SET)
|
|
|
|
|
mark_set (pat, insn);
|
|
|
|
|
else if (GET_CODE (pat) == PARALLEL)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = 0; i < XVECLEN (pat, 0); i++)
|
|
|
|
|
{
|
|
|
|
|
rtx x = XVECEXP (pat, 0, i);
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (x) == SET)
|
|
|
|
|
mark_set (x, insn);
|
|
|
|
|
else if (GET_CODE (x) == CLOBBER)
|
|
|
|
|
mark_clobber (x, insn);
|
|
|
|
|
else if (GET_CODE (x) == CALL)
|
|
|
|
|
mark_call (insn);
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
else if (GET_CODE (pat) == CLOBBER)
|
|
|
|
|
mark_clobber (pat, insn);
|
|
|
|
|
else if (GET_CODE (pat) == CALL)
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
mark_call (insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Classic GCSE reaching definition support. */
|
|
|
|
|
|
|
|
|
|
/* Allocate reaching def variables. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
alloc_rd_mem (n_blocks, n_insns)
|
|
|
|
|
int n_blocks, n_insns;
|
|
|
|
|
{
|
|
|
|
|
rd_kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
|
|
|
|
|
sbitmap_vector_zero (rd_kill, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
rd_gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
|
|
|
|
|
sbitmap_vector_zero (rd_gen, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
reaching_defs = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
|
|
|
|
|
sbitmap_vector_zero (reaching_defs, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
rd_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
|
|
|
|
|
sbitmap_vector_zero (rd_out, n_basic_blocks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free reaching def variables. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_rd_mem ()
|
|
|
|
|
{
|
|
|
|
|
free (rd_kill);
|
|
|
|
|
free (rd_gen);
|
|
|
|
|
free (reaching_defs);
|
|
|
|
|
free (rd_out);
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Add INSN to the kills of BB. REGNO, set in BB, is killed by INSN. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
handle_rd_kill_set (insn, regno, bb)
|
|
|
|
|
rtx insn;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
int regno;
|
|
|
|
|
basic_block bb;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct reg_set *this_reg;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (this_reg = reg_set_table[regno]; this_reg; this_reg = this_reg ->next)
|
|
|
|
|
if (BLOCK_NUM (this_reg->insn) != BLOCK_NUM (insn))
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
SET_BIT (rd_kill[bb->index], INSN_CUID (this_reg->insn));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute the set of kill's for reaching definitions. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_kill_rd ()
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int bb, cuid;
|
2001-02-16 20:29:49 +01:00
|
|
|
|
unsigned int regno;
|
|
|
|
|
int i;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* For each block
|
|
|
|
|
For each set bit in `gen' of the block (i.e each insn which
|
1999-03-10 21:18:59 +01:00
|
|
|
|
generates a definition in the block)
|
|
|
|
|
Call the reg set by the insn corresponding to that bit regx
|
|
|
|
|
Look at the linked list starting at reg_set_table[regx]
|
|
|
|
|
For each setting of regx in the linked list, which is not in
|
|
|
|
|
this block
|
2000-02-29 21:08:52 +01:00
|
|
|
|
Set the bit in `kill' corresponding to that insn. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (cuid = 0; cuid < max_cuid; cuid++)
|
|
|
|
|
if (TEST_BIT (rd_gen[bb], cuid))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
rtx insn = CUID_INSN (cuid);
|
|
|
|
|
rtx pat = PATTERN (insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (GET_CODE (insn) == CALL_INSN)
|
|
|
|
|
{
|
|
|
|
|
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
1999-03-10 21:18:59 +01:00
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if ((call_used_regs[regno]
|
|
|
|
|
&& regno != STACK_POINTER_REGNUM
|
1998-10-20 01:17:48 +02:00
|
|
|
|
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
2000-02-29 21:08:52 +01:00
|
|
|
|
&& regno != HARD_FRAME_POINTER_REGNUM
|
1998-10-20 01:17:48 +02:00
|
|
|
|
#endif
|
|
|
|
|
#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
2000-02-29 21:08:52 +01:00
|
|
|
|
&& ! (regno == ARG_POINTER_REGNUM
|
|
|
|
|
&& fixed_regs[regno])
|
1998-10-20 01:17:48 +02:00
|
|
|
|
#endif
|
2001-02-13 21:17:45 +01:00
|
|
|
|
#if !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
&& ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic)
|
1998-10-20 01:17:48 +02:00
|
|
|
|
#endif
|
2000-02-29 21:08:52 +01:00
|
|
|
|
&& regno != FRAME_POINTER_REGNUM)
|
|
|
|
|
|| global_regs[regno])
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
handle_rd_kill_set (insn, regno, BASIC_BLOCK (bb));
|
1999-03-10 21:18:59 +01:00
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (GET_CODE (pat) == PARALLEL)
|
|
|
|
|
{
|
|
|
|
|
for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
enum rtx_code code = GET_CODE (XVECEXP (pat, 0, i));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if ((code == SET || code == CLOBBER)
|
|
|
|
|
&& GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == REG)
|
|
|
|
|
handle_rd_kill_set (insn,
|
|
|
|
|
REGNO (XEXP (XVECEXP (pat, 0, i), 0)),
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
BASIC_BLOCK (bb));
|
1999-03-10 21:18:59 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
else if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == REG)
|
|
|
|
|
/* Each setting of this register outside of this block
|
|
|
|
|
must be marked in the set of kills in this block. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
handle_rd_kill_set (insn, REGNO (SET_DEST (pat)), BASIC_BLOCK (bb));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute the reaching definitions as in
|
|
|
|
|
Compilers Principles, Techniques, and Tools. Aho, Sethi, Ullman,
|
|
|
|
|
Chapter 10. It is the same algorithm as used for computing available
|
|
|
|
|
expressions but applied to the gens and kills of reaching definitions. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_rd ()
|
|
|
|
|
{
|
|
|
|
|
int bb, changed, passes;
|
|
|
|
|
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
sbitmap_copy (rd_out[bb] /*dst*/, rd_gen[bb] /*src*/);
|
|
|
|
|
|
|
|
|
|
passes = 0;
|
|
|
|
|
changed = 1;
|
|
|
|
|
while (changed)
|
|
|
|
|
{
|
|
|
|
|
changed = 0;
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
1999-03-10 21:18:59 +01:00
|
|
|
|
{
|
1999-08-25 20:01:48 +02:00
|
|
|
|
sbitmap_union_of_preds (reaching_defs[bb], rd_out, bb);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
changed |= sbitmap_union_of_diff (rd_out[bb], rd_gen[bb],
|
|
|
|
|
reaching_defs[bb], rd_kill[bb]);
|
1999-03-10 21:18:59 +01:00
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
passes++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
fprintf (gcse_file, "reaching def computation: %d passes\n", passes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Classic GCSE available expression support. */
|
|
|
|
|
|
|
|
|
|
/* Allocate memory for available expression computation. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
alloc_avail_expr_mem (n_blocks, n_exprs)
|
|
|
|
|
int n_blocks, n_exprs;
|
|
|
|
|
{
|
|
|
|
|
ae_kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
sbitmap_vector_zero (ae_kill, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
ae_gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
sbitmap_vector_zero (ae_gen, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
ae_in = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
sbitmap_vector_zero (ae_in, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
ae_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
sbitmap_vector_zero (ae_out, n_basic_blocks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_avail_expr_mem ()
|
|
|
|
|
{
|
|
|
|
|
free (ae_kill);
|
|
|
|
|
free (ae_gen);
|
|
|
|
|
free (ae_in);
|
|
|
|
|
free (ae_out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute the set of available expressions generated in each basic block. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_ae_gen ()
|
|
|
|
|
{
|
2000-04-10 13:33:18 +02:00
|
|
|
|
unsigned int i;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct expr *expr;
|
|
|
|
|
struct occr *occr;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* For each recorded occurrence of each expression, set ae_gen[bb][expr].
|
|
|
|
|
This is all we have to do because an expression is not recorded if it
|
|
|
|
|
is not available, and the only expressions we want to work with are the
|
|
|
|
|
ones that are recorded. */
|
|
|
|
|
for (i = 0; i < expr_hash_table_size; i++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (expr = expr_hash_table[i]; expr != 0; expr = expr->next_same_hash)
|
|
|
|
|
for (occr = expr->avail_occr; occr != 0; occr = occr->next)
|
|
|
|
|
SET_BIT (ae_gen[BLOCK_NUM (occr->insn)], expr->bitmap_index);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return non-zero if expression X is killed in BB. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
expr_killed_p (x, bb)
|
|
|
|
|
rtx x;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int i, j;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
enum rtx_code code;
|
rtl.h (rtx_format): Constify a char*.
* rtl.h (rtx_format): Constify a char*.
* rtl.c (rtx_format): Likewise.
(copy_rtx, copy_most_rtx, read_rtx): Likewise.
(init_rtl): Use accessor macro, not `rtx_format'.
* alias.c (rtx_equal_for_memref_p, find_symbolic_term): Constify a
char*.
* caller-save.c (mark_referenced_regs): Likewise.
* combine.c (subst, make_compound_operation, known_cond,
gen_rtx_combine, update_table_tick, get_last_value_validate,
use_crosses_set_p, mark_used_regs_combine, move_deaths): Likewise.
* cse.c (rtx_cost, mention_regs, canon_hash, exp_equiv_p,
refers_to_p, canon_reg, fold_rtx, cse_process_notes,
count_reg_usage): Likewise.
* emit-rtl.c (gen_rtx, copy_rtx_if_shared, reset_used_flags):
Likewise.
* final.c (leaf_renumber_regs_insn): Likewise.
* flow.c (mark_used_regs, find_use_as_address, dump_flow_info,
dump_edge_info, count_reg_references): Likewise.
* function.c (fixup_var_refs_1, walk_fixup_memory_subreg,
fixup_stack_1, purge_addressof_1, instantiate_virtual_regs_1):
Likewise.
* gcse.c (oprs_unchanged_p, hash_expr_1, expr_equiv_p,
oprs_not_set_p, expr_killed_p, compute_transp, find_used_regs,
add_label_notes): Likewise.
* genattrtab.c (attr_rtx, attr_copy_rtx, encode_units_mask,
clear_struct_flag, count_sub_rtxs, count_alternatives,
compares_alternatives_p, contained_in_p, walk_attr_value,
write_expr_attr_cache): Likewise.
* genconfig.c (walk_insn_part): Likewise.
* genemit.c (max_operand_1, gen_exp): Likewise.
* genextract.c (walk_rtx): Likewise.
* genflags.c (num_operands): Likewise.
* genoutput.c (scan_operands): Likewise.
* genpeep.c (match_rtx): Likewise.
* genrecog.c (add_to_sequence): Likewise.
* haifa-sched.c (may_trap_exp, sched_analyze_2, attach_deaths):
Likewise.
* integrate.c (save_constants, copy_for_inline,
copy_rtx_and_substitute, subst_constants, restore_constants):
Likewise.
* jump.c (mark_jump_label, invert_exp, redirect_exp,
rtx_renumbered_equal_p, rtx_equal_for_thread_p): Likewise.
* local-alloc.c (contains_replace_regs, memref_referenced_p):
Likewise.
* loop.c (record_excess_regs, rtx_equal_for_loop_p,
add_label_notes, replace_call_address, count_nonfixed_reads,
invariant_p, find_single_use_in_loop, find_mem_givs,
find_life_end, maybe_eliminate_biv_1, update_reg_last_use):
Likewise.
* print-rtl.c (reg_names, print_rtx): Likewise.
* recog.c (validate_replace_rtx_1, find_single_use_1): Likewise.
* reg-stack.c (stack_regs_mentioned_p, record_label_references,
record_reg_life_pat, swap_rtx_condition, goto_block_pat,
print_blocks): Likewise.
* regclass.c (fix_register, record_address_regs,
reg_scan_mark_refs): Likewise.
* regmove.c (stable_but_for_p): Likewise.
* reload.c (loc_mentioned_in_p, operands_match_p,
find_reloads_toplevsubst_reg_equivs, find_reloads_address_1,
copy_replacements, refers_to_regno_for_reload_p,
refers_to_mem_for_reload_p, find_inc_amount, regno_clobbered_p,
reload_when_needed_name, reg_class_names, debug_reload_to_stream):
Likewise.
* reload1.c (eliminate_regs, scan_paradoxical_subregs,
delete_address_reloads_1, count_occurrences,
reload_cse_mem_conflict_p, reload_combine_note_use,
add_auto_inc_notes): Likewise.
* resource.c (mark_referenced_resources, mark_set_resources):
Likewise.
* rtlanal.c (rtx_unstable_p, rtx_varies_p, rtx_addr_varies_p,
reg_mentioned_p, regs_set_between_p, modified_between_p,
modified_in_p, refers_to_regno_p, reg_overlap_mentioned_p,
rtx_equal_p, volatile_insn_p, volatile_refs_p, side_effects_p,
may_trap_p, inequality_comparisons_p, replace_rtx, replace_regs,
jmp_uses_reg_or_mem, for_each_rtx, regno_use_in): Likewise.
* sched.c (sched_analyze_2, attach_deaths): Likewise.
* stupid.c (stupid_mark_refs): Likewise.
* unroll.c (remap_split_bivs): Likewise.
* varasm.c (mark_constants): Likewise.
* a29k/a29k.c (uses_local_reg_p): Likewise.
* alpha/alpha.c (summarize_insn): Likewise.
* arm/arm.c (symbol_mentioned_p, label_mentioned_p,
eliminate_lr2ip): Likewise.
* arm/thumb.c (symbol_mentioned_p, label_mentioned_p): Likewise.
* i386/i386.c (symbolic_reference_mentioned_p, copy_all_rtx,
reg_mentioned_in_mem): Likewise.
* ns32k/ns32k.c (global_symbolic_reference_mentioned_p,
symbolic_reference_mentioned_p): Likewise.
* romp/romp.c (unsigned_comparisons_p, hash_rtx): Likewise.
* sh/sh.c (regs_used, mark_use): Likewise.
* vax/vax.c (vax_rtx_cost): Likewise.
From-SVN: r28784
1999-08-21 01:05:25 +02:00
|
|
|
|
const char *fmt;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (x == 0)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
code = GET_CODE (x);
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case REG:
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
return TEST_BIT (reg_set_in_block[bb->index], REGNO (x));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
case MEM:
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
if (load_killed_in_block_p (bb, get_max_uid () + 1, x, 0))
|
|
|
|
|
return 1;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (mem_set_in_block[bb->index])
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
else
|
|
|
|
|
return expr_killed_p (XEXP (x, 0), bb);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
case PC:
|
|
|
|
|
case CC0: /*FIXME*/
|
|
|
|
|
case CONST:
|
|
|
|
|
case CONST_INT:
|
|
|
|
|
case CONST_DOUBLE:
|
|
|
|
|
case SYMBOL_REF:
|
|
|
|
|
case LABEL_REF:
|
|
|
|
|
case ADDR_VEC:
|
|
|
|
|
case ADDR_DIFF_VEC:
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
{
|
|
|
|
|
/* If we are about to do the last recursive call
|
|
|
|
|
needed at this level, change it into iteration.
|
|
|
|
|
This function is called enough to be worth it. */
|
|
|
|
|
if (i == 0)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
return expr_killed_p (XEXP (x, i), bb);
|
|
|
|
|
else if (expr_killed_p (XEXP (x, i), bb))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else if (fmt[i] == 'E')
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (j = 0; j < XVECLEN (x, i); j++)
|
|
|
|
|
if (expr_killed_p (XVECEXP (x, i, j), bb))
|
|
|
|
|
return 1;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute the set of available expressions killed in each basic block. */
|
|
|
|
|
|
|
|
|
|
static void
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
compute_ae_kill (ae_gen, ae_kill)
|
|
|
|
|
sbitmap *ae_gen, *ae_kill;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
2000-04-10 13:33:18 +02:00
|
|
|
|
int bb;
|
|
|
|
|
unsigned int i;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct expr *expr;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = 0; i < expr_hash_table_size; i++)
|
|
|
|
|
for (expr = expr_hash_table[i]; expr; expr = expr->next_same_hash)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Skip EXPR if generated in this block. */
|
|
|
|
|
if (TEST_BIT (ae_gen[bb], expr->bitmap_index))
|
|
|
|
|
continue;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (expr_killed_p (expr->expr, BASIC_BLOCK (bb)))
|
2000-02-29 21:08:52 +01:00
|
|
|
|
SET_BIT (ae_kill[bb], expr->bitmap_index);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Actually perform the Classic GCSE optimizations. */
|
|
|
|
|
|
|
|
|
|
/* Return non-zero if occurrence OCCR of expression EXPR reaches block BB.
|
|
|
|
|
|
|
|
|
|
CHECK_SELF_LOOP is non-zero if we should consider a block reaching itself
|
|
|
|
|
as a positive reach. We want to do this when there are two computations
|
|
|
|
|
of the expression in the block.
|
|
|
|
|
|
|
|
|
|
VISITED is a pointer to a working buffer for tracking which BB's have
|
|
|
|
|
been visited. It is NULL for the top-level call.
|
|
|
|
|
|
|
|
|
|
We treat reaching expressions that go through blocks containing the same
|
|
|
|
|
reaching expression as "not reaching". E.g. if EXPR is generated in blocks
|
|
|
|
|
2 and 3, INSN is in block 4, and 2->3->4, we treat the expression in block
|
|
|
|
|
2 as not reaching. The intent is to improve the probability of finding
|
|
|
|
|
only one reaching expression and to reduce register lifetimes by picking
|
|
|
|
|
the closest such expression. */
|
|
|
|
|
|
|
|
|
|
static int
|
1999-10-27 07:16:12 +02:00
|
|
|
|
expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
struct occr *occr;
|
|
|
|
|
struct expr *expr;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
int check_self_loop;
|
|
|
|
|
char *visited;
|
|
|
|
|
{
|
1999-08-25 20:01:48 +02:00
|
|
|
|
edge pred;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block pred_bb = pred->src;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (visited[pred_bb->index])
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* This predecessor has already been visited. Nothing to do. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
;
|
|
|
|
|
else if (pred_bb == bb)
|
1999-03-10 21:18:59 +01:00
|
|
|
|
{
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* BB loops on itself. */
|
|
|
|
|
if (check_self_loop
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
&& TEST_BIT (ae_gen[pred_bb->index], expr->bitmap_index)
|
|
|
|
|
&& BLOCK_NUM (occr->insn) == pred_bb->index)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
visited[pred_bb->index] = 1;
|
1999-03-10 21:18:59 +01:00
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Ignore this predecessor if it kills the expression. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
else if (TEST_BIT (ae_kill[pred_bb->index], expr->bitmap_index))
|
|
|
|
|
visited[pred_bb->index] = 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Does this predecessor generate this expression? */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
else if (TEST_BIT (ae_gen[pred_bb->index], expr->bitmap_index))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* Is this the occurrence we're looking for?
|
|
|
|
|
Note that there's only one generating occurrence per block
|
|
|
|
|
so we just need to check the block number. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (BLOCK_NUM (occr->insn) == pred_bb->index)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
visited[pred_bb->index] = 1;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Neither gen nor kill. */
|
|
|
|
|
else
|
1999-03-10 21:18:59 +01:00
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
visited[pred_bb->index] = 1;
|
1999-10-27 07:16:12 +02:00
|
|
|
|
if (expr_reaches_here_p_work (occr, expr, pred_bb, check_self_loop,
|
|
|
|
|
visited))
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 1;
|
1999-03-10 21:18:59 +01:00
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* All paths have been checked. */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1999-10-27 07:16:12 +02:00
|
|
|
|
/* This wrapper for expr_reaches_here_p_work() is to ensure that any
|
|
|
|
|
memory allocated for that function is returned. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
expr_reaches_here_p (occr, expr, bb, check_self_loop)
|
|
|
|
|
struct occr *occr;
|
|
|
|
|
struct expr *expr;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
1999-10-27 07:16:12 +02:00
|
|
|
|
int check_self_loop;
|
|
|
|
|
{
|
|
|
|
|
int rval;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
char *visited = (char *) xcalloc (n_basic_blocks, 1);
|
1999-10-27 07:16:12 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
rval = expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited);
|
1999-10-27 07:16:12 +02:00
|
|
|
|
|
|
|
|
|
free (visited);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
return rval;
|
1999-10-27 07:16:12 +02:00
|
|
|
|
}
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Return the instruction that computes EXPR that reaches INSN's basic block.
|
|
|
|
|
If there is more than one such instruction, return NULL.
|
|
|
|
|
|
|
|
|
|
Called only by handle_avail_expr. */
|
|
|
|
|
|
|
|
|
|
static rtx
|
|
|
|
|
computing_insn (expr, insn)
|
|
|
|
|
struct expr *expr;
|
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb = BLOCK_FOR_INSN (insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (expr->avail_occr->next == NULL)
|
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (BLOCK_FOR_INSN (expr->avail_occr->insn) == bb)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* The available expression is actually itself
|
|
|
|
|
(i.e. a loop in the flow graph) so do nothing. */
|
|
|
|
|
return NULL;
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* (FIXME) Case that we found a pattern that was created by
|
|
|
|
|
a substitution that took place. */
|
|
|
|
|
return expr->avail_occr->insn;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Pattern is computed more than once.
|
|
|
|
|
Search backwards from this insn to see how many of these
|
|
|
|
|
computations actually reach this insn. */
|
|
|
|
|
struct occr *occr;
|
|
|
|
|
rtx insn_computes_expr = NULL;
|
|
|
|
|
int can_reach = 0;
|
|
|
|
|
|
|
|
|
|
for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
|
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (BLOCK_FOR_INSN (occr->insn) == bb)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* The expression is generated in this block.
|
|
|
|
|
The only time we care about this is when the expression
|
|
|
|
|
is generated later in the block [and thus there's a loop].
|
|
|
|
|
We let the normal cse pass handle the other cases. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (INSN_CUID (insn) < INSN_CUID (occr->insn)
|
|
|
|
|
&& expr_reaches_here_p (occr, expr, bb, 1))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
can_reach++;
|
|
|
|
|
if (can_reach > 1)
|
|
|
|
|
return NULL;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
insn_computes_expr = occr->insn;
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
else if (expr_reaches_here_p (occr, expr, bb, 0))
|
|
|
|
|
{
|
|
|
|
|
can_reach++;
|
|
|
|
|
if (can_reach > 1)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
insn_computes_expr = occr->insn;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (insn_computes_expr == NULL)
|
|
|
|
|
abort ();
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return insn_computes_expr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return non-zero if the definition in DEF_INSN can reach INSN.
|
|
|
|
|
Only called by can_disregard_other_sets. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
def_reaches_here_p (insn, def_insn)
|
|
|
|
|
rtx insn, def_insn;
|
|
|
|
|
{
|
|
|
|
|
rtx reg;
|
|
|
|
|
|
|
|
|
|
if (TEST_BIT (reaching_defs[BLOCK_NUM (insn)], INSN_CUID (def_insn)))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
if (BLOCK_NUM (insn) == BLOCK_NUM (def_insn))
|
|
|
|
|
{
|
|
|
|
|
if (INSN_CUID (def_insn) < INSN_CUID (insn))
|
1999-03-10 21:18:59 +01:00
|
|
|
|
{
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (GET_CODE (PATTERN (def_insn)) == PARALLEL)
|
|
|
|
|
return 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
else if (GET_CODE (PATTERN (def_insn)) == CLOBBER)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
reg = XEXP (PATTERN (def_insn), 0);
|
|
|
|
|
else if (GET_CODE (PATTERN (def_insn)) == SET)
|
|
|
|
|
reg = SET_DEST (PATTERN (def_insn));
|
|
|
|
|
else
|
|
|
|
|
abort ();
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return ! reg_set_between_p (reg, NEXT_INSN (def_insn), insn);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Return non-zero if *ADDR_THIS_REG can only have one value at INSN. The
|
|
|
|
|
value returned is the number of definitions that reach INSN. Returning a
|
|
|
|
|
value of zero means that [maybe] more than one definition reaches INSN and
|
|
|
|
|
the caller can't perform whatever optimization it is trying. i.e. it is
|
|
|
|
|
always safe to return zero. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
can_disregard_other_sets (addr_this_reg, insn, for_combine)
|
|
|
|
|
struct reg_set **addr_this_reg;
|
|
|
|
|
rtx insn;
|
|
|
|
|
int for_combine;
|
|
|
|
|
{
|
|
|
|
|
int number_of_reaching_defs = 0;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct reg_set *this_reg;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (this_reg = *addr_this_reg; this_reg != 0; this_reg = this_reg->next)
|
|
|
|
|
if (def_reaches_here_p (insn, this_reg->insn))
|
|
|
|
|
{
|
|
|
|
|
number_of_reaching_defs++;
|
|
|
|
|
/* Ignore parallels for now. */
|
|
|
|
|
if (GET_CODE (PATTERN (this_reg->insn)) == PARALLEL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (!for_combine
|
|
|
|
|
&& (GET_CODE (PATTERN (this_reg->insn)) == CLOBBER
|
|
|
|
|
|| ! rtx_equal_p (SET_SRC (PATTERN (this_reg->insn)),
|
|
|
|
|
SET_SRC (PATTERN (insn)))))
|
|
|
|
|
/* A setting of the reg to a different value reaches INSN. */
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (number_of_reaching_defs > 1)
|
|
|
|
|
{
|
|
|
|
|
/* If in this setting the value the register is being set to is
|
|
|
|
|
equal to the previous value the register was set to and this
|
|
|
|
|
setting reaches the insn we are trying to do the substitution
|
|
|
|
|
on then we are ok. */
|
|
|
|
|
if (GET_CODE (PATTERN (this_reg->insn)) == CLOBBER)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 0;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
else if (! rtx_equal_p (SET_SRC (PATTERN (this_reg->insn)),
|
|
|
|
|
SET_SRC (PATTERN (insn))))
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
*addr_this_reg = this_reg;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
return number_of_reaching_defs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Expression computed by insn is available and the substitution is legal,
|
|
|
|
|
so try to perform the substitution.
|
|
|
|
|
|
|
|
|
|
The result is non-zero if any changes were made. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
handle_avail_expr (insn, expr)
|
|
|
|
|
rtx insn;
|
|
|
|
|
struct expr *expr;
|
|
|
|
|
{
|
|
|
|
|
rtx pat, insn_computes_expr;
|
|
|
|
|
rtx to;
|
|
|
|
|
struct reg_set *this_reg;
|
|
|
|
|
int found_setting, use_src;
|
|
|
|
|
int changed = 0;
|
|
|
|
|
|
|
|
|
|
/* We only handle the case where one computation of the expression
|
|
|
|
|
reaches this instruction. */
|
|
|
|
|
insn_computes_expr = computing_insn (expr, insn);
|
|
|
|
|
if (insn_computes_expr == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
found_setting = 0;
|
|
|
|
|
use_src = 0;
|
|
|
|
|
|
|
|
|
|
/* At this point we know only one computation of EXPR outside of this
|
|
|
|
|
block reaches this insn. Now try to find a register that the
|
|
|
|
|
expression is computed into. */
|
|
|
|
|
if (GET_CODE (SET_SRC (PATTERN (insn_computes_expr))) == REG)
|
|
|
|
|
{
|
|
|
|
|
/* This is the case when the available expression that reaches
|
|
|
|
|
here has already been handled as an available expression. */
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int regnum_for_replacing
|
2000-02-29 21:08:52 +01:00
|
|
|
|
= REGNO (SET_SRC (PATTERN (insn_computes_expr)));
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* If the register was created by GCSE we can't use `reg_set_table',
|
|
|
|
|
however we know it's set only once. */
|
|
|
|
|
if (regnum_for_replacing >= max_gcse_regno
|
|
|
|
|
/* If the register the expression is computed into is set only once,
|
|
|
|
|
or only one set reaches this insn, we can use it. */
|
|
|
|
|
|| (((this_reg = reg_set_table[regnum_for_replacing]),
|
|
|
|
|
this_reg->next == NULL)
|
|
|
|
|
|| can_disregard_other_sets (&this_reg, insn, 0)))
|
|
|
|
|
{
|
|
|
|
|
use_src = 1;
|
|
|
|
|
found_setting = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!found_setting)
|
|
|
|
|
{
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int regnum_for_replacing
|
2000-02-29 21:08:52 +01:00
|
|
|
|
= REGNO (SET_DEST (PATTERN (insn_computes_expr)));
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* This shouldn't happen. */
|
|
|
|
|
if (regnum_for_replacing >= max_gcse_regno)
|
|
|
|
|
abort ();
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
this_reg = reg_set_table[regnum_for_replacing];
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* If the register the expression is computed into is set only once,
|
|
|
|
|
or only one set reaches this insn, use it. */
|
|
|
|
|
if (this_reg->next == NULL
|
|
|
|
|
|| can_disregard_other_sets (&this_reg, insn, 0))
|
|
|
|
|
found_setting = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (found_setting)
|
|
|
|
|
{
|
|
|
|
|
pat = PATTERN (insn);
|
|
|
|
|
if (use_src)
|
|
|
|
|
to = SET_SRC (PATTERN (insn_computes_expr));
|
|
|
|
|
else
|
|
|
|
|
to = SET_DEST (PATTERN (insn_computes_expr));
|
|
|
|
|
changed = validate_change (insn, &SET_SRC (pat), to, 0);
|
|
|
|
|
|
|
|
|
|
/* We should be able to ignore the return code from validate_change but
|
|
|
|
|
to play it safe we check. */
|
|
|
|
|
if (changed)
|
|
|
|
|
{
|
|
|
|
|
gcse_subst_count++;
|
|
|
|
|
if (gcse_file != NULL)
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, "GCSE: Replacing the source in insn %d with",
|
|
|
|
|
INSN_UID (insn));
|
|
|
|
|
fprintf (gcse_file, " reg %d %s insn %d\n",
|
|
|
|
|
REGNO (to), use_src ? "from" : "set in",
|
1998-05-20 02:24:32 +02:00
|
|
|
|
INSN_UID (insn_computes_expr));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* The register that the expr is computed into is set more than once. */
|
|
|
|
|
else if (1 /*expensive_op(this_pattrn->op) && do_expensive_gcse)*/)
|
|
|
|
|
{
|
|
|
|
|
/* Insert an insn after insnx that copies the reg set in insnx
|
|
|
|
|
into a new pseudo register call this new register REGN.
|
|
|
|
|
From insnb until end of basic block or until REGB is set
|
|
|
|
|
replace all uses of REGB with REGN. */
|
|
|
|
|
rtx new_insn;
|
|
|
|
|
|
|
|
|
|
to = gen_reg_rtx (GET_MODE (SET_DEST (PATTERN (insn_computes_expr))));
|
|
|
|
|
|
|
|
|
|
/* Generate the new insn. */
|
|
|
|
|
/* ??? If the change fails, we return 0, even though we created
|
|
|
|
|
an insn. I think this is ok. */
|
1998-06-24 16:49:51 +02:00
|
|
|
|
new_insn
|
|
|
|
|
= emit_insn_after (gen_rtx_SET (VOIDmode, to,
|
2000-02-29 21:08:52 +01:00
|
|
|
|
SET_DEST (PATTERN
|
|
|
|
|
(insn_computes_expr))),
|
|
|
|
|
insn_computes_expr);
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Keep block number table up to date. */
|
2001-04-09 17:17:08 +02:00
|
|
|
|
set_block_for_new_insns (new_insn, BLOCK_FOR_INSN (insn_computes_expr));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Keep register set table up to date. */
|
|
|
|
|
record_one_set (REGNO (to), new_insn);
|
|
|
|
|
|
|
|
|
|
gcse_create_count++;
|
|
|
|
|
if (gcse_file != NULL)
|
1999-03-10 21:18:59 +01:00
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, "GCSE: Creating insn %d to copy value of reg %d",
|
1998-05-20 02:24:32 +02:00
|
|
|
|
INSN_UID (NEXT_INSN (insn_computes_expr)),
|
2000-02-29 21:08:52 +01:00
|
|
|
|
REGNO (SET_SRC (PATTERN (NEXT_INSN (insn_computes_expr)))));
|
|
|
|
|
fprintf (gcse_file, ", computed in insn %d,\n",
|
1998-05-20 02:24:32 +02:00
|
|
|
|
INSN_UID (insn_computes_expr));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, " into newly allocated reg %d\n",
|
|
|
|
|
REGNO (to));
|
1999-03-10 21:18:59 +01:00
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
pat = PATTERN (insn);
|
|
|
|
|
|
|
|
|
|
/* Do register replacement for INSN. */
|
|
|
|
|
changed = validate_change (insn, &SET_SRC (pat),
|
2000-02-29 21:08:52 +01:00
|
|
|
|
SET_DEST (PATTERN
|
|
|
|
|
(NEXT_INSN (insn_computes_expr))),
|
1998-05-20 02:24:32 +02:00
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
/* We should be able to ignore the return code from validate_change but
|
|
|
|
|
to play it safe we check. */
|
|
|
|
|
if (changed)
|
|
|
|
|
{
|
|
|
|
|
gcse_subst_count++;
|
|
|
|
|
if (gcse_file != NULL)
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file,
|
|
|
|
|
"GCSE: Replacing the source in insn %d with reg %d ",
|
1998-05-20 02:24:32 +02:00
|
|
|
|
INSN_UID (insn),
|
2000-02-29 21:08:52 +01:00
|
|
|
|
REGNO (SET_DEST (PATTERN (NEXT_INSN
|
|
|
|
|
(insn_computes_expr)))));
|
|
|
|
|
fprintf (gcse_file, "set in insn %d\n",
|
1998-05-20 02:24:32 +02:00
|
|
|
|
INSN_UID (insn_computes_expr));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Perform classic GCSE. This is called by one_classic_gcse_pass after all
|
|
|
|
|
the dataflow analysis has been done.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
The result is non-zero if a change was made. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
classic_gcse ()
|
|
|
|
|
{
|
|
|
|
|
int bb, changed;
|
|
|
|
|
rtx insn;
|
|
|
|
|
|
|
|
|
|
/* Note we start at block 1. */
|
|
|
|
|
|
|
|
|
|
changed = 0;
|
|
|
|
|
for (bb = 1; bb < n_basic_blocks; bb++)
|
|
|
|
|
{
|
|
|
|
|
/* Reset tables used to keep track of what's still valid [since the
|
|
|
|
|
start of the block]. */
|
|
|
|
|
reset_opr_set_tables ();
|
|
|
|
|
|
basic-block.h (basic_block_head): Rename to x_basic_block_head.
* basic-block.h (basic_block_head): Rename to x_basic_block_head.
(basic_block_end): Rename to x_basic_block_end.
(BLOCK_HEAD, BLOCK_END): Update.
* caller-save.c: Change basic_block_head/end references to
BLOCK_HEAD/END.
* combine.c, flow.c, function.c, gcse.c, global.c: Likewise.
* graph.c, haifa-sched.c, local-alloc.c, regclass.c: Likewise.
* regmove.c, reload1.c, reorg.c, sched.c: Likewise.
From-SVN: r24622
1999-01-11 23:37:20 +01:00
|
|
|
|
for (insn = BLOCK_HEAD (bb);
|
|
|
|
|
insn != NULL && insn != NEXT_INSN (BLOCK_END (bb));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
insn = NEXT_INSN (insn))
|
|
|
|
|
{
|
|
|
|
|
/* Is insn of form (set (pseudo-reg) ...)? */
|
|
|
|
|
if (GET_CODE (insn) == INSN
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == SET
|
|
|
|
|
&& GET_CODE (SET_DEST (PATTERN (insn))) == REG
|
|
|
|
|
&& REGNO (SET_DEST (PATTERN (insn))) >= FIRST_PSEUDO_REGISTER)
|
|
|
|
|
{
|
|
|
|
|
rtx pat = PATTERN (insn);
|
|
|
|
|
rtx src = SET_SRC (pat);
|
|
|
|
|
struct expr *expr;
|
|
|
|
|
|
|
|
|
|
if (want_to_gcse_p (src)
|
|
|
|
|
/* Is the expression recorded? */
|
|
|
|
|
&& ((expr = lookup_expr (src)) != NULL)
|
|
|
|
|
/* Is the expression available [at the start of the
|
|
|
|
|
block]? */
|
|
|
|
|
&& TEST_BIT (ae_in[bb], expr->bitmap_index)
|
|
|
|
|
/* Are the operands unchanged since the start of the
|
|
|
|
|
block? */
|
|
|
|
|
&& oprs_not_set_p (src, insn))
|
|
|
|
|
changed |= handle_avail_expr (insn, expr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Keep track of everything modified by this insn. */
|
|
|
|
|
/* ??? Need to be careful w.r.t. mods done to INSN. */
|
2000-08-04 22:28:08 +02:00
|
|
|
|
if (INSN_P (insn))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
mark_oprs_set (insn);
|
1999-03-10 21:18:59 +01:00
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Top level routine to perform one classic GCSE pass.
|
|
|
|
|
|
|
|
|
|
Return non-zero if a change was made. */
|
|
|
|
|
|
|
|
|
|
static int
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
one_classic_gcse_pass (pass)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
int pass;
|
|
|
|
|
{
|
|
|
|
|
int changed = 0;
|
|
|
|
|
|
|
|
|
|
gcse_subst_count = 0;
|
|
|
|
|
gcse_create_count = 0;
|
|
|
|
|
|
|
|
|
|
alloc_expr_hash_table (max_cuid);
|
|
|
|
|
alloc_rd_mem (n_basic_blocks, max_cuid);
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
compute_expr_hash_table ();
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (gcse_file)
|
|
|
|
|
dump_hash_table (gcse_file, "Expression", expr_hash_table,
|
|
|
|
|
expr_hash_table_size, n_exprs);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (n_exprs > 0)
|
|
|
|
|
{
|
|
|
|
|
compute_kill_rd ();
|
|
|
|
|
compute_rd ();
|
|
|
|
|
alloc_avail_expr_mem (n_basic_blocks, n_exprs);
|
|
|
|
|
compute_ae_gen ();
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
compute_ae_kill (ae_gen, ae_kill);
|
1999-11-11 07:38:15 +01:00
|
|
|
|
compute_available (ae_gen, ae_kill, ae_out, ae_in);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
changed = classic_gcse ();
|
|
|
|
|
free_avail_expr_mem ();
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
free_rd_mem ();
|
|
|
|
|
free_expr_hash_table ();
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file, "\n");
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, "GCSE of %s, pass %d: %d bytes needed, %d substs,",
|
|
|
|
|
current_function_name, pass, bytes_used, gcse_subst_count);
|
|
|
|
|
fprintf (gcse_file, "%d insns created\n", gcse_create_count);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute copy/constant propagation working variables. */
|
|
|
|
|
|
|
|
|
|
/* Local properties of assignments. */
|
|
|
|
|
static sbitmap *cprop_pavloc;
|
|
|
|
|
static sbitmap *cprop_absaltered;
|
|
|
|
|
|
|
|
|
|
/* Global properties of assignments (computed from the local properties). */
|
|
|
|
|
static sbitmap *cprop_avin;
|
|
|
|
|
static sbitmap *cprop_avout;
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Allocate vars used for copy/const propagation. N_BLOCKS is the number of
|
|
|
|
|
basic blocks. N_SETS is the number of sets. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
alloc_cprop_mem (n_blocks, n_sets)
|
|
|
|
|
int n_blocks, n_sets;
|
|
|
|
|
{
|
|
|
|
|
cprop_pavloc = sbitmap_vector_alloc (n_blocks, n_sets);
|
|
|
|
|
cprop_absaltered = sbitmap_vector_alloc (n_blocks, n_sets);
|
|
|
|
|
|
|
|
|
|
cprop_avin = sbitmap_vector_alloc (n_blocks, n_sets);
|
|
|
|
|
cprop_avout = sbitmap_vector_alloc (n_blocks, n_sets);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free vars used by copy/const propagation. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_cprop_mem ()
|
|
|
|
|
{
|
|
|
|
|
free (cprop_pavloc);
|
|
|
|
|
free (cprop_absaltered);
|
|
|
|
|
free (cprop_avin);
|
|
|
|
|
free (cprop_avout);
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* For each block, compute whether X is transparent. X is either an
|
|
|
|
|
expression or an assignment [though we don't care which, for this context
|
|
|
|
|
an assignment is treated as an expression]. For each block where an
|
|
|
|
|
element of X is modified, set (SET_P == 1) or reset (SET_P == 0) the INDX
|
|
|
|
|
bit in BMAP. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_transp (x, indx, bmap, set_p)
|
|
|
|
|
rtx x;
|
|
|
|
|
int indx;
|
|
|
|
|
sbitmap *bmap;
|
|
|
|
|
int set_p;
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int bb, i, j;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
enum rtx_code code;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
reg_set *r;
|
rtl.h (rtx_format): Constify a char*.
* rtl.h (rtx_format): Constify a char*.
* rtl.c (rtx_format): Likewise.
(copy_rtx, copy_most_rtx, read_rtx): Likewise.
(init_rtl): Use accessor macro, not `rtx_format'.
* alias.c (rtx_equal_for_memref_p, find_symbolic_term): Constify a
char*.
* caller-save.c (mark_referenced_regs): Likewise.
* combine.c (subst, make_compound_operation, known_cond,
gen_rtx_combine, update_table_tick, get_last_value_validate,
use_crosses_set_p, mark_used_regs_combine, move_deaths): Likewise.
* cse.c (rtx_cost, mention_regs, canon_hash, exp_equiv_p,
refers_to_p, canon_reg, fold_rtx, cse_process_notes,
count_reg_usage): Likewise.
* emit-rtl.c (gen_rtx, copy_rtx_if_shared, reset_used_flags):
Likewise.
* final.c (leaf_renumber_regs_insn): Likewise.
* flow.c (mark_used_regs, find_use_as_address, dump_flow_info,
dump_edge_info, count_reg_references): Likewise.
* function.c (fixup_var_refs_1, walk_fixup_memory_subreg,
fixup_stack_1, purge_addressof_1, instantiate_virtual_regs_1):
Likewise.
* gcse.c (oprs_unchanged_p, hash_expr_1, expr_equiv_p,
oprs_not_set_p, expr_killed_p, compute_transp, find_used_regs,
add_label_notes): Likewise.
* genattrtab.c (attr_rtx, attr_copy_rtx, encode_units_mask,
clear_struct_flag, count_sub_rtxs, count_alternatives,
compares_alternatives_p, contained_in_p, walk_attr_value,
write_expr_attr_cache): Likewise.
* genconfig.c (walk_insn_part): Likewise.
* genemit.c (max_operand_1, gen_exp): Likewise.
* genextract.c (walk_rtx): Likewise.
* genflags.c (num_operands): Likewise.
* genoutput.c (scan_operands): Likewise.
* genpeep.c (match_rtx): Likewise.
* genrecog.c (add_to_sequence): Likewise.
* haifa-sched.c (may_trap_exp, sched_analyze_2, attach_deaths):
Likewise.
* integrate.c (save_constants, copy_for_inline,
copy_rtx_and_substitute, subst_constants, restore_constants):
Likewise.
* jump.c (mark_jump_label, invert_exp, redirect_exp,
rtx_renumbered_equal_p, rtx_equal_for_thread_p): Likewise.
* local-alloc.c (contains_replace_regs, memref_referenced_p):
Likewise.
* loop.c (record_excess_regs, rtx_equal_for_loop_p,
add_label_notes, replace_call_address, count_nonfixed_reads,
invariant_p, find_single_use_in_loop, find_mem_givs,
find_life_end, maybe_eliminate_biv_1, update_reg_last_use):
Likewise.
* print-rtl.c (reg_names, print_rtx): Likewise.
* recog.c (validate_replace_rtx_1, find_single_use_1): Likewise.
* reg-stack.c (stack_regs_mentioned_p, record_label_references,
record_reg_life_pat, swap_rtx_condition, goto_block_pat,
print_blocks): Likewise.
* regclass.c (fix_register, record_address_regs,
reg_scan_mark_refs): Likewise.
* regmove.c (stable_but_for_p): Likewise.
* reload.c (loc_mentioned_in_p, operands_match_p,
find_reloads_toplevsubst_reg_equivs, find_reloads_address_1,
copy_replacements, refers_to_regno_for_reload_p,
refers_to_mem_for_reload_p, find_inc_amount, regno_clobbered_p,
reload_when_needed_name, reg_class_names, debug_reload_to_stream):
Likewise.
* reload1.c (eliminate_regs, scan_paradoxical_subregs,
delete_address_reloads_1, count_occurrences,
reload_cse_mem_conflict_p, reload_combine_note_use,
add_auto_inc_notes): Likewise.
* resource.c (mark_referenced_resources, mark_set_resources):
Likewise.
* rtlanal.c (rtx_unstable_p, rtx_varies_p, rtx_addr_varies_p,
reg_mentioned_p, regs_set_between_p, modified_between_p,
modified_in_p, refers_to_regno_p, reg_overlap_mentioned_p,
rtx_equal_p, volatile_insn_p, volatile_refs_p, side_effects_p,
may_trap_p, inequality_comparisons_p, replace_rtx, replace_regs,
jmp_uses_reg_or_mem, for_each_rtx, regno_use_in): Likewise.
* sched.c (sched_analyze_2, attach_deaths): Likewise.
* stupid.c (stupid_mark_refs): Likewise.
* unroll.c (remap_split_bivs): Likewise.
* varasm.c (mark_constants): Likewise.
* a29k/a29k.c (uses_local_reg_p): Likewise.
* alpha/alpha.c (summarize_insn): Likewise.
* arm/arm.c (symbol_mentioned_p, label_mentioned_p,
eliminate_lr2ip): Likewise.
* arm/thumb.c (symbol_mentioned_p, label_mentioned_p): Likewise.
* i386/i386.c (symbolic_reference_mentioned_p, copy_all_rtx,
reg_mentioned_in_mem): Likewise.
* ns32k/ns32k.c (global_symbolic_reference_mentioned_p,
symbolic_reference_mentioned_p): Likewise.
* romp/romp.c (unsigned_comparisons_p, hash_rtx): Likewise.
* sh/sh.c (regs_used, mark_use): Likewise.
* vax/vax.c (vax_rtx_cost): Likewise.
From-SVN: r28784
1999-08-21 01:05:25 +02:00
|
|
|
|
const char *fmt;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* repeat is used to turn tail-recursion into iteration since GCC
|
|
|
|
|
can't do it when there's no return value. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
repeat:
|
|
|
|
|
|
|
|
|
|
if (x == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
code = GET_CODE (x);
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case REG:
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (set_p)
|
|
|
|
|
{
|
|
|
|
|
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
|
|
|
|
|
{
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
if (TEST_BIT (reg_set_in_block[bb], REGNO (x)))
|
|
|
|
|
SET_BIT (bmap[bb], indx);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (r = reg_set_table[REGNO (x)]; r != NULL; r = r->next)
|
|
|
|
|
SET_BIT (bmap[BLOCK_NUM (r->insn)], indx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
|
|
|
|
|
{
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
if (TEST_BIT (reg_set_in_block[bb], REGNO (x)))
|
|
|
|
|
RESET_BIT (bmap[bb], indx);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (r = reg_set_table[REGNO (x)]; r != NULL; r = r->next)
|
|
|
|
|
RESET_BIT (bmap[BLOCK_NUM (r->insn)], indx);
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
return;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
case MEM:
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
{
|
|
|
|
|
rtx list_entry = canon_modify_mem_list[bb];
|
|
|
|
|
|
|
|
|
|
while (list_entry)
|
|
|
|
|
{
|
|
|
|
|
rtx dest, dest_addr;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (XEXP (list_entry, 0)) == CALL_INSN)
|
|
|
|
|
{
|
|
|
|
|
if (set_p)
|
|
|
|
|
SET_BIT (bmap[bb], indx);
|
|
|
|
|
else
|
|
|
|
|
RESET_BIT (bmap[bb], indx);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
/* LIST_ENTRY must be an INSN of some kind that sets memory.
|
|
|
|
|
Examine each hunk of memory that is modified. */
|
|
|
|
|
|
|
|
|
|
dest = XEXP (list_entry, 0);
|
|
|
|
|
list_entry = XEXP (list_entry, 1);
|
|
|
|
|
dest_addr = XEXP (list_entry, 0);
|
|
|
|
|
|
|
|
|
|
if (canon_true_dependence (dest, GET_MODE (dest), dest_addr,
|
|
|
|
|
x, rtx_addr_varies_p))
|
|
|
|
|
{
|
|
|
|
|
if (set_p)
|
|
|
|
|
SET_BIT (bmap[bb], indx);
|
|
|
|
|
else
|
|
|
|
|
RESET_BIT (bmap[bb], indx);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
list_entry = XEXP (list_entry, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (set_p)
|
|
|
|
|
{
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
if (mem_set_in_block[bb])
|
|
|
|
|
SET_BIT (bmap[bb], indx);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
if (mem_set_in_block[bb])
|
|
|
|
|
RESET_BIT (bmap[bb], indx);
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
x = XEXP (x, 0);
|
|
|
|
|
goto repeat;
|
|
|
|
|
|
|
|
|
|
case PC:
|
|
|
|
|
case CC0: /*FIXME*/
|
|
|
|
|
case CONST:
|
|
|
|
|
case CONST_INT:
|
|
|
|
|
case CONST_DOUBLE:
|
|
|
|
|
case SYMBOL_REF:
|
|
|
|
|
case LABEL_REF:
|
|
|
|
|
case ADDR_VEC:
|
|
|
|
|
case ADDR_DIFF_VEC:
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
{
|
|
|
|
|
/* If we are about to do the last recursive call
|
|
|
|
|
needed at this level, change it into iteration.
|
|
|
|
|
This function is called enough to be worth it. */
|
|
|
|
|
if (i == 0)
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
x = XEXP (x, i);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
goto repeat;
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
compute_transp (XEXP (x, i), indx, bmap, set_p);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
else if (fmt[i] == 'E')
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (j = 0; j < XVECLEN (x, i); j++)
|
|
|
|
|
compute_transp (XVECEXP (x, i, j), indx, bmap, set_p);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Top level routine to do the dataflow analysis needed by copy/const
|
|
|
|
|
propagation. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_cprop_data ()
|
|
|
|
|
{
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
compute_local_properties (cprop_absaltered, cprop_pavloc, NULL, 1);
|
1999-11-11 10:21:12 +01:00
|
|
|
|
compute_available (cprop_pavloc, cprop_absaltered,
|
|
|
|
|
cprop_avout, cprop_avin);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy/constant propagation. */
|
|
|
|
|
|
|
|
|
|
/* Maximum number of register uses in an insn that we handle. */
|
|
|
|
|
#define MAX_USES 8
|
|
|
|
|
|
|
|
|
|
/* Table of uses found in an insn.
|
|
|
|
|
Allocated statically to avoid alloc/free complexity and overhead. */
|
|
|
|
|
static struct reg_use reg_use_table[MAX_USES];
|
|
|
|
|
|
|
|
|
|
/* Index into `reg_use_table' while building it. */
|
|
|
|
|
static int reg_use_count;
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Set up a list of register numbers used in INSN. The found uses are stored
|
|
|
|
|
in `reg_use_table'. `reg_use_count' is initialized to zero before entry,
|
|
|
|
|
and contains the number of uses in the table upon exit.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
??? If a register appears multiple times we will record it multiple times.
|
|
|
|
|
This doesn't hurt anything but it will slow things down. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
find_used_regs (x)
|
|
|
|
|
rtx x;
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int i, j;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
enum rtx_code code;
|
rtl.h (rtx_format): Constify a char*.
* rtl.h (rtx_format): Constify a char*.
* rtl.c (rtx_format): Likewise.
(copy_rtx, copy_most_rtx, read_rtx): Likewise.
(init_rtl): Use accessor macro, not `rtx_format'.
* alias.c (rtx_equal_for_memref_p, find_symbolic_term): Constify a
char*.
* caller-save.c (mark_referenced_regs): Likewise.
* combine.c (subst, make_compound_operation, known_cond,
gen_rtx_combine, update_table_tick, get_last_value_validate,
use_crosses_set_p, mark_used_regs_combine, move_deaths): Likewise.
* cse.c (rtx_cost, mention_regs, canon_hash, exp_equiv_p,
refers_to_p, canon_reg, fold_rtx, cse_process_notes,
count_reg_usage): Likewise.
* emit-rtl.c (gen_rtx, copy_rtx_if_shared, reset_used_flags):
Likewise.
* final.c (leaf_renumber_regs_insn): Likewise.
* flow.c (mark_used_regs, find_use_as_address, dump_flow_info,
dump_edge_info, count_reg_references): Likewise.
* function.c (fixup_var_refs_1, walk_fixup_memory_subreg,
fixup_stack_1, purge_addressof_1, instantiate_virtual_regs_1):
Likewise.
* gcse.c (oprs_unchanged_p, hash_expr_1, expr_equiv_p,
oprs_not_set_p, expr_killed_p, compute_transp, find_used_regs,
add_label_notes): Likewise.
* genattrtab.c (attr_rtx, attr_copy_rtx, encode_units_mask,
clear_struct_flag, count_sub_rtxs, count_alternatives,
compares_alternatives_p, contained_in_p, walk_attr_value,
write_expr_attr_cache): Likewise.
* genconfig.c (walk_insn_part): Likewise.
* genemit.c (max_operand_1, gen_exp): Likewise.
* genextract.c (walk_rtx): Likewise.
* genflags.c (num_operands): Likewise.
* genoutput.c (scan_operands): Likewise.
* genpeep.c (match_rtx): Likewise.
* genrecog.c (add_to_sequence): Likewise.
* haifa-sched.c (may_trap_exp, sched_analyze_2, attach_deaths):
Likewise.
* integrate.c (save_constants, copy_for_inline,
copy_rtx_and_substitute, subst_constants, restore_constants):
Likewise.
* jump.c (mark_jump_label, invert_exp, redirect_exp,
rtx_renumbered_equal_p, rtx_equal_for_thread_p): Likewise.
* local-alloc.c (contains_replace_regs, memref_referenced_p):
Likewise.
* loop.c (record_excess_regs, rtx_equal_for_loop_p,
add_label_notes, replace_call_address, count_nonfixed_reads,
invariant_p, find_single_use_in_loop, find_mem_givs,
find_life_end, maybe_eliminate_biv_1, update_reg_last_use):
Likewise.
* print-rtl.c (reg_names, print_rtx): Likewise.
* recog.c (validate_replace_rtx_1, find_single_use_1): Likewise.
* reg-stack.c (stack_regs_mentioned_p, record_label_references,
record_reg_life_pat, swap_rtx_condition, goto_block_pat,
print_blocks): Likewise.
* regclass.c (fix_register, record_address_regs,
reg_scan_mark_refs): Likewise.
* regmove.c (stable_but_for_p): Likewise.
* reload.c (loc_mentioned_in_p, operands_match_p,
find_reloads_toplevsubst_reg_equivs, find_reloads_address_1,
copy_replacements, refers_to_regno_for_reload_p,
refers_to_mem_for_reload_p, find_inc_amount, regno_clobbered_p,
reload_when_needed_name, reg_class_names, debug_reload_to_stream):
Likewise.
* reload1.c (eliminate_regs, scan_paradoxical_subregs,
delete_address_reloads_1, count_occurrences,
reload_cse_mem_conflict_p, reload_combine_note_use,
add_auto_inc_notes): Likewise.
* resource.c (mark_referenced_resources, mark_set_resources):
Likewise.
* rtlanal.c (rtx_unstable_p, rtx_varies_p, rtx_addr_varies_p,
reg_mentioned_p, regs_set_between_p, modified_between_p,
modified_in_p, refers_to_regno_p, reg_overlap_mentioned_p,
rtx_equal_p, volatile_insn_p, volatile_refs_p, side_effects_p,
may_trap_p, inequality_comparisons_p, replace_rtx, replace_regs,
jmp_uses_reg_or_mem, for_each_rtx, regno_use_in): Likewise.
* sched.c (sched_analyze_2, attach_deaths): Likewise.
* stupid.c (stupid_mark_refs): Likewise.
* unroll.c (remap_split_bivs): Likewise.
* varasm.c (mark_constants): Likewise.
* a29k/a29k.c (uses_local_reg_p): Likewise.
* alpha/alpha.c (summarize_insn): Likewise.
* arm/arm.c (symbol_mentioned_p, label_mentioned_p,
eliminate_lr2ip): Likewise.
* arm/thumb.c (symbol_mentioned_p, label_mentioned_p): Likewise.
* i386/i386.c (symbolic_reference_mentioned_p, copy_all_rtx,
reg_mentioned_in_mem): Likewise.
* ns32k/ns32k.c (global_symbolic_reference_mentioned_p,
symbolic_reference_mentioned_p): Likewise.
* romp/romp.c (unsigned_comparisons_p, hash_rtx): Likewise.
* sh/sh.c (regs_used, mark_use): Likewise.
* vax/vax.c (vax_rtx_cost): Likewise.
From-SVN: r28784
1999-08-21 01:05:25 +02:00
|
|
|
|
const char *fmt;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* repeat is used to turn tail-recursion into iteration since GCC
|
|
|
|
|
can't do it when there's no return value. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
repeat:
|
|
|
|
|
|
|
|
|
|
if (x == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
code = GET_CODE (x);
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case REG:
|
|
|
|
|
if (reg_use_count == MAX_USES)
|
|
|
|
|
return;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
reg_use_table[reg_use_count].reg_rtx = x;
|
|
|
|
|
reg_use_count++;
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case MEM:
|
|
|
|
|
x = XEXP (x, 0);
|
|
|
|
|
goto repeat;
|
|
|
|
|
|
|
|
|
|
case PC:
|
|
|
|
|
case CC0:
|
|
|
|
|
case CONST:
|
|
|
|
|
case CONST_INT:
|
|
|
|
|
case CONST_DOUBLE:
|
|
|
|
|
case SYMBOL_REF:
|
|
|
|
|
case LABEL_REF:
|
|
|
|
|
case CLOBBER:
|
|
|
|
|
case ADDR_VEC:
|
|
|
|
|
case ADDR_DIFF_VEC:
|
|
|
|
|
case ASM_INPUT: /*FIXME*/
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case SET:
|
|
|
|
|
if (GET_CODE (SET_DEST (x)) == MEM)
|
|
|
|
|
find_used_regs (SET_DEST (x));
|
|
|
|
|
x = SET_SRC (x);
|
|
|
|
|
goto repeat;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Recursively scan the operands of this expression. */
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
{
|
|
|
|
|
/* If we are about to do the last recursive call
|
|
|
|
|
needed at this level, change it into iteration.
|
|
|
|
|
This function is called enough to be worth it. */
|
|
|
|
|
if (i == 0)
|
|
|
|
|
{
|
|
|
|
|
x = XEXP (x, 0);
|
|
|
|
|
goto repeat;
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
find_used_regs (XEXP (x, i));
|
|
|
|
|
}
|
|
|
|
|
else if (fmt[i] == 'E')
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (j = 0; j < XVECLEN (x, i); j++)
|
|
|
|
|
find_used_regs (XVECEXP (x, i, j));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Try to replace all non-SET_DEST occurrences of FROM in INSN with TO.
|
|
|
|
|
Returns non-zero is successful. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
try_replace_reg (from, to, insn)
|
|
|
|
|
rtx from, to, insn;
|
|
|
|
|
{
|
2001-02-16 20:29:49 +01:00
|
|
|
|
rtx note = find_reg_equal_equiv_note (insn);
|
2001-02-19 00:56:34 +01:00
|
|
|
|
rtx src = 0;
|
2001-02-16 20:29:49 +01:00
|
|
|
|
int success = 0;
|
|
|
|
|
rtx set = single_set (insn);
|
1999-12-17 12:10:58 +01:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* If this is a single set, try to simplify the source of the set given
|
|
|
|
|
our substitution. We could perhaps try this for multiple SETs, but
|
|
|
|
|
it probably won't buy us anything. */
|
|
|
|
|
if (set != 0)
|
1999-12-17 12:10:58 +01:00
|
|
|
|
{
|
2001-02-16 20:29:49 +01:00
|
|
|
|
src = simplify_replace_rtx (SET_SRC (set), from, to);
|
|
|
|
|
|
|
|
|
|
/* Try this two ways: first just replace SET_SRC. If that doesn't
|
|
|
|
|
work and this is a PARALLEL, try to replace the whole pattern
|
|
|
|
|
with a new SET. */
|
|
|
|
|
if (validate_change (insn, &SET_SRC (set), src, 0))
|
|
|
|
|
success = 1;
|
|
|
|
|
else if (GET_CODE (PATTERN (insn)) == PARALLEL
|
|
|
|
|
&& validate_change (insn, &PATTERN (insn),
|
|
|
|
|
gen_rtx_SET (VOIDmode, SET_DEST (set),
|
|
|
|
|
src),
|
|
|
|
|
0))
|
|
|
|
|
success = 1;
|
1999-12-17 12:10:58 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* Otherwise, try to do a global replacement within the insn. */
|
|
|
|
|
if (!success)
|
|
|
|
|
success = validate_replace_src (from, to, insn);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
2001-02-19 00:56:34 +01:00
|
|
|
|
/* If we've failed to do replacement, have a single SET, and don't already
|
|
|
|
|
have a note, add a REG_EQUAL note to not lose information. */
|
2001-02-16 20:29:49 +01:00
|
|
|
|
if (!success && note == 0 && set != 0)
|
2001-02-19 00:56:34 +01:00
|
|
|
|
note = REG_NOTES (insn)
|
2001-02-16 20:29:49 +01:00
|
|
|
|
= gen_rtx_EXPR_LIST (REG_EQUAL, src, REG_NOTES (insn));
|
2000-07-30 20:44:13 +02:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* If there is already a NOTE, update the expression in it with our
|
|
|
|
|
replacement. */
|
|
|
|
|
else if (note != 0)
|
|
|
|
|
XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), from, to);
|
1999-12-17 12:10:58 +01:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* REG_EQUAL may get simplified into register.
|
|
|
|
|
We don't allow that. Remove that note. This code ought
|
|
|
|
|
not to hapen, because previous code ought to syntetize
|
|
|
|
|
reg-reg move, but be on the safe side. */
|
|
|
|
|
if (note && REG_P (XEXP (note, 0)))
|
|
|
|
|
remove_note (insn, note);
|
1999-12-17 12:10:58 +01:00
|
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
/* Find a set of REGNOs that are available on entry to INSN's block. Returns
|
|
|
|
|
NULL no such set is found. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static struct expr *
|
|
|
|
|
find_avail_set (regno, insn)
|
|
|
|
|
int regno;
|
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
1999-08-25 06:24:36 +02:00
|
|
|
|
/* SET1 contains the last set found that can be returned to the caller for
|
|
|
|
|
use in a substitution. */
|
|
|
|
|
struct expr *set1 = 0;
|
|
|
|
|
|
|
|
|
|
/* Loops are not possible here. To get a loop we would need two sets
|
|
|
|
|
available at the start of the block containing INSN. ie we would
|
|
|
|
|
need two sets like this available at the start of the block:
|
|
|
|
|
|
|
|
|
|
(set (reg X) (reg Y))
|
|
|
|
|
(set (reg Y) (reg X))
|
|
|
|
|
|
|
|
|
|
This can not happen since the set of (reg Y) would have killed the
|
|
|
|
|
set of (reg X) making it unavailable at the start of this block. */
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
rtx src;
|
|
|
|
|
struct expr *set = lookup_set (regno, NULL_RTX);
|
|
|
|
|
|
|
|
|
|
/* Find a set that is available at the start of the block
|
|
|
|
|
which contains INSN. */
|
|
|
|
|
while (set)
|
|
|
|
|
{
|
|
|
|
|
if (TEST_BIT (cprop_avin[BLOCK_NUM (insn)], set->bitmap_index))
|
|
|
|
|
break;
|
|
|
|
|
set = next_set (regno, set);
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-08-25 06:24:36 +02:00
|
|
|
|
/* If no available set was found we've reached the end of the
|
|
|
|
|
(possibly empty) copy chain. */
|
|
|
|
|
if (set == 0)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (set->expr) != SET)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
src = SET_SRC (set->expr);
|
|
|
|
|
|
|
|
|
|
/* We know the set is available.
|
|
|
|
|
Now check that SRC is ANTLOC (i.e. none of the source operands
|
|
|
|
|
have changed since the start of the block).
|
|
|
|
|
|
|
|
|
|
If the source operand changed, we may still use it for the next
|
|
|
|
|
iteration of this loop, but we may not use it for substitutions. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-08-25 06:24:36 +02:00
|
|
|
|
if (CONSTANT_P (src) || oprs_not_set_p (src, insn))
|
|
|
|
|
set1 = set;
|
|
|
|
|
|
|
|
|
|
/* If the source of the set is anything except a register, then
|
|
|
|
|
we have reached the end of the copy chain. */
|
|
|
|
|
if (GET_CODE (src) != REG)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
break;
|
|
|
|
|
|
1999-08-25 06:24:36 +02:00
|
|
|
|
/* Follow the copy chain, ie start another iteration of the loop
|
|
|
|
|
and see if we have an available copy into SRC. */
|
|
|
|
|
regno = REGNO (src);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* SET1 holds the last set that was available and anticipatable at
|
|
|
|
|
INSN. */
|
|
|
|
|
return set1;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-08-25 05:30:45 +02:00
|
|
|
|
/* Subroutine of cprop_insn that tries to propagate constants into
|
2001-02-16 20:29:49 +01:00
|
|
|
|
JUMP_INSNS. INSN must be a conditional jump. FROM is what we will try to
|
|
|
|
|
replace, SRC is the constant we will try to substitute for it. Returns
|
|
|
|
|
nonzero if a change was made. We know INSN has just a SET. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-08-25 05:30:45 +02:00
|
|
|
|
static int
|
2001-02-16 20:29:49 +01:00
|
|
|
|
cprop_jump (insn, from, src)
|
|
|
|
|
rtx insn;
|
|
|
|
|
rtx from;
|
1999-08-25 05:30:45 +02:00
|
|
|
|
rtx src;
|
|
|
|
|
{
|
2001-02-16 20:29:49 +01:00
|
|
|
|
rtx set = PATTERN (insn);
|
|
|
|
|
rtx new = simplify_replace_rtx (SET_SRC (set), from, src);
|
1999-08-25 05:30:45 +02:00
|
|
|
|
|
|
|
|
|
/* If no simplification can be made, then try the next
|
|
|
|
|
register. */
|
2001-02-16 20:29:49 +01:00
|
|
|
|
if (rtx_equal_p (new, SET_SRC (set)))
|
1999-08-25 05:30:45 +02:00
|
|
|
|
return 0;
|
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* If this is now a no-op leave it that way, but update LABEL_NUSED if
|
|
|
|
|
necessary. */
|
|
|
|
|
if (new == pc_rtx)
|
1999-08-25 05:30:45 +02:00
|
|
|
|
{
|
2001-02-16 20:29:49 +01:00
|
|
|
|
SET_SRC (set) = new;
|
|
|
|
|
|
|
|
|
|
if (JUMP_LABEL (insn) != 0)
|
1999-08-25 05:30:45 +02:00
|
|
|
|
--LABEL_NUSES (JUMP_LABEL (insn));
|
2001-02-16 20:29:49 +01:00
|
|
|
|
}
|
1999-08-25 05:30:45 +02:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* Otherwise, this must be a valid instruction. */
|
|
|
|
|
else if (! validate_change (insn, &SET_SRC (set), new, 0))
|
|
|
|
|
return 0;
|
1999-08-25 05:30:45 +02:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* If this has turned into an unconditional jump,
|
|
|
|
|
then put a barrier after it so that the unreachable
|
|
|
|
|
code will be deleted. */
|
|
|
|
|
if (GET_CODE (SET_SRC (set)) == LABEL_REF)
|
|
|
|
|
emit_barrier_after (insn);
|
1999-08-25 05:30:45 +02:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
run_jump_opt_after_gcse = 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
const_prop_count++;
|
|
|
|
|
if (gcse_file != NULL)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file,
|
|
|
|
|
"CONST-PROP: Replacing reg %d in insn %d with constant ",
|
|
|
|
|
REGNO (from), INSN_UID (insn));
|
|
|
|
|
print_rtl (gcse_file, src);
|
|
|
|
|
fprintf (gcse_file, "\n");
|
1999-08-25 05:30:45 +02:00
|
|
|
|
}
|
2001-02-16 20:29:49 +01:00
|
|
|
|
|
|
|
|
|
return 1;
|
1999-08-25 05:30:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_cc0
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
/* Subroutine of cprop_insn that tries to propagate constants into JUMP_INSNS
|
|
|
|
|
for machines that have CC0. INSN is a single set that stores into CC0;
|
|
|
|
|
the insn following it is a conditional jump. REG_USED is the use we will
|
|
|
|
|
try to replace, SRC is the constant we will try to substitute for it.
|
1999-08-25 05:30:45 +02:00
|
|
|
|
Returns nonzero if a change was made. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-08-25 05:30:45 +02:00
|
|
|
|
static int
|
|
|
|
|
cprop_cc0_jump (insn, reg_used, src)
|
|
|
|
|
rtx insn;
|
|
|
|
|
struct reg_use *reg_used;
|
|
|
|
|
rtx src;
|
|
|
|
|
{
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* First substitute in the SET_SRC of INSN, then substitute that for
|
|
|
|
|
CC0 in JUMP. */
|
1999-08-25 05:30:45 +02:00
|
|
|
|
rtx jump = NEXT_INSN (insn);
|
2001-02-16 20:29:49 +01:00
|
|
|
|
rtx new_src = simplify_replace_rtx (SET_SRC (PATTERN (insn)),
|
|
|
|
|
reg_used->reg_rtx, src);
|
1999-08-25 05:30:45 +02:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
if (! cprop_jump (jump, cc0_rtx, new_src))
|
1999-08-25 05:30:45 +02:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* If we succeeded, delete the cc0 setter. */
|
|
|
|
|
PUT_CODE (insn, NOTE);
|
|
|
|
|
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
|
|
|
|
|
NOTE_SOURCE_FILE (insn) = 0;
|
2001-02-16 20:29:49 +01:00
|
|
|
|
|
1999-08-25 05:30:45 +02:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Perform constant and copy propagation on INSN.
|
|
|
|
|
The result is non-zero if a change was made. */
|
|
|
|
|
|
|
|
|
|
static int
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
cprop_insn (insn, alter_jumps)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
rtx insn;
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
int alter_jumps;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
struct reg_use *reg_used;
|
|
|
|
|
int changed = 0;
|
1999-12-17 12:10:58 +01:00
|
|
|
|
rtx note;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-03-10 20:45:18 +01:00
|
|
|
|
/* Only propagate into SETs. Note that a conditional jump is a
|
|
|
|
|
SET with pc_rtx as the destination. */
|
2001-02-16 20:29:49 +01:00
|
|
|
|
if (GET_CODE (insn) != INSN && GET_CODE (insn) != JUMP_INSN)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
reg_use_count = 0;
|
|
|
|
|
find_used_regs (PATTERN (insn));
|
1999-12-17 12:10:58 +01:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
note = find_reg_equal_equiv_note (insn);
|
1999-12-17 12:10:58 +01:00
|
|
|
|
|
|
|
|
|
/* We may win even when propagating constants into notes. */
|
|
|
|
|
if (note)
|
|
|
|
|
find_used_regs (XEXP (note, 0));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (reg_used = ®_use_table[0]; reg_use_count > 0;
|
|
|
|
|
reg_used++, reg_use_count--)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int regno = REGNO (reg_used->reg_rtx);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
rtx pat, src;
|
|
|
|
|
struct expr *set;
|
|
|
|
|
|
|
|
|
|
/* Ignore registers created by GCSE.
|
|
|
|
|
We do this because ... */
|
|
|
|
|
if (regno >= max_gcse_regno)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* If the register has already been set in this block, there's
|
|
|
|
|
nothing we can do. */
|
|
|
|
|
if (! oprs_not_set_p (reg_used->reg_rtx, insn))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Find an assignment that sets reg_used and is available
|
|
|
|
|
at the start of the block. */
|
|
|
|
|
set = find_avail_set (regno, insn);
|
|
|
|
|
if (! set)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
pat = set->expr;
|
|
|
|
|
/* ??? We might be able to handle PARALLELs. Later. */
|
|
|
|
|
if (GET_CODE (pat) != SET)
|
|
|
|
|
abort ();
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
src = SET_SRC (pat);
|
|
|
|
|
|
1999-03-10 20:45:18 +01:00
|
|
|
|
/* Constant propagation. */
|
1999-08-07 10:13:28 +02:00
|
|
|
|
if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE
|
|
|
|
|
|| GET_CODE (src) == SYMBOL_REF)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
1999-03-10 20:45:18 +01:00
|
|
|
|
/* Handle normal insns first. */
|
|
|
|
|
if (GET_CODE (insn) == INSN
|
|
|
|
|
&& try_replace_reg (reg_used->reg_rtx, src, insn))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
changed = 1;
|
|
|
|
|
const_prop_count++;
|
|
|
|
|
if (gcse_file != NULL)
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, "CONST-PROP: Replacing reg %d in ",
|
|
|
|
|
regno);
|
|
|
|
|
fprintf (gcse_file, "insn %d with constant ",
|
|
|
|
|
INSN_UID (insn));
|
1999-03-10 20:45:18 +01:00
|
|
|
|
print_rtl (gcse_file, src);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
fprintf (gcse_file, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The original insn setting reg_used may or may not now be
|
|
|
|
|
deletable. We leave the deletion to flow. */
|
|
|
|
|
}
|
1999-03-10 20:45:18 +01:00
|
|
|
|
|
|
|
|
|
/* Try to propagate a CONST_INT into a conditional jump.
|
|
|
|
|
We're pretty specific about what we will handle in this
|
|
|
|
|
code, we can extend this as necessary over time.
|
|
|
|
|
|
|
|
|
|
Right now the insn in question must look like
|
1999-08-25 05:30:45 +02:00
|
|
|
|
(set (pc) (if_then_else ...)) */
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
else if (alter_jumps
|
1999-05-09 14:25:03 +02:00
|
|
|
|
&& GET_CODE (insn) == JUMP_INSN
|
|
|
|
|
&& condjump_p (insn)
|
|
|
|
|
&& ! simplejump_p (insn))
|
2001-02-16 20:29:49 +01:00
|
|
|
|
changed |= cprop_jump (insn, reg_used->reg_rtx, src);
|
|
|
|
|
|
1999-08-25 05:30:45 +02:00
|
|
|
|
#ifdef HAVE_cc0
|
|
|
|
|
/* Similar code for machines that use a pair of CC0 setter and
|
|
|
|
|
conditional jump insn. */
|
|
|
|
|
else if (alter_jumps
|
|
|
|
|
&& GET_CODE (PATTERN (insn)) == SET
|
|
|
|
|
&& SET_DEST (PATTERN (insn)) == cc0_rtx
|
|
|
|
|
&& GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
|
|
|
|
|
&& condjump_p (NEXT_INSN (insn))
|
2001-02-16 20:29:49 +01:00
|
|
|
|
&& ! simplejump_p (NEXT_INSN (insn))
|
|
|
|
|
&& cprop_cc0_jump (insn, reg_used, src))
|
|
|
|
|
{
|
|
|
|
|
changed = 1;
|
|
|
|
|
break;
|
2000-10-25 00:49:39 +02:00
|
|
|
|
}
|
1999-08-25 05:30:45 +02:00
|
|
|
|
#endif
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
else if (GET_CODE (src) == REG
|
|
|
|
|
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
|
|
|
|
|
&& REGNO (src) != regno)
|
|
|
|
|
{
|
1999-08-25 06:24:36 +02:00
|
|
|
|
if (try_replace_reg (reg_used->reg_rtx, src, insn))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
1999-08-25 06:24:36 +02:00
|
|
|
|
changed = 1;
|
|
|
|
|
copy_prop_count++;
|
|
|
|
|
if (gcse_file != NULL)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, "COPY-PROP: Replacing reg %d in insn %d",
|
|
|
|
|
regno, INSN_UID (insn));
|
|
|
|
|
fprintf (gcse_file, " with reg %d\n", REGNO (src));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
1999-08-25 06:24:36 +02:00
|
|
|
|
|
|
|
|
|
/* The original insn setting reg_used may or may not now be
|
|
|
|
|
deletable. We leave the deletion to flow. */
|
|
|
|
|
/* FIXME: If it turns out that the insn isn't deletable,
|
|
|
|
|
then we may have unnecessarily extended register lifetimes
|
|
|
|
|
and made things worse. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Forward propagate copies. This includes copies and constants. Return
|
|
|
|
|
non-zero if a change was made. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static int
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
cprop (alter_jumps)
|
|
|
|
|
int alter_jumps;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
int bb, changed;
|
|
|
|
|
rtx insn;
|
|
|
|
|
|
|
|
|
|
/* Note we start at block 1. */
|
|
|
|
|
|
|
|
|
|
changed = 0;
|
|
|
|
|
for (bb = 1; bb < n_basic_blocks; bb++)
|
|
|
|
|
{
|
|
|
|
|
/* Reset tables used to keep track of what's still valid [since the
|
|
|
|
|
start of the block]. */
|
|
|
|
|
reset_opr_set_tables ();
|
|
|
|
|
|
basic-block.h (basic_block_head): Rename to x_basic_block_head.
* basic-block.h (basic_block_head): Rename to x_basic_block_head.
(basic_block_end): Rename to x_basic_block_end.
(BLOCK_HEAD, BLOCK_END): Update.
* caller-save.c: Change basic_block_head/end references to
BLOCK_HEAD/END.
* combine.c, flow.c, function.c, gcse.c, global.c: Likewise.
* graph.c, haifa-sched.c, local-alloc.c, regclass.c: Likewise.
* regmove.c, reload1.c, reorg.c, sched.c: Likewise.
From-SVN: r24622
1999-01-11 23:37:20 +01:00
|
|
|
|
for (insn = BLOCK_HEAD (bb);
|
|
|
|
|
insn != NULL && insn != NEXT_INSN (BLOCK_END (bb));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
insn = NEXT_INSN (insn))
|
2001-02-16 20:29:49 +01:00
|
|
|
|
if (INSN_P (insn))
|
|
|
|
|
{
|
|
|
|
|
changed |= cprop_insn (insn, alter_jumps);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2001-02-16 20:29:49 +01:00
|
|
|
|
/* Keep track of everything modified by this insn. */
|
|
|
|
|
/* ??? Need to be careful w.r.t. mods done to INSN. Don't
|
|
|
|
|
call mark_oprs_set if we turned the insn into a NOTE. */
|
|
|
|
|
if (GET_CODE (insn) != NOTE)
|
|
|
|
|
mark_oprs_set (insn);
|
1999-03-10 21:18:59 +01:00
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gcse_file != NULL)
|
|
|
|
|
fprintf (gcse_file, "\n");
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Perform one copy/constant propagation pass.
|
|
|
|
|
F is the first insn in the function.
|
|
|
|
|
PASS is the pass count. */
|
|
|
|
|
|
|
|
|
|
static int
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
one_cprop_pass (pass, alter_jumps)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
int pass;
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
int alter_jumps;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
int changed = 0;
|
|
|
|
|
|
|
|
|
|
const_prop_count = 0;
|
|
|
|
|
copy_prop_count = 0;
|
|
|
|
|
|
|
|
|
|
alloc_set_hash_table (max_cuid);
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
compute_set_hash_table ();
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (gcse_file)
|
|
|
|
|
dump_hash_table (gcse_file, "SET", set_hash_table, set_hash_table_size,
|
|
|
|
|
n_sets);
|
|
|
|
|
if (n_sets > 0)
|
|
|
|
|
{
|
|
|
|
|
alloc_cprop_mem (n_basic_blocks, n_sets);
|
|
|
|
|
compute_cprop_data ();
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
changed = cprop (alter_jumps);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
free_cprop_mem ();
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
free_set_hash_table ();
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, "CPROP of %s, pass %d: %d bytes needed, ",
|
|
|
|
|
current_function_name, pass, bytes_used);
|
|
|
|
|
fprintf (gcse_file, "%d const props, %d copy props\n\n",
|
|
|
|
|
const_prop_count, copy_prop_count);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Compute PRE+LCM working variables. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Local properties of expressions. */
|
|
|
|
|
/* Nonzero for expressions that are transparent in the block. */
|
1999-03-21 21:49:10 +01:00
|
|
|
|
static sbitmap *transp;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1998-10-08 03:26:18 +02:00
|
|
|
|
/* Nonzero for expressions that are transparent at the end of the block.
|
|
|
|
|
This is only zero for expressions killed by abnormal critical edge
|
|
|
|
|
created by a calls. */
|
1999-03-21 21:49:10 +01:00
|
|
|
|
static sbitmap *transpout;
|
1998-10-08 03:26:18 +02:00
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Nonzero for expressions that are computed (available) in the block. */
|
|
|
|
|
static sbitmap *comp;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Nonzero for expressions that are locally anticipatable in the block. */
|
|
|
|
|
static sbitmap *antloc;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Nonzero for expressions where this block is an optimal computation
|
|
|
|
|
point. */
|
|
|
|
|
static sbitmap *pre_optimal;
|
1998-10-08 03:26:18 +02:00
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Nonzero for expressions which are redundant in a particular block. */
|
|
|
|
|
static sbitmap *pre_redundant;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
/* Nonzero for expressions which should be inserted on a specific edge. */
|
|
|
|
|
static sbitmap *pre_insert_map;
|
|
|
|
|
|
|
|
|
|
/* Nonzero for expressions which should be deleted in a specific block. */
|
|
|
|
|
static sbitmap *pre_delete_map;
|
|
|
|
|
|
|
|
|
|
/* Contains the edge_list returned by pre_edge_lcm. */
|
|
|
|
|
static struct edge_list *edge_list;
|
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Redundant insns. */
|
|
|
|
|
static sbitmap pre_redundant_insns;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Allocate vars used for PRE analysis. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
1999-03-21 21:49:10 +01:00
|
|
|
|
alloc_pre_mem (n_blocks, n_exprs)
|
|
|
|
|
int n_blocks, n_exprs;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
1999-03-21 21:49:10 +01:00
|
|
|
|
transp = sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
comp = sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
antloc = sbitmap_vector_alloc (n_blocks, n_exprs);
|
1999-10-29 11:49:23 +02:00
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
pre_optimal = NULL;
|
|
|
|
|
pre_redundant = NULL;
|
|
|
|
|
pre_insert_map = NULL;
|
|
|
|
|
pre_delete_map = NULL;
|
|
|
|
|
ae_in = NULL;
|
|
|
|
|
ae_out = NULL;
|
|
|
|
|
ae_kill = sbitmap_vector_alloc (n_blocks, n_exprs);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
/* pre_insert and pre_delete are allocated later. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Free vars used for PRE analysis. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
1999-03-21 21:49:10 +01:00
|
|
|
|
free_pre_mem ()
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
1999-03-21 21:49:10 +01:00
|
|
|
|
free (transp);
|
|
|
|
|
free (comp);
|
2000-07-24 17:21:16 +02:00
|
|
|
|
|
|
|
|
|
/* ANTLOC and AE_KILL are freed just after pre_lcm finishes. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
if (pre_optimal)
|
|
|
|
|
free (pre_optimal);
|
|
|
|
|
if (pre_redundant)
|
|
|
|
|
free (pre_redundant);
|
|
|
|
|
if (pre_insert_map)
|
|
|
|
|
free (pre_insert_map);
|
|
|
|
|
if (pre_delete_map)
|
|
|
|
|
free (pre_delete_map);
|
|
|
|
|
|
|
|
|
|
if (ae_in)
|
|
|
|
|
free (ae_in);
|
|
|
|
|
if (ae_out)
|
|
|
|
|
free (ae_out);
|
|
|
|
|
|
2000-07-24 17:21:16 +02:00
|
|
|
|
transp = comp = NULL;
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
pre_optimal = pre_redundant = pre_insert_map = pre_delete_map = NULL;
|
2000-07-24 17:47:06 +02:00
|
|
|
|
ae_in = ae_out = NULL;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Top level routine to do the dataflow analysis needed by PRE. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_pre_data ()
|
|
|
|
|
{
|
2000-12-06 19:45:31 +01:00
|
|
|
|
sbitmap trapping_expr;
|
2000-07-03 08:49:31 +02:00
|
|
|
|
int i;
|
2000-12-06 19:45:31 +01:00
|
|
|
|
unsigned int ui;
|
2000-07-03 08:49:31 +02:00
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
compute_local_properties (transp, comp, antloc, 0);
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
sbitmap_vector_zero (ae_kill, n_basic_blocks);
|
2000-07-03 08:49:31 +02:00
|
|
|
|
|
2000-12-06 19:45:31 +01:00
|
|
|
|
/* Collect expressions which might trap. */
|
|
|
|
|
trapping_expr = sbitmap_alloc (n_exprs);
|
|
|
|
|
sbitmap_zero (trapping_expr);
|
|
|
|
|
for (ui = 0; ui < expr_hash_table_size; ui++)
|
|
|
|
|
{
|
|
|
|
|
struct expr *e;
|
|
|
|
|
for (e = expr_hash_table[ui]; e != NULL; e = e->next_same_hash)
|
|
|
|
|
if (may_trap_p (e->expr))
|
|
|
|
|
SET_BIT (trapping_expr, e->bitmap_index);
|
|
|
|
|
}
|
|
|
|
|
|
2000-07-03 08:49:31 +02:00
|
|
|
|
/* Compute ae_kill for each basic block using:
|
|
|
|
|
|
|
|
|
|
~(TRANSP | COMP)
|
|
|
|
|
|
2000-07-03 08:50:29 +02:00
|
|
|
|
This is significantly faster than compute_ae_kill. */
|
2000-07-03 08:49:31 +02:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < n_basic_blocks; i++)
|
|
|
|
|
{
|
2000-12-06 19:45:31 +01:00
|
|
|
|
edge e;
|
|
|
|
|
|
|
|
|
|
/* If the current block is the destination of an abnormal edge, we
|
|
|
|
|
kill all trapping expressions because we won't be able to properly
|
|
|
|
|
place the instruction on the edge. So make them neither
|
|
|
|
|
anticipatable nor transparent. This is fairly conservative. */
|
|
|
|
|
for (e = BASIC_BLOCK (i)->pred; e ; e = e->pred_next)
|
|
|
|
|
if (e->flags & EDGE_ABNORMAL)
|
|
|
|
|
{
|
|
|
|
|
sbitmap_difference (antloc[i], antloc[i], trapping_expr);
|
|
|
|
|
sbitmap_difference (transp[i], transp[i], trapping_expr);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2000-07-03 08:49:31 +02:00
|
|
|
|
sbitmap_a_or_b (ae_kill[i], transp[i], comp[i]);
|
|
|
|
|
sbitmap_not (ae_kill[i], ae_kill[i]);
|
|
|
|
|
}
|
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
edge_list = pre_edge_lcm (gcse_file, n_exprs, transp, comp, antloc,
|
|
|
|
|
ae_kill, &pre_insert_map, &pre_delete_map);
|
2000-07-24 17:21:16 +02:00
|
|
|
|
free (antloc);
|
|
|
|
|
antloc = NULL;
|
|
|
|
|
free (ae_kill);
|
|
|
|
|
ae_kill = NULL;
|
2000-12-06 19:45:31 +01:00
|
|
|
|
free (trapping_expr);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* PRE utilities */
|
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Return non-zero if an occurrence of expression EXPR in OCCR_BB would reach
|
|
|
|
|
block BB.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
VISITED is a pointer to a working buffer for tracking which BB's have
|
|
|
|
|
been visited. It is NULL for the top-level call.
|
|
|
|
|
|
|
|
|
|
We treat reaching expressions that go through blocks containing the same
|
|
|
|
|
reaching expression as "not reaching". E.g. if EXPR is generated in blocks
|
|
|
|
|
2 and 3, INSN is in block 4, and 2->3->4, we treat the expression in block
|
|
|
|
|
2 as not reaching. The intent is to improve the probability of finding
|
|
|
|
|
only one reaching expression and to reduce register lifetimes by picking
|
|
|
|
|
the closest such expression. */
|
|
|
|
|
|
|
|
|
|
static int
|
1999-11-15 07:12:50 +01:00
|
|
|
|
pre_expr_reaches_here_p_work (occr_bb, expr, bb, visited)
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block occr_bb;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
struct expr *expr;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
char *visited;
|
|
|
|
|
{
|
1999-08-25 20:01:48 +02:00
|
|
|
|
edge pred;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block pred_bb = pred->src;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-08-25 20:01:48 +02:00
|
|
|
|
if (pred->src == ENTRY_BLOCK_PTR
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Has predecessor has already been visited? */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
|| visited[pred_bb->index])
|
2000-02-29 21:08:52 +01:00
|
|
|
|
;/* Nothing to do. */
|
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Does this predecessor generate this expression? */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
else if (TEST_BIT (comp[pred_bb->index], expr->bitmap_index))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
/* Is this the occurrence we're looking for?
|
|
|
|
|
Note that there's only one generating occurrence per block
|
|
|
|
|
so we just need to check the block number. */
|
1999-03-21 21:49:10 +01:00
|
|
|
|
if (occr_bb == pred_bb)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
visited[pred_bb->index] = 1;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
/* Ignore this predecessor if it kills the expression. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
else if (! TEST_BIT (transp[pred_bb->index], expr->bitmap_index))
|
|
|
|
|
visited[pred_bb->index] = 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Neither gen nor kill. */
|
|
|
|
|
else
|
1999-03-10 21:18:59 +01:00
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
visited[pred_bb->index] = 1;
|
1999-11-15 07:12:50 +01:00
|
|
|
|
if (pre_expr_reaches_here_p_work (occr_bb, expr, pred_bb, visited))
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return 1;
|
1999-03-10 21:18:59 +01:00
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* All paths have been checked. */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1999-10-27 07:16:12 +02:00
|
|
|
|
|
|
|
|
|
/* The wrapper for pre_expr_reaches_here_work that ensures that any
|
|
|
|
|
memory allocated for that function is returned. */
|
|
|
|
|
|
|
|
|
|
static int
|
1999-11-15 07:12:50 +01:00
|
|
|
|
pre_expr_reaches_here_p (occr_bb, expr, bb)
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block occr_bb;
|
1999-10-27 07:16:12 +02:00
|
|
|
|
struct expr *expr;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
1999-10-27 07:16:12 +02:00
|
|
|
|
{
|
|
|
|
|
int rval;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
char *visited = (char *) xcalloc (n_basic_blocks, 1);
|
1999-10-27 07:16:12 +02:00
|
|
|
|
|
1999-11-15 07:12:50 +01:00
|
|
|
|
rval = pre_expr_reaches_here_p_work(occr_bb, expr, bb, visited);
|
1999-10-27 07:16:12 +02:00
|
|
|
|
|
|
|
|
|
free (visited);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
return rval;
|
1999-10-27 07:16:12 +02:00
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
|
|
|
|
|
/* Given an expr, generate RTL which we can insert at the end of a BB,
|
|
|
|
|
or on an edge. Set the block number of any insns generated to
|
|
|
|
|
the value of BB. */
|
|
|
|
|
|
|
|
|
|
static rtx
|
|
|
|
|
process_insert_insn (expr)
|
|
|
|
|
struct expr *expr;
|
|
|
|
|
{
|
|
|
|
|
rtx reg = expr->reaching_reg;
|
2001-02-19 00:56:34 +01:00
|
|
|
|
rtx exp = copy_rtx (expr->expr);
|
|
|
|
|
rtx pat;
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
|
|
|
|
|
start_sequence ();
|
2001-02-19 00:56:34 +01:00
|
|
|
|
|
|
|
|
|
/* If the expression is something that's an operand, like a constant,
|
|
|
|
|
just copy it to a register. */
|
|
|
|
|
if (general_operand (exp, GET_MODE (reg)))
|
|
|
|
|
emit_move_insn (reg, exp);
|
|
|
|
|
|
|
|
|
|
/* Otherwise, make a new insn to compute this expression and make sure the
|
|
|
|
|
insn will be recognized (this also adds any needed CLOBBERs). Copy the
|
|
|
|
|
expression to make sure we don't have any sharing issues. */
|
2001-02-19 04:19:23 +01:00
|
|
|
|
else if (insn_invalid_p (emit_insn (gen_rtx_SET (VOIDmode, reg, exp))))
|
2001-02-19 00:56:34 +01:00
|
|
|
|
abort ();
|
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
pat = gen_sequence ();
|
|
|
|
|
end_sequence ();
|
|
|
|
|
|
|
|
|
|
return pat;
|
|
|
|
|
}
|
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Add EXPR to the end of basic block BB.
|
|
|
|
|
|
|
|
|
|
This is used by both the PRE and code hoisting.
|
|
|
|
|
|
|
|
|
|
For PRE, we want to verify that the expr is either transparent
|
|
|
|
|
or locally anticipatable in the target block. This check makes
|
|
|
|
|
no sense for code hoisting. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
1999-03-21 21:49:10 +01:00
|
|
|
|
insert_insn_end_bb (expr, bb, pre)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
struct expr *expr;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
1999-03-21 21:49:10 +01:00
|
|
|
|
int pre;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
rtx insn = bb->end;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
rtx new_insn;
|
|
|
|
|
rtx reg = expr->reaching_reg;
|
|
|
|
|
int regno = REGNO (reg);
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
rtx pat;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int i;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
pat = process_insert_insn (expr);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* If the last insn is a jump, insert EXPR in front [taking care to
|
|
|
|
|
handle cc0, etc. properly]. */
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (insn) == JUMP_INSN)
|
|
|
|
|
{
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
#ifdef HAVE_cc0
|
1998-05-20 02:24:32 +02:00
|
|
|
|
rtx note;
|
Warning fixes:
* Makefile.in (varasm.o): Depend on dbxout.h.
(cse.o): Depend on toplev.h and output.h.
(gcse.o): Depend on output.h.
* mips.c: Include system.h and toplev.h and remove redundant code.
Include output.h after tree.h so all its prototypes get activated.
* mips.md (table_jump): Remove unused variable `dest'.
* sparc.h: Add prototype for `v8plus_regcmp_op'.
* crtstuff.c (fini_dummy, init_dummy): Mark function definitions
with __attribute__ ((__unused__)).
(__frame_dummy): Provide prototype before use, wrap it with
EH_FRAME_SECTION_ASM_OP.
* cse.c: Move inclusion of <setjmp.h> above local headers.
Include toplev.h and output.h.
* dbxout.h: Add prototype for `dbxout_begin_function'.
* final.c (final_scan_insn): Wrap variable `max_skip' in macro
ASM_OUTPUT_MAX_SKIP_ALIGN.
* gcse.c: Include system.h and output.h.
(dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data):
Make extern instead of static.
(compute_can_copy): Only declare variables `reg' and `insn' when
AVOID_CCMODE_COPIES is not defined.
(record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED.
(hash_scan_clobber): Likewise for `x' and `insn'.
(hash_scan_call): Likewise.
(record_last_set_info): Likewise for `setter'.
(mark_call): Likewise for `pat'.
(pre_insert_insn): Wrap variable `note' in macro HAVE_cc0.
* libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the
length parameter so that it multiplies the number of elements by
the sizeof(element).
* output.h: Add prototype for `weak_finish'.
* recog.h: Likewise for `validate_replace_src'.
* rtl.h: Likewise for `optimize_save_area_alloca',
`fix_sched_param', `purge_addressof', `gcse_main',
`regmove_optimize', `dbr_schedule', `branch_prob' and
`end_branch_prob'.
* toplev.h: Likewise for `set_float_handler' and
`output_quoted_string'.
* varasm.c: Include dbxout.h.
From-SVN: r20351
1998-06-08 20:30:27 +02:00
|
|
|
|
#endif
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* If this is a jump table, then we can't insert stuff here. Since
|
|
|
|
|
we know the previous real insn must be the tablejump, we insert
|
|
|
|
|
the new instruction just before the tablejump. */
|
|
|
|
|
if (GET_CODE (PATTERN (insn)) == ADDR_VEC
|
|
|
|
|
|| GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
|
|
|
|
|
insn = prev_real_insn (insn);
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_cc0
|
|
|
|
|
/* FIXME: 'twould be nice to call prev_cc0_setter here but it aborts
|
|
|
|
|
if cc0 isn't set. */
|
|
|
|
|
note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
|
|
|
|
|
if (note)
|
|
|
|
|
insn = XEXP (note, 0);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rtx maybe_cc0_setter = prev_nonnote_insn (insn);
|
|
|
|
|
if (maybe_cc0_setter
|
2000-08-04 22:28:08 +02:00
|
|
|
|
&& INSN_P (maybe_cc0_setter)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
&& sets_cc0_p (PATTERN (maybe_cc0_setter)))
|
|
|
|
|
insn = maybe_cc0_setter;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
/* FIXME: What if something in cc0/jump uses value set in new insn? */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
new_insn = emit_block_insn_before (pat, insn, bb);
|
1998-10-07 12:08:16 +02:00
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-10-07 12:08:16 +02:00
|
|
|
|
/* Likewise if the last insn is a call, as will happen in the presence
|
|
|
|
|
of exception handling. */
|
1998-10-08 03:26:18 +02:00
|
|
|
|
else if (GET_CODE (insn) == CALL_INSN)
|
1998-10-07 12:08:16 +02:00
|
|
|
|
{
|
|
|
|
|
HARD_REG_SET parm_regs;
|
|
|
|
|
int nparm_regs;
|
|
|
|
|
rtx p;
|
|
|
|
|
|
|
|
|
|
/* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers,
|
|
|
|
|
we search backward and place the instructions before the first
|
|
|
|
|
parameter is loaded. Do this for everyone for consistency and a
|
2000-02-29 21:08:52 +01:00
|
|
|
|
presumtion that we'll get better code elsewhere as well.
|
1998-10-07 12:08:16 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
It should always be the case that we can put these instructions
|
1999-03-21 21:49:10 +01:00
|
|
|
|
anywhere in the basic block with performing PRE optimizations.
|
|
|
|
|
Check this. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
if (pre
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
&& !TEST_BIT (antloc[bb->index], expr->bitmap_index)
|
|
|
|
|
&& !TEST_BIT (transp[bb->index], expr->bitmap_index))
|
1998-10-07 12:08:16 +02:00
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
/* Since different machines initialize their parameter registers
|
|
|
|
|
in different orders, assume nothing. Collect the set of all
|
|
|
|
|
parameter registers. */
|
|
|
|
|
CLEAR_HARD_REG_SET (parm_regs);
|
|
|
|
|
nparm_regs = 0;
|
|
|
|
|
for (p = CALL_INSN_FUNCTION_USAGE (insn); p ; p = XEXP (p, 1))
|
|
|
|
|
if (GET_CODE (XEXP (p, 0)) == USE
|
|
|
|
|
&& GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
|
1998-10-08 03:26:18 +02:00
|
|
|
|
abort ();
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
SET_HARD_REG_BIT (parm_regs, REGNO (XEXP (XEXP (p, 0), 0)));
|
1998-10-07 12:08:16 +02:00
|
|
|
|
nparm_regs++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Search backward for the first set of a register in this set. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
while (nparm_regs && bb->head != insn)
|
1998-10-07 12:08:16 +02:00
|
|
|
|
{
|
|
|
|
|
insn = PREV_INSN (insn);
|
|
|
|
|
p = single_set (insn);
|
|
|
|
|
if (p && GET_CODE (SET_DEST (p)) == REG
|
|
|
|
|
&& REGNO (SET_DEST (p)) < FIRST_PSEUDO_REGISTER
|
|
|
|
|
&& TEST_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p))))
|
|
|
|
|
{
|
|
|
|
|
CLEAR_HARD_REG_BIT (parm_regs, REGNO (SET_DEST (p)));
|
|
|
|
|
nparm_regs--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-06-03 02:19:42 +02:00
|
|
|
|
/* If we found all the parameter loads, then we want to insert
|
|
|
|
|
before the first parameter load.
|
|
|
|
|
|
|
|
|
|
If we did not find all the parameter loads, then we might have
|
|
|
|
|
stopped on the head of the block, which could be a CODE_LABEL.
|
|
|
|
|
If we inserted before the CODE_LABEL, then we would be putting
|
|
|
|
|
the insn in the wrong basic block. In that case, put the insn
|
2000-01-15 21:46:21 +01:00
|
|
|
|
after the CODE_LABEL. Also, respect NOTE_INSN_BASIC_BLOCK. */
|
2000-06-19 03:40:32 +02:00
|
|
|
|
while (GET_CODE (insn) == CODE_LABEL
|
2000-07-27 19:25:14 +02:00
|
|
|
|
|| NOTE_INSN_BASIC_BLOCK_P (insn))
|
2000-01-15 21:46:21 +01:00
|
|
|
|
insn = NEXT_INSN (insn);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
new_insn = emit_block_insn_before (pat, insn, bb);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
new_insn = emit_insn_after (pat, insn);
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
bb->end = new_insn;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Keep block number table up to date.
|
|
|
|
|
Note, PAT could be a multiple insn sequence, we have to make
|
|
|
|
|
sure that each insn in the sequence is handled. */
|
|
|
|
|
if (GET_CODE (pat) == SEQUENCE)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < XVECLEN (pat, 0); i++)
|
|
|
|
|
{
|
|
|
|
|
rtx insn = XVECEXP (pat, 0, i);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
set_block_for_insn (insn, bb);
|
2000-08-04 22:28:08 +02:00
|
|
|
|
if (INSN_P (insn))
|
1999-03-21 21:49:10 +01:00
|
|
|
|
add_label_notes (PATTERN (insn), new_insn);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-10-27 21:27:41 +02:00
|
|
|
|
note_stores (PATTERN (insn), record_set_info, insn);
|
1999-03-21 21:49:10 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
add_label_notes (SET_SRC (pat), new_insn);
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
set_block_for_new_insns (new_insn, bb);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
/* Keep register set table up to date. */
|
|
|
|
|
record_one_set (regno, new_insn);
|
|
|
|
|
}
|
1998-10-07 12:08:16 +02:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
gcse_create_count++;
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, "PRE/HOIST: end of bb %d, insn %d, ",
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
bb->index, INSN_UID (new_insn));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, "copying expression %d to reg %d\n",
|
|
|
|
|
expr->bitmap_index, regno);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
/* Insert partially redundant expressions on edges in the CFG to make
|
|
|
|
|
the expressions fully redundant. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
static int
|
|
|
|
|
pre_edge_insert (edge_list, index_map)
|
|
|
|
|
struct edge_list *edge_list;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
struct expr **index_map;
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
int e, i, j, num_edges, set_size, did_insert = 0;
|
1999-03-21 21:49:10 +01:00
|
|
|
|
sbitmap *inserted;
|
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
/* Where PRE_INSERT_MAP is nonzero, we add the expression on that edge
|
|
|
|
|
if it reaches any of the deleted expressions. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
set_size = pre_insert_map[0]->size;
|
|
|
|
|
num_edges = NUM_EDGES (edge_list);
|
|
|
|
|
inserted = sbitmap_vector_alloc (num_edges, n_exprs);
|
|
|
|
|
sbitmap_vector_zero (inserted, num_edges);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
for (e = 0; e < num_edges; e++)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
|
|
|
|
int indx;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb = INDEX_EDGE_PRED_BB (edge_list, e);
|
1999-03-21 21:49:10 +01:00
|
|
|
|
|
|
|
|
|
for (i = indx = 0; i < set_size; i++, indx += SBITMAP_ELT_BITS)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
{
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
SBITMAP_ELT_TYPE insert = pre_insert_map[e]->elms[i];
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-03-21 21:49:10 +01:00
|
|
|
|
for (j = indx; insert && j < n_exprs; j++, insert >>= 1)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if ((insert & 1) != 0 && index_map[j]->reaching_reg != NULL_RTX)
|
|
|
|
|
{
|
|
|
|
|
struct expr *expr = index_map[j];
|
|
|
|
|
struct occr *occr;
|
1999-03-21 21:49:10 +01:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Now look at each deleted occurence of this expression. */
|
|
|
|
|
for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
|
|
|
|
|
{
|
|
|
|
|
if (! occr->deleted_p)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Insert this expression on this edge if if it would
|
|
|
|
|
reach the deleted occurence in BB. */
|
|
|
|
|
if (!TEST_BIT (inserted[e], j))
|
|
|
|
|
{
|
|
|
|
|
rtx insn;
|
|
|
|
|
edge eg = INDEX_EDGE (edge_list, e);
|
|
|
|
|
|
|
|
|
|
/* We can't insert anything on an abnormal and
|
|
|
|
|
critical edge, so we insert the insn at the end of
|
|
|
|
|
the previous block. There are several alternatives
|
|
|
|
|
detailed in Morgans book P277 (sec 10.5) for
|
|
|
|
|
handling this situation. This one is easiest for
|
|
|
|
|
now. */
|
|
|
|
|
|
|
|
|
|
if ((eg->flags & EDGE_ABNORMAL) == EDGE_ABNORMAL)
|
|
|
|
|
insert_insn_end_bb (index_map[j], bb, 0);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
insn = process_insert_insn (index_map[j]);
|
|
|
|
|
insert_insn_on_edge (insn, eg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file, "PRE/HOIST: edge (%d,%d), ",
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
bb->index,
|
2000-02-29 21:08:52 +01:00
|
|
|
|
INDEX_EDGE_SUCC_BB (edge_list, e)->index);
|
|
|
|
|
fprintf (gcse_file, "copy expression %d\n",
|
|
|
|
|
expr->bitmap_index);
|
|
|
|
|
}
|
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
update_ld_motion_stores (expr);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
SET_BIT (inserted[e], j);
|
|
|
|
|
did_insert = 1;
|
|
|
|
|
gcse_create_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-10-29 11:49:23 +02:00
|
|
|
|
|
|
|
|
|
free (inserted);
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
return did_insert;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Copy the result of INSN to REG. INDX is the expression number. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
pre_insert_copy_insn (expr, insn)
|
|
|
|
|
struct expr *expr;
|
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
|
|
|
|
rtx reg = expr->reaching_reg;
|
|
|
|
|
int regno = REGNO (reg);
|
|
|
|
|
int indx = expr->bitmap_index;
|
|
|
|
|
rtx set = single_set (insn);
|
|
|
|
|
rtx new_insn;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb = BLOCK_FOR_INSN (insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
if (!set)
|
|
|
|
|
abort ();
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-06-24 16:49:51 +02:00
|
|
|
|
new_insn = emit_insn_after (gen_rtx_SET (VOIDmode, reg, SET_DEST (set)),
|
1998-05-20 02:24:32 +02:00
|
|
|
|
insn);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Keep block number table up to date. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
set_block_for_new_insns (new_insn, bb);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* Keep register set table up to date. */
|
|
|
|
|
record_one_set (regno, new_insn);
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (insn == bb->end)
|
|
|
|
|
bb->end = new_insn;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
gcse_create_count++;
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
fprintf (gcse_file,
|
|
|
|
|
"PRE: bb %d, insn %d, copy expression %d in insn %d to reg %d\n",
|
|
|
|
|
BLOCK_NUM (insn), INSN_UID (new_insn), indx,
|
|
|
|
|
INSN_UID (insn), regno);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy available expressions that reach the redundant expression
|
|
|
|
|
to `reaching_reg'. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
pre_insert_copies ()
|
|
|
|
|
{
|
2000-04-10 13:33:18 +02:00
|
|
|
|
unsigned int i;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct expr *expr;
|
|
|
|
|
struct occr *occr;
|
|
|
|
|
struct occr *avail;
|
1999-03-21 21:49:10 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* For each available expression in the table, copy the result to
|
|
|
|
|
`reaching_reg' if the expression reaches a deleted one.
|
|
|
|
|
|
|
|
|
|
??? The current algorithm is rather brute force.
|
|
|
|
|
Need to do some profiling. */
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < expr_hash_table_size; i++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (expr = expr_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
|
|
|
|
|
{
|
|
|
|
|
/* If the basic block isn't reachable, PPOUT will be TRUE. However,
|
|
|
|
|
we don't want to insert a copy here because the expression may not
|
|
|
|
|
really be redundant. So only insert an insn if the expression was
|
|
|
|
|
deleted. This test also avoids further processing if the
|
|
|
|
|
expression wasn't deleted anywhere. */
|
|
|
|
|
if (expr->reaching_reg == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
|
|
|
|
|
{
|
|
|
|
|
if (! occr->deleted_p)
|
|
|
|
|
continue;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (avail = expr->avail_occr; avail != NULL; avail = avail->next)
|
|
|
|
|
{
|
|
|
|
|
rtx insn = avail->insn;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* No need to handle this one if handled already. */
|
|
|
|
|
if (avail->copied_p)
|
|
|
|
|
continue;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Don't handle this one if it's a redundant one. */
|
|
|
|
|
if (TEST_BIT (pre_redundant_insns, INSN_CUID (insn)))
|
|
|
|
|
continue;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Or if the expression doesn't reach the deleted one. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (! pre_expr_reaches_here_p (BLOCK_FOR_INSN (avail->insn),
|
|
|
|
|
expr,
|
|
|
|
|
BLOCK_FOR_INSN (occr->insn)))
|
2000-02-29 21:08:52 +01:00
|
|
|
|
continue;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* Copy the result of avail to reaching_reg. */
|
|
|
|
|
pre_insert_copy_insn (expr, insn);
|
|
|
|
|
avail->copied_p = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Delete redundant computations.
|
|
|
|
|
Deletion is done by changing the insn to copy the `reaching_reg' of
|
|
|
|
|
the expression into the result of the SET. It is left to later passes
|
|
|
|
|
(cprop, cse2, flow, combine, regmove) to propagate the copy or eliminate it.
|
|
|
|
|
|
|
|
|
|
Returns non-zero if a change is made. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
pre_delete ()
|
|
|
|
|
{
|
2000-04-10 13:33:18 +02:00
|
|
|
|
unsigned int i;
|
2000-07-28 18:08:54 +02:00
|
|
|
|
int changed;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct expr *expr;
|
|
|
|
|
struct occr *occr;
|
1999-03-21 21:49:10 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
changed = 0;
|
|
|
|
|
for (i = 0; i < expr_hash_table_size; i++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (expr = expr_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
|
|
|
|
|
{
|
|
|
|
|
int indx = expr->bitmap_index;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* We only need to search antic_occr since we require
|
|
|
|
|
ANTLOC != 0. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
|
|
|
|
|
{
|
|
|
|
|
rtx insn = occr->insn;
|
|
|
|
|
rtx set;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb = BLOCK_FOR_INSN (insn);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (TEST_BIT (pre_delete_map[bb->index], indx))
|
2000-02-29 21:08:52 +01:00
|
|
|
|
{
|
|
|
|
|
set = single_set (insn);
|
|
|
|
|
if (! set)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
/* Create a pseudo-reg to store the result of reaching
|
|
|
|
|
expressions into. Get the mode for the new pseudo from
|
|
|
|
|
the mode of the original destination pseudo. */
|
|
|
|
|
if (expr->reaching_reg == NULL)
|
|
|
|
|
expr->reaching_reg
|
|
|
|
|
= gen_reg_rtx (GET_MODE (SET_DEST (set)));
|
|
|
|
|
|
|
|
|
|
/* In theory this should never fail since we're creating
|
|
|
|
|
a reg->reg copy.
|
|
|
|
|
|
|
|
|
|
However, on the x86 some of the movXX patterns actually
|
|
|
|
|
contain clobbers of scratch regs. This may cause the
|
|
|
|
|
insn created by validate_change to not match any pattern
|
|
|
|
|
and thus cause validate_change to fail. */
|
|
|
|
|
if (validate_change (insn, &SET_SRC (set),
|
|
|
|
|
expr->reaching_reg, 0))
|
|
|
|
|
{
|
|
|
|
|
occr->deleted_p = 1;
|
|
|
|
|
SET_BIT (pre_redundant_insns, INSN_CUID (insn));
|
|
|
|
|
changed = 1;
|
|
|
|
|
gcse_subst_count++;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file,
|
|
|
|
|
"PRE: redundant insn %d (expression %d) in ",
|
|
|
|
|
INSN_UID (insn), indx);
|
|
|
|
|
fprintf (gcse_file, "bb %d, reaching reg is %d\n",
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
bb->index, REGNO (expr->reaching_reg));
|
2000-02-29 21:08:52 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Perform GCSE optimizations using PRE.
|
|
|
|
|
This is called by one_pre_gcse_pass after all the dataflow analysis
|
|
|
|
|
has been done.
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
This is based on the original Morel-Renvoise paper Fred Chow's thesis, and
|
|
|
|
|
lazy code motion from Knoop, Ruthing and Steffen as described in Advanced
|
|
|
|
|
Compiler Design and Implementation.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
??? A new pseudo reg is created to hold the reaching expression. The nice
|
|
|
|
|
thing about the classical approach is that it would try to use an existing
|
|
|
|
|
reg. If the register can't be adequately optimized [i.e. we introduce
|
|
|
|
|
reload problems], one could add a pass here to propagate the new register
|
|
|
|
|
through the block.
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
??? We don't handle single sets in PARALLELs because we're [currently] not
|
|
|
|
|
able to copy the rest of the parallel when we insert copies to create full
|
|
|
|
|
redundancies from partial redundancies. However, there's no reason why we
|
|
|
|
|
can't handle PARALLELs in the cases where there are no partial
|
1998-05-20 02:24:32 +02:00
|
|
|
|
redundancies. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
pre_gcse ()
|
|
|
|
|
{
|
2000-04-10 13:33:18 +02:00
|
|
|
|
unsigned int i;
|
|
|
|
|
int did_insert, changed;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
struct expr **index_map;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct expr *expr;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Compute a mapping from expression number (`bitmap_index') to
|
|
|
|
|
hash table entry. */
|
|
|
|
|
|
2000-01-05 07:55:02 +01:00
|
|
|
|
index_map = (struct expr **) xcalloc (n_exprs, sizeof (struct expr *));
|
1998-05-20 02:24:32 +02:00
|
|
|
|
for (i = 0; i < expr_hash_table_size; i++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (expr = expr_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
|
|
|
|
|
index_map[expr->bitmap_index] = expr;
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Reset bitmap used to track which insns are redundant. */
|
1999-03-21 21:49:10 +01:00
|
|
|
|
pre_redundant_insns = sbitmap_alloc (max_cuid);
|
|
|
|
|
sbitmap_zero (pre_redundant_insns);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
|
|
|
|
/* Delete the redundant insns first so that
|
|
|
|
|
- we know what register to use for the new insns and for the other
|
|
|
|
|
ones with reaching expressions
|
|
|
|
|
- we know which insns are redundant when we go to create copies */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
changed = pre_delete ();
|
|
|
|
|
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
did_insert = pre_edge_insert (edge_list, index_map);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
/* In other places with reaching expressions, copy the expression to the
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
specially allocated pseudo-reg that reaches the redundant expr. */
|
1998-05-20 02:24:32 +02:00
|
|
|
|
pre_insert_copies ();
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
if (did_insert)
|
|
|
|
|
{
|
|
|
|
|
commit_edge_insertions ();
|
|
|
|
|
changed = 1;
|
|
|
|
|
}
|
1998-05-20 02:24:32 +02:00
|
|
|
|
|
1999-10-27 07:16:12 +02:00
|
|
|
|
free (index_map);
|
1999-03-21 21:49:10 +01:00
|
|
|
|
free (pre_redundant_insns);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Top level routine to perform one PRE GCSE pass.
|
|
|
|
|
|
|
|
|
|
Return non-zero if a change was made. */
|
|
|
|
|
|
|
|
|
|
static int
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
one_pre_gcse_pass (pass)
|
1998-05-20 02:24:32 +02:00
|
|
|
|
int pass;
|
|
|
|
|
{
|
|
|
|
|
int changed = 0;
|
|
|
|
|
|
|
|
|
|
gcse_subst_count = 0;
|
|
|
|
|
gcse_create_count = 0;
|
|
|
|
|
|
|
|
|
|
alloc_expr_hash_table (max_cuid);
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
add_noreturn_fake_exit_edges ();
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
if (flag_gcse_lm)
|
|
|
|
|
compute_ld_motion_mems ();
|
|
|
|
|
|
gcse.c: More comments, whitespace and similar fixes.
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
From-SVN: r25677
1999-03-10 22:29:44 +01:00
|
|
|
|
compute_expr_hash_table ();
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
trim_ld_motion_mems ();
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (gcse_file)
|
|
|
|
|
dump_hash_table (gcse_file, "Expression", expr_hash_table,
|
|
|
|
|
expr_hash_table_size, n_exprs);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-05-20 02:24:32 +02:00
|
|
|
|
if (n_exprs > 0)
|
|
|
|
|
{
|
|
|
|
|
alloc_pre_mem (n_basic_blocks, n_exprs);
|
|
|
|
|
compute_pre_data ();
|
|
|
|
|
changed |= pre_gcse ();
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
free_edge_list (edge_list);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
free_pre_mem ();
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
free_ldst_mems ();
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
remove_fake_edges ();
|
1998-05-20 02:24:32 +02:00
|
|
|
|
free_expr_hash_table ();
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
2000-02-29 21:08:52 +01:00
|
|
|
|
fprintf (gcse_file, "\nPRE GCSE of %s, pass %d: %d bytes needed, ",
|
|
|
|
|
current_function_name, pass, bytes_used);
|
|
|
|
|
fprintf (gcse_file, "%d substs, %d insns created\n",
|
|
|
|
|
gcse_subst_count, gcse_create_count);
|
1998-05-20 02:24:32 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
1998-06-22 14:02:52 +02:00
|
|
|
|
|
|
|
|
|
/* If X contains any LABEL_REF's, add REG_LABEL notes for them to INSN.
|
2001-01-02 01:58:27 +01:00
|
|
|
|
If notes are added to an insn which references a CODE_LABEL, the
|
|
|
|
|
LABEL_NUSES count is incremented. We have to add REG_LABEL notes,
|
|
|
|
|
because the following loop optimization pass requires them. */
|
1998-06-22 14:02:52 +02:00
|
|
|
|
|
|
|
|
|
/* ??? This is very similar to the loop.c add_label_notes function. We
|
|
|
|
|
could probably share code here. */
|
|
|
|
|
|
|
|
|
|
/* ??? If there was a jump optimization pass after gcse and before loop,
|
|
|
|
|
then we would not need to do this here, because jump would add the
|
|
|
|
|
necessary REG_LABEL notes. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
add_label_notes (x, insn)
|
|
|
|
|
rtx x;
|
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
|
|
|
|
enum rtx_code code = GET_CODE (x);
|
|
|
|
|
int i, j;
|
rtl.h (rtx_format): Constify a char*.
* rtl.h (rtx_format): Constify a char*.
* rtl.c (rtx_format): Likewise.
(copy_rtx, copy_most_rtx, read_rtx): Likewise.
(init_rtl): Use accessor macro, not `rtx_format'.
* alias.c (rtx_equal_for_memref_p, find_symbolic_term): Constify a
char*.
* caller-save.c (mark_referenced_regs): Likewise.
* combine.c (subst, make_compound_operation, known_cond,
gen_rtx_combine, update_table_tick, get_last_value_validate,
use_crosses_set_p, mark_used_regs_combine, move_deaths): Likewise.
* cse.c (rtx_cost, mention_regs, canon_hash, exp_equiv_p,
refers_to_p, canon_reg, fold_rtx, cse_process_notes,
count_reg_usage): Likewise.
* emit-rtl.c (gen_rtx, copy_rtx_if_shared, reset_used_flags):
Likewise.
* final.c (leaf_renumber_regs_insn): Likewise.
* flow.c (mark_used_regs, find_use_as_address, dump_flow_info,
dump_edge_info, count_reg_references): Likewise.
* function.c (fixup_var_refs_1, walk_fixup_memory_subreg,
fixup_stack_1, purge_addressof_1, instantiate_virtual_regs_1):
Likewise.
* gcse.c (oprs_unchanged_p, hash_expr_1, expr_equiv_p,
oprs_not_set_p, expr_killed_p, compute_transp, find_used_regs,
add_label_notes): Likewise.
* genattrtab.c (attr_rtx, attr_copy_rtx, encode_units_mask,
clear_struct_flag, count_sub_rtxs, count_alternatives,
compares_alternatives_p, contained_in_p, walk_attr_value,
write_expr_attr_cache): Likewise.
* genconfig.c (walk_insn_part): Likewise.
* genemit.c (max_operand_1, gen_exp): Likewise.
* genextract.c (walk_rtx): Likewise.
* genflags.c (num_operands): Likewise.
* genoutput.c (scan_operands): Likewise.
* genpeep.c (match_rtx): Likewise.
* genrecog.c (add_to_sequence): Likewise.
* haifa-sched.c (may_trap_exp, sched_analyze_2, attach_deaths):
Likewise.
* integrate.c (save_constants, copy_for_inline,
copy_rtx_and_substitute, subst_constants, restore_constants):
Likewise.
* jump.c (mark_jump_label, invert_exp, redirect_exp,
rtx_renumbered_equal_p, rtx_equal_for_thread_p): Likewise.
* local-alloc.c (contains_replace_regs, memref_referenced_p):
Likewise.
* loop.c (record_excess_regs, rtx_equal_for_loop_p,
add_label_notes, replace_call_address, count_nonfixed_reads,
invariant_p, find_single_use_in_loop, find_mem_givs,
find_life_end, maybe_eliminate_biv_1, update_reg_last_use):
Likewise.
* print-rtl.c (reg_names, print_rtx): Likewise.
* recog.c (validate_replace_rtx_1, find_single_use_1): Likewise.
* reg-stack.c (stack_regs_mentioned_p, record_label_references,
record_reg_life_pat, swap_rtx_condition, goto_block_pat,
print_blocks): Likewise.
* regclass.c (fix_register, record_address_regs,
reg_scan_mark_refs): Likewise.
* regmove.c (stable_but_for_p): Likewise.
* reload.c (loc_mentioned_in_p, operands_match_p,
find_reloads_toplevsubst_reg_equivs, find_reloads_address_1,
copy_replacements, refers_to_regno_for_reload_p,
refers_to_mem_for_reload_p, find_inc_amount, regno_clobbered_p,
reload_when_needed_name, reg_class_names, debug_reload_to_stream):
Likewise.
* reload1.c (eliminate_regs, scan_paradoxical_subregs,
delete_address_reloads_1, count_occurrences,
reload_cse_mem_conflict_p, reload_combine_note_use,
add_auto_inc_notes): Likewise.
* resource.c (mark_referenced_resources, mark_set_resources):
Likewise.
* rtlanal.c (rtx_unstable_p, rtx_varies_p, rtx_addr_varies_p,
reg_mentioned_p, regs_set_between_p, modified_between_p,
modified_in_p, refers_to_regno_p, reg_overlap_mentioned_p,
rtx_equal_p, volatile_insn_p, volatile_refs_p, side_effects_p,
may_trap_p, inequality_comparisons_p, replace_rtx, replace_regs,
jmp_uses_reg_or_mem, for_each_rtx, regno_use_in): Likewise.
* sched.c (sched_analyze_2, attach_deaths): Likewise.
* stupid.c (stupid_mark_refs): Likewise.
* unroll.c (remap_split_bivs): Likewise.
* varasm.c (mark_constants): Likewise.
* a29k/a29k.c (uses_local_reg_p): Likewise.
* alpha/alpha.c (summarize_insn): Likewise.
* arm/arm.c (symbol_mentioned_p, label_mentioned_p,
eliminate_lr2ip): Likewise.
* arm/thumb.c (symbol_mentioned_p, label_mentioned_p): Likewise.
* i386/i386.c (symbolic_reference_mentioned_p, copy_all_rtx,
reg_mentioned_in_mem): Likewise.
* ns32k/ns32k.c (global_symbolic_reference_mentioned_p,
symbolic_reference_mentioned_p): Likewise.
* romp/romp.c (unsigned_comparisons_p, hash_rtx): Likewise.
* sh/sh.c (regs_used, mark_use): Likewise.
* vax/vax.c (vax_rtx_cost): Likewise.
From-SVN: r28784
1999-08-21 01:05:25 +02:00
|
|
|
|
const char *fmt;
|
1998-06-22 14:02:52 +02:00
|
|
|
|
|
|
|
|
|
if (code == LABEL_REF && !LABEL_REF_NONLOCAL_P (x))
|
|
|
|
|
{
|
1998-08-15 02:33:57 +02:00
|
|
|
|
/* This code used to ignore labels that referred to dispatch tables to
|
1999-03-10 21:18:59 +01:00
|
|
|
|
avoid flow generating (slighly) worse code.
|
1998-08-15 02:33:57 +02:00
|
|
|
|
|
1999-03-10 21:18:59 +01:00
|
|
|
|
We no longer ignore such label references (see LABEL_REF handling in
|
|
|
|
|
mark_jump_label for additional information). */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1998-08-15 02:33:57 +02:00
|
|
|
|
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL, XEXP (x, 0),
|
|
|
|
|
REG_NOTES (insn));
|
2001-01-02 01:58:27 +01:00
|
|
|
|
if (LABEL_P (XEXP (x, 0)))
|
|
|
|
|
LABEL_NUSES (XEXP (x, 0))++;
|
1998-06-22 14:02:52 +02:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
|
1998-06-22 14:02:52 +02:00
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
add_label_notes (XEXP (x, i), insn);
|
|
|
|
|
else if (fmt[i] == 'E')
|
|
|
|
|
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
|
|
|
|
|
add_label_notes (XVECEXP (x, i, j), insn);
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-03-21 21:49:10 +01:00
|
|
|
|
|
|
|
|
|
/* Compute transparent outgoing information for each block.
|
|
|
|
|
|
|
|
|
|
An expression is transparent to an edge unless it is killed by
|
|
|
|
|
the edge itself. This can only happen with abnormal control flow,
|
|
|
|
|
when the edge is traversed through a call. This happens with
|
|
|
|
|
non-local labels and exceptions.
|
|
|
|
|
|
|
|
|
|
This would not be necessary if we split the edge. While this is
|
|
|
|
|
normally impossible for abnormal critical edges, with some effort
|
|
|
|
|
it should be possible with exception handling, since we still have
|
|
|
|
|
control over which handler should be invoked. But due to increased
|
|
|
|
|
EH table sizes, this may not be worthwhile. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_transpout ()
|
|
|
|
|
{
|
|
|
|
|
int bb;
|
2000-04-10 13:33:18 +02:00
|
|
|
|
unsigned int i;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct expr *expr;
|
1999-03-21 21:49:10 +01:00
|
|
|
|
|
|
|
|
|
sbitmap_vector_ones (transpout, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; ++bb)
|
|
|
|
|
{
|
|
|
|
|
/* Note that flow inserted a nop a the end of basic blocks that
|
|
|
|
|
end in call instructions for reasons other than abnormal
|
|
|
|
|
control flow. */
|
|
|
|
|
if (GET_CODE (BLOCK_END (bb)) != CALL_INSN)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < expr_hash_table_size; i++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (expr = expr_hash_table[i]; expr ; expr = expr->next_same_hash)
|
|
|
|
|
if (GET_CODE (expr->expr) == MEM)
|
|
|
|
|
{
|
|
|
|
|
if (GET_CODE (XEXP (expr->expr, 0)) == SYMBOL_REF
|
|
|
|
|
&& CONSTANT_POOL_ADDRESS_P (XEXP (expr->expr, 0)))
|
|
|
|
|
continue;
|
1999-03-21 21:49:10 +01:00
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
/* ??? Optimally, we would use interprocedural alias
|
|
|
|
|
analysis to determine if this mem is actually killed
|
|
|
|
|
by this call. */
|
|
|
|
|
RESET_BIT (transpout[bb], expr->bitmap_index);
|
|
|
|
|
}
|
1999-03-21 21:49:10 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-09-20 15:58:33 +02:00
|
|
|
|
|
|
|
|
|
/* Removal of useless null pointer checks */
|
|
|
|
|
|
|
|
|
|
/* Called via note_stores. X is set by SETTER. If X is a register we must
|
1999-11-03 23:45:45 +01:00
|
|
|
|
invalidate nonnull_local and set nonnull_killed. DATA is really a
|
|
|
|
|
`null_pointer_info *'.
|
1999-09-20 15:58:33 +02:00
|
|
|
|
|
|
|
|
|
We ignore hard registers. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 15:58:33 +02:00
|
|
|
|
static void
|
1999-10-27 21:27:41 +02:00
|
|
|
|
invalidate_nonnull_info (x, setter, data)
|
1999-09-20 15:58:33 +02:00
|
|
|
|
rtx x;
|
|
|
|
|
rtx setter ATTRIBUTE_UNUSED;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
void *data;
|
1999-09-20 15:58:33 +02:00
|
|
|
|
{
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int regno;
|
|
|
|
|
struct null_pointer_info *npi = (struct null_pointer_info *) data;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 15:58:33 +02:00
|
|
|
|
while (GET_CODE (x) == SUBREG)
|
|
|
|
|
x = SUBREG_REG (x);
|
|
|
|
|
|
|
|
|
|
/* Ignore anything that is not a register or is a hard register. */
|
|
|
|
|
if (GET_CODE (x) != REG
|
1999-11-03 23:45:45 +01:00
|
|
|
|
|| REGNO (x) < npi->min_reg
|
|
|
|
|
|| REGNO (x) >= npi->max_reg)
|
1999-09-20 15:58:33 +02:00
|
|
|
|
return;
|
|
|
|
|
|
1999-11-03 23:45:45 +01:00
|
|
|
|
regno = REGNO (x) - npi->min_reg;
|
1999-09-20 15:58:33 +02:00
|
|
|
|
|
1999-11-03 23:45:45 +01:00
|
|
|
|
RESET_BIT (npi->nonnull_local[npi->current_block], regno);
|
|
|
|
|
SET_BIT (npi->nonnull_killed[npi->current_block], regno);
|
1999-09-20 15:58:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-11-03 23:45:45 +01:00
|
|
|
|
/* Do null-pointer check elimination for the registers indicated in
|
|
|
|
|
NPI. NONNULL_AVIN and NONNULL_AVOUT are pre-allocated sbitmaps;
|
|
|
|
|
they are not our responsibility to free. */
|
1999-09-20 15:58:33 +02:00
|
|
|
|
|
1999-11-03 23:45:45 +01:00
|
|
|
|
static void
|
2001-04-04 22:19:23 +02:00
|
|
|
|
delete_null_pointer_checks_1 (delete_list, block_reg, nonnull_avin,
|
|
|
|
|
nonnull_avout, npi)
|
|
|
|
|
varray_type *delete_list;
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int *block_reg;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
sbitmap *nonnull_avin;
|
|
|
|
|
sbitmap *nonnull_avout;
|
|
|
|
|
struct null_pointer_info *npi;
|
1999-09-20 15:58:33 +02:00
|
|
|
|
{
|
1999-11-11 10:21:12 +01:00
|
|
|
|
int bb;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
int current_block;
|
|
|
|
|
sbitmap *nonnull_local = npi->nonnull_local;
|
|
|
|
|
sbitmap *nonnull_killed = npi->nonnull_killed;
|
1999-09-20 15:58:33 +02:00
|
|
|
|
|
|
|
|
|
/* Compute local properties, nonnull and killed. A register will have
|
|
|
|
|
the nonnull property if at the end of the current block its value is
|
|
|
|
|
known to be nonnull. The killed property indicates that somewhere in
|
|
|
|
|
the block any information we had about the register is killed.
|
|
|
|
|
|
|
|
|
|
Note that a register can have both properties in a single block. That
|
|
|
|
|
indicates that it's killed, then later in the block a new value is
|
|
|
|
|
computed. */
|
|
|
|
|
sbitmap_vector_zero (nonnull_local, n_basic_blocks);
|
|
|
|
|
sbitmap_vector_zero (nonnull_killed, n_basic_blocks);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 15:58:33 +02:00
|
|
|
|
for (current_block = 0; current_block < n_basic_blocks; current_block++)
|
|
|
|
|
{
|
|
|
|
|
rtx insn, stop_insn;
|
|
|
|
|
|
1999-11-03 23:45:45 +01:00
|
|
|
|
/* Set the current block for invalidate_nonnull_info. */
|
|
|
|
|
npi->current_block = current_block;
|
|
|
|
|
|
1999-09-20 15:58:33 +02:00
|
|
|
|
/* Scan each insn in the basic block looking for memory references and
|
|
|
|
|
register sets. */
|
|
|
|
|
stop_insn = NEXT_INSN (BLOCK_END (current_block));
|
|
|
|
|
for (insn = BLOCK_HEAD (current_block);
|
|
|
|
|
insn != stop_insn;
|
|
|
|
|
insn = NEXT_INSN (insn))
|
|
|
|
|
{
|
|
|
|
|
rtx set;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
rtx reg;
|
1999-09-20 15:58:33 +02:00
|
|
|
|
|
|
|
|
|
/* Ignore anything that is not a normal insn. */
|
2000-08-04 22:28:08 +02:00
|
|
|
|
if (! INSN_P (insn))
|
1999-09-20 15:58:33 +02:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Basically ignore anything that is not a simple SET. We do have
|
|
|
|
|
to make sure to invalidate nonnull_local and set nonnull_killed
|
|
|
|
|
for such insns though. */
|
|
|
|
|
set = single_set (insn);
|
|
|
|
|
if (!set)
|
|
|
|
|
{
|
1999-11-03 23:45:45 +01:00
|
|
|
|
note_stores (PATTERN (insn), invalidate_nonnull_info, npi);
|
1999-09-20 15:58:33 +02:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* See if we've got a useable memory load. We handle it first
|
|
|
|
|
in case it uses its address register as a dest (which kills
|
|
|
|
|
the nonnull property). */
|
|
|
|
|
if (GET_CODE (SET_SRC (set)) == MEM
|
1999-11-03 23:45:45 +01:00
|
|
|
|
&& GET_CODE ((reg = XEXP (SET_SRC (set), 0))) == REG
|
|
|
|
|
&& REGNO (reg) >= npi->min_reg
|
|
|
|
|
&& REGNO (reg) < npi->max_reg)
|
1999-09-20 15:58:33 +02:00
|
|
|
|
SET_BIT (nonnull_local[current_block],
|
1999-11-03 23:45:45 +01:00
|
|
|
|
REGNO (reg) - npi->min_reg);
|
1999-09-20 15:58:33 +02:00
|
|
|
|
|
|
|
|
|
/* Now invalidate stuff clobbered by this insn. */
|
1999-11-03 23:45:45 +01:00
|
|
|
|
note_stores (PATTERN (insn), invalidate_nonnull_info, npi);
|
1999-09-20 15:58:33 +02:00
|
|
|
|
|
|
|
|
|
/* And handle stores, we do these last since any sets in INSN can
|
|
|
|
|
not kill the nonnull property if it is derived from a MEM
|
|
|
|
|
appearing in a SET_DEST. */
|
|
|
|
|
if (GET_CODE (SET_DEST (set)) == MEM
|
1999-11-03 23:45:45 +01:00
|
|
|
|
&& GET_CODE ((reg = XEXP (SET_DEST (set), 0))) == REG
|
|
|
|
|
&& REGNO (reg) >= npi->min_reg
|
|
|
|
|
&& REGNO (reg) < npi->max_reg)
|
1999-09-20 15:58:33 +02:00
|
|
|
|
SET_BIT (nonnull_local[current_block],
|
1999-11-03 23:45:45 +01:00
|
|
|
|
REGNO (reg) - npi->min_reg);
|
1999-09-20 15:58:33 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now compute global properties based on the local properties. This
|
|
|
|
|
is a classic global availablity algorithm. */
|
1999-11-11 10:21:12 +01:00
|
|
|
|
compute_available (nonnull_local, nonnull_killed,
|
|
|
|
|
nonnull_avout, nonnull_avin);
|
1999-09-20 15:58:33 +02:00
|
|
|
|
|
|
|
|
|
/* Now look at each bb and see if it ends with a compare of a value
|
|
|
|
|
against zero. */
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
{
|
|
|
|
|
rtx last_insn = BLOCK_END (bb);
|
1999-11-03 23:45:45 +01:00
|
|
|
|
rtx condition, earliest;
|
1999-09-20 15:58:33 +02:00
|
|
|
|
int compare_and_branch;
|
|
|
|
|
|
1999-11-03 23:45:45 +01:00
|
|
|
|
/* Since MIN_REG is always at least FIRST_PSEUDO_REGISTER, and
|
|
|
|
|
since BLOCK_REG[BB] is zero if this block did not end with a
|
|
|
|
|
comparison against zero, this condition works. */
|
|
|
|
|
if (block_reg[bb] < npi->min_reg
|
|
|
|
|
|| block_reg[bb] >= npi->max_reg)
|
1999-09-20 15:58:33 +02:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* LAST_INSN is a conditional jump. Get its condition. */
|
|
|
|
|
condition = get_condition (last_insn, &earliest);
|
|
|
|
|
|
2000-01-12 11:16:04 +01:00
|
|
|
|
/* If we can't determine the condition then skip. */
|
|
|
|
|
if (! condition)
|
|
|
|
|
continue;
|
|
|
|
|
|
1999-09-20 15:58:33 +02:00
|
|
|
|
/* Is the register known to have a nonzero value? */
|
1999-11-03 23:45:45 +01:00
|
|
|
|
if (!TEST_BIT (nonnull_avout[bb], block_reg[bb] - npi->min_reg))
|
1999-09-20 15:58:33 +02:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Try to compute whether the compare/branch at the loop end is one or
|
|
|
|
|
two instructions. */
|
|
|
|
|
if (earliest == last_insn)
|
|
|
|
|
compare_and_branch = 1;
|
|
|
|
|
else if (earliest == prev_nonnote_insn (last_insn))
|
|
|
|
|
compare_and_branch = 2;
|
|
|
|
|
else
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* We know the register in this comparison is nonnull at exit from
|
|
|
|
|
this block. We can optimize this comparison. */
|
|
|
|
|
if (GET_CODE (condition) == NE)
|
|
|
|
|
{
|
|
|
|
|
rtx new_jump;
|
|
|
|
|
|
|
|
|
|
new_jump = emit_jump_insn_before (gen_jump (JUMP_LABEL (last_insn)),
|
|
|
|
|
last_insn);
|
|
|
|
|
JUMP_LABEL (new_jump) = JUMP_LABEL (last_insn);
|
|
|
|
|
LABEL_NUSES (JUMP_LABEL (new_jump))++;
|
|
|
|
|
emit_barrier_after (new_jump);
|
|
|
|
|
}
|
2001-04-04 22:19:23 +02:00
|
|
|
|
if (!*delete_list)
|
|
|
|
|
VARRAY_RTX_INIT (*delete_list, 10, "delete_list");
|
|
|
|
|
|
|
|
|
|
VARRAY_PUSH_RTX (*delete_list, last_insn);
|
1999-09-20 15:58:33 +02:00
|
|
|
|
if (compare_and_branch == 2)
|
2001-04-04 22:19:23 +02:00
|
|
|
|
VARRAY_PUSH_RTX (*delete_list, earliest);
|
1999-11-03 23:45:45 +01:00
|
|
|
|
|
|
|
|
|
/* Don't check this block again. (Note that BLOCK_END is
|
|
|
|
|
invalid here; we deleted the last instruction in the
|
|
|
|
|
block.) */
|
|
|
|
|
block_reg[bb] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find EQ/NE comparisons against zero which can be (indirectly) evaluated
|
|
|
|
|
at compile time.
|
|
|
|
|
|
|
|
|
|
This is conceptually similar to global constant/copy propagation and
|
|
|
|
|
classic global CSE (it even uses the same dataflow equations as cprop).
|
|
|
|
|
|
|
|
|
|
If a register is used as memory address with the form (mem (reg)), then we
|
|
|
|
|
know that REG can not be zero at that point in the program. Any instruction
|
|
|
|
|
which sets REG "kills" this property.
|
|
|
|
|
|
|
|
|
|
So, if every path leading to a conditional branch has an available memory
|
|
|
|
|
reference of that form, then we know the register can not have the value
|
|
|
|
|
zero at the conditional branch.
|
|
|
|
|
|
|
|
|
|
So we merely need to compute the local properies and propagate that data
|
|
|
|
|
around the cfg, then optimize where possible.
|
|
|
|
|
|
|
|
|
|
We run this pass two times. Once before CSE, then again after CSE. This
|
|
|
|
|
has proven to be the most profitable approach. It is rare for new
|
|
|
|
|
optimization opportunities of this nature to appear after the first CSE
|
|
|
|
|
pass.
|
|
|
|
|
|
|
|
|
|
This could probably be integrated with global cprop with a little work. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
delete_null_pointer_checks (f)
|
2000-04-10 13:33:18 +02:00
|
|
|
|
rtx f ATTRIBUTE_UNUSED;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
{
|
|
|
|
|
sbitmap *nonnull_avin, *nonnull_avout;
|
* Rework fields used to describe positions of bitfields and
modify sizes to be unsigned and use HOST_WIDE_INT.
* alias.c (reg_known_value_size): Now unsigned.
* c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
(really_start_incremental_init): Use bitsize_zero_node.
(push_init_level, pop_init_level, output_init_element): Likewise.
Use bitsize_unit_node and bitsize_one_node.
(output_pending_init_elements, process_init_element): Likewise.
* combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
(make_extraction): Position and length HOST_WIDE_INT and unsigned
HOST_WIDE_INT, respectively.
(get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
(num_sign_bit_copies): Returns unsigned.
BITWIDTH now unsigned; rework arithmetic.
Remove recursive call from arg to MAX.
(combine_instructions, init_reg_last_arrays): NREGS now unsigned.
(setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
REGNO now unsigned.
(set_nonzero_bit_and_sign_copies): NUM now unsigned.
(find_split_point, expand_compound_operation, make_extraction): LEN
now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
(make_field_assignment): Likewise.
(combine_simplify_rtx): Add cast.
(expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
(force_to_mode): WIDTH now unsigned; add cast.
(if_then_else_cond): SIZE now unsigned.
(nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
(extended_count): Now returns unsigned.
(simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
(simplify_comparison): MODE_WIDTH now unsigned.
(update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
(mark_used_regs_combine): Likewise; rework arithmetic.
(record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
(record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
(record_promoted_value): REGNO now unsigned.
(get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
(get_last_value): REGNO now unsigned.
(use_crosses_set_p): REGNO and ENDREGNO now unsigned.
(reg_dead_regno, reg_dead_endregno): Now unsigned.
(remove_death): Arg REGNO now unsigned.
(move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
(reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
now unsigned.
* convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
* cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
(struct cse_reg_info): REGNO now unsigned.
(cached_regno): Now unsigned.
(REGNO_QTY_VALID_P): Add cast.
(make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
(remove_invalid_regs): Likewise.
(remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
as are variables END and I.
(get_cse_reg_info, insert): Likewise.
(mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
(canon_hash): Likewise.
(insert_regs, lookup_for_remove): REGNO now unsigned.
(invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
New variable RN.
* dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
* dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
* emit-rtl.c (subreg_realpart_p): Add cast.
(operand_subword): Arg I is now unsigned as is var PARTWORDS.
(operand_subword_force): Arg I is now unsigned.
* except.c (eh_regs): Variable I is now unsigned.
* explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
* expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
length is unsigned HOST_WIDE_INT; likewise for internal variables.
(store_split_bit_field, extract_fixed_bit_field): Likewise.
(extract_split_bit_field, store_bit_field, extract_bit_field):
Likewise.
* expr.c (store_constructor_fields, store_constructor, store_field):
Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
(expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
(do_jump): Likewise.
(move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
MAX_SIZE is now unsigned.
(emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
(emit_group_store): Likewise.
(emit_move_insn): I now unsigned.
(store_constructor): Use host_integerp, tree_low_cst, and
bitsize_unit_node.
(get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
Rework all calculations to use trees and new fields.
* expr.h (promoted_input_arg): Regno now unsigned.
(store_bit_field, extract_bit_field): Adjust types of pos and size.
(mark_seen_cases): Arg is HOST_WIDE_INT.
* flow.c (verify_wide_reg_1): REGNO now unsigned.
* fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
precisions and alignments are unsigned.
(optimize_bit_field_compare, fold_truthop): Likewise.
(int_const_binop): Adjust threshold for size_int_type_wide call.
(fold_convert): Likewise.
(size_int_type_wide): Make table larger and fix thinko that only
had half of table used.
(all_ones_mask_p, fold): Precisions are unsigned.
* function.c (put_reg_info_stack): REGNO is unsigned.
(instantiate_decl): Size is HOST_WIDE_INT.
(instantiate_virtual_regs): I is unsigned.
(assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
(promoted_input_arg): REGNO is unsigned.
* function.h (struct function): x_max_parm_reg is now unsigned.
* gcse.c (max_gcse_regno): Now unsigned.
(struct null_pointer_info): min_reg and max_reg now unsigned.
(lookup_set, next_set): REGNO arg now unsigned.
(compute_hash_table): REGNO and I now unsigned.
(handle_avail_expr): regnum_for_replacing now unsigned.
(cprop_insn): REGNO now unsigned.
(delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
* ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
* global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
* hard-reg-set.h (reg_class_size): Now unsigned.
* integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
* jump.c (mark_modified_reg): I now unsigned; add cast.
(rtx_equal_for_thread_p): Add cast.
* loop.c (max_reg_before_loop): Now unsigned.
(struct_movable): REGNO now unsigned.
(try_copy_prop): REGNO arg unsigned.
(regs_match_p): XN and YN now unsigned.
(consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
(strength_reduce): Likewise; NREGS also unsigned.
(first_increment_giv, last_increment_giv unsigned): Now unsigned.
* loop.h (struct iv_class): REGNO now unsigned.
(max_reg_before_loop, first_increment_giv, last_increment_giv):
Now unsigned.
* machmode.h (mode_size, mode_unit_size): Now unsigned.
(mode_for_size, smallest_mode_for_size): Pass size as unsigned.
* optabs.c (expand_binop): I and NWORDS now unsigned.
(expand_unop): I now unsigned.
* print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
* real.c (significand_size): Now returns unsigned.
* real.h (significand_size): Likewise.
* regclass.c (reg_class_size): Now unsigned.
(choose_hard_reg_mode): Both operands now unsigned.
(record_reg_classes): REGNO and NR now unsigned.
(reg_scan): NREGS now unsigned.
(reg_scan_update): old_max_regno now unsigned.
(reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
* reload.c (find_valid_class): BEST_SIZE now unsigned.
(find_dummy_reload): REGNO, NWORDS, and I now unsigned.
(hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
Likewise for variable R.
(refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
(find_equiv_reg): Add casts.
(regno_clobbered_p): Arg REGNO now unsigned.
* reload.h (struct reload): NREGS now unsigned.
(refers_to_regno_for_reload_p): Regno args are unsigned.
(regno_clobbered_p): Likewise.
* reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
(compute_use_by_pseudos): REGNO now unsigned.
(find_reg): I and J now unsigned, new variable K, and change loop
variables accordingly; THIS_NREGS now unsigned.
(alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
(spill_hard_reg): REGNO arg now unsigned; add casts.
(forget_old_reloads_1): REGNO, NR, and I now unsigned.
(mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
(clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
(reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
(choose_reload_regs): MAX_GROUP_SIZE now unsigned.
(emit_reload_insns): REGNO now unsigned.
(reload_cse_move2add): Add cast.
(move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
and rework loop.
* resource.c (mark_referenced_resources, mark_set_resources): New
variable R; REGNO and LAST_REGNO now unsigned.
(mark_target_live_regs): J and REGNO now unsigned.
* rtl.c (mode_size, mode_unit_size): Now unsigned.
* rtl.h (union rtunion_def): New field rtuint.
(XCUINT): New macro.
(ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
(operand_subword, operand_subword_force): Word number is unsigned.
(choose_hard_reg_mode): Operands are unsigned.
(refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
(find_regno_note, find_regno_fusage, replace_regs): Likewise.
(regno_use_in, combine_instructions, remove_death): Likewise.
(reg_scan, reg_scan_update): Likewise.
(extended_count): Return is unsigned.
* rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
(reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
(reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
(reg_reg_last_1): FIRS and LAST now unsigned.
(dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
(dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
now unsigned.
(find_regno_note, regno_use_in): Arg REGNO now unsigned.
(find_regno_fusage): Likewise; also var REGNOTE now unsigned.
(find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
(replace_regs): Arg NREGS now unsigned.
* sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
* simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
(simplify_binary_operation): Likewise.
(cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
THIS_LAST now unsigned.
(cselib_record_set): Add cast.
* ssa.c (ssa_max_reg_num): Now unsigned.
(rename_block): REGNO now unsigned.
* stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
sizes now unsigned.
(all_cases_count): Just return -1 not -2.
COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
Rework tests to use trees whenever possible.
Use host_integerp and tree_low_cst.
(mark_seen_cases): COUNT arg now HOST_WIDE_INT;
Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
(check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
* stor-layout.c (mode_for_size): SIZE arg now unsigned.
(smallest_mode_for_size): Likewise.
(layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
KNOWN_ALIGN is now an alignment, so simplify code.
Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
(start_record_layout): Renamed from new_record_layout_info.
Update to new fields.
(debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
New functions.
(place_union_field): Renamed from layout_union_field.
Update to use new fields in rli.
(place_field): Renamed from layout_field.
Major rewrite to use new fields in rli; pass alignment to layout_decl.
(finalize_record_size): Rework to use new fields in rli and handle
union.
(compute_record_mode): Rework to simplify and to use new DECL fields.
(finalize_type_size): Make rounding more consistent.
(finish_union_layout): Deleted.
(layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
(layout_type, case RECORD_TYPE): Call new function names.
(initialize_sizetypes): Set TYPE_IS_SIZETYPE.
(set_sizetype): Set TYPE_IS_SIZETYPE earlier.
(get_best_mode): UNIT is now unsigned; remove casts.
* tree.c (bit_position): Compute from new fields.
(byte_position, int_byte_position): New functions.
(print_type_hash_statistics): Cast to remove warning.
(build_range_type): Use host_integerp and tree_low_cst to try to hash.
(build_index_type): Likewise; make subtype of sizetype.
(build_index_2_type): Pass sizetype to build_range_type.
(build_common_tree_nodes): Use size_int and bitsize_int to
initialize nodes; add bitsize_{zero,one,unit}_node.
* tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
(DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
(DECL_PACKED, DECL_BIT_FIELD): Likewise.
(DECL_FIELD_BITPOS): Deleted.
(DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
(DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
(DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
(DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
(DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
(DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
(DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
(DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
(DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
(DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
(DECL_ALIGN): Adjust to new field in union.
(DECL_OFFSET_ALIGN): New field.
(DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
(DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
(union tree_decl): Add struct for both aligns.
(enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
(bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
(struct record_layout_info): Rework fields to have offset
alignment and byte and bit position.
(start_record_layout, place_field): Renamed from old names.
(rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
(byte_position, int_byte_position): Likewise.
(get_inner_reference): Change types of position and length.
* unroll.c (unroll_loop): New variable R; use for some loops.
MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
(calculate_giv_inc): Arg REGNO now unsigned.
(copy_loop_body): REGNO and SRC_REGNO now unsigned.
* varasm.c (assemble_variable): Clean up handling of size using
host_integerp and tree_low_cst.
(decode_addr_const): Use byte, not bit, position.
(output_constructor): bitpos and offsets are HOST_WIDE_INT;
use tree_low_cst and int_bit_position.
* objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
* ch/actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
* ch/typeck.c (expand_constant_to_buffer): Use int_byte_position.
(extract_constant_from_buffer): Likewise.
* cp/class.c (build_vbase_pointer_fields): layout_field now
place_field.
(get_vfield_offset): Use byte_position.
(set_rtti_entry): Set OFFSET to ssizetype zero.
(get_binfo_offset_as_int): Deleted.
(dfs_record_base_offsets): Use tree_low_cst.
(dfs_search_base_offsets): Likewise.
(layout_nonempty_base_or_field): Reflect changes in RLI format
and call byte_position.
(layout_empty_base): Convert offset to ssizetype.
(build_base_field): use rli_size_unit_so_far.
(dfs_propagate_binfo_offsets): Do computation in proper type.
(layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
(layout_class_type): Reflect changes in RLI names and fields.
(finish_struct_1): Set DECL_FIELD_OFFSET.
* cp/dump.c (dequeue_and_dump): Call bit_position.
* cp/expr.c (cplus_expand_constant): Use byte_position.
* cp/rtti.c (expand_class_desc): Use bitsize_one_node.
* cp/typeck.c (build_component_addr): Use byte_position and don't
special case for zero offset.
* f/com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
(ffecom_tree_canonize_ref_): Likewise.
* java/class.c (make_field_value): Use byte_position.
* java/expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
(java_array_data_offset): Likewise.
* java/java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
bzero call.
From-SVN: r32742
2000-03-25 19:34:13 +01:00
|
|
|
|
unsigned int *block_reg;
|
2001-04-04 22:19:23 +02:00
|
|
|
|
varray_type delete_list = NULL;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
int bb;
|
|
|
|
|
int reg;
|
|
|
|
|
int regs_per_pass;
|
|
|
|
|
int max_reg;
|
2001-04-04 22:19:23 +02:00
|
|
|
|
unsigned int i;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
struct null_pointer_info npi;
|
|
|
|
|
|
|
|
|
|
/* If we have only a single block, then there's nothing to do. */
|
|
|
|
|
if (n_basic_blocks <= 1)
|
2000-04-07 11:23:29 +02:00
|
|
|
|
return;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
|
|
|
|
|
/* Trying to perform global optimizations on flow graphs which have
|
|
|
|
|
a high connectivity will take a long time and is unlikely to be
|
|
|
|
|
particularly useful.
|
|
|
|
|
|
|
|
|
|
In normal circumstances a cfg should have about twice has many edges
|
|
|
|
|
as blocks. But we do not want to punish small functions which have
|
|
|
|
|
a couple switch statements. So we require a relatively large number
|
|
|
|
|
of basic blocks and the ratio of edges to blocks to be high. */
|
|
|
|
|
if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
|
2000-04-07 11:23:29 +02:00
|
|
|
|
return;
|
1999-11-03 23:45:45 +01:00
|
|
|
|
|
|
|
|
|
/* We need four bitmaps, each with a bit for each register in each
|
|
|
|
|
basic block. */
|
|
|
|
|
max_reg = max_reg_num ();
|
|
|
|
|
regs_per_pass = get_bitmap_width (4, n_basic_blocks, max_reg);
|
|
|
|
|
|
|
|
|
|
/* Allocate bitmaps to hold local and global properties. */
|
|
|
|
|
npi.nonnull_local = sbitmap_vector_alloc (n_basic_blocks, regs_per_pass);
|
|
|
|
|
npi.nonnull_killed = sbitmap_vector_alloc (n_basic_blocks, regs_per_pass);
|
|
|
|
|
nonnull_avin = sbitmap_vector_alloc (n_basic_blocks, regs_per_pass);
|
|
|
|
|
nonnull_avout = sbitmap_vector_alloc (n_basic_blocks, regs_per_pass);
|
|
|
|
|
|
|
|
|
|
/* Go through the basic blocks, seeing whether or not each block
|
|
|
|
|
ends with a conditional branch whose condition is a comparison
|
|
|
|
|
against zero. Record the register compared in BLOCK_REG. */
|
2000-05-04 23:15:05 +02:00
|
|
|
|
block_reg = (unsigned int *) xcalloc (n_basic_blocks, sizeof (int));
|
1999-11-03 23:45:45 +01:00
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
{
|
|
|
|
|
rtx last_insn = BLOCK_END (bb);
|
|
|
|
|
rtx condition, earliest, reg;
|
|
|
|
|
|
|
|
|
|
/* We only want conditional branches. */
|
|
|
|
|
if (GET_CODE (last_insn) != JUMP_INSN
|
combine.c (try_combine): Use any_condjump_p...
* combine.c (try_combine): Use any_condjump_p, any_uncondjump_p
and pc_set at the place of simplejump_p and condjump_p.
* cse.c (record_jump_equiv): Likewise.
* emit-rtl.c (emit): Likewise.
* explow.c (find_next_ref): Likewise.
* flow.c (tidy_fallthru_edge): Likewise.
(init_propagate_block_info): Likewise.
* gcse.c (delete_null_pointer_checks): Likewise.
* ifcvt.c (cond_exec_get_condition, noce_get_condition,
dead_or_predicable): Likewise.
* integrate.c (copy_insn_list): Likewise.
* loop.c (scan_loop, verify_dominator, find_and_verify_loops,
for_each_insn_in_loop, check_dbra_loop, get_condition,
insert_bct, load_mems): Likewise.
* resource.c (find_dead_or_set_registers): Likewise.
* sibcalls.c (simplejump_p): Likewise.
* unroll.c (copy_loop_body, reg_dead_after_loop): Likewise.
From-SVN: r34175
2000-05-25 23:38:49 +02:00
|
|
|
|
|| !any_condjump_p (last_insn)
|
|
|
|
|
|| !onlyjump_p (last_insn))
|
1999-11-03 23:45:45 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* LAST_INSN is a conditional jump. Get its condition. */
|
|
|
|
|
condition = get_condition (last_insn, &earliest);
|
|
|
|
|
|
|
|
|
|
/* If we were unable to get the condition, or it is not a equality
|
|
|
|
|
comparison against zero then there's nothing we can do. */
|
|
|
|
|
if (!condition
|
|
|
|
|
|| (GET_CODE (condition) != NE && GET_CODE (condition) != EQ)
|
|
|
|
|
|| GET_CODE (XEXP (condition, 1)) != CONST_INT
|
|
|
|
|
|| (XEXP (condition, 1)
|
|
|
|
|
!= CONST0_RTX (GET_MODE (XEXP (condition, 0)))))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* We must be checking a register against zero. */
|
|
|
|
|
reg = XEXP (condition, 0);
|
|
|
|
|
if (GET_CODE (reg) != REG)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
block_reg[bb] = REGNO (reg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Go through the algorithm for each block of registers. */
|
|
|
|
|
for (reg = FIRST_PSEUDO_REGISTER; reg < max_reg; reg += regs_per_pass)
|
|
|
|
|
{
|
|
|
|
|
npi.min_reg = reg;
|
|
|
|
|
npi.max_reg = MIN (reg + regs_per_pass, max_reg);
|
2001-04-04 22:19:23 +02:00
|
|
|
|
delete_null_pointer_checks_1 (&delete_list, block_reg, nonnull_avin,
|
1999-11-03 23:45:45 +01:00
|
|
|
|
nonnull_avout, &npi);
|
1999-09-20 15:58:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
2001-04-04 22:19:23 +02:00
|
|
|
|
/* Now delete the instructions all at once. This breaks the CFG. */
|
|
|
|
|
if (delete_list)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < VARRAY_ACTIVE_SIZE (delete_list); i++)
|
|
|
|
|
delete_insn (VARRAY_RTX (delete_list, i));
|
|
|
|
|
VARRAY_FREE (delete_list);
|
|
|
|
|
}
|
|
|
|
|
|
1999-11-03 23:45:45 +01:00
|
|
|
|
/* Free the table of registers compared at the end of every block. */
|
|
|
|
|
free (block_reg);
|
|
|
|
|
|
1999-09-20 15:58:33 +02:00
|
|
|
|
/* Free bitmaps. */
|
1999-11-03 23:45:45 +01:00
|
|
|
|
free (npi.nonnull_local);
|
|
|
|
|
free (npi.nonnull_killed);
|
1999-09-20 15:58:33 +02:00
|
|
|
|
free (nonnull_avin);
|
|
|
|
|
free (nonnull_avout);
|
|
|
|
|
}
|
1999-09-20 16:53:51 +02:00
|
|
|
|
|
|
|
|
|
/* Code Hoisting variables and subroutines. */
|
|
|
|
|
|
|
|
|
|
/* Very busy expressions. */
|
|
|
|
|
static sbitmap *hoist_vbein;
|
|
|
|
|
static sbitmap *hoist_vbeout;
|
|
|
|
|
|
|
|
|
|
/* Hoistable expressions. */
|
|
|
|
|
static sbitmap *hoist_exprs;
|
|
|
|
|
|
|
|
|
|
/* Dominator bitmaps. */
|
|
|
|
|
static sbitmap *dominators;
|
|
|
|
|
|
|
|
|
|
/* ??? We could compute post dominators and run this algorithm in
|
|
|
|
|
reverse to to perform tail merging, doing so would probably be
|
|
|
|
|
more effective than the tail merging code in jump.c.
|
|
|
|
|
|
|
|
|
|
It's unclear if tail merging could be run in parallel with
|
|
|
|
|
code hoisting. It would be nice. */
|
|
|
|
|
|
|
|
|
|
/* Allocate vars used for code hoisting analysis. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
alloc_code_hoist_mem (n_blocks, n_exprs)
|
|
|
|
|
int n_blocks, n_exprs;
|
|
|
|
|
{
|
|
|
|
|
antloc = sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
transp = sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
comp = sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
|
|
|
|
|
hoist_vbein = sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
hoist_vbeout = sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
hoist_exprs = sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
transpout = sbitmap_vector_alloc (n_blocks, n_exprs);
|
|
|
|
|
|
|
|
|
|
dominators = sbitmap_vector_alloc (n_blocks, n_blocks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free vars used for code hoisting analysis. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_code_hoist_mem ()
|
|
|
|
|
{
|
|
|
|
|
free (antloc);
|
|
|
|
|
free (transp);
|
|
|
|
|
free (comp);
|
|
|
|
|
|
|
|
|
|
free (hoist_vbein);
|
|
|
|
|
free (hoist_vbeout);
|
|
|
|
|
free (hoist_exprs);
|
|
|
|
|
free (transpout);
|
|
|
|
|
|
|
|
|
|
free (dominators);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute the very busy expressions at entry/exit from each block.
|
|
|
|
|
|
|
|
|
|
An expression is very busy if all paths from a given point
|
|
|
|
|
compute the expression. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_code_hoist_vbeinout ()
|
|
|
|
|
{
|
|
|
|
|
int bb, changed, passes;
|
|
|
|
|
|
|
|
|
|
sbitmap_vector_zero (hoist_vbeout, n_basic_blocks);
|
|
|
|
|
sbitmap_vector_zero (hoist_vbein, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
passes = 0;
|
|
|
|
|
changed = 1;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
while (changed)
|
|
|
|
|
{
|
|
|
|
|
changed = 0;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
/* We scan the blocks in the reverse order to speed up
|
|
|
|
|
the convergence. */
|
|
|
|
|
for (bb = n_basic_blocks - 1; bb >= 0; bb--)
|
|
|
|
|
{
|
|
|
|
|
changed |= sbitmap_a_or_b_and_c (hoist_vbein[bb], antloc[bb],
|
|
|
|
|
hoist_vbeout[bb], transp[bb]);
|
|
|
|
|
if (bb != n_basic_blocks - 1)
|
basic-block.h (pre_edge_lcm, [...]): Prototype for exported functions.
* basic-block.h (pre_edge_lcm, pre_edge_rev_lcm, compute_available):
Prototype for exported functions.
(pre_lcm, pre_rev_lcm): Remove prototypes.
* gcse.c (compute_ae_kill): Add ae_gen and ae_kill as parameters.
(compute_available): Move to lcm.c, and change parameter order.
(one_classic_gcse_pass): Call compute_ae_kill with parameters.
(pre_insert, s_preds, s_succs, num_preds, num_succs): Delete.
(gcse_main): No longer call compute_preds_succs. Rebuild the
set table after reach pre pass.
(pre_insert_map, pre_delete_map, edge_list): New.
(alloc_pre_mem): Allocate edge vectors.
(free_pre_mem): Delete edge vectors.
(compute_pre_data): Call new edge based lcm routines.
(process_insert_insn): New function.
(insert_insn_end_bb): Use it.
(pre_edge_insert): New function.
(pre_insert_copy_insn): Formatting fixes. Update BLOCK_END as
needed.
(pre_insert_copies): Revamp using new edge based lcm outputs.
(pre_delete): Likewise.
(one_pre_gcse_pass): Insert & remove fake edges to the exit
block.
(compute_code_hoist_vbeinout): New new edge based routines.
* lcm.c: Remove all the old LCM functions. Replace with new ones
that work with the new cfg datastructures and work with edges
instead of blocks.
From-SVN: r30055
1999-10-17 11:21:25 +02:00
|
|
|
|
sbitmap_intersection_of_succs (hoist_vbeout[bb], hoist_vbein, bb);
|
1999-09-20 16:53:51 +02:00
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
passes++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
fprintf (gcse_file, "hoisting vbeinout computation: %d passes\n", passes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Top level routine to do the dataflow analysis needed by code hoisting. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_code_hoist_data ()
|
|
|
|
|
{
|
|
|
|
|
compute_local_properties (transp, comp, antloc, 0);
|
|
|
|
|
compute_transpout ();
|
|
|
|
|
compute_code_hoist_vbeinout ();
|
2000-11-14 10:58:40 +01:00
|
|
|
|
calculate_dominance_info (NULL, dominators, CDI_DOMINATORS);
|
1999-09-20 16:53:51 +02:00
|
|
|
|
if (gcse_file)
|
|
|
|
|
fprintf (gcse_file, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Determine if the expression identified by EXPR_INDEX would
|
|
|
|
|
reach BB unimpared if it was placed at the end of EXPR_BB.
|
|
|
|
|
|
|
|
|
|
It's unclear exactly what Muchnick meant by "unimpared". It seems
|
|
|
|
|
to me that the expression must either be computed or transparent in
|
|
|
|
|
*every* block in the path(s) from EXPR_BB to BB. Any other definition
|
|
|
|
|
would allow the expression to be hoisted out of loops, even if
|
|
|
|
|
the expression wasn't a loop invariant.
|
|
|
|
|
|
|
|
|
|
Contrast this to reachability for PRE where an expression is
|
|
|
|
|
considered reachable if *any* path reaches instead of *all*
|
|
|
|
|
paths. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
hoist_expr_reaches_here_p (expr_bb, expr_index, bb, visited)
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block expr_bb;
|
1999-09-20 16:53:51 +02:00
|
|
|
|
int expr_index;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
1999-09-20 16:53:51 +02:00
|
|
|
|
char *visited;
|
|
|
|
|
{
|
|
|
|
|
edge pred;
|
1999-10-27 07:16:12 +02:00
|
|
|
|
int visited_allocated_locally = 0;
|
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
|
|
|
|
|
if (visited == NULL)
|
|
|
|
|
{
|
1999-10-27 07:16:12 +02:00
|
|
|
|
visited_allocated_locally = 1;
|
|
|
|
|
visited = xcalloc (n_basic_blocks, 1);
|
1999-09-20 16:53:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
|
1999-09-20 16:53:51 +02:00
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block pred_bb = pred->src;
|
1999-09-20 16:53:51 +02:00
|
|
|
|
|
|
|
|
|
if (pred->src == ENTRY_BLOCK_PTR)
|
|
|
|
|
break;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
else if (visited[pred_bb->index])
|
1999-09-20 16:53:51 +02:00
|
|
|
|
continue;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
/* Does this predecessor generate this expression? */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
else if (TEST_BIT (comp[pred_bb->index], expr_index))
|
1999-09-20 16:53:51 +02:00
|
|
|
|
break;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
else if (! TEST_BIT (transp[pred_bb->index], expr_index))
|
1999-09-20 16:53:51 +02:00
|
|
|
|
break;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
/* Not killed. */
|
|
|
|
|
else
|
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
visited[pred_bb->index] = 1;
|
1999-09-20 16:53:51 +02:00
|
|
|
|
if (! hoist_expr_reaches_here_p (expr_bb, expr_index,
|
|
|
|
|
pred_bb, visited))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-10-27 07:16:12 +02:00
|
|
|
|
if (visited_allocated_locally)
|
|
|
|
|
free (visited);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
return (pred == NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Actually perform code hoisting. */
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
static void
|
|
|
|
|
hoist_code ()
|
|
|
|
|
{
|
2000-04-10 13:33:18 +02:00
|
|
|
|
int bb, dominated;
|
|
|
|
|
unsigned int i;
|
1999-09-20 16:53:51 +02:00
|
|
|
|
struct expr **index_map;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
struct expr *expr;
|
1999-09-20 16:53:51 +02:00
|
|
|
|
|
|
|
|
|
sbitmap_vector_zero (hoist_exprs, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
/* Compute a mapping from expression number (`bitmap_index') to
|
|
|
|
|
hash table entry. */
|
|
|
|
|
|
2000-01-05 07:55:02 +01:00
|
|
|
|
index_map = (struct expr **) xcalloc (n_exprs, sizeof (struct expr *));
|
1999-09-20 16:53:51 +02:00
|
|
|
|
for (i = 0; i < expr_hash_table_size; i++)
|
2000-02-29 21:08:52 +01:00
|
|
|
|
for (expr = expr_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
|
|
|
|
|
index_map[expr->bitmap_index] = expr;
|
1999-09-20 16:53:51 +02:00
|
|
|
|
|
|
|
|
|
/* Walk over each basic block looking for potentially hoistable
|
|
|
|
|
expressions, nothing gets hoisted from the entry block. */
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
{
|
|
|
|
|
int found = 0;
|
|
|
|
|
int insn_inserted_p;
|
|
|
|
|
|
|
|
|
|
/* Examine each expression that is very busy at the exit of this
|
|
|
|
|
block. These are the potentially hoistable expressions. */
|
|
|
|
|
for (i = 0; i < hoist_vbeout[bb]->n_bits; i++)
|
|
|
|
|
{
|
|
|
|
|
int hoistable = 0;
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
|
|
|
|
if (TEST_BIT (hoist_vbeout[bb], i) && TEST_BIT (transpout[bb], i))
|
1999-09-20 16:53:51 +02:00
|
|
|
|
{
|
|
|
|
|
/* We've found a potentially hoistable expression, now
|
|
|
|
|
we look at every block BB dominates to see if it
|
|
|
|
|
computes the expression. */
|
|
|
|
|
for (dominated = 0; dominated < n_basic_blocks; dominated++)
|
|
|
|
|
{
|
|
|
|
|
/* Ignore self dominance. */
|
|
|
|
|
if (bb == dominated
|
|
|
|
|
|| ! TEST_BIT (dominators[dominated], bb))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* We've found a dominated block, now see if it computes
|
|
|
|
|
the busy expression and whether or not moving that
|
|
|
|
|
expression to the "beginning" of that block is safe. */
|
|
|
|
|
if (!TEST_BIT (antloc[dominated], i))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Note if the expression would reach the dominated block
|
|
|
|
|
unimpared if it was placed at the end of BB.
|
|
|
|
|
|
|
|
|
|
Keep track of how many times this expression is hoistable
|
|
|
|
|
from a dominated block into BB. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (hoist_expr_reaches_here_p (BASIC_BLOCK (bb), i,
|
|
|
|
|
BASIC_BLOCK (dominated), NULL))
|
1999-09-20 16:53:51 +02:00
|
|
|
|
hoistable++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we found more than one hoistable occurence of this
|
|
|
|
|
expression, then note it in the bitmap of expressions to
|
|
|
|
|
hoist. It makes no sense to hoist things which are computed
|
|
|
|
|
in only one BB, and doing so tends to pessimize register
|
|
|
|
|
allocation. One could increase this value to try harder
|
|
|
|
|
to avoid any possible code expansion due to register
|
|
|
|
|
allocation issues; however experiments have shown that
|
|
|
|
|
the vast majority of hoistable expressions are only movable
|
|
|
|
|
from two successors, so raising this threshhold is likely
|
|
|
|
|
to nullify any benefit we get from code hoisting. */
|
|
|
|
|
if (hoistable > 1)
|
|
|
|
|
{
|
|
|
|
|
SET_BIT (hoist_exprs[bb], i);
|
|
|
|
|
found = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we found nothing to hoist, then quit now. */
|
|
|
|
|
if (! found)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Loop over all the hoistable expressions. */
|
|
|
|
|
for (i = 0; i < hoist_exprs[bb]->n_bits; i++)
|
|
|
|
|
{
|
|
|
|
|
/* We want to insert the expression into BB only once, so
|
|
|
|
|
note when we've inserted it. */
|
|
|
|
|
insn_inserted_p = 0;
|
|
|
|
|
|
|
|
|
|
/* These tests should be the same as the tests above. */
|
|
|
|
|
if (TEST_BIT (hoist_vbeout[bb], i))
|
|
|
|
|
{
|
|
|
|
|
/* We've found a potentially hoistable expression, now
|
|
|
|
|
we look at every block BB dominates to see if it
|
|
|
|
|
computes the expression. */
|
|
|
|
|
for (dominated = 0; dominated < n_basic_blocks; dominated++)
|
|
|
|
|
{
|
|
|
|
|
/* Ignore self dominance. */
|
|
|
|
|
if (bb == dominated
|
|
|
|
|
|| ! TEST_BIT (dominators[dominated], bb))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* We've found a dominated block, now see if it computes
|
|
|
|
|
the busy expression and whether or not moving that
|
|
|
|
|
expression to the "beginning" of that block is safe. */
|
|
|
|
|
if (!TEST_BIT (antloc[dominated], i))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* The expression is computed in the dominated block and
|
|
|
|
|
it would be safe to compute it at the start of the
|
|
|
|
|
dominated block. Now we have to determine if the
|
|
|
|
|
expresion would reach the dominated block if it was
|
|
|
|
|
placed at the end of BB. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (hoist_expr_reaches_here_p (BASIC_BLOCK (bb), i,
|
|
|
|
|
BASIC_BLOCK (dominated), NULL))
|
1999-09-20 16:53:51 +02:00
|
|
|
|
{
|
|
|
|
|
struct expr *expr = index_map[i];
|
|
|
|
|
struct occr *occr = expr->antic_occr;
|
|
|
|
|
rtx insn;
|
|
|
|
|
rtx set;
|
|
|
|
|
|
|
|
|
|
/* Find the right occurence of this expression. */
|
|
|
|
|
while (BLOCK_NUM (occr->insn) != dominated && occr)
|
|
|
|
|
occr = occr->next;
|
|
|
|
|
|
|
|
|
|
/* Should never happen. */
|
|
|
|
|
if (!occr)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
insn = occr->insn;
|
|
|
|
|
|
|
|
|
|
set = single_set (insn);
|
|
|
|
|
if (! set)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
/* Create a pseudo-reg to store the result of reaching
|
|
|
|
|
expressions into. Get the mode for the new pseudo
|
|
|
|
|
from the mode of the original destination pseudo. */
|
|
|
|
|
if (expr->reaching_reg == NULL)
|
|
|
|
|
expr->reaching_reg
|
|
|
|
|
= gen_reg_rtx (GET_MODE (SET_DEST (set)));
|
|
|
|
|
|
|
|
|
|
/* In theory this should never fail since we're creating
|
|
|
|
|
a reg->reg copy.
|
|
|
|
|
|
2000-02-29 21:08:52 +01:00
|
|
|
|
However, on the x86 some of the movXX patterns
|
|
|
|
|
actually contain clobbers of scratch regs. This may
|
|
|
|
|
cause the insn created by validate_change to not
|
|
|
|
|
match any pattern and thus cause validate_change to
|
|
|
|
|
fail. */
|
1999-09-20 16:53:51 +02:00
|
|
|
|
if (validate_change (insn, &SET_SRC (set),
|
|
|
|
|
expr->reaching_reg, 0))
|
|
|
|
|
{
|
|
|
|
|
occr->deleted_p = 1;
|
|
|
|
|
if (!insn_inserted_p)
|
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
insert_insn_end_bb (index_map[i],
|
|
|
|
|
BASIC_BLOCK (bb), 0);
|
1999-09-20 16:53:51 +02:00
|
|
|
|
insn_inserted_p = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-10-27 07:16:12 +02:00
|
|
|
|
free (index_map);
|
1999-09-20 16:53:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Top level routine to perform one code hoisting (aka unification) pass
|
|
|
|
|
|
|
|
|
|
Return non-zero if a change was made. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
one_code_hoisting_pass ()
|
|
|
|
|
{
|
|
|
|
|
int changed = 0;
|
|
|
|
|
|
|
|
|
|
alloc_expr_hash_table (max_cuid);
|
|
|
|
|
compute_expr_hash_table ();
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
dump_hash_table (gcse_file, "Code Hosting Expressions", expr_hash_table,
|
|
|
|
|
expr_hash_table_size, n_exprs);
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
if (n_exprs > 0)
|
|
|
|
|
{
|
|
|
|
|
alloc_code_hoist_mem (n_basic_blocks, n_exprs);
|
|
|
|
|
compute_code_hoist_data ();
|
|
|
|
|
hoist_code ();
|
|
|
|
|
free_code_hoist_mem ();
|
|
|
|
|
}
|
2000-02-29 21:08:52 +01:00
|
|
|
|
|
1999-09-20 16:53:51 +02:00
|
|
|
|
free_expr_hash_table ();
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
/* Here we provide the things required to do store motion towards
|
|
|
|
|
the exit. In order for this to be effective, gcse also needed to
|
|
|
|
|
be taught how to move a load when it is kill only by a store to itself.
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
float a[10];
|
|
|
|
|
|
|
|
|
|
void foo(float scale)
|
|
|
|
|
{
|
|
|
|
|
for (i=0; i<10; i++)
|
|
|
|
|
a[i] *= scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
'i' is both loaded and stored to in the loop. Normally, gcse cannot move
|
|
|
|
|
the load out since its live around the loop, and stored at the bottom
|
|
|
|
|
of the loop.
|
|
|
|
|
|
|
|
|
|
The 'Load Motion' referred to and implemented in this file is
|
|
|
|
|
an enhancement to gcse which when using edge based lcm, recognizes
|
|
|
|
|
this situation and allows gcse to move the load out of the loop.
|
|
|
|
|
|
|
|
|
|
Once gcse has hoisted the load, store motion can then push this
|
|
|
|
|
load towards the exit, and we end up with no loads or stores of 'i'
|
|
|
|
|
in the loop. */
|
|
|
|
|
|
|
|
|
|
/* This will search the ldst list for a matching expresion. If it
|
|
|
|
|
doesn't find one, we create one and initialize it. */
|
|
|
|
|
|
|
|
|
|
static struct ls_expr *
|
|
|
|
|
ldst_entry (x)
|
|
|
|
|
rtx x;
|
|
|
|
|
{
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
|
|
|
|
|
for (ptr = first_ls_expr(); ptr != NULL; ptr = next_ls_expr (ptr))
|
|
|
|
|
if (expr_equiv_p (ptr->pattern, x))
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (!ptr)
|
|
|
|
|
{
|
|
|
|
|
ptr = (struct ls_expr *) xmalloc (sizeof (struct ls_expr));
|
|
|
|
|
|
|
|
|
|
ptr->next = pre_ldst_mems;
|
|
|
|
|
ptr->expr = NULL;
|
|
|
|
|
ptr->pattern = x;
|
|
|
|
|
ptr->loads = NULL_RTX;
|
|
|
|
|
ptr->stores = NULL_RTX;
|
|
|
|
|
ptr->reaching_reg = NULL_RTX;
|
|
|
|
|
ptr->invalid = 0;
|
|
|
|
|
ptr->index = 0;
|
|
|
|
|
ptr->hash_index = 0;
|
|
|
|
|
pre_ldst_mems = ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free up an individual ldst entry. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_ldst_entry (ptr)
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
{
|
|
|
|
|
free_INSN_LIST_list (& ptr->loads);
|
|
|
|
|
free_INSN_LIST_list (& ptr->stores);
|
|
|
|
|
|
|
|
|
|
free (ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free up all memory associated with the ldst list. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_ldst_mems ()
|
|
|
|
|
{
|
|
|
|
|
while (pre_ldst_mems)
|
|
|
|
|
{
|
|
|
|
|
struct ls_expr * tmp = pre_ldst_mems;
|
|
|
|
|
|
|
|
|
|
pre_ldst_mems = pre_ldst_mems->next;
|
|
|
|
|
|
|
|
|
|
free_ldst_entry (tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pre_ldst_mems = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dump debugging info about the ldst list. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
print_ldst_list (file)
|
|
|
|
|
FILE * file;
|
|
|
|
|
{
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
|
|
|
|
|
fprintf (file, "LDST list: \n");
|
|
|
|
|
|
|
|
|
|
for (ptr = first_ls_expr(); ptr != NULL; ptr = next_ls_expr (ptr))
|
|
|
|
|
{
|
|
|
|
|
fprintf (file, " Pattern (%3d): ", ptr->index);
|
|
|
|
|
|
|
|
|
|
print_rtl (file, ptr->pattern);
|
|
|
|
|
|
|
|
|
|
fprintf (file, "\n Loads : ");
|
|
|
|
|
|
|
|
|
|
if (ptr->loads)
|
|
|
|
|
print_rtl (file, ptr->loads);
|
|
|
|
|
else
|
|
|
|
|
fprintf (file, "(nil)");
|
|
|
|
|
|
|
|
|
|
fprintf (file, "\n Stores : ");
|
|
|
|
|
|
|
|
|
|
if (ptr->stores)
|
|
|
|
|
print_rtl (file, ptr->stores);
|
|
|
|
|
else
|
|
|
|
|
fprintf (file, "(nil)");
|
|
|
|
|
|
|
|
|
|
fprintf (file, "\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf (file, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns 1 if X is in the list of ldst only expressions. */
|
|
|
|
|
|
|
|
|
|
static struct ls_expr *
|
|
|
|
|
find_rtx_in_ldst (x)
|
|
|
|
|
rtx x;
|
|
|
|
|
{
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
|
|
|
|
|
for (ptr = pre_ldst_mems; ptr != NULL; ptr = ptr->next)
|
|
|
|
|
if (expr_equiv_p (ptr->pattern, x) && ! ptr->invalid)
|
|
|
|
|
return ptr;
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Assign each element of the list of mems a monotonically increasing value. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
enumerate_ldsts ()
|
|
|
|
|
{
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
|
|
for (ptr = pre_ldst_mems; ptr != NULL; ptr = ptr->next)
|
|
|
|
|
ptr->index = n++;
|
|
|
|
|
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return first item in the list. */
|
|
|
|
|
|
|
|
|
|
static inline struct ls_expr *
|
|
|
|
|
first_ls_expr ()
|
|
|
|
|
{
|
|
|
|
|
return pre_ldst_mems;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the next item in ther list after the specified one. */
|
|
|
|
|
|
|
|
|
|
static inline struct ls_expr *
|
|
|
|
|
next_ls_expr (ptr)
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
{
|
|
|
|
|
return ptr->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Load Motion for loads which only kill themselves. */
|
|
|
|
|
|
|
|
|
|
/* Return true if x is a simple MEM operation, with no registers or
|
|
|
|
|
side effects. These are the types of loads we consider for the
|
|
|
|
|
ld_motion list, otherwise we let the usual aliasing take care of it. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
simple_mem (x)
|
|
|
|
|
rtx x;
|
|
|
|
|
{
|
|
|
|
|
if (GET_CODE (x) != MEM)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (MEM_VOLATILE_P (x))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (GET_MODE (x) == BLKmode)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (!rtx_varies_p (XEXP (x, 0), 0))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make sure there isn't a buried reference in this pattern anywhere.
|
|
|
|
|
If there is, invalidate the entry for it since we're not capable
|
|
|
|
|
of fixing it up just yet.. We have to be sure we know about ALL
|
|
|
|
|
loads since the aliasing code will allow all entries in the
|
|
|
|
|
ld_motion list to not-alias itself. If we miss a load, we will get
|
|
|
|
|
the wrong value since gcse might common it and we won't know to
|
|
|
|
|
fix it up. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
invalidate_any_buried_refs (x)
|
|
|
|
|
rtx x;
|
|
|
|
|
{
|
|
|
|
|
const char * fmt;
|
|
|
|
|
int i,j;
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
|
|
|
|
|
/* Invalidate it in the list. */
|
|
|
|
|
if (GET_CODE (x) == MEM && simple_mem (x))
|
|
|
|
|
{
|
|
|
|
|
ptr = ldst_entry (x);
|
|
|
|
|
ptr->invalid = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Recursively process the insn. */
|
|
|
|
|
fmt = GET_RTX_FORMAT (GET_CODE (x));
|
|
|
|
|
|
|
|
|
|
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
invalidate_any_buried_refs (XEXP (x, i));
|
|
|
|
|
else if (fmt[i] == 'E')
|
|
|
|
|
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
|
|
|
|
|
invalidate_any_buried_refs (XVECEXP (x, i, j));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find all the 'simple' MEMs which are used in LOADs and STORES. Simple
|
|
|
|
|
being defined as MEM loads and stores to symbols, with no
|
|
|
|
|
side effects and no registers in the expression. If there are any
|
|
|
|
|
uses/defs which dont match this criteria, it is invalidated and
|
|
|
|
|
trimmed out later. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
compute_ld_motion_mems ()
|
|
|
|
|
{
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
int bb;
|
|
|
|
|
rtx insn;
|
|
|
|
|
|
|
|
|
|
pre_ldst_mems = NULL;
|
|
|
|
|
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
{
|
|
|
|
|
for (insn = BLOCK_HEAD (bb);
|
|
|
|
|
insn && insn != NEXT_INSN (BLOCK_END (bb));
|
|
|
|
|
insn = NEXT_INSN (insn))
|
|
|
|
|
{
|
|
|
|
|
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
|
|
|
|
|
{
|
|
|
|
|
if (GET_CODE (PATTERN (insn)) == SET)
|
|
|
|
|
{
|
|
|
|
|
rtx src = SET_SRC (PATTERN (insn));
|
|
|
|
|
rtx dest = SET_DEST (PATTERN (insn));
|
|
|
|
|
|
|
|
|
|
/* Check for a simple LOAD... */
|
|
|
|
|
if (GET_CODE (src) == MEM && simple_mem (src))
|
|
|
|
|
{
|
|
|
|
|
ptr = ldst_entry (src);
|
|
|
|
|
if (GET_CODE (dest) == REG)
|
|
|
|
|
ptr->loads = alloc_INSN_LIST (insn, ptr->loads);
|
|
|
|
|
else
|
|
|
|
|
ptr->invalid = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Make sure there isn't a buried load somewhere. */
|
|
|
|
|
invalidate_any_buried_refs (src);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check for stores. Don't worry about aliased ones, they
|
|
|
|
|
will block any movement we might do later. We only care
|
|
|
|
|
about this exact pattern since those are the only
|
|
|
|
|
circumstance that we will ignore the aliasing info. */
|
|
|
|
|
if (GET_CODE (dest) == MEM && simple_mem (dest))
|
|
|
|
|
{
|
|
|
|
|
ptr = ldst_entry (dest);
|
|
|
|
|
|
2001-04-15 18:50:51 +02:00
|
|
|
|
if (GET_CODE (src) != MEM
|
|
|
|
|
&& GET_CODE (src) != ASM_OPERANDS)
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
ptr->stores = alloc_INSN_LIST (insn, ptr->stores);
|
|
|
|
|
else
|
|
|
|
|
ptr->invalid = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
invalidate_any_buried_refs (PATTERN (insn));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Remove any references that have been either invalidated or are not in the
|
|
|
|
|
expression list for pre gcse. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
trim_ld_motion_mems ()
|
|
|
|
|
{
|
|
|
|
|
struct ls_expr * last = NULL;
|
|
|
|
|
struct ls_expr * ptr = first_ls_expr ();
|
|
|
|
|
|
|
|
|
|
while (ptr != NULL)
|
|
|
|
|
{
|
|
|
|
|
int del = ptr->invalid;
|
|
|
|
|
struct expr * expr = NULL;
|
|
|
|
|
|
|
|
|
|
/* Delete if entry has been made invalid. */
|
|
|
|
|
if (!del)
|
|
|
|
|
{
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
del = 1;
|
|
|
|
|
/* Delete if we cannot find this mem in the expression list. */
|
|
|
|
|
for (i = 0; i < expr_hash_table_size && del; i++)
|
|
|
|
|
{
|
|
|
|
|
for (expr = expr_hash_table[i];
|
|
|
|
|
expr != NULL;
|
|
|
|
|
expr = expr->next_same_hash)
|
|
|
|
|
if (expr_equiv_p (expr->expr, ptr->pattern))
|
|
|
|
|
{
|
|
|
|
|
del = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (del)
|
|
|
|
|
{
|
|
|
|
|
if (last != NULL)
|
|
|
|
|
{
|
|
|
|
|
last->next = ptr->next;
|
|
|
|
|
free_ldst_entry (ptr);
|
|
|
|
|
ptr = last->next;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pre_ldst_mems = pre_ldst_mems->next;
|
|
|
|
|
free_ldst_entry (ptr);
|
|
|
|
|
ptr = pre_ldst_mems;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Set the expression field if we are keeping it. */
|
|
|
|
|
last = ptr;
|
|
|
|
|
ptr->expr = expr;
|
|
|
|
|
ptr = ptr->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Show the world what we've found. */
|
|
|
|
|
if (gcse_file && pre_ldst_mems != NULL)
|
|
|
|
|
print_ldst_list (gcse_file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This routine will take an expression which we are replacing with
|
|
|
|
|
a reaching register, and update any stores that are needed if
|
|
|
|
|
that expression is in the ld_motion list. Stores are updated by
|
|
|
|
|
copying their SRC to the reaching register, and then storeing
|
|
|
|
|
the reaching register into the store location. These keeps the
|
|
|
|
|
correct value in the reaching register for the loads. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
update_ld_motion_stores (expr)
|
|
|
|
|
struct expr * expr;
|
|
|
|
|
{
|
|
|
|
|
struct ls_expr * mem_ptr;
|
|
|
|
|
|
|
|
|
|
if ((mem_ptr = find_rtx_in_ldst (expr->expr)))
|
|
|
|
|
{
|
|
|
|
|
/* We can try to find just the REACHED stores, but is shouldn't
|
|
|
|
|
matter to set the reaching reg everywhere... some might be
|
|
|
|
|
dead and should be eliminated later. */
|
|
|
|
|
|
|
|
|
|
/* We replace SET mem = expr with
|
|
|
|
|
SET reg = expr
|
|
|
|
|
SET mem = reg , where reg is the
|
|
|
|
|
reaching reg used in the load. */
|
|
|
|
|
rtx list = mem_ptr->stores;
|
|
|
|
|
|
|
|
|
|
for ( ; list != NULL_RTX; list = XEXP (list, 1))
|
|
|
|
|
{
|
|
|
|
|
rtx insn = XEXP (list, 0);
|
|
|
|
|
rtx pat = PATTERN (insn);
|
|
|
|
|
rtx src = SET_SRC (pat);
|
|
|
|
|
rtx reg = expr->reaching_reg;
|
2001-04-10 23:45:12 +02:00
|
|
|
|
rtx copy, new;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
/* If we've already copied it, continue. */
|
|
|
|
|
if (expr->reaching_reg == src)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file, "PRE: store updated with reaching reg ");
|
|
|
|
|
print_rtl (gcse_file, expr->reaching_reg);
|
|
|
|
|
fprintf (gcse_file, ":\n ");
|
|
|
|
|
print_inline_rtx (gcse_file, insn, 8);
|
|
|
|
|
fprintf (gcse_file, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
copy = gen_move_insn ( reg, SET_SRC (pat));
|
2001-04-10 23:45:12 +02:00
|
|
|
|
new = emit_insn_before (copy, insn);
|
|
|
|
|
record_one_set (REGNO (reg), new);
|
|
|
|
|
set_block_for_new_insns (new, BLOCK_FOR_INSN (insn));
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
SET_SRC (pat) = reg;
|
|
|
|
|
|
|
|
|
|
/* un-recognize this pattern since it's probably different now. */
|
|
|
|
|
INSN_CODE (insn) = -1;
|
|
|
|
|
gcse_create_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Store motion code. */
|
|
|
|
|
|
|
|
|
|
/* This is used to communicate the target bitvector we want to use in the
|
|
|
|
|
reg_set_info routine when called via the note_stores mechanism. */
|
|
|
|
|
static sbitmap * regvec;
|
|
|
|
|
|
|
|
|
|
/* Used in computing the reverse edge graph bit vectors. */
|
|
|
|
|
static sbitmap * st_antloc;
|
|
|
|
|
|
|
|
|
|
/* Global holding the number of store expressions we are dealing with. */
|
|
|
|
|
static int num_stores;
|
|
|
|
|
|
|
|
|
|
/* Checks to set if we need to mark a register set. Called from note_stores. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
reg_set_info (dest, setter, data)
|
|
|
|
|
rtx dest, setter ATTRIBUTE_UNUSED;
|
|
|
|
|
void * data ATTRIBUTE_UNUSED;
|
|
|
|
|
{
|
|
|
|
|
if (GET_CODE (dest) == SUBREG)
|
|
|
|
|
dest = SUBREG_REG (dest);
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (dest) == REG)
|
|
|
|
|
SET_BIT (*regvec, REGNO (dest));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return non-zero if the register operands of expression X are killed
|
|
|
|
|
anywhere in basic block BB. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
store_ops_ok (x, bb)
|
|
|
|
|
rtx x;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
enum rtx_code code;
|
|
|
|
|
const char * fmt;
|
|
|
|
|
|
|
|
|
|
/* Repeat is used to turn tail-recursion into iteration. */
|
|
|
|
|
repeat:
|
|
|
|
|
|
|
|
|
|
if (x == 0)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
code = GET_CODE (x);
|
|
|
|
|
switch (code)
|
|
|
|
|
{
|
|
|
|
|
case REG:
|
|
|
|
|
/* If a reg has changed after us in this
|
|
|
|
|
block, the operand has been killed. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
return TEST_BIT (reg_set_in_block[bb->index], REGNO (x));
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
case MEM:
|
|
|
|
|
x = XEXP (x, 0);
|
|
|
|
|
goto repeat;
|
|
|
|
|
|
|
|
|
|
case PRE_DEC:
|
|
|
|
|
case PRE_INC:
|
|
|
|
|
case POST_DEC:
|
|
|
|
|
case POST_INC:
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
case PC:
|
|
|
|
|
case CC0: /*FIXME*/
|
|
|
|
|
case CONST:
|
|
|
|
|
case CONST_INT:
|
|
|
|
|
case CONST_DOUBLE:
|
|
|
|
|
case SYMBOL_REF:
|
|
|
|
|
case LABEL_REF:
|
|
|
|
|
case ADDR_VEC:
|
|
|
|
|
case ADDR_DIFF_VEC:
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = GET_RTX_LENGTH (code) - 1;
|
|
|
|
|
fmt = GET_RTX_FORMAT (code);
|
|
|
|
|
|
|
|
|
|
for (; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
{
|
|
|
|
|
rtx tem = XEXP (x, i);
|
|
|
|
|
|
|
|
|
|
/* If we are about to do the last recursive call
|
|
|
|
|
needed at this level, change it into iteration.
|
|
|
|
|
This function is called enough to be worth it. */
|
|
|
|
|
if (i == 0)
|
|
|
|
|
{
|
|
|
|
|
x = tem;
|
|
|
|
|
goto repeat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! store_ops_ok (tem, bb))
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if (fmt[i] == 'E')
|
|
|
|
|
{
|
|
|
|
|
int j;
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < XVECLEN (x, i); j++)
|
|
|
|
|
{
|
|
|
|
|
if (! store_ops_ok (XVECEXP (x, i, j), bb))
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Determine whether insn is MEM store pattern that we will consider moving. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
find_moveable_store (insn)
|
|
|
|
|
rtx insn;
|
|
|
|
|
{
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
rtx dest = PATTERN (insn);
|
|
|
|
|
|
2001-04-15 18:50:51 +02:00
|
|
|
|
if (GET_CODE (dest) != SET
|
|
|
|
|
|| GET_CODE (SET_SRC (dest)) == ASM_OPERANDS)
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
dest = SET_DEST (dest);
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (dest) != MEM || MEM_VOLATILE_P (dest)
|
|
|
|
|
|| GET_MODE (dest) == BLKmode)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (XEXP (dest, 0)) != SYMBOL_REF)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (rtx_varies_p (XEXP (dest, 0), 0))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ptr = ldst_entry (dest);
|
|
|
|
|
ptr->stores = alloc_INSN_LIST (insn, ptr->stores);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Perform store motion. Much like gcse, except we move expressions the
|
|
|
|
|
other way by looking at the flowgraph in reverse. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
compute_store_table ()
|
|
|
|
|
{
|
|
|
|
|
int bb, ret;
|
|
|
|
|
unsigned regno;
|
|
|
|
|
rtx insn, pat;
|
|
|
|
|
|
|
|
|
|
max_gcse_regno = max_reg_num ();
|
|
|
|
|
|
|
|
|
|
reg_set_in_block = (sbitmap *) sbitmap_vector_alloc (n_basic_blocks,
|
|
|
|
|
max_gcse_regno);
|
|
|
|
|
sbitmap_vector_zero (reg_set_in_block, n_basic_blocks);
|
|
|
|
|
pre_ldst_mems = 0;
|
|
|
|
|
|
|
|
|
|
/* Find all the stores we care about. */
|
|
|
|
|
for (bb = 0; bb < n_basic_blocks; bb++)
|
|
|
|
|
{
|
|
|
|
|
regvec = & (reg_set_in_block[bb]);
|
|
|
|
|
for (insn = BLOCK_END (bb);
|
|
|
|
|
insn && insn != PREV_INSN (BLOCK_HEAD (bb));
|
|
|
|
|
insn = PREV_INSN (insn))
|
|
|
|
|
{
|
|
|
|
|
#ifdef NON_SAVING_SETJMP
|
|
|
|
|
if (NON_SAVING_SETJMP && GET_CODE (insn) == NOTE
|
|
|
|
|
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
|
|
|
|
|
{
|
|
|
|
|
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
|
|
|
|
SET_BIT (reg_set_in_block[bb], regno);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
/* Ignore anything that is not a normal insn. */
|
|
|
|
|
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (insn) == CALL_INSN)
|
|
|
|
|
{
|
|
|
|
|
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
|
|
|
|
if ((call_used_regs[regno]
|
|
|
|
|
&& regno != STACK_POINTER_REGNUM
|
|
|
|
|
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
|
|
|
|
&& regno != HARD_FRAME_POINTER_REGNUM
|
|
|
|
|
#endif
|
|
|
|
|
#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
|
|
|
|
&& ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
|
|
|
|
|
#endif
|
|
|
|
|
#if defined (PIC_OFFSET_TABLE_REGNUM) && !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
|
|
|
|
|
&& ! (regno == PIC_OFFSET_TABLE_REGNUM && flag_pic)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
&& regno != FRAME_POINTER_REGNUM)
|
|
|
|
|
|| global_regs[regno])
|
|
|
|
|
SET_BIT (reg_set_in_block[bb], regno);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pat = PATTERN (insn);
|
|
|
|
|
note_stores (pat, reg_set_info, NULL);
|
|
|
|
|
|
|
|
|
|
/* Now that we've marked regs, look for stores. */
|
|
|
|
|
if (GET_CODE (pat) == SET)
|
|
|
|
|
find_moveable_store (insn);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = enumerate_ldsts ();
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file, "Store Motion Expressions.\n");
|
|
|
|
|
print_ldst_list (gcse_file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check to see if the load X is aliased with STORE_PATTERN. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
load_kills_store (x, store_pattern)
|
|
|
|
|
rtx x, store_pattern;
|
|
|
|
|
{
|
|
|
|
|
if (true_dependence (x, GET_MODE (x), store_pattern, rtx_addr_varies_p))
|
|
|
|
|
return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Go through the entire insn X, looking for any loads which might alias
|
|
|
|
|
STORE_PATTERN. Return 1 if found. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
find_loads (x, store_pattern)
|
|
|
|
|
rtx x, store_pattern;
|
|
|
|
|
{
|
|
|
|
|
const char * fmt;
|
|
|
|
|
int i,j;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (x) == SET)
|
|
|
|
|
x = SET_SRC (x);
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (x) == MEM)
|
|
|
|
|
{
|
|
|
|
|
if (load_kills_store (x, store_pattern))
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Recursively process the insn. */
|
|
|
|
|
fmt = GET_RTX_FORMAT (GET_CODE (x));
|
|
|
|
|
|
|
|
|
|
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0 && !ret; i--)
|
|
|
|
|
{
|
|
|
|
|
if (fmt[i] == 'e')
|
|
|
|
|
ret |= find_loads (XEXP (x, i), store_pattern);
|
|
|
|
|
else if (fmt[i] == 'E')
|
|
|
|
|
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
|
|
|
|
|
ret |= find_loads (XVECEXP (x, i, j), store_pattern);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check if INSN kills the store pattern X (is aliased with it).
|
|
|
|
|
Return 1 if it it does. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
store_killed_in_insn (x, insn)
|
|
|
|
|
rtx x, insn;
|
|
|
|
|
{
|
|
|
|
|
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (insn) == CALL_INSN)
|
|
|
|
|
{
|
|
|
|
|
if (CONST_CALL_P (insn))
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GET_CODE (PATTERN (insn)) == SET)
|
|
|
|
|
{
|
|
|
|
|
rtx pat = PATTERN (insn);
|
|
|
|
|
/* Check for memory stores to aliased objects. */
|
|
|
|
|
if (GET_CODE (SET_DEST (pat)) == MEM && !expr_equiv_p (SET_DEST (pat), x))
|
|
|
|
|
/* pretend its a load and check for aliasing. */
|
|
|
|
|
if (find_loads (SET_DEST (pat), x))
|
|
|
|
|
return 1;
|
|
|
|
|
return find_loads (SET_SRC (pat), x);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return find_loads (PATTERN (insn), x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns 1 if the expression X is loaded or clobbered on or after INSN
|
|
|
|
|
within basic block BB. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
store_killed_after (x, insn, bb)
|
|
|
|
|
rtx x, insn;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
rtx last = bb->end;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
if (insn == last)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* Check if the register operands of the store are OK in this block.
|
|
|
|
|
Note that if registers are changed ANYWHERE in the block, we'll
|
|
|
|
|
decide we can't move it, regardless of whether it changed above
|
|
|
|
|
or below the store. This could be improved by checking the register
|
|
|
|
|
operands while lookinng for aliasing in each insn. */
|
|
|
|
|
if (!store_ops_ok (XEXP (x, 0), bb))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
for ( ; insn && insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
|
|
|
|
|
if (store_killed_in_insn (x, insn))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns 1 if the expression X is loaded or clobbered on or before INSN
|
|
|
|
|
within basic block BB. */
|
|
|
|
|
static int
|
|
|
|
|
store_killed_before (x, insn, bb)
|
|
|
|
|
rtx x, insn;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
rtx first = bb->head;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
if (insn == first)
|
|
|
|
|
return store_killed_in_insn (x, insn);
|
|
|
|
|
|
|
|
|
|
/* Check if the register operands of the store are OK in this block.
|
|
|
|
|
Note that if registers are changed ANYWHERE in the block, we'll
|
|
|
|
|
decide we can't move it, regardless of whether it changed above
|
|
|
|
|
or below the store. This could be improved by checking the register
|
|
|
|
|
operands while lookinng for aliasing in each insn. */
|
|
|
|
|
if (!store_ops_ok (XEXP (x, 0), bb))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
for ( ; insn && insn != PREV_INSN (first); insn = PREV_INSN (insn))
|
|
|
|
|
if (store_killed_in_insn (x, insn))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define ANTIC_STORE_LIST(x) ((x)->loads)
|
|
|
|
|
#define AVAIL_STORE_LIST(x) ((x)->stores)
|
|
|
|
|
|
|
|
|
|
/* Given the table of available store insns at the end of blocks,
|
|
|
|
|
determine which ones are not killed by aliasing, and generate
|
|
|
|
|
the appropriate vectors for gen and killed. */
|
|
|
|
|
static void
|
|
|
|
|
build_store_vectors ()
|
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
|
|
|
|
int b;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
rtx insn, st;
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
|
|
|
|
|
/* Build the gen_vector. This is any store in the table which is not killed
|
|
|
|
|
by aliasing later in its block. */
|
|
|
|
|
ae_gen = (sbitmap *) sbitmap_vector_alloc (n_basic_blocks, num_stores);
|
|
|
|
|
sbitmap_vector_zero (ae_gen, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
st_antloc = (sbitmap *) sbitmap_vector_alloc (n_basic_blocks, num_stores);
|
|
|
|
|
sbitmap_vector_zero (st_antloc, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
|
|
|
|
|
{
|
|
|
|
|
/* Put all the stores into either the antic list, or the avail list,
|
|
|
|
|
or both. */
|
|
|
|
|
rtx store_list = ptr->stores;
|
|
|
|
|
ptr->stores = NULL_RTX;
|
|
|
|
|
|
|
|
|
|
for (st = store_list; st != NULL; st = XEXP (st, 1))
|
|
|
|
|
{
|
|
|
|
|
insn = XEXP (st, 0);
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
bb = BLOCK_FOR_INSN (insn);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
if (!store_killed_after (ptr->pattern, insn, bb))
|
|
|
|
|
{
|
|
|
|
|
/* If we've already seen an availale expression in this block,
|
|
|
|
|
we can delete the one we saw already (It occurs earlier in
|
|
|
|
|
the block), and replace it with this one). We'll copy the
|
|
|
|
|
old SRC expression to an unused register in case there
|
|
|
|
|
are any side effects. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (TEST_BIT (ae_gen[bb->index], ptr->index))
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
|
|
|
|
/* Find previous store. */
|
|
|
|
|
rtx st;
|
|
|
|
|
for (st = AVAIL_STORE_LIST (ptr); st ; st = XEXP (st, 1))
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (BLOCK_FOR_INSN (XEXP (st, 0)) == bb)
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
break;
|
|
|
|
|
if (st)
|
|
|
|
|
{
|
|
|
|
|
rtx r = gen_reg_rtx (GET_MODE (ptr->pattern));
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
fprintf(gcse_file, "Removing redundant store:\n");
|
|
|
|
|
replace_store_insn (r, XEXP (st, 0), bb);
|
|
|
|
|
XEXP (st, 0) = insn;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
SET_BIT (ae_gen[bb->index], ptr->index);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
AVAIL_STORE_LIST (ptr) = alloc_INSN_LIST (insn,
|
|
|
|
|
AVAIL_STORE_LIST (ptr));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!store_killed_before (ptr->pattern, insn, bb))
|
|
|
|
|
{
|
|
|
|
|
SET_BIT (st_antloc[BLOCK_NUM (insn)], ptr->index);
|
|
|
|
|
ANTIC_STORE_LIST (ptr) = alloc_INSN_LIST (insn,
|
|
|
|
|
ANTIC_STORE_LIST (ptr));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free the original list of store insns. */
|
|
|
|
|
free_INSN_LIST_list (&store_list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ae_kill = (sbitmap *) sbitmap_vector_alloc (n_basic_blocks, num_stores);
|
|
|
|
|
sbitmap_vector_zero (ae_kill, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
transp = (sbitmap *) sbitmap_vector_alloc (n_basic_blocks, num_stores);
|
|
|
|
|
sbitmap_vector_zero (transp, n_basic_blocks);
|
|
|
|
|
|
|
|
|
|
for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
for (b = 0; b < n_basic_blocks; b++)
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (store_killed_after (ptr->pattern, BLOCK_HEAD (b), BASIC_BLOCK (b)))
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
|
|
|
|
/* The anticipatable expression is not killed if it's gen'd. */
|
|
|
|
|
/*
|
|
|
|
|
We leave this check out for now. If we have a code sequence
|
|
|
|
|
in a block which looks like:
|
|
|
|
|
ST MEMa = x
|
|
|
|
|
L y = MEMa
|
|
|
|
|
ST MEMa = z
|
|
|
|
|
We should flag this as having an ANTIC expression, NOT
|
|
|
|
|
transparent, NOT killed, and AVAIL.
|
|
|
|
|
Unfortunately, since we haven't re-written all loads to
|
|
|
|
|
use the reaching reg, we'll end up doing an incorrect
|
|
|
|
|
Load in the middle here if we push the store down. It happens in
|
|
|
|
|
gcc.c-torture/execute/960311-1.c with -O3
|
|
|
|
|
If we always kill it in this case, we'll sometimes do
|
|
|
|
|
uneccessary work, but it shouldn't actually hurt anything.
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (!TEST_BIT (ae_gen[b], ptr->index)). */
|
|
|
|
|
SET_BIT (ae_kill[b], ptr->index);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
SET_BIT (transp[b], ptr->index);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Any block with no exits calls some non-returning function, so
|
|
|
|
|
we better mark the store killed here, or we might not store to
|
|
|
|
|
it at all. If we knew it was abort, we wouldn't have to store,
|
|
|
|
|
but we don't know that for sure. */
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file, "ST_avail and ST_antic (shown under loads..)\n");
|
|
|
|
|
print_ldst_list (gcse_file);
|
|
|
|
|
dump_sbitmap_vector (gcse_file, "st_antloc", "", st_antloc, n_basic_blocks);
|
|
|
|
|
dump_sbitmap_vector (gcse_file, "st_kill", "", ae_kill, n_basic_blocks);
|
|
|
|
|
dump_sbitmap_vector (gcse_file, "Transpt", "", transp, n_basic_blocks);
|
|
|
|
|
dump_sbitmap_vector (gcse_file, "st_avloc", "", ae_gen, n_basic_blocks);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Insert an instruction at the begining of a basic block, and update
|
|
|
|
|
the BLOCK_HEAD if needed. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
insert_insn_start_bb (insn, bb)
|
|
|
|
|
rtx insn;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
|
|
|
|
/* Insert at start of successor block. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
rtx prev = PREV_INSN (bb->head);
|
|
|
|
|
rtx before = bb->head;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
while (before != 0)
|
|
|
|
|
{
|
|
|
|
|
if (GET_CODE (before) != CODE_LABEL
|
|
|
|
|
&& (GET_CODE (before) != NOTE
|
|
|
|
|
|| NOTE_LINE_NUMBER (before) != NOTE_INSN_BASIC_BLOCK))
|
|
|
|
|
break;
|
|
|
|
|
prev = before;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (prev == bb->end)
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
break;
|
|
|
|
|
before = NEXT_INSN (before);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
insn = emit_insn_after (insn, prev);
|
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (prev == bb->end)
|
|
|
|
|
bb->end = insn;
|
2001-04-09 17:17:08 +02:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
set_block_for_new_insns (insn, bb);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file, "STORE_MOTION insert store at start of BB %d:\n",
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
bb->index);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
print_inline_rtx (gcse_file, insn, 6);
|
|
|
|
|
fprintf (gcse_file, "\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This routine will insert a store on an edge. EXPR is the ldst entry for
|
|
|
|
|
the memory reference, and E is the edge to insert it on. Returns non-zero
|
|
|
|
|
if an edge insertion was performed. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
insert_store (expr, e)
|
|
|
|
|
struct ls_expr * expr;
|
|
|
|
|
edge e;
|
|
|
|
|
{
|
|
|
|
|
rtx reg, insn;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
edge tmp;
|
|
|
|
|
|
|
|
|
|
/* We did all the deleted before this insert, so if we didn't delete a
|
|
|
|
|
store, then we haven't set the reaching reg yet either. */
|
|
|
|
|
if (expr->reaching_reg == NULL_RTX)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
reg = expr->reaching_reg;
|
|
|
|
|
insn = gen_move_insn (expr->pattern, reg);
|
|
|
|
|
|
|
|
|
|
/* If we are inserting this expression on ALL predecessor edges of a BB,
|
|
|
|
|
insert it at the start of the BB, and reset the insert bits on the other
|
|
|
|
|
edges so we don;t try to insert it on the other edges. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
bb = e->dest;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
for (tmp = e->dest->pred; tmp ; tmp = tmp->pred_next)
|
|
|
|
|
{
|
|
|
|
|
int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
|
|
|
|
|
if (index == EDGE_INDEX_NO_EDGE)
|
|
|
|
|
abort ();
|
|
|
|
|
if (! TEST_BIT (pre_insert_map[index], expr->index))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If tmp is NULL, we found an insertion on every edge, blank the
|
|
|
|
|
insertion vector for these edges, and insert at the start of the BB. */
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (!tmp && bb != EXIT_BLOCK_PTR)
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
|
|
|
|
for (tmp = e->dest->pred; tmp ; tmp = tmp->pred_next)
|
|
|
|
|
{
|
|
|
|
|
int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
|
|
|
|
|
RESET_BIT (pre_insert_map[index], expr->index);
|
|
|
|
|
}
|
|
|
|
|
insert_insn_start_bb (insn, bb);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We can't insert on this edge, so we'll insert at the head of the
|
|
|
|
|
successors block. See Morgan, sec 10.5. */
|
|
|
|
|
if ((e->flags & EDGE_ABNORMAL) == EDGE_ABNORMAL)
|
|
|
|
|
{
|
|
|
|
|
insert_insn_start_bb (insn, bb);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
insert_insn_on_edge (insn, e);
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file, "STORE_MOTION insert insn on edge (%d, %d):\n",
|
|
|
|
|
e->src->index, e->dest->index);
|
|
|
|
|
print_inline_rtx (gcse_file, insn, 6);
|
|
|
|
|
fprintf (gcse_file, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This routine will replace a store with a SET to a specified register. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
replace_store_insn (reg, del, bb)
|
|
|
|
|
rtx reg, del;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
|
|
|
|
rtx insn;
|
|
|
|
|
|
|
|
|
|
insn = gen_move_insn (reg, SET_SRC (PATTERN (del)));
|
|
|
|
|
insn = emit_insn_after (insn, del);
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
set_block_for_new_insns (insn, bb);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file,
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
"STORE_MOTION delete insn in BB %d:\n ", bb->index);
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
print_inline_rtx (gcse_file, del, 6);
|
|
|
|
|
fprintf(gcse_file, "\nSTORE MOTION replaced with insn:\n ");
|
|
|
|
|
print_inline_rtx (gcse_file, insn, 6);
|
|
|
|
|
fprintf(gcse_file, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (bb->end == del)
|
|
|
|
|
bb->end = insn;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (bb->head == del)
|
|
|
|
|
bb->head = insn;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
delete_insn (del);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Delete a store, but copy the value that would have been stored into
|
|
|
|
|
the reaching_reg for later storing. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
delete_store (expr, bb)
|
|
|
|
|
struct ls_expr * expr;
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
basic_block bb;
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
|
|
|
|
rtx reg, i, del;
|
|
|
|
|
|
|
|
|
|
if (expr->reaching_reg == NULL_RTX)
|
|
|
|
|
expr->reaching_reg = gen_reg_rtx (GET_MODE (expr->pattern));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* If there is more than 1 store, the earlier ones will be dead,
|
|
|
|
|
but it doesn't hurt to replace them here. */
|
|
|
|
|
reg = expr->reaching_reg;
|
|
|
|
|
|
|
|
|
|
for (i = AVAIL_STORE_LIST (expr); i; i = XEXP (i, 1))
|
|
|
|
|
{
|
|
|
|
|
del = XEXP (i, 0);
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
if (BLOCK_FOR_INSN (del) == bb)
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
{
|
|
|
|
|
/* We know there is only one since we deleted redundant
|
|
|
|
|
ones during the available computation. */
|
|
|
|
|
replace_store_insn (reg, del, bb);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free memory used by store motion. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_store_memory ()
|
|
|
|
|
{
|
|
|
|
|
free_ldst_mems ();
|
|
|
|
|
|
|
|
|
|
if (ae_gen)
|
|
|
|
|
free (ae_gen);
|
|
|
|
|
if (ae_kill)
|
|
|
|
|
free (ae_kill);
|
|
|
|
|
if (transp)
|
|
|
|
|
free (transp);
|
|
|
|
|
if (st_antloc)
|
|
|
|
|
free (st_antloc);
|
|
|
|
|
if (pre_insert_map)
|
|
|
|
|
free (pre_insert_map);
|
|
|
|
|
if (pre_delete_map)
|
|
|
|
|
free (pre_delete_map);
|
|
|
|
|
if (reg_set_in_block)
|
|
|
|
|
free (reg_set_in_block);
|
|
|
|
|
|
|
|
|
|
ae_gen = ae_kill = transp = st_antloc = NULL;
|
|
|
|
|
pre_insert_map = pre_delete_map = reg_set_in_block = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Perform store motion. Much like gcse, except we move expressions the
|
|
|
|
|
other way by looking at the flowgraph in reverse. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
store_motion ()
|
|
|
|
|
{
|
|
|
|
|
int x;
|
|
|
|
|
struct ls_expr * ptr;
|
|
|
|
|
int update_flow = 0;
|
|
|
|
|
|
|
|
|
|
if (gcse_file)
|
|
|
|
|
{
|
|
|
|
|
fprintf (gcse_file, "before store motion\n");
|
|
|
|
|
print_rtl (gcse_file, get_insns ());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
init_alias_analysis ();
|
|
|
|
|
|
|
|
|
|
/* Find all the stores that are live to the end of their block. */
|
|
|
|
|
num_stores = compute_store_table ();
|
|
|
|
|
if (num_stores == 0)
|
|
|
|
|
{
|
|
|
|
|
free (reg_set_in_block);
|
|
|
|
|
end_alias_analysis ();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now compute whats actually available to move. */
|
|
|
|
|
add_noreturn_fake_exit_edges ();
|
|
|
|
|
build_store_vectors ();
|
|
|
|
|
|
|
|
|
|
edge_list = pre_edge_rev_lcm (gcse_file, num_stores, transp, ae_gen,
|
|
|
|
|
st_antloc, ae_kill, &pre_insert_map,
|
|
|
|
|
&pre_delete_map);
|
|
|
|
|
|
|
|
|
|
/* Now we want to insert the new stores which are going to be needed. */
|
|
|
|
|
for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
|
|
|
|
|
{
|
|
|
|
|
for (x = 0; x < n_basic_blocks; x++)
|
|
|
|
|
if (TEST_BIT (pre_delete_map[x], ptr->index))
|
gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
* gcse.c (oprs_unchanged_p): Pass basic_block to load_killed_in_block_p.
(load_killed_in_block_p): Change bb parameter from int to basic_block.
(oprs_not_set_p): Pass basic_blocks instead of ints as parameters.
(handle_rd_kill_set): Change bb parameter from int to basic_block.
(compute_kill_rd): Pass basic_blocks instead of ints as parameters.
(expr_killed_p): Change bb parameter from int to basic_block, pass
basic_blocks instead of ints as parameters.
(compute_ae_kill): Pass basic_blocks instead of ints as parameters.
(expr_reaches_here_p_work, expr_reaches_here_p): Change bb parameter
from int to basic_block, pass basic_blocks instead of ints as parms.
(pre_expr_reaches_here_p_work, pre_expr_reaches_here_p): Change bb
parameter from int to basic_block, pass basic_blocks instead of ints.
(process_insert_insn): Pass basic_blocks instead of ints as parameters.
(insert_insn_end_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(pre_edge_insert, pre_insert_copy_insn, pre_insert_copies): Pass
basic_blocks instead of ints as parameters.
(pre_delete): Pass basic_blocks instead of ints as parameters.
(hoist_expr_reaches_here_p): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(hoist_code): Pass basic_blocks instead of ints as parameters.
(reg_set_info, store_ops_ok, store_killed_after, store_killed_before):
Change bb parameter from int to basic_block.
(build_store_vectors): Pass basic_blocks instead of ints as parameters.
(insert_insn_start_bb): Change bb parameter from int to basic_block,
pass basic_blocks instead of ints.
(insert_store): Pass basic_blocks instead of ints as parameters.
(replace_store_insn, delete_store): Change bb parameter from int to
basic_block, pass basic_blocks instead of ints.
(store_motion): Pass basic_blocks instead of ints as parameters.
From-SVN: r41209
2001-04-09 17:20:26 +02:00
|
|
|
|
delete_store (ptr, BASIC_BLOCK (x));
|
alias.c (get_addr): Externalize.
2001-04-09 Andrew MacLeod <amacleod@redhat.com>
Jeff Law <law@cygnus.com>
* alias.c (get_addr): Externalize.
(canon_true_dependence): New function. Behaves like true_dependance
except it already assumes a MEM has been canonicalized.
* flags.h (flag_gcse_lm, flag_gcse_sm): New optimization flags.
* gcse.c (struct ls_expr): Add load/store expressions structure.
(modify_mem_list, canon_modify_mem_list): New variable.
(gcse_main): Initialize & finalize alias analysis. Use enhanced
load motion and store motion if requested.
(alloc_gcse_mem): Allocate space for modify_mem_list array.
(free_gcse_mem): Free the modify_mem_list array.
(oprs_unchanged_p): Use load_killed_in_block_p.
(gcse_mems_conflict_p, gcse_mem_operand): New variables.
(mems_conflict_for_gcse_p): New function. Don't kill loads
with stores to themselves if its in the load/store expression list.
(load_killed_in_block_p): New function.
(canon_list_insert): New Function.
(record_last_mem_set_info): Keep a list of all instructions which
can modify memory for each basic block.
(compute_hash_table, reset_opr_set_tables): Clear modify_mem_list.
(oprs_not_set_p): Use load_killed_in_block_p.
(mark_call, mark_set, mark_clobber): Use record_last_mem_set_info.
(expr_killed_p): Use load_killed_in_block_p.
(compute_transp): Do not pessimize memory references.
(pre_edge_insert): Update stores for a load motion expression.
(one_pre_gcse_pass): Check loads/stores for extra load motion.
(ldst_entry): Find or create a ldst_expr structure.
(free_ldst_entry): Free memory for an individual item.
(free_ldst_mems): Free entire load/store expression list.
(print_ldst_list): Print debug info.
(find_rtx_in_ldst): Try to find an rtx expression in the ldst list.
(enumerate_ldsts): Assign integer values to each entry in list.
(first_ls_expr): First expression in the list.
(next_ls_expr): Next expression in the list.
(simple_mem): Check if expression qualifies for ld/st expression list.
(invalidate_any_buried_refs): Remove from expression list if its
used in some other way we dont understand.
(compute_ld_motion_mems): Find all potential enhanced load motion
expression.
(trim_ld_motion_mems): Remove any expressions which are invalid.
(update_ld_motion_stores): Copy store values to registers for loads
which have been moved.
(regvec, st_antloc, num_store): New global statics.
(reg_set_info): Marks registers as set.
(store_ops_ok): Verfies registers expressions are valid in a block.
(find_moveable_store): Look for moveable stores in a pattern.
(compute_store_table): Find stores in a function worth moving, maybe.
(load_kills_store): Check dependance of a load and store.
(find_loads): Find any loads in a pattern.
(store_killed_in_insn): Check if a store is killed in an insn.
(store_killed_after): Check is store killed after an insn in a block.
(store_killed_before): Check is store killed before an insn in a block.
(build_store_vectors): Generate the antic and avail vectors.
(insert_insn_start_bb): Insert at the start of a BB, update BLOCK_HEAD.
(insert_store): Add a store to an edge.
(replace_store_insn): Replace a store with a SET insn.
(delete_store): Delete a store insn.
(free_store_memory): Free memory.
(store_motion): Perform store motion.
* invoke.texi: Add documentation for -fcse-lm and -fgcse-sm.
* rtl.h (get_addr, canon_true_dependence): Add prototypes.
* toplev.c (flag_gcse_lm, flag_gcse_sm): New Variables.
(f_options): Add gcse-lm and gcse-sm.
Co-Authored-By: Jeff Law <law@redhat.com>
From-SVN: r41207
2001-04-09 16:27:05 +02:00
|
|
|
|
|
|
|
|
|
for (x = 0; x < NUM_EDGES (edge_list); x++)
|
|
|
|
|
if (TEST_BIT (pre_insert_map[x], ptr->index))
|
|
|
|
|
update_flow |= insert_store (ptr, INDEX_EDGE (edge_list, x));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (update_flow)
|
|
|
|
|
commit_edge_insertions ();
|
|
|
|
|
|
|
|
|
|
free_store_memory ();
|
|
|
|
|
free_edge_list (edge_list);
|
|
|
|
|
remove_fake_edges ();
|
|
|
|
|
end_alias_analysis ();
|
|
|
|
|
}
|