1 |
691 |
jeremybenn |
/* { dg-do compile } */
|
2 |
|
|
/* { dg-options "-w -O2 -fselective-scheduling2 -fsel-sched-pipelining" } */
|
3 |
|
|
|
4 |
|
|
typedef struct rtx_def *rtx;
|
5 |
|
|
typedef const struct rtx_def *const_rtx;
|
6 |
|
|
typedef struct basic_block_def *basic_block;
|
7 |
|
|
enum machine_mode {
|
8 |
|
|
VOIDmode, BLKmode, CCmode, CCImode, BImode, QImode, HImode, SImode, DImode, TImode, OImode, QQmode, HQmode, SQmode, DQmode, TQmode, UQQmode, UHQmode, USQmode, UDQmode, UTQmode, HAmode, SAmode, DAmode, TAmode, UHAmode, USAmode, UDAmode, UTAmode, SFmode, DFmode, XFmode, RFmode, TFmode, SDmode, DDmode, TDmode, CQImode, CHImode, CSImode, CDImode, CTImode, COImode, SCmode, DCmode, XCmode, RCmode, TCmode, V4QImode, V2HImode, V8QImode, V4HImode, V2SImode, V16QImode, V8HImode, V4SImode, V2SFmode, V4SFmode, MAX_MACHINE_MODE, MIN_MODE_RANDOM = VOIDmode, MAX_MODE_RANDOM = BLKmode, MIN_MODE_CC = CCmode, MAX_MODE_CC = CCImode, MIN_MODE_INT = QImode, MAX_MODE_INT = OImode, MIN_MODE_PARTIAL_INT = VOIDmode, MAX_MODE_PARTIAL_INT = VOIDmode, MIN_MODE_FRACT = QQmode, MAX_MODE_FRACT = TQmode, MIN_MODE_UFRACT = UQQmode, MAX_MODE_UFRACT = UTQmode, MIN_MODE_ACCUM = HAmode, MAX_MODE_ACCUM = TAmode, MIN_MODE_UACCUM = UHAmode, MAX_MODE_UACCUM = UTAmode, MIN_MODE_FLOAT = SFmode, MAX_MODE_FLOAT = TFmode, MIN_MODE_DECIMAL_FLOAT = SDmode, MAX_MODE_DECIMAL_FLOAT = TDmode, MIN_MODE_COMPLEX_INT = CQImode, MAX_MODE_COMPLEX_INT = COImode, MIN_MODE_COMPLEX_FLOAT = SCmode, MAX_MODE_COMPLEX_FLOAT = TCmode, MIN_MODE_VECTOR_INT = V4QImode, MAX_MODE_VECTOR_INT = V4SImode, MIN_MODE_VECTOR_FRACT = VOIDmode, MAX_MODE_VECTOR_FRACT = VOIDmode, MIN_MODE_VECTOR_UFRACT = VOIDmode, MAX_MODE_VECTOR_UFRACT = VOIDmode, MIN_MODE_VECTOR_ACCUM = VOIDmode, MAX_MODE_VECTOR_ACCUM = VOIDmode, MIN_MODE_VECTOR_UACCUM = VOIDmode, MAX_MODE_VECTOR_UACCUM = VOIDmode, MIN_MODE_VECTOR_FLOAT = V2SFmode, MAX_MODE_VECTOR_FLOAT = V4SFmode, NUM_MACHINE_MODES = MAX_MACHINE_MODE };
|
9 |
|
|
struct real_value {
|
10 |
|
|
};
|
11 |
|
|
extern void vec_assert_fail (const char *, const char * ,const char *file_,unsigned line_,const char *function_) __attribute__ ((__noreturn__));
|
12 |
|
|
typedef struct vec_prefix {
|
13 |
|
|
unsigned num;
|
14 |
|
|
};
|
15 |
|
|
enum rtx_code {
|
16 |
|
|
UNKNOWN , VALUE , DEBUG_EXPR , EXPR_LIST , INSN_LIST , SEQUENCE , ADDRESS , DEBUG_INSN , INSN , JUMP_INSN , CALL_INSN , BARRIER , CODE_LABEL , NOTE , COND_EXEC , PARALLEL , ASM_INPUT , ASM_OPERANDS , UNSPEC , UNSPEC_VOLATILE , ADDR_VEC , ADDR_DIFF_VEC , PREFETCH , SET , USE , CLOBBER , CALL , RETURN , EH_RETURN , TRAP_IF , CONST_INT , CONST_FIXED , CONST_DOUBLE , CONST_VECTOR , CONST_STRING , CONST , PC , REG , SCRATCH , SUBREG , STRICT_LOW_PART , CONCAT , CONCATN , MEM , LABEL_REF , SYMBOL_REF , CC0 , IF_THEN_ELSE , COMPARE , PLUS , MINUS , NEG , MULT , SS_MULT , US_MULT , DIV , SS_DIV , US_DIV , MOD , UDIV , UMOD , AND , IOR , XOR , NOT , ASHIFT , ROTATE , ASHIFTRT , LSHIFTRT , ROTATERT , SMIN , SMAX , UMIN , UMAX , PRE_DEC , PRE_INC , POST_DEC , POST_INC , PRE_MODIFY , POST_MODIFY , NE , EQ , GE , GT , LE , LT , GEU , GTU , LEU , LTU , UNORDERED , ORDERED , UNEQ , UNGE , UNGT , UNLE , UNLT , LTGT , SIGN_EXTEND , ZERO_EXTEND , TRUNCATE , FLOAT_EXTEND , FLOAT_TRUNCATE , FLOAT , FIX , UNSIGNED_FLOAT , UNSIGNED_FIX , FRACT_CONVERT , UNSIGNED_FRACT_CONVERT , SAT_FRACT , UNSIGNED_SAT_FRACT , ABS , SQRT , BSWAP , FFS , CLZ , CTZ , POPCOUNT , PARITY , SIGN_EXTRACT , ZERO_EXTRACT , HIGH , LO_SUM , VEC_MERGE , VEC_SELECT , VEC_CONCAT , VEC_DUPLICATE , SS_PLUS , US_PLUS , SS_MINUS , SS_NEG , US_NEG , SS_ABS , SS_ASHIFT , US_ASHIFT , US_MINUS , SS_TRUNCATE , US_TRUNCATE , FMA , VAR_LOCATION , DEBUG_IMPLICIT_PTR , ENTRY_VALUE , LAST_AND_UNUSED_RTX_CODE};
|
17 |
|
|
enum rtx_class {
|
18 |
|
|
RTX_COMPARE, RTX_COMM_COMPARE, RTX_BIN_ARITH, RTX_COMM_ARITH, RTX_UNARY, RTX_EXTRA, RTX_MATCH, RTX_INSN, RTX_OBJ, RTX_CONST_OBJ, RTX_TERNARY, RTX_BITFIELD_OPS, RTX_AUTOINC };
|
19 |
|
|
extern const enum rtx_class rtx_class[((int) LAST_AND_UNUSED_RTX_CODE)];
|
20 |
|
|
union rtunion_def {
|
21 |
|
|
int rt_int;
|
22 |
|
|
unsigned int rt_uint;
|
23 |
|
|
rtx rt_rtx;
|
24 |
|
|
};
|
25 |
|
|
typedef union rtunion_def rtunion;
|
26 |
|
|
struct rtx_def {
|
27 |
|
|
__extension__ enum rtx_code code: 16;
|
28 |
|
|
__extension__ enum machine_mode mode : 8;
|
29 |
|
|
unsigned int unchanging : 1;
|
30 |
|
|
union u {
|
31 |
|
|
rtunion fld[1];
|
32 |
|
|
}
|
33 |
|
|
u;
|
34 |
|
|
};
|
35 |
|
|
static __inline__ unsigned int rhs_regno (const_rtx x) {
|
36 |
|
|
return (((x)->u.fld[0]).rt_uint);
|
37 |
|
|
}
|
38 |
|
|
struct regstat_n_sets_and_refs_t {
|
39 |
|
|
int sets;
|
40 |
|
|
};
|
41 |
|
|
extern struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs;
|
42 |
|
|
static __inline__ int REG_N_SETS (int regno) {
|
43 |
|
|
return regstat_n_sets_and_refs[regno].sets;
|
44 |
|
|
}
|
45 |
|
|
struct target_regs {
|
46 |
|
|
unsigned char x_hard_regno_nregs[334][MAX_MACHINE_MODE];
|
47 |
|
|
};
|
48 |
|
|
extern struct target_regs default_target_regs;
|
49 |
|
|
static __inline__ unsigned int end_hard_regno (enum machine_mode mode, unsigned int regno) {
|
50 |
|
|
return regno + ((&default_target_regs)->x_hard_regno_nregs)[regno][(int) mode];
|
51 |
|
|
}
|
52 |
|
|
struct function {
|
53 |
|
|
struct eh_status *eh;
|
54 |
|
|
struct control_flow_graph *cfg;
|
55 |
|
|
};
|
56 |
|
|
extern struct function *cfun;
|
57 |
|
|
typedef struct VEC_edge_gc {
|
58 |
|
|
}
|
59 |
|
|
VEC_edge_gc;
|
60 |
|
|
struct basic_block_def {
|
61 |
|
|
VEC_edge_gc *preds;
|
62 |
|
|
struct basic_block_def *next_bb;
|
63 |
|
|
int index;
|
64 |
|
|
}
|
65 |
|
|
VEC_basic_block_gc;
|
66 |
|
|
struct control_flow_graph {
|
67 |
|
|
basic_block x_entry_block_ptr;
|
68 |
|
|
}
|
69 |
|
|
bitmap_obstack;
|
70 |
|
|
typedef struct bitmap_element_def {
|
71 |
|
|
}
|
72 |
|
|
bitmap_element;
|
73 |
|
|
typedef struct bitmap_head_def {
|
74 |
|
|
bitmap_element *first;
|
75 |
|
|
bitmap_element *current;
|
76 |
|
|
}
|
77 |
|
|
bitmap_head;
|
78 |
|
|
struct dataflow {
|
79 |
|
|
struct df_problem *problem;
|
80 |
|
|
void *block_info;
|
81 |
|
|
unsigned int block_info_size;
|
82 |
|
|
};
|
83 |
|
|
struct df_insn_info {
|
84 |
|
|
int luid;
|
85 |
|
|
};
|
86 |
|
|
struct df_d {
|
87 |
|
|
struct dataflow *problems_by_index[(7 + 1)];
|
88 |
|
|
struct df_insn_info **insns;
|
89 |
|
|
};
|
90 |
|
|
struct df_lr_bb_info {
|
91 |
|
|
bitmap_head def;
|
92 |
|
|
bitmap_head in;
|
93 |
|
|
};
|
94 |
|
|
extern struct df_d *df;
|
95 |
|
|
static __inline__ struct df_lr_bb_info * df_lr_get_bb_info (unsigned int index) {
|
96 |
|
|
if (index < (df->problems_by_index[1])->block_info_size) return &((struct df_lr_bb_info *) (df->problems_by_index[1])->block_info)[index];
|
97 |
|
|
else return ((void *)0);
|
98 |
|
|
}
|
99 |
|
|
typedef struct reg_stat_struct {
|
100 |
|
|
int last_set_label;
|
101 |
|
|
unsigned long last_set_nonzero_bits;
|
102 |
|
|
char last_set_invalid;
|
103 |
|
|
}
|
104 |
|
|
reg_stat_type;
|
105 |
|
|
typedef struct VEC_reg_stat_type_base {
|
106 |
|
|
struct vec_prefix prefix;
|
107 |
|
|
reg_stat_type vec[1];
|
108 |
|
|
}
|
109 |
|
|
VEC_reg_stat_type_base;
|
110 |
|
|
static __inline__ reg_stat_type *VEC_reg_stat_type_base_index (VEC_reg_stat_type_base *vec_, unsigned ix_ ,const char *file_,unsigned line_,const char *function_) {
|
111 |
|
|
(void)((vec_ && ix_ < vec_->prefix.num) ? 0 : (vec_assert_fail ("index","VEC(reg_stat_type,base)" ,file_,line_,function_), 0));
|
112 |
|
|
return &vec_->vec[ix_];
|
113 |
|
|
}
|
114 |
|
|
typedef struct VEC_reg_stat_type_heap {
|
115 |
|
|
VEC_reg_stat_type_base base;
|
116 |
|
|
}
|
117 |
|
|
VEC_reg_stat_type_heap;
|
118 |
|
|
static VEC_reg_stat_type_heap *reg_stat;
|
119 |
|
|
static int mem_last_set;
|
120 |
|
|
static int label_tick;
|
121 |
|
|
int get_last_value_validate (rtx *loc, rtx insn, int tick, int replace)
|
122 |
|
|
{
|
123 |
|
|
rtx x = *loc;
|
124 |
|
|
int i, j;
|
125 |
|
|
if ((((enum rtx_code) (x)->code) == REG))
|
126 |
|
|
{
|
127 |
|
|
unsigned int regno = (rhs_regno(x));
|
128 |
|
|
unsigned int endregno = (((((rhs_regno(x))) < 334)) ? end_hard_regno (((enum machine_mode) (x)->mode), (rhs_regno(x))) : (rhs_regno(x)) + 1);
|
129 |
|
|
for (j = regno;
|
130 |
|
|
j < endregno;
|
131 |
|
|
j++)
|
132 |
|
|
{
|
133 |
|
|
reg_stat_type *rsp = (VEC_reg_stat_type_base_index(((reg_stat) ? &(reg_stat)->base : 0),j ,"/gcc/combine.c",12640,__FUNCTION__));
|
134 |
|
|
if (
|
135 |
|
|
rsp->last_set_invalid
|
136 |
|
|
||
|
137 |
|
|
(
|
138 |
|
|
(
|
139 |
|
|
regno >= 334
|
140 |
|
|
&& REG_N_SETS (regno) == 1
|
141 |
|
|
&& (!bitmap_bit_p ((&(df_lr_get_bb_info((((cfun + 0)->cfg->x_entry_block_ptr)->next_bb)->index))->in), regno) )
|
142 |
|
|
)
|
143 |
|
|
&& rsp->last_set_label > tick
|
144 |
|
|
)
|
145 |
|
|
)
|
146 |
|
|
{
|
147 |
|
|
return replace;
|
148 |
|
|
}
|
149 |
|
|
}
|
150 |
|
|
}
|
151 |
|
|
else if ((((enum rtx_code) (x)->code) == MEM)
|
152 |
|
|
&&
|
153 |
|
|
(
|
154 |
|
|
(
|
155 |
|
|
{
|
156 |
|
|
__typeof ((x)) const _rtx = ((x));
|
157 |
|
|
_rtx;
|
158 |
|
|
}
|
159 |
|
|
)->unchanging
|
160 |
|
|
)
|
161 |
|
|
&&
|
162 |
|
|
(
|
163 |
|
|
tick != label_tick
|
164 |
|
|
|| ((((df->insns[((((insn)->u.fld[0]).rt_int))]))->luid)) <= mem_last_set
|
165 |
|
|
)
|
166 |
|
|
)
|
167 |
|
|
{
|
168 |
|
|
{
|
169 |
|
|
if (
|
170 |
|
|
i == 1
|
171 |
|
|
)
|
172 |
|
|
{
|
173 |
|
|
rtx x0 = (((x)->u.fld[0]).rt_rtx);
|
174 |
|
|
rtx x1 = (((x)->u.fld[1]).rt_rtx);
|
175 |
|
|
if ((((rtx_class[(int) (((enum rtx_code) (x1)->code))]) & (~1)) == (RTX_COMM_ARITH & (~1)))
|
176 |
|
|
&&
|
177 |
|
|
(
|
178 |
|
|
x0 == (((x1)->u.fld[0]).rt_rtx)
|
179 |
|
|
)
|
180 |
|
|
)
|
181 |
|
|
return get_last_value_validate (&(((x1)->u.fld[x0 == (((x1)->u.fld[0]).rt_rtx) ? 1 : 0]).rt_rtx) , insn, tick, replace);
|
182 |
|
|
}
|
183 |
|
|
}
|
184 |
|
|
}
|
185 |
|
|
}
|