OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [tree-complex.c] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* Lower complex number operations to scalar operations.
2
   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
3
   Free Software Foundation, Inc.
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 3, 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 COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
#include "config.h"
22
#include "system.h"
23
#include "coretypes.h"
24
#include "tm.h"
25
#include "tree.h"
26
#include "rtl.h"
27
#include "real.h"
28
#include "flags.h"
29
#include "tree-flow.h"
30
#include "gimple.h"
31
#include "tree-iterator.h"
32
#include "tree-pass.h"
33
#include "tree-ssa-propagate.h"
34
#include "diagnostic.h"
35
 
36
 
37
/* For each complex ssa name, a lattice value.  We're interested in finding
38
   out whether a complex number is degenerate in some way, having only real
39
   or only complex parts.  */
40
 
41
enum
42
{
43
  UNINITIALIZED = 0,
44
  ONLY_REAL = 1,
45
  ONLY_IMAG = 2,
46
  VARYING = 3
47
};
48
 
49
/* The type complex_lattice_t holds combinations of the above
50
   constants.  */
51
typedef int complex_lattice_t;
52
 
53
#define PAIR(a, b)  ((a) << 2 | (b))
54
 
55
DEF_VEC_I(complex_lattice_t);
56
DEF_VEC_ALLOC_I(complex_lattice_t, heap);
57
 
58
static VEC(complex_lattice_t, heap) *complex_lattice_values;
59
 
60
/* For each complex variable, a pair of variables for the components exists in
61
   the hashtable.  */
62
static htab_t complex_variable_components;
63
 
64
/* For each complex SSA_NAME, a pair of ssa names for the components.  */
65
static VEC(tree, heap) *complex_ssa_name_components;
66
 
67
/* Lookup UID in the complex_variable_components hashtable and return the
68
   associated tree.  */
69
static tree
70
cvc_lookup (unsigned int uid)
71
{
72
  struct int_tree_map *h, in;
73
  in.uid = uid;
74
  h = (struct int_tree_map *) htab_find_with_hash (complex_variable_components, &in, uid);
75
  return h ? h->to : NULL;
76
}
77
 
78
/* Insert the pair UID, TO into the complex_variable_components hashtable.  */
79
 
80
static void
81
cvc_insert (unsigned int uid, tree to)
82
{
83
  struct int_tree_map *h;
84
  void **loc;
85
 
86
  h = XNEW (struct int_tree_map);
87
  h->uid = uid;
88
  h->to = to;
89
  loc = htab_find_slot_with_hash (complex_variable_components, h,
90
                                  uid, INSERT);
91
  *(struct int_tree_map **) loc = h;
92
}
93
 
94
/* Return true if T is not a zero constant.  In the case of real values,
95
   we're only interested in +0.0.  */
96
 
97
static int
98
some_nonzerop (tree t)
99
{
100
  int zerop = false;
101
 
102
  /* Operations with real or imaginary part of a complex number zero
103
     cannot be treated the same as operations with a real or imaginary
104
     operand if we care about the signs of zeros in the result.  */
105
  if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
106
    zerop = REAL_VALUES_IDENTICAL (TREE_REAL_CST (t), dconst0);
107
  else if (TREE_CODE (t) == FIXED_CST)
108
    zerop = fixed_zerop (t);
109
  else if (TREE_CODE (t) == INTEGER_CST)
110
    zerop = integer_zerop (t);
111
 
112
  return !zerop;
113
}
114
 
115
 
116
/* Compute a lattice value from the components of a complex type REAL
117
   and IMAG.  */
118
 
119
static complex_lattice_t
120
find_lattice_value_parts (tree real, tree imag)
121
{
122
  int r, i;
123
  complex_lattice_t ret;
124
 
125
  r = some_nonzerop (real);
126
  i = some_nonzerop (imag);
127
  ret = r * ONLY_REAL + i * ONLY_IMAG;
128
 
129
  /* ??? On occasion we could do better than mapping 0+0i to real, but we
130
     certainly don't want to leave it UNINITIALIZED, which eventually gets
131
     mapped to VARYING.  */
132
  if (ret == UNINITIALIZED)
133
    ret = ONLY_REAL;
134
 
135
  return ret;
136
}
137
 
138
 
139
/* Compute a lattice value from gimple_val T.  */
140
 
141
static complex_lattice_t
142
find_lattice_value (tree t)
143
{
144
  tree real, imag;
145
 
146
  switch (TREE_CODE (t))
147
    {
148
    case SSA_NAME:
149
      return VEC_index (complex_lattice_t, complex_lattice_values,
150
                        SSA_NAME_VERSION (t));
151
 
152
    case COMPLEX_CST:
153
      real = TREE_REALPART (t);
154
      imag = TREE_IMAGPART (t);
155
      break;
156
 
157
    default:
158
      gcc_unreachable ();
159
    }
160
 
161
  return find_lattice_value_parts (real, imag);
162
}
163
 
164
/* Determine if LHS is something for which we're interested in seeing
165
   simulation results.  */
166
 
167
static bool
168
is_complex_reg (tree lhs)
169
{
170
  return TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE && is_gimple_reg (lhs);
171
}
172
 
173
/* Mark the incoming parameters to the function as VARYING.  */
174
 
175
static void
176
init_parameter_lattice_values (void)
177
{
178
  tree parm, ssa_name;
179
 
180
  for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = TREE_CHAIN (parm))
181
    if (is_complex_reg (parm)
182
        && var_ann (parm) != NULL
183
        && (ssa_name = gimple_default_def (cfun, parm)) != NULL_TREE)
184
      VEC_replace (complex_lattice_t, complex_lattice_values,
185
                   SSA_NAME_VERSION (ssa_name), VARYING);
186
}
187
 
188
/* Initialize simulation state for each statement.  Return false if we
189
   found no statements we want to simulate, and thus there's nothing
190
   for the entire pass to do.  */
191
 
192
static bool
193
init_dont_simulate_again (void)
194
{
195
  basic_block bb;
196
  gimple_stmt_iterator gsi;
197
  gimple phi;
198
  bool saw_a_complex_op = false;
199
 
200
  FOR_EACH_BB (bb)
201
    {
202
      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
203
        {
204
          phi = gsi_stmt (gsi);
205
          prop_set_simulate_again (phi,
206
                                   is_complex_reg (gimple_phi_result (phi)));
207
        }
208
 
209
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
210
        {
211
          gimple stmt;
212
          tree op0, op1;
213
          bool sim_again_p;
214
 
215
          stmt = gsi_stmt (gsi);
216
          op0 = op1 = NULL_TREE;
217
 
218
          /* Most control-altering statements must be initially
219
             simulated, else we won't cover the entire cfg.  */
220
          sim_again_p = stmt_ends_bb_p (stmt);
221
 
222
          switch (gimple_code (stmt))
223
            {
224
            case GIMPLE_CALL:
225
              if (gimple_call_lhs (stmt))
226
                sim_again_p = is_complex_reg (gimple_call_lhs (stmt));
227
              break;
228
 
229
            case GIMPLE_ASSIGN:
230
              sim_again_p = is_complex_reg (gimple_assign_lhs (stmt));
231
              if (gimple_assign_rhs_code (stmt) == REALPART_EXPR
232
                  || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
233
                op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
234
              else
235
                op0 = gimple_assign_rhs1 (stmt);
236
              if (gimple_num_ops (stmt) > 2)
237
                op1 = gimple_assign_rhs2 (stmt);
238
              break;
239
 
240
            case GIMPLE_COND:
241
              op0 = gimple_cond_lhs (stmt);
242
              op1 = gimple_cond_rhs (stmt);
243
              break;
244
 
245
            default:
246
              break;
247
            }
248
 
249
          if (op0 || op1)
250
            switch (gimple_expr_code (stmt))
251
              {
252
              case EQ_EXPR:
253
              case NE_EXPR:
254
              case PLUS_EXPR:
255
              case MINUS_EXPR:
256
              case MULT_EXPR:
257
              case TRUNC_DIV_EXPR:
258
              case CEIL_DIV_EXPR:
259
              case FLOOR_DIV_EXPR:
260
              case ROUND_DIV_EXPR:
261
              case RDIV_EXPR:
262
                if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE
263
                    || TREE_CODE (TREE_TYPE (op1)) == COMPLEX_TYPE)
264
                  saw_a_complex_op = true;
265
                break;
266
 
267
              case NEGATE_EXPR:
268
              case CONJ_EXPR:
269
                if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE)
270
                  saw_a_complex_op = true;
271
                break;
272
 
273
              case REALPART_EXPR:
274
              case IMAGPART_EXPR:
275
                /* The total store transformation performed during
276
                  gimplification creates such uninitialized loads
277
                  and we need to lower the statement to be able
278
                  to fix things up.  */
279
                if (TREE_CODE (op0) == SSA_NAME
280
                    && ssa_undefined_value_p (op0))
281
                  saw_a_complex_op = true;
282
                break;
283
 
284
              default:
285
                break;
286
              }
287
 
288
          prop_set_simulate_again (stmt, sim_again_p);
289
        }
290
    }
291
 
292
  return saw_a_complex_op;
293
}
294
 
295
 
296
/* Evaluate statement STMT against the complex lattice defined above.  */
297
 
298
static enum ssa_prop_result
299
complex_visit_stmt (gimple stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
300
                    tree *result_p)
301
{
302
  complex_lattice_t new_l, old_l, op1_l, op2_l;
303
  unsigned int ver;
304
  tree lhs;
305
 
306
  lhs = gimple_get_lhs (stmt);
307
  /* Skip anything but GIMPLE_ASSIGN and GIMPLE_CALL with a lhs.  */
308
  if (!lhs)
309
    return SSA_PROP_VARYING;
310
 
311
  /* These conditions should be satisfied due to the initial filter
312
     set up in init_dont_simulate_again.  */
313
  gcc_assert (TREE_CODE (lhs) == SSA_NAME);
314
  gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
315
 
316
  *result_p = lhs;
317
  ver = SSA_NAME_VERSION (lhs);
318
  old_l = VEC_index (complex_lattice_t, complex_lattice_values, ver);
319
 
320
  switch (gimple_expr_code (stmt))
321
    {
322
    case SSA_NAME:
323
    case COMPLEX_CST:
324
      new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
325
      break;
326
 
327
    case COMPLEX_EXPR:
328
      new_l = find_lattice_value_parts (gimple_assign_rhs1 (stmt),
329
                                        gimple_assign_rhs2 (stmt));
330
      break;
331
 
332
    case PLUS_EXPR:
333
    case MINUS_EXPR:
334
      op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
335
      op2_l = find_lattice_value (gimple_assign_rhs2 (stmt));
336
 
337
      /* We've set up the lattice values such that IOR neatly
338
         models addition.  */
339
      new_l = op1_l | op2_l;
340
      break;
341
 
342
    case MULT_EXPR:
343
    case RDIV_EXPR:
344
    case TRUNC_DIV_EXPR:
345
    case CEIL_DIV_EXPR:
346
    case FLOOR_DIV_EXPR:
347
    case ROUND_DIV_EXPR:
348
      op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
349
      op2_l = find_lattice_value (gimple_assign_rhs2 (stmt));
350
 
351
      /* Obviously, if either varies, so does the result.  */
352
      if (op1_l == VARYING || op2_l == VARYING)
353
        new_l = VARYING;
354
      /* Don't prematurely promote variables if we've not yet seen
355
         their inputs.  */
356
      else if (op1_l == UNINITIALIZED)
357
        new_l = op2_l;
358
      else if (op2_l == UNINITIALIZED)
359
        new_l = op1_l;
360
      else
361
        {
362
          /* At this point both numbers have only one component. If the
363
             numbers are of opposite kind, the result is imaginary,
364
             otherwise the result is real. The add/subtract translates
365
             the real/imag from/to 0/1; the ^ performs the comparison.  */
366
          new_l = ((op1_l - ONLY_REAL) ^ (op2_l - ONLY_REAL)) + ONLY_REAL;
367
 
368
          /* Don't allow the lattice value to flip-flop indefinitely.  */
369
          new_l |= old_l;
370
        }
371
      break;
372
 
373
    case NEGATE_EXPR:
374
    case CONJ_EXPR:
375
      new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
376
      break;
377
 
378
    default:
379
      new_l = VARYING;
380
      break;
381
    }
382
 
383
  /* If nothing changed this round, let the propagator know.  */
384
  if (new_l == old_l)
385
    return SSA_PROP_NOT_INTERESTING;
386
 
387
  VEC_replace (complex_lattice_t, complex_lattice_values, ver, new_l);
388
  return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
389
}
390
 
391
/* Evaluate a PHI node against the complex lattice defined above.  */
392
 
393
static enum ssa_prop_result
394
complex_visit_phi (gimple phi)
395
{
396
  complex_lattice_t new_l, old_l;
397
  unsigned int ver;
398
  tree lhs;
399
  int i;
400
 
401
  lhs = gimple_phi_result (phi);
402
 
403
  /* This condition should be satisfied due to the initial filter
404
     set up in init_dont_simulate_again.  */
405
  gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
406
 
407
  /* We've set up the lattice values such that IOR neatly models PHI meet.  */
408
  new_l = UNINITIALIZED;
409
  for (i = gimple_phi_num_args (phi) - 1; i >= 0; --i)
410
    new_l |= find_lattice_value (gimple_phi_arg_def (phi, i));
411
 
412
  ver = SSA_NAME_VERSION (lhs);
413
  old_l = VEC_index (complex_lattice_t, complex_lattice_values, ver);
414
 
415
  if (new_l == old_l)
416
    return SSA_PROP_NOT_INTERESTING;
417
 
418
  VEC_replace (complex_lattice_t, complex_lattice_values, ver, new_l);
419
  return new_l == VARYING ? SSA_PROP_VARYING : SSA_PROP_INTERESTING;
420
}
421
 
422
/* Create one backing variable for a complex component of ORIG.  */
423
 
424
static tree
425
create_one_component_var (tree type, tree orig, const char *prefix,
426
                          const char *suffix, enum tree_code code)
427
{
428
  tree r = create_tmp_var (type, prefix);
429
  add_referenced_var (r);
430
 
431
  DECL_SOURCE_LOCATION (r) = DECL_SOURCE_LOCATION (orig);
432
  DECL_ARTIFICIAL (r) = 1;
433
 
434
  if (DECL_NAME (orig) && !DECL_IGNORED_P (orig))
435
    {
436
      const char *name = IDENTIFIER_POINTER (DECL_NAME (orig));
437
 
438
      DECL_NAME (r) = get_identifier (ACONCAT ((name, suffix, NULL)));
439
 
440
      SET_DECL_DEBUG_EXPR (r, build1 (code, type, orig));
441
      DECL_DEBUG_EXPR_IS_FROM (r) = 1;
442
      DECL_IGNORED_P (r) = 0;
443
      TREE_NO_WARNING (r) = TREE_NO_WARNING (orig);
444
    }
445
  else
446
    {
447
      DECL_IGNORED_P (r) = 1;
448
      TREE_NO_WARNING (r) = 1;
449
    }
450
 
451
  return r;
452
}
453
 
454
/* Retrieve a value for a complex component of VAR.  */
455
 
456
static tree
457
get_component_var (tree var, bool imag_p)
458
{
459
  size_t decl_index = DECL_UID (var) * 2 + imag_p;
460
  tree ret = cvc_lookup (decl_index);
461
 
462
  if (ret == NULL)
463
    {
464
      ret = create_one_component_var (TREE_TYPE (TREE_TYPE (var)), var,
465
                                      imag_p ? "CI" : "CR",
466
                                      imag_p ? "$imag" : "$real",
467
                                      imag_p ? IMAGPART_EXPR : REALPART_EXPR);
468
      cvc_insert (decl_index, ret);
469
    }
470
 
471
  return ret;
472
}
473
 
474
/* Retrieve a value for a complex component of SSA_NAME.  */
475
 
476
static tree
477
get_component_ssa_name (tree ssa_name, bool imag_p)
478
{
479
  complex_lattice_t lattice = find_lattice_value (ssa_name);
480
  size_t ssa_name_index;
481
  tree ret;
482
 
483
  if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG))
484
    {
485
      tree inner_type = TREE_TYPE (TREE_TYPE (ssa_name));
486
      if (SCALAR_FLOAT_TYPE_P (inner_type))
487
        return build_real (inner_type, dconst0);
488
      else
489
        return build_int_cst (inner_type, 0);
490
    }
491
 
492
  ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
493
  ret = VEC_index (tree, complex_ssa_name_components, ssa_name_index);
494
  if (ret == NULL)
495
    {
496
      ret = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
497
      ret = make_ssa_name (ret, NULL);
498
 
499
      /* Copy some properties from the original.  In particular, whether it
500
         is used in an abnormal phi, and whether it's uninitialized.  */
501
      SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ret)
502
        = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name);
503
      if (TREE_CODE (SSA_NAME_VAR (ssa_name)) == VAR_DECL
504
          && gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name)))
505
        {
506
          SSA_NAME_DEF_STMT (ret) = SSA_NAME_DEF_STMT (ssa_name);
507
          set_default_def (SSA_NAME_VAR (ret), ret);
508
        }
509
 
510
      VEC_replace (tree, complex_ssa_name_components, ssa_name_index, ret);
511
    }
512
 
513
  return ret;
514
}
515
 
516
/* Set a value for a complex component of SSA_NAME, return a
517
   gimple_seq of stuff that needs doing.  */
518
 
519
static gimple_seq
520
set_component_ssa_name (tree ssa_name, bool imag_p, tree value)
521
{
522
  complex_lattice_t lattice = find_lattice_value (ssa_name);
523
  size_t ssa_name_index;
524
  tree comp;
525
  gimple last;
526
  gimple_seq list;
527
 
528
  /* We know the value must be zero, else there's a bug in our lattice
529
     analysis.  But the value may well be a variable known to contain
530
     zero.  We should be safe ignoring it.  */
531
  if (lattice == (imag_p ? ONLY_REAL : ONLY_IMAG))
532
    return NULL;
533
 
534
  /* If we've already assigned an SSA_NAME to this component, then this
535
     means that our walk of the basic blocks found a use before the set.
536
     This is fine.  Now we should create an initialization for the value
537
     we created earlier.  */
538
  ssa_name_index = SSA_NAME_VERSION (ssa_name) * 2 + imag_p;
539
  comp = VEC_index (tree, complex_ssa_name_components, ssa_name_index);
540
  if (comp)
541
    ;
542
 
543
  /* If we've nothing assigned, and the value we're given is already stable,
544
     then install that as the value for this SSA_NAME.  This preemptively
545
     copy-propagates the value, which avoids unnecessary memory allocation.  */
546
  else if (is_gimple_min_invariant (value)
547
           && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
548
    {
549
      VEC_replace (tree, complex_ssa_name_components, ssa_name_index, value);
550
      return NULL;
551
    }
552
  else if (TREE_CODE (value) == SSA_NAME
553
           && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
554
    {
555
      /* Replace an anonymous base value with the variable from cvc_lookup.
556
         This should result in better debug info.  */
557
      if (DECL_IGNORED_P (SSA_NAME_VAR (value))
558
          && !DECL_IGNORED_P (SSA_NAME_VAR (ssa_name)))
559
        {
560
          comp = get_component_var (SSA_NAME_VAR (ssa_name), imag_p);
561
          replace_ssa_name_symbol (value, comp);
562
        }
563
 
564
      VEC_replace (tree, complex_ssa_name_components, ssa_name_index, value);
565
      return NULL;
566
    }
567
 
568
  /* Finally, we need to stabilize the result by installing the value into
569
     a new ssa name.  */
570
  else
571
    comp = get_component_ssa_name (ssa_name, imag_p);
572
 
573
  /* Do all the work to assign VALUE to COMP.  */
574
  list = NULL;
575
  value = force_gimple_operand (value, &list, false, NULL);
576
  last =  gimple_build_assign (comp, value);
577
  gimple_seq_add_stmt (&list, last);
578
  gcc_assert (SSA_NAME_DEF_STMT (comp) == last);
579
 
580
  return list;
581
}
582
 
583
/* Extract the real or imaginary part of a complex variable or constant.
584
   Make sure that it's a proper gimple_val and gimplify it if not.
585
   Emit any new code before gsi.  */
586
 
587
static tree
588
extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p,
589
                   bool gimple_p)
590
{
591
  switch (TREE_CODE (t))
592
    {
593
    case COMPLEX_CST:
594
      return imagpart_p ? TREE_IMAGPART (t) : TREE_REALPART (t);
595
 
596
    case COMPLEX_EXPR:
597
      gcc_unreachable ();
598
 
599
    case VAR_DECL:
600
    case RESULT_DECL:
601
    case PARM_DECL:
602
    case INDIRECT_REF:
603
    case COMPONENT_REF:
604
    case ARRAY_REF:
605
    case VIEW_CONVERT_EXPR:
606
      {
607
        tree inner_type = TREE_TYPE (TREE_TYPE (t));
608
 
609
        t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
610
                    inner_type, unshare_expr (t));
611
 
612
        if (gimple_p)
613
          t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
614
                                        GSI_SAME_STMT);
615
 
616
        return t;
617
      }
618
 
619
    case SSA_NAME:
620
      return get_component_ssa_name (t, imagpart_p);
621
 
622
    default:
623
      gcc_unreachable ();
624
    }
625
}
626
 
627
/* Update the complex components of the ssa name on the lhs of STMT.  */
628
 
629
static void
630
update_complex_components (gimple_stmt_iterator *gsi, gimple stmt, tree r,
631
                           tree i)
632
{
633
  tree lhs;
634
  gimple_seq list;
635
 
636
  lhs = gimple_get_lhs (stmt);
637
 
638
  list = set_component_ssa_name (lhs, false, r);
639
  if (list)
640
    gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
641
 
642
  list = set_component_ssa_name (lhs, true, i);
643
  if (list)
644
    gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
645
}
646
 
647
static void
648
update_complex_components_on_edge (edge e, tree lhs, tree r, tree i)
649
{
650
  gimple_seq list;
651
 
652
  list = set_component_ssa_name (lhs, false, r);
653
  if (list)
654
    gsi_insert_seq_on_edge (e, list);
655
 
656
  list = set_component_ssa_name (lhs, true, i);
657
  if (list)
658
    gsi_insert_seq_on_edge (e, list);
659
}
660
 
661
 
662
/* Update an assignment to a complex variable in place.  */
663
 
664
static void
665
update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i)
666
{
667
  gimple_stmt_iterator orig_si = *gsi;
668
 
669
  if (gimple_in_ssa_p (cfun))
670
    update_complex_components (gsi, gsi_stmt (*gsi), r, i);
671
 
672
  gimple_assign_set_rhs_with_ops (&orig_si, COMPLEX_EXPR, r, i);
673
  update_stmt (gsi_stmt (orig_si));
674
}
675
 
676
 
677
/* Generate code at the entry point of the function to initialize the
678
   component variables for a complex parameter.  */
679
 
680
static void
681
update_parameter_components (void)
682
{
683
  edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR);
684
  tree parm;
685
 
686
  for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = TREE_CHAIN (parm))
687
    {
688
      tree type = TREE_TYPE (parm);
689
      tree ssa_name, r, i;
690
 
691
      if (TREE_CODE (type) != COMPLEX_TYPE || !is_gimple_reg (parm))
692
        continue;
693
 
694
      type = TREE_TYPE (type);
695
      ssa_name = gimple_default_def (cfun, parm);
696
      if (!ssa_name)
697
        continue;
698
 
699
      r = build1 (REALPART_EXPR, type, ssa_name);
700
      i = build1 (IMAGPART_EXPR, type, ssa_name);
701
      update_complex_components_on_edge (entry_edge, ssa_name, r, i);
702
    }
703
}
704
 
705
/* Generate code to set the component variables of a complex variable
706
   to match the PHI statements in block BB.  */
707
 
708
static void
709
update_phi_components (basic_block bb)
710
{
711
  gimple_stmt_iterator gsi;
712
 
713
  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
714
    {
715
      gimple phi = gsi_stmt (gsi);
716
 
717
      if (is_complex_reg (gimple_phi_result (phi)))
718
        {
719
          tree lr, li;
720
          gimple pr = NULL, pi = NULL;
721
          unsigned int i, n;
722
 
723
          lr = get_component_ssa_name (gimple_phi_result (phi), false);
724
          if (TREE_CODE (lr) == SSA_NAME)
725
            {
726
              pr = create_phi_node (lr, bb);
727
              SSA_NAME_DEF_STMT (lr) = pr;
728
            }
729
 
730
          li = get_component_ssa_name (gimple_phi_result (phi), true);
731
          if (TREE_CODE (li) == SSA_NAME)
732
            {
733
              pi = create_phi_node (li, bb);
734
              SSA_NAME_DEF_STMT (li) = pi;
735
            }
736
 
737
          for (i = 0, n = gimple_phi_num_args (phi); i < n; ++i)
738
            {
739
              tree comp, arg = gimple_phi_arg_def (phi, i);
740
              if (pr)
741
                {
742
                  comp = extract_component (NULL, arg, false, false);
743
                  SET_PHI_ARG_DEF (pr, i, comp);
744
                }
745
              if (pi)
746
                {
747
                  comp = extract_component (NULL, arg, true, false);
748
                  SET_PHI_ARG_DEF (pi, i, comp);
749
                }
750
            }
751
        }
752
    }
753
}
754
 
755
/* Expand a complex move to scalars.  */
756
 
757
static void
758
expand_complex_move (gimple_stmt_iterator *gsi, tree type)
759
{
760
  tree inner_type = TREE_TYPE (type);
761
  tree r, i, lhs, rhs;
762
  gimple stmt = gsi_stmt (*gsi);
763
 
764
  if (is_gimple_assign (stmt))
765
    {
766
      lhs = gimple_assign_lhs (stmt);
767
      if (gimple_num_ops (stmt) == 2)
768
        rhs = gimple_assign_rhs1 (stmt);
769
      else
770
        rhs = NULL_TREE;
771
    }
772
  else if (is_gimple_call (stmt))
773
    {
774
      lhs = gimple_call_lhs (stmt);
775
      rhs = NULL_TREE;
776
    }
777
  else
778
    gcc_unreachable ();
779
 
780
  if (TREE_CODE (lhs) == SSA_NAME)
781
    {
782
      if (is_ctrl_altering_stmt (stmt))
783
        {
784
          edge_iterator ei;
785
          edge e;
786
 
787
          /* The value is not assigned on the exception edges, so we need not
788
             concern ourselves there.  We do need to update on the fallthru
789
             edge.  Find it.  */
790
          FOR_EACH_EDGE (e, ei, gsi_bb (*gsi)->succs)
791
            if (e->flags & EDGE_FALLTHRU)
792
              goto found_fallthru;
793
          gcc_unreachable ();
794
        found_fallthru:
795
 
796
          r = build1 (REALPART_EXPR, inner_type, lhs);
797
          i = build1 (IMAGPART_EXPR, inner_type, lhs);
798
          update_complex_components_on_edge (e, lhs, r, i);
799
        }
800
      else if (is_gimple_call (stmt)
801
               || gimple_has_side_effects (stmt)
802
               || gimple_assign_rhs_code (stmt) == PAREN_EXPR)
803
        {
804
          r = build1 (REALPART_EXPR, inner_type, lhs);
805
          i = build1 (IMAGPART_EXPR, inner_type, lhs);
806
          update_complex_components (gsi, stmt, r, i);
807
        }
808
      else
809
        {
810
          if (gimple_assign_rhs_code (stmt) != COMPLEX_EXPR)
811
            {
812
              r = extract_component (gsi, rhs, 0, true);
813
              i = extract_component (gsi, rhs, 1, true);
814
            }
815
          else
816
            {
817
              r = gimple_assign_rhs1 (stmt);
818
              i = gimple_assign_rhs2 (stmt);
819
            }
820
          update_complex_assignment (gsi, r, i);
821
        }
822
    }
823
  else if (rhs && TREE_CODE (rhs) == SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
824
    {
825
      tree x;
826
      gimple t;
827
 
828
      r = extract_component (gsi, rhs, 0, false);
829
      i = extract_component (gsi, rhs, 1, false);
830
 
831
      x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs));
832
      t = gimple_build_assign (x, r);
833
      gsi_insert_before (gsi, t, GSI_SAME_STMT);
834
 
835
      if (stmt == gsi_stmt (*gsi))
836
        {
837
          x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
838
          gimple_assign_set_lhs (stmt, x);
839
          gimple_assign_set_rhs1 (stmt, i);
840
        }
841
      else
842
        {
843
          x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
844
          t = gimple_build_assign (x, i);
845
          gsi_insert_before (gsi, t, GSI_SAME_STMT);
846
 
847
          stmt = gsi_stmt (*gsi);
848
          gcc_assert (gimple_code (stmt) == GIMPLE_RETURN);
849
          gimple_return_set_retval (stmt, lhs);
850
        }
851
 
852
      update_stmt (stmt);
853
    }
854
}
855
 
856
/* Expand complex addition to scalars:
857
        a + b = (ar + br) + i(ai + bi)
858
        a - b = (ar - br) + i(ai + bi)
859
*/
860
 
861
static void
862
expand_complex_addition (gimple_stmt_iterator *gsi, tree inner_type,
863
                         tree ar, tree ai, tree br, tree bi,
864
                         enum tree_code code,
865
                         complex_lattice_t al, complex_lattice_t bl)
866
{
867
  tree rr, ri;
868
 
869
  switch (PAIR (al, bl))
870
    {
871
    case PAIR (ONLY_REAL, ONLY_REAL):
872
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
873
      ri = ai;
874
      break;
875
 
876
    case PAIR (ONLY_REAL, ONLY_IMAG):
877
      rr = ar;
878
      if (code == MINUS_EXPR)
879
        ri = gimplify_build2 (gsi, MINUS_EXPR, inner_type, ai, bi);
880
      else
881
        ri = bi;
882
      break;
883
 
884
    case PAIR (ONLY_IMAG, ONLY_REAL):
885
      if (code == MINUS_EXPR)
886
        rr = gimplify_build2 (gsi, MINUS_EXPR, inner_type, ar, br);
887
      else
888
        rr = br;
889
      ri = ai;
890
      break;
891
 
892
    case PAIR (ONLY_IMAG, ONLY_IMAG):
893
      rr = ar;
894
      ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
895
      break;
896
 
897
    case PAIR (VARYING, ONLY_REAL):
898
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
899
      ri = ai;
900
      break;
901
 
902
    case PAIR (VARYING, ONLY_IMAG):
903
      rr = ar;
904
      ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
905
      break;
906
 
907
    case PAIR (ONLY_REAL, VARYING):
908
      if (code == MINUS_EXPR)
909
        goto general;
910
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
911
      ri = bi;
912
      break;
913
 
914
    case PAIR (ONLY_IMAG, VARYING):
915
      if (code == MINUS_EXPR)
916
        goto general;
917
      rr = br;
918
      ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
919
      break;
920
 
921
    case PAIR (VARYING, VARYING):
922
    general:
923
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
924
      ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
925
      break;
926
 
927
    default:
928
      gcc_unreachable ();
929
    }
930
 
931
  update_complex_assignment (gsi, rr, ri);
932
}
933
 
934
/* Expand a complex multiplication or division to a libcall to the c99
935
   compliant routines.  */
936
 
937
static void
938
expand_complex_libcall (gimple_stmt_iterator *gsi, tree ar, tree ai,
939
                        tree br, tree bi, enum tree_code code)
940
{
941
  enum machine_mode mode;
942
  enum built_in_function bcode;
943
  tree fn, type, lhs;
944
  gimple old_stmt, stmt;
945
 
946
  old_stmt = gsi_stmt (*gsi);
947
  lhs = gimple_assign_lhs (old_stmt);
948
  type = TREE_TYPE (lhs);
949
 
950
  mode = TYPE_MODE (type);
951
  gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
952
 
953
  if (code == MULT_EXPR)
954
    bcode = ((enum built_in_function)
955
             (BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
956
  else if (code == RDIV_EXPR)
957
    bcode = ((enum built_in_function)
958
             (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
959
  else
960
    gcc_unreachable ();
961
  fn = built_in_decls[bcode];
962
 
963
  stmt = gimple_build_call (fn, 4, ar, ai, br, bi);
964
  gimple_call_set_lhs (stmt, lhs);
965
  update_stmt (stmt);
966
  gsi_replace (gsi, stmt, false);
967
 
968
  if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
969
    gimple_purge_dead_eh_edges (gsi_bb (*gsi));
970
 
971
  if (gimple_in_ssa_p (cfun))
972
    {
973
      type = TREE_TYPE (type);
974
      update_complex_components (gsi, stmt,
975
                                 build1 (REALPART_EXPR, type, lhs),
976
                                 build1 (IMAGPART_EXPR, type, lhs));
977
      SSA_NAME_DEF_STMT (lhs) = stmt;
978
    }
979
}
980
 
981
/* Expand complex multiplication to scalars:
982
        a * b = (ar*br - ai*bi) + i(ar*bi + br*ai)
983
*/
984
 
985
static void
986
expand_complex_multiplication (gimple_stmt_iterator *gsi, tree inner_type,
987
                               tree ar, tree ai, tree br, tree bi,
988
                               complex_lattice_t al, complex_lattice_t bl)
989
{
990
  tree rr, ri;
991
 
992
  if (al < bl)
993
    {
994
      complex_lattice_t tl;
995
      rr = ar, ar = br, br = rr;
996
      ri = ai, ai = bi, bi = ri;
997
      tl = al, al = bl, bl = tl;
998
    }
999
 
1000
  switch (PAIR (al, bl))
1001
    {
1002
    case PAIR (ONLY_REAL, ONLY_REAL):
1003
      rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
1004
      ri = ai;
1005
      break;
1006
 
1007
    case PAIR (ONLY_IMAG, ONLY_REAL):
1008
      rr = ar;
1009
      if (TREE_CODE (ai) == REAL_CST
1010
          && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst1))
1011
        ri = br;
1012
      else
1013
        ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
1014
      break;
1015
 
1016
    case PAIR (ONLY_IMAG, ONLY_IMAG):
1017
      rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
1018
      rr = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, rr);
1019
      ri = ar;
1020
      break;
1021
 
1022
    case PAIR (VARYING, ONLY_REAL):
1023
      rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
1024
      ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
1025
      break;
1026
 
1027
    case PAIR (VARYING, ONLY_IMAG):
1028
      rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
1029
      rr = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, rr);
1030
      ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, bi);
1031
      break;
1032
 
1033
    case PAIR (VARYING, VARYING):
1034
      if (flag_complex_method == 2 && SCALAR_FLOAT_TYPE_P (inner_type))
1035
        {
1036
          expand_complex_libcall (gsi, ar, ai, br, bi, MULT_EXPR);
1037
          return;
1038
        }
1039
      else
1040
        {
1041
          tree t1, t2, t3, t4;
1042
 
1043
          t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
1044
          t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
1045
          t3 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, bi);
1046
 
1047
          /* Avoid expanding redundant multiplication for the common
1048
             case of squaring a complex number.  */
1049
          if (ar == br && ai == bi)
1050
            t4 = t3;
1051
          else
1052
            t4 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
1053
 
1054
          rr = gimplify_build2 (gsi, MINUS_EXPR, inner_type, t1, t2);
1055
          ri = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t3, t4);
1056
        }
1057
      break;
1058
 
1059
    default:
1060
      gcc_unreachable ();
1061
    }
1062
 
1063
  update_complex_assignment (gsi, rr, ri);
1064
}
1065
 
1066
/* Keep this algorithm in sync with fold-const.c:const_binop().
1067
 
1068
   Expand complex division to scalars, straightforward algorithm.
1069
        a / b = ((ar*br + ai*bi)/t) + i((ai*br - ar*bi)/t)
1070
            t = br*br + bi*bi
1071
*/
1072
 
1073
static void
1074
expand_complex_div_straight (gimple_stmt_iterator *gsi, tree inner_type,
1075
                             tree ar, tree ai, tree br, tree bi,
1076
                             enum tree_code code)
1077
{
1078
  tree rr, ri, div, t1, t2, t3;
1079
 
1080
  t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, br, br);
1081
  t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, bi, bi);
1082
  div = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, t2);
1083
 
1084
  t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
1085
  t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
1086
  t3 = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, t2);
1087
  rr = gimplify_build2 (gsi, code, inner_type, t3, div);
1088
 
1089
  t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
1090
  t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, bi);
1091
  t3 = gimplify_build2 (gsi, MINUS_EXPR, inner_type, t1, t2);
1092
  ri = gimplify_build2 (gsi, code, inner_type, t3, div);
1093
 
1094
  update_complex_assignment (gsi, rr, ri);
1095
}
1096
 
1097
/* Keep this algorithm in sync with fold-const.c:const_binop().
1098
 
1099
   Expand complex division to scalars, modified algorithm to minimize
1100
   overflow with wide input ranges.  */
1101
 
1102
static void
1103
expand_complex_div_wide (gimple_stmt_iterator *gsi, tree inner_type,
1104
                         tree ar, tree ai, tree br, tree bi,
1105
                         enum tree_code code)
1106
{
1107
  tree rr, ri, ratio, div, t1, t2, tr, ti, compare;
1108
  basic_block bb_cond, bb_true, bb_false, bb_join;
1109
  gimple stmt;
1110
 
1111
  /* Examine |br| < |bi|, and branch.  */
1112
  t1 = gimplify_build1 (gsi, ABS_EXPR, inner_type, br);
1113
  t2 = gimplify_build1 (gsi, ABS_EXPR, inner_type, bi);
1114
  compare = fold_build2_loc (gimple_location (gsi_stmt (*gsi)),
1115
                             LT_EXPR, boolean_type_node, t1, t2);
1116
  STRIP_NOPS (compare);
1117
 
1118
  bb_cond = bb_true = bb_false = bb_join = NULL;
1119
  rr = ri = tr = ti = NULL;
1120
  if (TREE_CODE (compare) != INTEGER_CST)
1121
    {
1122
      edge e;
1123
      gimple stmt;
1124
      tree cond, tmp;
1125
 
1126
      tmp = create_tmp_var (boolean_type_node, NULL);
1127
      stmt = gimple_build_assign (tmp, compare);
1128
      if (gimple_in_ssa_p (cfun))
1129
        {
1130
          tmp = make_ssa_name (tmp,  stmt);
1131
          gimple_assign_set_lhs (stmt, tmp);
1132
        }
1133
 
1134
      gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1135
 
1136
      cond = fold_build2_loc (gimple_location (stmt),
1137
                          EQ_EXPR, boolean_type_node, tmp, boolean_true_node);
1138
      stmt = gimple_build_cond_from_tree (cond, NULL_TREE, NULL_TREE);
1139
      gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1140
 
1141
      /* Split the original block, and create the TRUE and FALSE blocks.  */
1142
      e = split_block (gsi_bb (*gsi), stmt);
1143
      bb_cond = e->src;
1144
      bb_join = e->dest;
1145
      bb_true = create_empty_bb (bb_cond);
1146
      bb_false = create_empty_bb (bb_true);
1147
 
1148
      /* Wire the blocks together.  */
1149
      e->flags = EDGE_TRUE_VALUE;
1150
      redirect_edge_succ (e, bb_true);
1151
      make_edge (bb_cond, bb_false, EDGE_FALSE_VALUE);
1152
      make_edge (bb_true, bb_join, EDGE_FALLTHRU);
1153
      make_edge (bb_false, bb_join, EDGE_FALLTHRU);
1154
 
1155
      /* Update dominance info.  Note that bb_join's data was
1156
         updated by split_block.  */
1157
      if (dom_info_available_p (CDI_DOMINATORS))
1158
        {
1159
          set_immediate_dominator (CDI_DOMINATORS, bb_true, bb_cond);
1160
          set_immediate_dominator (CDI_DOMINATORS, bb_false, bb_cond);
1161
        }
1162
 
1163
      rr = make_rename_temp (inner_type, NULL);
1164
      ri = make_rename_temp (inner_type, NULL);
1165
    }
1166
 
1167
  /* In the TRUE branch, we compute
1168
      ratio = br/bi;
1169
      div = (br * ratio) + bi;
1170
      tr = (ar * ratio) + ai;
1171
      ti = (ai * ratio) - ar;
1172
      tr = tr / div;
1173
      ti = ti / div;  */
1174
  if (bb_true || integer_nonzerop (compare))
1175
    {
1176
      if (bb_true)
1177
        {
1178
          *gsi = gsi_last_bb (bb_true);
1179
          gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
1180
        }
1181
 
1182
      ratio = gimplify_build2 (gsi, code, inner_type, br, bi);
1183
 
1184
      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, br, ratio);
1185
      div = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, bi);
1186
 
1187
      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, ratio);
1188
      tr = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, ai);
1189
 
1190
      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, ratio);
1191
      ti = gimplify_build2 (gsi, MINUS_EXPR, inner_type, t1, ar);
1192
 
1193
      tr = gimplify_build2 (gsi, code, inner_type, tr, div);
1194
      ti = gimplify_build2 (gsi, code, inner_type, ti, div);
1195
 
1196
     if (bb_true)
1197
       {
1198
         stmt = gimple_build_assign (rr, tr);
1199
         gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1200
         stmt = gimple_build_assign (ri, ti);
1201
         gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1202
         gsi_remove (gsi, true);
1203
       }
1204
    }
1205
 
1206
  /* In the FALSE branch, we compute
1207
      ratio = d/c;
1208
      divisor = (d * ratio) + c;
1209
      tr = (b * ratio) + a;
1210
      ti = b - (a * ratio);
1211
      tr = tr / div;
1212
      ti = ti / div;  */
1213
  if (bb_false || integer_zerop (compare))
1214
    {
1215
      if (bb_false)
1216
        {
1217
          *gsi = gsi_last_bb (bb_false);
1218
          gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
1219
        }
1220
 
1221
      ratio = gimplify_build2 (gsi, code, inner_type, bi, br);
1222
 
1223
      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, bi, ratio);
1224
      div = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, br);
1225
 
1226
      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, ratio);
1227
      tr = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, ar);
1228
 
1229
      t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, ratio);
1230
      ti = gimplify_build2 (gsi, MINUS_EXPR, inner_type, ai, t1);
1231
 
1232
      tr = gimplify_build2 (gsi, code, inner_type, tr, div);
1233
      ti = gimplify_build2 (gsi, code, inner_type, ti, div);
1234
 
1235
     if (bb_false)
1236
       {
1237
         stmt = gimple_build_assign (rr, tr);
1238
         gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1239
         stmt = gimple_build_assign (ri, ti);
1240
         gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1241
         gsi_remove (gsi, true);
1242
       }
1243
    }
1244
 
1245
  if (bb_join)
1246
    *gsi = gsi_start_bb (bb_join);
1247
  else
1248
    rr = tr, ri = ti;
1249
 
1250
  update_complex_assignment (gsi, rr, ri);
1251
}
1252
 
1253
/* Expand complex division to scalars.  */
1254
 
1255
static void
1256
expand_complex_division (gimple_stmt_iterator *gsi, tree inner_type,
1257
                         tree ar, tree ai, tree br, tree bi,
1258
                         enum tree_code code,
1259
                         complex_lattice_t al, complex_lattice_t bl)
1260
{
1261
  tree rr, ri;
1262
 
1263
  switch (PAIR (al, bl))
1264
    {
1265
    case PAIR (ONLY_REAL, ONLY_REAL):
1266
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
1267
      ri = ai;
1268
      break;
1269
 
1270
    case PAIR (ONLY_REAL, ONLY_IMAG):
1271
      rr = ai;
1272
      ri = gimplify_build2 (gsi, code, inner_type, ar, bi);
1273
      ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ri);
1274
      break;
1275
 
1276
    case PAIR (ONLY_IMAG, ONLY_REAL):
1277
      rr = ar;
1278
      ri = gimplify_build2 (gsi, code, inner_type, ai, br);
1279
      break;
1280
 
1281
    case PAIR (ONLY_IMAG, ONLY_IMAG):
1282
      rr = gimplify_build2 (gsi, code, inner_type, ai, bi);
1283
      ri = ar;
1284
      break;
1285
 
1286
    case PAIR (VARYING, ONLY_REAL):
1287
      rr = gimplify_build2 (gsi, code, inner_type, ar, br);
1288
      ri = gimplify_build2 (gsi, code, inner_type, ai, br);
1289
      break;
1290
 
1291
    case PAIR (VARYING, ONLY_IMAG):
1292
      rr = gimplify_build2 (gsi, code, inner_type, ai, bi);
1293
      ri = gimplify_build2 (gsi, code, inner_type, ar, bi);
1294
      ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ri);
1295
 
1296
    case PAIR (ONLY_REAL, VARYING):
1297
    case PAIR (ONLY_IMAG, VARYING):
1298
    case PAIR (VARYING, VARYING):
1299
      switch (flag_complex_method)
1300
        {
1301
        case 0:
1302
          /* straightforward implementation of complex divide acceptable.  */
1303
          expand_complex_div_straight (gsi, inner_type, ar, ai, br, bi, code);
1304
          break;
1305
 
1306
        case 2:
1307
          if (SCALAR_FLOAT_TYPE_P (inner_type))
1308
            {
1309
              expand_complex_libcall (gsi, ar, ai, br, bi, code);
1310
              break;
1311
            }
1312
          /* FALLTHRU */
1313
 
1314
        case 1:
1315
          /* wide ranges of inputs must work for complex divide.  */
1316
          expand_complex_div_wide (gsi, inner_type, ar, ai, br, bi, code);
1317
          break;
1318
 
1319
        default:
1320
          gcc_unreachable ();
1321
        }
1322
      return;
1323
 
1324
    default:
1325
      gcc_unreachable ();
1326
    }
1327
 
1328
  update_complex_assignment (gsi, rr, ri);
1329
}
1330
 
1331
/* Expand complex negation to scalars:
1332
        -a = (-ar) + i(-ai)
1333
*/
1334
 
1335
static void
1336
expand_complex_negation (gimple_stmt_iterator *gsi, tree inner_type,
1337
                         tree ar, tree ai)
1338
{
1339
  tree rr, ri;
1340
 
1341
  rr = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ar);
1342
  ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ai);
1343
 
1344
  update_complex_assignment (gsi, rr, ri);
1345
}
1346
 
1347
/* Expand complex conjugate to scalars:
1348
        ~a = (ar) + i(-ai)
1349
*/
1350
 
1351
static void
1352
expand_complex_conjugate (gimple_stmt_iterator *gsi, tree inner_type,
1353
                          tree ar, tree ai)
1354
{
1355
  tree ri;
1356
 
1357
  ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ai);
1358
 
1359
  update_complex_assignment (gsi, ar, ri);
1360
}
1361
 
1362
/* Expand complex comparison (EQ or NE only).  */
1363
 
1364
static void
1365
expand_complex_comparison (gimple_stmt_iterator *gsi, tree ar, tree ai,
1366
                           tree br, tree bi, enum tree_code code)
1367
{
1368
  tree cr, ci, cc, type;
1369
  gimple stmt;
1370
 
1371
  cr = gimplify_build2 (gsi, code, boolean_type_node, ar, br);
1372
  ci = gimplify_build2 (gsi, code, boolean_type_node, ai, bi);
1373
  cc = gimplify_build2 (gsi,
1374
                        (code == EQ_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR),
1375
                        boolean_type_node, cr, ci);
1376
 
1377
  stmt = gsi_stmt (*gsi);
1378
 
1379
  switch (gimple_code (stmt))
1380
    {
1381
    case GIMPLE_RETURN:
1382
      type = TREE_TYPE (gimple_return_retval (stmt));
1383
      gimple_return_set_retval (stmt, fold_convert (type, cc));
1384
      break;
1385
 
1386
    case GIMPLE_ASSIGN:
1387
      type = TREE_TYPE (gimple_assign_lhs (stmt));
1388
      gimple_assign_set_rhs_from_tree (gsi, fold_convert (type, cc));
1389
      stmt = gsi_stmt (*gsi);
1390
      break;
1391
 
1392
    case GIMPLE_COND:
1393
      gimple_cond_set_code (stmt, EQ_EXPR);
1394
      gimple_cond_set_lhs (stmt, cc);
1395
      gimple_cond_set_rhs (stmt, boolean_true_node);
1396
      break;
1397
 
1398
    default:
1399
      gcc_unreachable ();
1400
    }
1401
 
1402
  update_stmt (stmt);
1403
}
1404
 
1405
 
1406
/* Process one statement.  If we identify a complex operation, expand it.  */
1407
 
1408
static void
1409
expand_complex_operations_1 (gimple_stmt_iterator *gsi)
1410
{
1411
  gimple stmt = gsi_stmt (*gsi);
1412
  tree type, inner_type, lhs;
1413
  tree ac, ar, ai, bc, br, bi;
1414
  complex_lattice_t al, bl;
1415
  enum tree_code code;
1416
 
1417
  lhs = gimple_get_lhs (stmt);
1418
  if (!lhs && gimple_code (stmt) != GIMPLE_COND)
1419
    return;
1420
 
1421
  type = TREE_TYPE (gimple_op (stmt, 0));
1422
  code = gimple_expr_code (stmt);
1423
 
1424
  /* Initial filter for operations we handle.  */
1425
  switch (code)
1426
    {
1427
    case PLUS_EXPR:
1428
    case MINUS_EXPR:
1429
    case MULT_EXPR:
1430
    case TRUNC_DIV_EXPR:
1431
    case CEIL_DIV_EXPR:
1432
    case FLOOR_DIV_EXPR:
1433
    case ROUND_DIV_EXPR:
1434
    case RDIV_EXPR:
1435
    case NEGATE_EXPR:
1436
    case CONJ_EXPR:
1437
      if (TREE_CODE (type) != COMPLEX_TYPE)
1438
        return;
1439
      inner_type = TREE_TYPE (type);
1440
      break;
1441
 
1442
    case EQ_EXPR:
1443
    case NE_EXPR:
1444
      /* Note, both GIMPLE_ASSIGN and GIMPLE_COND may have an EQ_EXPR
1445
         subocde, so we need to access the operands using gimple_op.  */
1446
      inner_type = TREE_TYPE (gimple_op (stmt, 1));
1447
      if (TREE_CODE (inner_type) != COMPLEX_TYPE)
1448
        return;
1449
      break;
1450
 
1451
    default:
1452
      {
1453
        tree rhs;
1454
 
1455
        /* GIMPLE_COND may also fallthru here, but we do not need to
1456
           do anything with it.  */
1457
        if (gimple_code (stmt) == GIMPLE_COND)
1458
          return;
1459
 
1460
        if (TREE_CODE (type) == COMPLEX_TYPE)
1461
          expand_complex_move (gsi, type);
1462
        else if (is_gimple_assign (stmt)
1463
                 && (gimple_assign_rhs_code (stmt) == REALPART_EXPR
1464
                     || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
1465
                 && TREE_CODE (lhs) == SSA_NAME)
1466
          {
1467
            rhs = gimple_assign_rhs1 (stmt);
1468
            rhs = extract_component (gsi, TREE_OPERAND (rhs, 0),
1469
                                     gimple_assign_rhs_code (stmt)
1470
                                       == IMAGPART_EXPR,
1471
                                     false);
1472
            gimple_assign_set_rhs_from_tree (gsi, rhs);
1473
            stmt = gsi_stmt (*gsi);
1474
            update_stmt (stmt);
1475
          }
1476
      }
1477
      return;
1478
    }
1479
 
1480
  /* Extract the components of the two complex values.  Make sure and
1481
     handle the common case of the same value used twice specially.  */
1482
  if (is_gimple_assign (stmt))
1483
    {
1484
      ac = gimple_assign_rhs1 (stmt);
1485
      bc = (gimple_num_ops (stmt) > 2) ? gimple_assign_rhs2 (stmt) : NULL;
1486
    }
1487
  /* GIMPLE_CALL can not get here.  */
1488
  else
1489
    {
1490
      ac = gimple_cond_lhs (stmt);
1491
      bc = gimple_cond_rhs (stmt);
1492
    }
1493
 
1494
  ar = extract_component (gsi, ac, false, true);
1495
  ai = extract_component (gsi, ac, true, true);
1496
 
1497
  if (ac == bc)
1498
    br = ar, bi = ai;
1499
  else if (bc)
1500
    {
1501
      br = extract_component (gsi, bc, 0, true);
1502
      bi = extract_component (gsi, bc, 1, true);
1503
    }
1504
  else
1505
    br = bi = NULL_TREE;
1506
 
1507
  if (gimple_in_ssa_p (cfun))
1508
    {
1509
      al = find_lattice_value (ac);
1510
      if (al == UNINITIALIZED)
1511
        al = VARYING;
1512
 
1513
      if (TREE_CODE_CLASS (code) == tcc_unary)
1514
        bl = UNINITIALIZED;
1515
      else if (ac == bc)
1516
        bl = al;
1517
      else
1518
        {
1519
          bl = find_lattice_value (bc);
1520
          if (bl == UNINITIALIZED)
1521
            bl = VARYING;
1522
        }
1523
    }
1524
  else
1525
    al = bl = VARYING;
1526
 
1527
  switch (code)
1528
    {
1529
    case PLUS_EXPR:
1530
    case MINUS_EXPR:
1531
      expand_complex_addition (gsi, inner_type, ar, ai, br, bi, code, al, bl);
1532
      break;
1533
 
1534
    case MULT_EXPR:
1535
      expand_complex_multiplication (gsi, inner_type, ar, ai, br, bi, al, bl);
1536
      break;
1537
 
1538
    case TRUNC_DIV_EXPR:
1539
    case CEIL_DIV_EXPR:
1540
    case FLOOR_DIV_EXPR:
1541
    case ROUND_DIV_EXPR:
1542
    case RDIV_EXPR:
1543
      expand_complex_division (gsi, inner_type, ar, ai, br, bi, code, al, bl);
1544
      break;
1545
 
1546
    case NEGATE_EXPR:
1547
      expand_complex_negation (gsi, inner_type, ar, ai);
1548
      break;
1549
 
1550
    case CONJ_EXPR:
1551
      expand_complex_conjugate (gsi, inner_type, ar, ai);
1552
      break;
1553
 
1554
    case EQ_EXPR:
1555
    case NE_EXPR:
1556
      expand_complex_comparison (gsi, ar, ai, br, bi, code);
1557
      break;
1558
 
1559
    default:
1560
      gcc_unreachable ();
1561
    }
1562
}
1563
 
1564
 
1565
/* Entry point for complex operation lowering during optimization.  */
1566
 
1567
static unsigned int
1568
tree_lower_complex (void)
1569
{
1570
  int old_last_basic_block;
1571
  gimple_stmt_iterator gsi;
1572
  basic_block bb;
1573
 
1574
  if (!init_dont_simulate_again ())
1575
    return 0;
1576
 
1577
  complex_lattice_values = VEC_alloc (complex_lattice_t, heap, num_ssa_names);
1578
  VEC_safe_grow_cleared (complex_lattice_t, heap,
1579
                         complex_lattice_values, num_ssa_names);
1580
 
1581
  init_parameter_lattice_values ();
1582
  ssa_propagate (complex_visit_stmt, complex_visit_phi);
1583
 
1584
  complex_variable_components = htab_create (10,  int_tree_map_hash,
1585
                                             int_tree_map_eq, free);
1586
 
1587
  complex_ssa_name_components = VEC_alloc (tree, heap, 2*num_ssa_names);
1588
  VEC_safe_grow_cleared (tree, heap, complex_ssa_name_components,
1589
                         2 * num_ssa_names);
1590
 
1591
  update_parameter_components ();
1592
 
1593
  /* ??? Ideally we'd traverse the blocks in breadth-first order.  */
1594
  old_last_basic_block = last_basic_block;
1595
  FOR_EACH_BB (bb)
1596
    {
1597
      if (bb->index >= old_last_basic_block)
1598
        continue;
1599
 
1600
      update_phi_components (bb);
1601
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1602
        expand_complex_operations_1 (&gsi);
1603
    }
1604
 
1605
  gsi_commit_edge_inserts ();
1606
 
1607
  htab_delete (complex_variable_components);
1608
  VEC_free (tree, heap, complex_ssa_name_components);
1609
  VEC_free (complex_lattice_t, heap, complex_lattice_values);
1610
  return 0;
1611
}
1612
 
1613
struct gimple_opt_pass pass_lower_complex =
1614
{
1615
 {
1616
  GIMPLE_PASS,
1617
  "cplxlower",                          /* name */
1618
  0,                                     /* gate */
1619
  tree_lower_complex,                   /* execute */
1620
  NULL,                                 /* sub */
1621
  NULL,                                 /* next */
1622
  0,                                     /* static_pass_number */
1623
  TV_NONE,                              /* tv_id */
1624
  PROP_ssa,                             /* properties_required */
1625
  PROP_gimple_lcx,                      /* properties_provided */
1626
  0,                                     /* properties_destroyed */
1627
  0,                                     /* todo_flags_start */
1628
  TODO_dump_func
1629
    | TODO_ggc_collect
1630
    | TODO_update_ssa
1631
    | TODO_verify_stmts                 /* todo_flags_finish */
1632
 }
1633
};
1634
 
1635
 
1636
static bool
1637
gate_no_optimization (void)
1638
{
1639
  /* With errors, normal optimization passes are not run.  If we don't
1640
     lower complex operations at all, rtl expansion will abort.  */
1641
  return !(cfun->curr_properties & PROP_gimple_lcx);
1642
}
1643
 
1644
struct gimple_opt_pass pass_lower_complex_O0 =
1645
{
1646
 {
1647
  GIMPLE_PASS,
1648
  "cplxlower0",                         /* name */
1649
  gate_no_optimization,                 /* gate */
1650
  tree_lower_complex,                   /* execute */
1651
  NULL,                                 /* sub */
1652
  NULL,                                 /* next */
1653
  0,                                     /* static_pass_number */
1654
  TV_NONE,                              /* tv_id */
1655
  PROP_cfg,                             /* properties_required */
1656
  PROP_gimple_lcx,                      /* properties_provided */
1657
  0,                                     /* properties_destroyed */
1658
  0,                                     /* todo_flags_start */
1659
  TODO_dump_func
1660
    | TODO_ggc_collect
1661
    | TODO_update_ssa
1662
    | TODO_verify_stmts                 /* todo_flags_finish */
1663
 }
1664
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.