View | Details | Return to bug 15459
Collapse All | Expand All

(-)tree-ssa-combine.c (+252 lines)
Added Link Here
1
/* Optimize by combining SSA trees for GNU compiler.
2
   Copyright (C) 2004 Free Software Foundation, Inc.
3
   Contributed by Andrew Pinski.
4
5
This file is part of GCC.
6
   
7
GCC is free software; you can redistribute it and/or modify it
8
under the terms of the GNU General Public License as published by the
9
Free Software Foundation; either version 2, or (at your option) any
10
later version.
11
   
12
GCC is distributed in the hope that it will be useful, but WITHOUT
13
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
   
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING.  If not, write to the Free
19
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20
02111-1307, USA.  */
21
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "errors.h"
27
#include "ggc.h"
28
#include "tree.h"
29
#include "rtl.h"
30
#include "tm_p.h"
31
#include "basic-block.h"
32
#include "timevar.h"
33
#include "diagnostic.h"
34
#include "tree-flow.h"
35
#include "tree-pass.h"
36
#include "tree-dump.h"
37
#include "langhooks.h"
38
39
   
40
static void
41
tree_ssa_combine (void)
42
{
43
  basic_block bb;
44
45
  /* Search every basic block for PHI nodes we may be able to optimize.  */
46
  FOR_EACH_BB (bb)
47
    {
48
      block_stmt_iterator bsi;
49
      for(bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
50
        {
51
          tree stmt = bsi_stmt (bsi);
52
          tree orginal_stmt = stmt;
53
          tree arg0, arg1 = NULL_TREE;
54
          tree variable0, variable1 = NULL_TREE;
55
          tree arg0Mod, arg1Mod;
56
          tree folded;
57
          bool twovariables;
58
          enum tree_code code;
59
60
          tree rhs;
61
          tree *tomodif;
62
          
63
          if (TREE_CODE (stmt) == RETURN_EXPR)
64
            stmt = TREE_OPERAND (stmt, 0);
65
66
          if (stmt == NULL)
67
            continue;
68
          else if (TREE_CODE (stmt) == COND_EXPR)
69
            {
70
              tomodif = &TREE_OPERAND (stmt, 0);
71
              rhs = *tomodif;
72
            }
73
          else if (TREE_CODE (stmt) == MODIFY_EXPR)
74
            {
75
              tomodif = &TREE_OPERAND (stmt, 1);
76
              rhs = *tomodif;
77
            }
78
	  else
79
	    continue;
80
81
          code = TREE_CODE (rhs);
82
83
          /* FIXME: handle different length other than one or two, maybe
84
             using an array.  */
85
          if (TREE_CODE_LENGTH (code) != 1
86
              && TREE_CODE_LENGTH (code) != 2)
87
            continue;
88
89
          twovariables = TREE_CODE_LENGTH (code) == 2;
90
91
          variable0 = TREE_OPERAND (rhs, 0);
92
93
          if (variable0 == NULL || TREE_CODE (variable0) != SSA_NAME
94
	      || TREE_ADDRESSABLE (SSA_NAME_VAR (variable0)))
95
            continue;
96
97
          arg0Mod = SSA_NAME_DEF_STMT (variable0);
98
99
          if (TREE_CODE (arg0Mod) != MODIFY_EXPR)
100
            continue;
101
102
          get_stmt_operands (arg0Mod);
103
104
          /* We only want ones which are used only once.  */
105
          if (NUM_USES (USE_OPS (stmt_ann (arg0Mod))) != 1)
106
            continue;
107
108
          arg0 = TREE_OPERAND (arg0Mod, 1);
109
110
          if (TREE_CODE_CLASS (TREE_CODE (arg0)) == 'r')
111
            continue;
112
113
          if (twovariables)
114
            {
115
              variable1 = TREE_OPERAND (rhs, 1);
116
  
117
              if (variable1 == NULL || TREE_CODE (variable1) != SSA_NAME
118
                  || TREE_ADDRESSABLE (SSA_NAME_VAR (variable1)))
119
                twovariables = false;
120
              else
121
                {
122
123
                  arg1Mod = SSA_NAME_DEF_STMT (variable1);
124
  
125
                  if (TREE_CODE (arg1Mod) != MODIFY_EXPR)
126
                    continue;
127
                  
128
                  get_stmt_operands (arg1Mod);
129
130
                  /* We only want ones which are used only once.  */
131
                  if (NUM_USES (USE_OPS (stmt_ann (arg1Mod))) != 1)
132
                    continue;
133
      
134
                  arg1 = TREE_OPERAND (arg1Mod, 1);
135
136
                  if (TREE_CODE_CLASS (TREE_CODE (arg1)) == 'r')
137
                    continue;
138
      
139
                  TREE_OPERAND (rhs, 1) = arg1;
140
                }
141
            }
142
143
          TREE_OPERAND (rhs, 0) = arg0;
144
145
          folded = fold (rhs);
146
147
          if (folded == rhs)
148
            {
149
              /* Undo the creation of non-gimple code.  */
150
              TREE_OPERAND (rhs, 0) = variable0;
151
              if (twovariables)
152
                TREE_OPERAND (rhs, 1) = variable1;
153
              continue;
154
            }
155
          else
156
            {
157
              debug_generic_expr (rhs);
158
              debug_generic_expr (folded);
159
              
160
              /* We got a variable or constant out of this, just use the variable
161
                 or that constant.  */
162
              if (TREE_CODE (folded) == SSA_NAME
163
                  || TREE_CODE_CLASS (TREE_CODE (folded))
164
                      == 'c')
165
                {
166
                  modify_stmt (orginal_stmt);
167
                  *tomodif = folded;
168
                }
169
              else if (TREE_CODE_LENGTH (TREE_CODE (folded)) == 1)
170
                {
171
                  /* Try to gimplify the new folded result.  */
172
                  if (TREE_CODE (TREE_OPERAND (folded, 0)) != SSA_NAME
173
                      && ! DECL_P (TREE_OPERAND (folded, 0)))
174
                    {
175
                      fprintf (stderr, "false\n");
176
                      /* XXX: for right now just undo the non-gimple, just wantted
177
                         to print out what would have folded to. */
178
                      TREE_OPERAND (rhs, 0) = variable0;
179
                      if (twovariables)
180
                        TREE_OPERAND (rhs, 1) = variable1;
181
                    }
182
                  else
183
                    {
184
                      modify_stmt (orginal_stmt);
185
                      *tomodif = folded;
186
                    }
187
                }
188
              else if (TREE_CODE_LENGTH (TREE_CODE (folded)) == 2)
189
                {
190
                  /* Try to gimplify the new folded result.  */
191
                  if (TREE_CODE (TREE_OPERAND (folded, 0)) != SSA_NAME
192
                      || (TREE_CODE (TREE_OPERAND (folded, 1)) != SSA_NAME
193
                          && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (folded, 1)))
194
                               != 'c'))
195
                    {
196
                      fprintf (stderr, "false\n");
197
                      /* XXX: for right now just undo the non-gimple, just wantted
198
                         to print out what would have folded to. */
199
                      TREE_OPERAND (rhs, 0) = variable0;
200
                      if (twovariables)
201
                        TREE_OPERAND (rhs, 1) = variable1;
202
                    }
203
                  else
204
                    {
205
                      modify_stmt (orginal_stmt);
206
                      *tomodif = folded;
207
                    }
208
                }
209
              else
210
                {
211
                  /* XXX: for right now just undo the non-gimple, just wantted
212
                    to print out what would have folded to. */
213
                  TREE_OPERAND (rhs, 0) = variable0;
214
                  if (twovariables)
215
                    TREE_OPERAND (rhs, 1) = variable1;
216
                  fprintf (stderr, "false\n");
217
                }
218
              fprintf(stderr, "\n");
219
            }
220
        
221
        }
222
    
223
    }
224
225
}
226
227
/* Always do these optimizations if we have SSA
228
   trees to work on.  */						
229
static bool
230
gate_combine (void)
231
{
232
  return 1;
233
}
234
												
235
struct tree_opt_pass pass_combine =
236
{
237
  "combine",				/* name */
238
  gate_combine,				/* gate */
239
  tree_ssa_combine,			/* execute */
240
  NULL,					/* sub */
241
  NULL,					/* next */
242
  0,					/* static_pass_number */
243
  TV_TREE_PHIOPT,			/* tv_id */
244
  PROP_cfg | PROP_ssa,			/* properties_required */
245
  0,					/* properties_provided */
246
  0,					/* properties_destroyed */
247
  0,					/* todo_flags_start */
248
  TODO_dump_func | TODO_ggc_collect	/* todo_flags_finish */
249
    | TODO_verify_ssa
250
};
251
												
252
(-)tree-optimize.c (+1 lines)
Lines 284-289 init_tree_optimization_passes (void) Link Here
284
  NEXT_PASS (pass_early_warn_uninitialized);
284
  NEXT_PASS (pass_early_warn_uninitialized);
285
  NEXT_PASS (pass_dce);
285
  NEXT_PASS (pass_dce);
286
  NEXT_PASS (pass_dominator);
286
  NEXT_PASS (pass_dominator);
287
  NEXT_PASS (pass_combine);
287
  NEXT_PASS (pass_redundant_phi);
288
  NEXT_PASS (pass_redundant_phi);
288
  NEXT_PASS (DUP_PASS (pass_dce));
289
  NEXT_PASS (DUP_PASS (pass_dce));
289
  NEXT_PASS (pass_forwprop);
290
  NEXT_PASS (pass_forwprop);
(-)tree-pass.h (+1 lines)
Lines 125-130 extern struct tree_opt_pass pass_dse; Link Here
125
extern struct tree_opt_pass pass_nrv;
125
extern struct tree_opt_pass pass_nrv;
126
extern struct tree_opt_pass pass_remove_useless_vars;
126
extern struct tree_opt_pass pass_remove_useless_vars;
127
extern struct tree_opt_pass pass_rename_ssa_copies;
127
extern struct tree_opt_pass pass_rename_ssa_copies;
128
extern struct tree_opt_pass pass_combine;
128
129
129
130
130
#endif /* GCC_TREE_PASS_H */
131
#endif /* GCC_TREE_PASS_H */
(-)Makefile.in (+4 lines)
Lines 873-878 OBJS-common = \ Link Here
873
 @ANDER@ tree-ssa-dce.o  tree-ssa-copy.o tree-nrv.o tree-ssa-copyrename.o  \
873
 @ANDER@ tree-ssa-dce.o  tree-ssa-copy.o tree-nrv.o tree-ssa-copyrename.o  \
874
 tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o       \
874
 tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o       \
875
 tree-ssa-phiopt.o tree-ssa-forwprop.o tree-nested.o tree-ssa-dse.o	   \
875
 tree-ssa-phiopt.o tree-ssa-forwprop.o tree-nested.o tree-ssa-dse.o	   \
876
 tree-ssa-combine.o							   \
876
 tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o	   \
877
 tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o	   \
877
 tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o tree-ssa-loop.o \
878
 tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o tree-ssa-loop.o \
878
 alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o	  	   \
879
 alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o	  	   \
Lines 1579-1584 tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG Link Here
1579
tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
1580
tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
1580
   $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
1581
   $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
1581
   $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H)
1582
   $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H)
1583
tree-ssa-combine.o : tree-ssa-combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
1584
   $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
1585
   $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h
1582
tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
1586
tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
1583
   $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
1587
   $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
1584
   $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h
1588
   $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h

Return to bug 15459