Enable dumping of alias graphs.
[official-gcc/Ramakrishna.git] / gcc / tree-ssa-address.c
blob7a2ba3991721e6d6e5112d2503f3994c535b064c
1 /* Memory address lowering and addressing mode selection.
2 Copyright (C) 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 /* Utility functions for manipulation with TARGET_MEM_REFs -- tree expressions
21 that directly map to addressing modes of the target. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "rtl.h"
29 #include "tm_p.h"
30 #include "hard-reg-set.h"
31 #include "basic-block.h"
32 #include "output.h"
33 #include "diagnostic.h"
34 #include "tree-flow.h"
35 #include "tree-dump.h"
36 #include "tree-pass.h"
37 #include "timevar.h"
38 #include "flags.h"
39 #include "tree-inline.h"
40 #include "insn-config.h"
41 #include "recog.h"
42 #include "expr.h"
43 #include "ggc.h"
44 #include "tree-affine.h"
46 /* TODO -- handling of symbols (according to Richard Hendersons
47 comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html):
49 There are at least 5 different kinds of symbols that we can run up against:
51 (1) binds_local_p, small data area.
52 (2) binds_local_p, eg local statics
53 (3) !binds_local_p, eg global variables
54 (4) thread local, local_exec
55 (5) thread local, !local_exec
57 Now, (1) won't appear often in an array context, but it certainly can.
58 All you have to do is set -GN high enough, or explicitly mark any
59 random object __attribute__((section (".sdata"))).
61 All of these affect whether or not a symbol is in fact a valid address.
62 The only one tested here is (3). And that result may very well
63 be incorrect for (4) or (5).
65 An incorrect result here does not cause incorrect results out the
66 back end, because the expander in expr.c validizes the address. However
67 it would be nice to improve the handling here in order to produce more
68 precise results. */
70 /* A "template" for memory address, used to determine whether the address is
71 valid for mode. */
73 struct GTY (()) mem_addr_template {
74 rtx ref; /* The template. */
75 rtx * GTY ((skip)) step_p; /* The point in template where the step should be
76 filled in. */
77 rtx * GTY ((skip)) off_p; /* The point in template where the offset should
78 be filled in. */
81 /* The templates. Each of the five bits of the index corresponds to one
82 component of TARGET_MEM_REF being present, see TEMPL_IDX. */
84 static GTY (()) struct mem_addr_template templates[32];
86 #define TEMPL_IDX(SYMBOL, BASE, INDEX, STEP, OFFSET) \
87 (((SYMBOL != 0) << 4) \
88 | ((BASE != 0) << 3) \
89 | ((INDEX != 0) << 2) \
90 | ((STEP != 0) << 1) \
91 | (OFFSET != 0))
93 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX,
94 STEP and OFFSET to *ADDR. Stores pointers to where step is placed to
95 *STEP_P and offset to *OFFSET_P. */
97 static void
98 gen_addr_rtx (rtx symbol, rtx base, rtx index, rtx step, rtx offset,
99 rtx *addr, rtx **step_p, rtx **offset_p)
101 rtx act_elem;
103 *addr = NULL_RTX;
104 if (step_p)
105 *step_p = NULL;
106 if (offset_p)
107 *offset_p = NULL;
109 if (index)
111 act_elem = index;
112 if (step)
114 act_elem = gen_rtx_MULT (Pmode, act_elem, step);
116 if (step_p)
117 *step_p = &XEXP (act_elem, 1);
120 *addr = act_elem;
123 if (base)
125 if (*addr)
126 *addr = simplify_gen_binary (PLUS, Pmode, base, *addr);
127 else
128 *addr = base;
131 if (symbol)
133 act_elem = symbol;
134 if (offset)
136 act_elem = gen_rtx_PLUS (Pmode, act_elem, offset);
138 if (offset_p)
139 *offset_p = &XEXP (act_elem, 1);
141 if (GET_CODE (symbol) == SYMBOL_REF
142 || GET_CODE (symbol) == LABEL_REF
143 || GET_CODE (symbol) == CONST)
144 act_elem = gen_rtx_CONST (Pmode, act_elem);
147 if (*addr)
148 *addr = gen_rtx_PLUS (Pmode, *addr, act_elem);
149 else
150 *addr = act_elem;
152 else if (offset)
154 if (*addr)
156 *addr = gen_rtx_PLUS (Pmode, *addr, offset);
157 if (offset_p)
158 *offset_p = &XEXP (*addr, 1);
160 else
162 *addr = offset;
163 if (offset_p)
164 *offset_p = addr;
168 if (!*addr)
169 *addr = const0_rtx;
172 /* Returns address for TARGET_MEM_REF with parameters given by ADDR.
173 If REALLY_EXPAND is false, just make fake registers instead
174 of really expanding the operands, and perform the expansion in-place
175 by using one of the "templates". */
178 addr_for_mem_ref (struct mem_address *addr, bool really_expand)
180 rtx address, sym, bse, idx, st, off;
181 static bool templates_initialized = false;
182 struct mem_addr_template *templ;
184 if (addr->step && !integer_onep (addr->step))
185 st = immed_double_const (TREE_INT_CST_LOW (addr->step),
186 TREE_INT_CST_HIGH (addr->step), Pmode);
187 else
188 st = NULL_RTX;
190 if (addr->offset && !integer_zerop (addr->offset))
191 off = immed_double_const (TREE_INT_CST_LOW (addr->offset),
192 TREE_INT_CST_HIGH (addr->offset), Pmode);
193 else
194 off = NULL_RTX;
196 if (!really_expand)
198 /* Reuse the templates for addresses, so that we do not waste memory. */
199 if (!templates_initialized)
201 unsigned i;
203 templates_initialized = true;
204 sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup ("test_symbol"));
205 bse = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1);
206 idx = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 2);
208 for (i = 0; i < 32; i++)
209 gen_addr_rtx ((i & 16 ? sym : NULL_RTX),
210 (i & 8 ? bse : NULL_RTX),
211 (i & 4 ? idx : NULL_RTX),
212 (i & 2 ? const0_rtx : NULL_RTX),
213 (i & 1 ? const0_rtx : NULL_RTX),
214 &templates[i].ref,
215 &templates[i].step_p,
216 &templates[i].off_p);
219 templ = templates + TEMPL_IDX (addr->symbol, addr->base, addr->index,
220 st, off);
221 if (st)
222 *templ->step_p = st;
223 if (off)
224 *templ->off_p = off;
226 return templ->ref;
229 /* Otherwise really expand the expressions. */
230 sym = (addr->symbol
231 ? expand_expr (build_addr (addr->symbol, current_function_decl),
232 NULL_RTX, Pmode, EXPAND_NORMAL)
233 : NULL_RTX);
234 bse = (addr->base
235 ? expand_expr (addr->base, NULL_RTX, Pmode, EXPAND_NORMAL)
236 : NULL_RTX);
237 idx = (addr->index
238 ? expand_expr (addr->index, NULL_RTX, Pmode, EXPAND_NORMAL)
239 : NULL_RTX);
241 gen_addr_rtx (sym, bse, idx, st, off, &address, NULL, NULL);
242 return address;
245 /* Returns address of MEM_REF in TYPE. */
247 tree
248 tree_mem_ref_addr (tree type, tree mem_ref)
250 tree addr;
251 tree act_elem;
252 tree step = TMR_STEP (mem_ref), offset = TMR_OFFSET (mem_ref);
253 tree sym = TMR_SYMBOL (mem_ref), base = TMR_BASE (mem_ref);
254 tree addr_base = NULL_TREE, addr_off = NULL_TREE;
256 if (sym)
257 addr_base = fold_convert (type, build_addr (sym, current_function_decl));
258 else if (base && POINTER_TYPE_P (TREE_TYPE (base)))
260 addr_base = fold_convert (type, base);
261 base = NULL_TREE;
264 act_elem = TMR_INDEX (mem_ref);
265 if (act_elem)
267 if (step)
268 act_elem = fold_build2 (MULT_EXPR, sizetype, act_elem, step);
269 addr_off = act_elem;
272 act_elem = base;
273 if (act_elem)
275 if (addr_off)
276 addr_off = fold_build2 (PLUS_EXPR, sizetype, addr_off, act_elem);
277 else
278 addr_off = act_elem;
281 if (offset && !integer_zerop (offset))
283 if (addr_off)
284 addr_off = fold_build2 (PLUS_EXPR, sizetype, addr_off, offset);
285 else
286 addr_off = offset;
289 if (addr_off)
291 if (addr_base)
292 addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_off);
293 else
294 addr = fold_convert (type, addr_off);
296 else if (addr_base)
297 addr = addr_base;
298 else
299 addr = build_int_cst (type, 0);
301 return addr;
304 /* Returns true if a memory reference in MODE and with parameters given by
305 ADDR is valid on the current target. */
307 static bool
308 valid_mem_ref_p (enum machine_mode mode, struct mem_address *addr)
310 rtx address;
312 address = addr_for_mem_ref (addr, false);
313 if (!address)
314 return false;
316 return memory_address_p (mode, address);
319 /* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR
320 is valid on the current target and if so, creates and returns the
321 TARGET_MEM_REF. */
323 static tree
324 create_mem_ref_raw (tree type, struct mem_address *addr)
326 if (!valid_mem_ref_p (TYPE_MODE (type), addr))
327 return NULL_TREE;
329 if (addr->step && integer_onep (addr->step))
330 addr->step = NULL_TREE;
332 if (addr->offset && integer_zerop (addr->offset))
333 addr->offset = NULL_TREE;
335 return build6 (TARGET_MEM_REF, type,
336 addr->symbol, addr->base, addr->index,
337 addr->step, addr->offset, NULL);
340 /* Returns true if OBJ is an object whose address is a link time constant. */
342 static bool
343 fixed_address_object_p (tree obj)
345 return (TREE_CODE (obj) == VAR_DECL
346 && (TREE_STATIC (obj)
347 || DECL_EXTERNAL (obj))
348 && ! DECL_DLLIMPORT_P (obj));
351 /* If ADDR contains an address of object that is a link time constant,
352 move it to PARTS->symbol. */
354 static void
355 move_fixed_address_to_symbol (struct mem_address *parts, aff_tree *addr)
357 unsigned i;
358 tree val = NULL_TREE;
360 for (i = 0; i < addr->n; i++)
362 if (!double_int_one_p (addr->elts[i].coef))
363 continue;
365 val = addr->elts[i].val;
366 if (TREE_CODE (val) == ADDR_EXPR
367 && fixed_address_object_p (TREE_OPERAND (val, 0)))
368 break;
371 if (i == addr->n)
372 return;
374 parts->symbol = TREE_OPERAND (val, 0);
375 aff_combination_remove_elt (addr, i);
378 /* If ADDR contains an address of a dereferenced pointer, move it to
379 PARTS->base. */
381 static void
382 move_pointer_to_base (struct mem_address *parts, aff_tree *addr)
384 unsigned i;
385 tree val = NULL_TREE;
387 for (i = 0; i < addr->n; i++)
389 if (!double_int_one_p (addr->elts[i].coef))
390 continue;
392 val = addr->elts[i].val;
393 if (POINTER_TYPE_P (TREE_TYPE (val)))
394 break;
397 if (i == addr->n)
398 return;
400 parts->base = val;
401 aff_combination_remove_elt (addr, i);
404 /* Adds ELT to PARTS. */
406 static void
407 add_to_parts (struct mem_address *parts, tree elt)
409 tree type;
411 if (!parts->index)
413 parts->index = fold_convert (sizetype, elt);
414 return;
417 if (!parts->base)
419 parts->base = elt;
420 return;
423 /* Add ELT to base. */
424 type = TREE_TYPE (parts->base);
425 if (POINTER_TYPE_P (type))
426 parts->base = fold_build2 (POINTER_PLUS_EXPR, type,
427 parts->base,
428 fold_convert (sizetype, elt));
429 else
430 parts->base = fold_build2 (PLUS_EXPR, type,
431 parts->base, elt);
434 /* Finds the most expensive multiplication in ADDR that can be
435 expressed in an addressing mode and move the corresponding
436 element(s) to PARTS. */
438 static void
439 most_expensive_mult_to_index (struct mem_address *parts, aff_tree *addr,
440 bool speed)
442 HOST_WIDE_INT coef;
443 double_int best_mult, amult, amult_neg;
444 unsigned best_mult_cost = 0, acost;
445 tree mult_elt = NULL_TREE, elt;
446 unsigned i, j;
447 enum tree_code op_code;
449 best_mult = double_int_zero;
450 for (i = 0; i < addr->n; i++)
452 if (!double_int_fits_in_shwi_p (addr->elts[i].coef))
453 continue;
455 /* FIXME: Should use the correct memory mode rather than Pmode. */
457 coef = double_int_to_shwi (addr->elts[i].coef);
458 if (coef == 1
459 || !multiplier_allowed_in_address_p (coef, Pmode))
460 continue;
462 acost = multiply_by_cost (coef, Pmode, speed);
464 if (acost > best_mult_cost)
466 best_mult_cost = acost;
467 best_mult = addr->elts[i].coef;
471 if (!best_mult_cost)
472 return;
474 /* Collect elements multiplied by best_mult. */
475 for (i = j = 0; i < addr->n; i++)
477 amult = addr->elts[i].coef;
478 amult_neg = double_int_ext_for_comb (double_int_neg (amult), addr);
480 if (double_int_equal_p (amult, best_mult))
481 op_code = PLUS_EXPR;
482 else if (double_int_equal_p (amult_neg, best_mult))
483 op_code = MINUS_EXPR;
484 else
486 addr->elts[j] = addr->elts[i];
487 j++;
488 continue;
491 elt = fold_convert (sizetype, addr->elts[i].val);
492 if (mult_elt)
493 mult_elt = fold_build2 (op_code, sizetype, mult_elt, elt);
494 else if (op_code == PLUS_EXPR)
495 mult_elt = elt;
496 else
497 mult_elt = fold_build1 (NEGATE_EXPR, sizetype, elt);
499 addr->n = j;
501 parts->index = mult_elt;
502 parts->step = double_int_to_tree (sizetype, best_mult);
505 /* Splits address ADDR into PARTS.
507 TODO -- be more clever about the distribution of the elements of ADDR
508 to PARTS. Some architectures do not support anything but single
509 register in address, possibly with a small integer offset; while
510 create_mem_ref will simplify the address to an acceptable shape
511 later, it would be more efficient to know that asking for complicated
512 addressing modes is useless. */
514 static void
515 addr_to_parts (aff_tree *addr, struct mem_address *parts, bool speed)
517 tree part;
518 unsigned i;
520 parts->symbol = NULL_TREE;
521 parts->base = NULL_TREE;
522 parts->index = NULL_TREE;
523 parts->step = NULL_TREE;
525 if (!double_int_zero_p (addr->offset))
526 parts->offset = double_int_to_tree (sizetype, addr->offset);
527 else
528 parts->offset = NULL_TREE;
530 /* Try to find a symbol. */
531 move_fixed_address_to_symbol (parts, addr);
533 /* First move the most expensive feasible multiplication
534 to index. */
535 most_expensive_mult_to_index (parts, addr, speed);
537 /* Try to find a base of the reference. Since at the moment
538 there is no reliable way how to distinguish between pointer and its
539 offset, this is just a guess. */
540 if (!parts->symbol)
541 move_pointer_to_base (parts, addr);
543 /* Then try to process the remaining elements. */
544 for (i = 0; i < addr->n; i++)
546 part = fold_convert (sizetype, addr->elts[i].val);
547 if (!double_int_one_p (addr->elts[i].coef))
548 part = fold_build2 (MULT_EXPR, sizetype, part,
549 double_int_to_tree (sizetype, addr->elts[i].coef));
550 add_to_parts (parts, part);
552 if (addr->rest)
553 add_to_parts (parts, fold_convert (sizetype, addr->rest));
556 /* Force the PARTS to register. */
558 static void
559 gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts)
561 if (parts->base)
562 parts->base = force_gimple_operand_gsi (gsi, parts->base,
563 true, NULL_TREE,
564 true, GSI_SAME_STMT);
565 if (parts->index)
566 parts->index = force_gimple_operand_gsi (gsi, parts->index,
567 true, NULL_TREE,
568 true, GSI_SAME_STMT);
571 /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
572 computations are emitted in front of GSI. TYPE is the mode
573 of created memory reference. */
575 tree
576 create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
577 bool speed)
579 tree mem_ref, tmp;
580 tree atype;
581 struct mem_address parts;
583 addr_to_parts (addr, &parts, speed);
584 gimplify_mem_ref_parts (gsi, &parts);
585 mem_ref = create_mem_ref_raw (type, &parts);
586 if (mem_ref)
587 return mem_ref;
589 /* The expression is too complicated. Try making it simpler. */
591 if (parts.step && !integer_onep (parts.step))
593 /* Move the multiplication to index. */
594 gcc_assert (parts.index);
595 parts.index = force_gimple_operand_gsi (gsi,
596 fold_build2 (MULT_EXPR, sizetype,
597 parts.index, parts.step),
598 true, NULL_TREE, true, GSI_SAME_STMT);
599 parts.step = NULL_TREE;
601 mem_ref = create_mem_ref_raw (type, &parts);
602 if (mem_ref)
603 return mem_ref;
606 if (parts.symbol)
608 tmp = build_addr (parts.symbol, current_function_decl);
609 gcc_assert (is_gimple_val (tmp));
611 /* Add the symbol to base, eventually forcing it to register. */
612 if (parts.base)
614 gcc_assert (useless_type_conversion_p
615 (sizetype, TREE_TYPE (parts.base)));
617 if (parts.index)
619 atype = TREE_TYPE (tmp);
620 parts.base = force_gimple_operand_gsi (gsi,
621 fold_build2 (POINTER_PLUS_EXPR, atype,
622 tmp,
623 fold_convert (sizetype, parts.base)),
624 true, NULL_TREE, true, GSI_SAME_STMT);
626 else
628 parts.index = parts.base;
629 parts.base = tmp;
632 else
633 parts.base = tmp;
634 parts.symbol = NULL_TREE;
636 mem_ref = create_mem_ref_raw (type, &parts);
637 if (mem_ref)
638 return mem_ref;
641 if (parts.index)
643 /* Add index to base. */
644 if (parts.base)
646 atype = TREE_TYPE (parts.base);
647 parts.base = force_gimple_operand_gsi (gsi,
648 fold_build2 (POINTER_PLUS_EXPR, atype,
649 parts.base,
650 parts.index),
651 true, NULL_TREE, true, GSI_SAME_STMT);
653 else
654 parts.base = parts.index;
655 parts.index = NULL_TREE;
657 mem_ref = create_mem_ref_raw (type, &parts);
658 if (mem_ref)
659 return mem_ref;
662 if (parts.offset && !integer_zerop (parts.offset))
664 /* Try adding offset to base. */
665 if (parts.base)
667 atype = TREE_TYPE (parts.base);
668 parts.base = force_gimple_operand_gsi (gsi,
669 fold_build2 (POINTER_PLUS_EXPR, atype,
670 parts.base,
671 fold_convert (sizetype, parts.offset)),
672 true, NULL_TREE, true, GSI_SAME_STMT);
674 else
675 parts.base = parts.offset;
677 parts.offset = NULL_TREE;
679 mem_ref = create_mem_ref_raw (type, &parts);
680 if (mem_ref)
681 return mem_ref;
684 /* Verify that the address is in the simplest possible shape
685 (only a register). If we cannot create such a memory reference,
686 something is really wrong. */
687 gcc_assert (parts.symbol == NULL_TREE);
688 gcc_assert (parts.index == NULL_TREE);
689 gcc_assert (!parts.step || integer_onep (parts.step));
690 gcc_assert (!parts.offset || integer_zerop (parts.offset));
691 gcc_unreachable ();
694 /* Copies components of the address from OP to ADDR. */
696 void
697 get_address_description (tree op, struct mem_address *addr)
699 addr->symbol = TMR_SYMBOL (op);
700 addr->base = TMR_BASE (op);
701 addr->index = TMR_INDEX (op);
702 addr->step = TMR_STEP (op);
703 addr->offset = TMR_OFFSET (op);
706 /* Copies the additional information attached to target_mem_ref FROM to TO. */
708 void
709 copy_mem_ref_info (tree to, tree from)
711 /* And the info about the original reference. */
712 TMR_ORIGINAL (to) = TMR_ORIGINAL (from);
715 /* Move constants in target_mem_ref REF to offset. Returns the new target
716 mem ref if anything changes, NULL_TREE otherwise. */
718 tree
719 maybe_fold_tmr (tree ref)
721 struct mem_address addr;
722 bool changed = false;
723 tree ret, off;
725 get_address_description (ref, &addr);
727 if (addr.base && TREE_CODE (addr.base) == INTEGER_CST)
729 if (addr.offset)
730 addr.offset = fold_binary_to_constant (PLUS_EXPR, sizetype,
731 addr.offset,
732 fold_convert (sizetype, addr.base));
733 else
734 addr.offset = addr.base;
736 addr.base = NULL_TREE;
737 changed = true;
740 if (addr.index && TREE_CODE (addr.index) == INTEGER_CST)
742 off = addr.index;
743 if (addr.step)
745 off = fold_binary_to_constant (MULT_EXPR, sizetype,
746 off, addr.step);
747 addr.step = NULL_TREE;
750 if (addr.offset)
752 addr.offset = fold_binary_to_constant (PLUS_EXPR, sizetype,
753 addr.offset, off);
755 else
756 addr.offset = off;
758 addr.index = NULL_TREE;
759 changed = true;
762 if (!changed)
763 return NULL_TREE;
765 ret = create_mem_ref_raw (TREE_TYPE (ref), &addr);
766 if (!ret)
767 return NULL_TREE;
769 copy_mem_ref_info (ret, ref);
770 return ret;
773 /* Dump PARTS to FILE. */
775 extern void dump_mem_address (FILE *, struct mem_address *);
776 void
777 dump_mem_address (FILE *file, struct mem_address *parts)
779 if (parts->symbol)
781 fprintf (file, "symbol: ");
782 print_generic_expr (file, parts->symbol, TDF_SLIM);
783 fprintf (file, "\n");
785 if (parts->base)
787 fprintf (file, "base: ");
788 print_generic_expr (file, parts->base, TDF_SLIM);
789 fprintf (file, "\n");
791 if (parts->index)
793 fprintf (file, "index: ");
794 print_generic_expr (file, parts->index, TDF_SLIM);
795 fprintf (file, "\n");
797 if (parts->step)
799 fprintf (file, "step: ");
800 print_generic_expr (file, parts->step, TDF_SLIM);
801 fprintf (file, "\n");
803 if (parts->offset)
805 fprintf (file, "offset: ");
806 print_generic_expr (file, parts->offset, TDF_SLIM);
807 fprintf (file, "\n");
811 #include "gt-tree-ssa-address.h"