comparison gcc/tree-data-ref.h @ 67:f6334be47118

update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Mar 2011 17:18:12 +0900
parents b7f97abdc517
children 04ced10e8804
comparison
equal deleted inserted replaced
65:65488c3d617d 67:f6334be47118
1 /* Data references and dependences detectors. 1 /* Data references and dependences detectors.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 Contributed by Sebastian Pop <pop@cri.ensmp.fr> 4 Contributed by Sebastian Pop <pop@cri.ensmp.fr>
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
21 21
22 #ifndef GCC_TREE_DATA_REF_H 22 #ifndef GCC_TREE_DATA_REF_H
23 #define GCC_TREE_DATA_REF_H 23 #define GCC_TREE_DATA_REF_H
24 24
25 #include "graphds.h" 25 #include "graphds.h"
26 #include "lambda.h"
27 #include "omega.h" 26 #include "omega.h"
28 #include "tree-chrec.h" 27 #include "tree-chrec.h"
29 28
30 /* 29 /*
31 innermost_loop_behavior describes the evolution of the address of the memory 30 innermost_loop_behavior describes the evolution of the address of the memory
93 /* The set of virtual operands corresponding to this memory reference, 92 /* The set of virtual operands corresponding to this memory reference,
94 serving as a description of the alias information for the memory 93 serving as a description of the alias information for the memory
95 reference. This could be eliminated if we had alias oracle. */ 94 reference. This could be eliminated if we had alias oracle. */
96 bitmap vops; 95 bitmap vops;
97 }; 96 };
97
98 /* An integer vector. A vector formally consists of an element of a vector
99 space. A vector space is a set that is closed under vector addition
100 and scalar multiplication. In this vector space, an element is a list of
101 integers. */
102 typedef int *lambda_vector;
103 DEF_VEC_P(lambda_vector);
104 DEF_VEC_ALLOC_P(lambda_vector,heap);
105 DEF_VEC_ALLOC_P(lambda_vector,gc);
106
107 /* An integer matrix. A matrix consists of m vectors of length n (IE
108 all vectors are the same length). */
109 typedef lambda_vector *lambda_matrix;
98 110
99 /* Each vector of the access matrix represents a linear access 111 /* Each vector of the access matrix represents a linear access
100 function for a subscript. First elements correspond to the 112 function for a subscript. First elements correspond to the
101 leftmost indices, ie. for a[i][j] the first vector corresponds to 113 leftmost indices, ie. for a[i][j] the first vector corresponds to
102 the subscript in "i". The elements of a vector are relative to 114 the subscript in "i". The elements of a vector are relative to
191 #define DR_BASE_OBJECT(DR) (DR)->indices.base_object 203 #define DR_BASE_OBJECT(DR) (DR)->indices.base_object
192 #define DR_ACCESS_FNS(DR) (DR)->indices.access_fns 204 #define DR_ACCESS_FNS(DR) (DR)->indices.access_fns
193 #define DR_ACCESS_FN(DR, I) VEC_index (tree, DR_ACCESS_FNS (DR), I) 205 #define DR_ACCESS_FN(DR, I) VEC_index (tree, DR_ACCESS_FNS (DR), I)
194 #define DR_NUM_DIMENSIONS(DR) VEC_length (tree, DR_ACCESS_FNS (DR)) 206 #define DR_NUM_DIMENSIONS(DR) VEC_length (tree, DR_ACCESS_FNS (DR))
195 #define DR_IS_READ(DR) (DR)->is_read 207 #define DR_IS_READ(DR) (DR)->is_read
208 #define DR_IS_WRITE(DR) (!DR_IS_READ (DR))
196 #define DR_BASE_ADDRESS(DR) (DR)->innermost.base_address 209 #define DR_BASE_ADDRESS(DR) (DR)->innermost.base_address
197 #define DR_OFFSET(DR) (DR)->innermost.offset 210 #define DR_OFFSET(DR) (DR)->innermost.offset
198 #define DR_INIT(DR) (DR)->innermost.init 211 #define DR_INIT(DR) (DR)->innermost.init
199 #define DR_STEP(DR) (DR)->innermost.step 212 #define DR_STEP(DR) (DR)->innermost.step
200 #define DR_PTR_INFO(DR) (DR)->alias.ptr_info 213 #define DR_PTR_INFO(DR) (DR)->alias.ptr_info
373 DEF_VEC_ALLOC_O (data_ref_loc, heap); 386 DEF_VEC_ALLOC_O (data_ref_loc, heap);
374 387
375 bool get_references_in_stmt (gimple, VEC (data_ref_loc, heap) **); 388 bool get_references_in_stmt (gimple, VEC (data_ref_loc, heap) **);
376 bool dr_analyze_innermost (struct data_reference *); 389 bool dr_analyze_innermost (struct data_reference *);
377 extern bool compute_data_dependences_for_loop (struct loop *, bool, 390 extern bool compute_data_dependences_for_loop (struct loop *, bool,
391 VEC (loop_p, heap) **,
378 VEC (data_reference_p, heap) **, 392 VEC (data_reference_p, heap) **,
379 VEC (ddr_p, heap) **); 393 VEC (ddr_p, heap) **);
380 extern bool compute_data_dependences_for_bb (basic_block, bool, 394 extern bool compute_data_dependences_for_bb (basic_block, bool,
381 VEC (data_reference_p, heap) **, 395 VEC (data_reference_p, heap) **,
382 VEC (ddr_p, heap) **); 396 VEC (ddr_p, heap) **);
403 extern void free_dependence_relations (VEC (ddr_p, heap) *); 417 extern void free_dependence_relations (VEC (ddr_p, heap) *);
404 extern void free_data_ref (data_reference_p); 418 extern void free_data_ref (data_reference_p);
405 extern void free_data_refs (VEC (data_reference_p, heap) *); 419 extern void free_data_refs (VEC (data_reference_p, heap) *);
406 extern bool find_data_references_in_stmt (struct loop *, gimple, 420 extern bool find_data_references_in_stmt (struct loop *, gimple,
407 VEC (data_reference_p, heap) **); 421 VEC (data_reference_p, heap) **);
408 extern bool graphite_find_data_references_in_stmt (struct loop *, gimple, 422 extern bool graphite_find_data_references_in_stmt (loop_p, loop_p, gimple,
409 VEC (data_reference_p, heap) **); 423 VEC (data_reference_p, heap) **);
410 struct data_reference *create_data_ref (struct loop *, tree, gimple, bool); 424 struct data_reference *create_data_ref (loop_p, loop_p, tree, gimple, bool);
411 extern bool find_loop_nest (struct loop *, VEC (loop_p, heap) **); 425 extern bool find_loop_nest (struct loop *, VEC (loop_p, heap) **);
412 extern void compute_all_dependences (VEC (data_reference_p, heap) *, 426 extern void compute_all_dependences (VEC (data_reference_p, heap) *,
413 VEC (ddr_p, heap) **, VEC (loop_p, heap) *, 427 VEC (ddr_p, heap) **, VEC (loop_p, heap) *,
414 bool); 428 bool);
415 429
416 extern void create_rdg_vertices (struct graph *, VEC (gimple, heap) *); 430 extern void create_rdg_vertices (struct graph *, VEC (gimple, heap) *);
417 extern bool dr_may_alias_p (const struct data_reference *, 431 extern bool dr_may_alias_p (const struct data_reference *,
418 const struct data_reference *); 432 const struct data_reference *);
419 433
434
435 /* Return true when the base objects of data references A and B are
436 the same memory object. */
437
438 static inline bool
439 same_data_refs_base_objects (data_reference_p a, data_reference_p b)
440 {
441 return DR_NUM_DIMENSIONS (a) == DR_NUM_DIMENSIONS (b)
442 && operand_equal_p (DR_BASE_OBJECT (a), DR_BASE_OBJECT (b), 0);
443 }
444
445 /* Return true when the data references A and B are accessing the same
446 memory object with the same access functions. */
447
448 static inline bool
449 same_data_refs (data_reference_p a, data_reference_p b)
450 {
451 unsigned int i;
452
453 /* The references are exactly the same. */
454 if (operand_equal_p (DR_REF (a), DR_REF (b), 0))
455 return true;
456
457 if (!same_data_refs_base_objects (a, b))
458 return false;
459
460 for (i = 0; i < DR_NUM_DIMENSIONS (a); i++)
461 if (!eq_evolutions_p (DR_ACCESS_FN (a, i), DR_ACCESS_FN (b, i)))
462 return false;
463
464 return true;
465 }
466
420 /* Return true when the DDR contains two data references that have the 467 /* Return true when the DDR contains two data references that have the
421 same access functions. */ 468 same access functions. */
422 469
423 static inline bool 470 static inline bool
424 same_access_functions (const struct data_dependence_relation *ddr) 471 same_access_functions (const struct data_dependence_relation *ddr)
438 static inline bool 485 static inline bool
439 ddr_is_anti_dependent (ddr_p ddr) 486 ddr_is_anti_dependent (ddr_p ddr)
440 { 487 {
441 return (DDR_ARE_DEPENDENT (ddr) == NULL_TREE 488 return (DDR_ARE_DEPENDENT (ddr) == NULL_TREE
442 && DR_IS_READ (DDR_A (ddr)) 489 && DR_IS_READ (DDR_A (ddr))
443 && !DR_IS_READ (DDR_B (ddr)) 490 && DR_IS_WRITE (DDR_B (ddr))
444 && !same_access_functions (ddr)); 491 && !same_access_functions (ddr));
445 } 492 }
446 493
447 /* Return true when DEPENDENCE_RELATIONS contains an anti-dependence. */ 494 /* Return true when DEPENDENCE_RELATIONS contains an anti-dependence. */
448 495
455 for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++) 502 for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++)
456 if (ddr_is_anti_dependent (ddr)) 503 if (ddr_is_anti_dependent (ddr))
457 return true; 504 return true;
458 505
459 return false; 506 return false;
507 }
508
509 /* Returns the dependence level for a vector DIST of size LENGTH.
510 LEVEL = 0 means a lexicographic dependence, i.e. a dependence due
511 to the sequence of statements, not carried by any loop. */
512
513 static inline unsigned
514 dependence_level (lambda_vector dist_vect, int length)
515 {
516 int i;
517
518 for (i = 0; i < length; i++)
519 if (dist_vect[i] != 0)
520 return i + 1;
521
522 return 0;
460 } 523 }
461 524
462 /* Return the dependence level for the DDR relation. */ 525 /* Return the dependence level for the DDR relation. */
463 526
464 static inline unsigned 527 static inline unsigned
541 604
542 #define RDGE_TYPE(E) ((struct rdg_edge *) ((E)->data))->type 605 #define RDGE_TYPE(E) ((struct rdg_edge *) ((E)->data))->type
543 #define RDGE_LEVEL(E) ((struct rdg_edge *) ((E)->data))->level 606 #define RDGE_LEVEL(E) ((struct rdg_edge *) ((E)->data))->level
544 #define RDGE_RELATION(E) ((struct rdg_edge *) ((E)->data))->relation 607 #define RDGE_RELATION(E) ((struct rdg_edge *) ((E)->data))->relation
545 608
546 struct graph *build_rdg (struct loop *); 609 struct graph *build_rdg (struct loop *,
610 VEC (loop_p, heap) **,
611 VEC (ddr_p, heap) **,
612 VEC (data_reference_p, heap) **);
547 struct graph *build_empty_rdg (int); 613 struct graph *build_empty_rdg (int);
548 void free_rdg (struct graph *); 614 void free_rdg (struct graph *);
549 615
550 /* Return the index of the variable VAR in the LOOP_NEST array. */ 616 /* Return the index of the variable VAR in the LOOP_NEST array. */
551 617
562 628
563 return var_index; 629 return var_index;
564 } 630 }
565 631
566 void stores_from_loop (struct loop *, VEC (gimple, heap) **); 632 void stores_from_loop (struct loop *, VEC (gimple, heap) **);
633 void stores_zero_from_loop (struct loop *, VEC (gimple, heap) **);
567 void remove_similar_memory_refs (VEC (gimple, heap) **); 634 void remove_similar_memory_refs (VEC (gimple, heap) **);
568 bool rdg_defs_used_in_other_loops_p (struct graph *, int); 635 bool rdg_defs_used_in_other_loops_p (struct graph *, int);
569 bool have_similar_memory_accesses (gimple, gimple); 636 bool have_similar_memory_accesses (gimple, gimple);
637 bool stmt_with_adjacent_zero_store_dr_p (gimple);
638
639 /* Returns true when STRIDE is equal in absolute value to the size of
640 the unit type of TYPE. */
641
642 static inline bool
643 stride_of_unit_type_p (tree stride, tree type)
644 {
645 return tree_int_cst_equal (fold_unary (ABS_EXPR, TREE_TYPE (stride),
646 stride),
647 TYPE_SIZE_UNIT (type));
648 }
570 649
571 /* Determines whether RDG vertices V1 and V2 access to similar memory 650 /* Determines whether RDG vertices V1 and V2 access to similar memory
572 locations, in which case they have to be in the same partition. */ 651 locations, in which case they have to be in the same partition. */
573 652
574 static inline bool 653 static inline bool
575 rdg_has_similar_memory_accesses (struct graph *rdg, int v1, int v2) 654 rdg_has_similar_memory_accesses (struct graph *rdg, int v1, int v2)
576 { 655 {
577 return have_similar_memory_accesses (RDG_STMT (rdg, v1), 656 return have_similar_memory_accesses (RDG_STMT (rdg, v1),
578 RDG_STMT (rdg, v2)); 657 RDG_STMT (rdg, v2));
579 } 658 }
580
581 /* In lambda-code.c */
582 bool lambda_transform_legal_p (lambda_trans_matrix, int,
583 VEC (ddr_p, heap) *);
584 void lambda_collect_parameters (VEC (data_reference_p, heap) *,
585 VEC (tree, heap) **);
586 bool lambda_compute_access_matrices (VEC (data_reference_p, heap) *,
587 VEC (tree, heap) *,
588 VEC (loop_p, heap) *,
589 struct obstack *);
590 659
591 /* In tree-data-ref.c */ 660 /* In tree-data-ref.c */
592 void split_constant_offset (tree , tree *, tree *); 661 void split_constant_offset (tree , tree *, tree *);
593 662
594 /* Strongly connected components of the reduced data dependence graph. */ 663 /* Strongly connected components of the reduced data dependence graph. */
603 DEF_VEC_ALLOC_P (rdgc, heap); 672 DEF_VEC_ALLOC_P (rdgc, heap);
604 673
605 DEF_VEC_P (bitmap); 674 DEF_VEC_P (bitmap);
606 DEF_VEC_ALLOC_P (bitmap, heap); 675 DEF_VEC_ALLOC_P (bitmap, heap);
607 676
677 /* Compute the greatest common divisor of a VECTOR of SIZE numbers. */
678
679 static inline int
680 lambda_vector_gcd (lambda_vector vector, int size)
681 {
682 int i;
683 int gcd1 = 0;
684
685 if (size > 0)
686 {
687 gcd1 = vector[0];
688 for (i = 1; i < size; i++)
689 gcd1 = gcd (gcd1, vector[i]);
690 }
691 return gcd1;
692 }
693
694 /* Allocate a new vector of given SIZE. */
695
696 static inline lambda_vector
697 lambda_vector_new (int size)
698 {
699 return (lambda_vector) ggc_alloc_cleared_atomic (sizeof (int) * size);
700 }
701
702 /* Clear out vector VEC1 of length SIZE. */
703
704 static inline void
705 lambda_vector_clear (lambda_vector vec1, int size)
706 {
707 memset (vec1, 0, size * sizeof (*vec1));
708 }
709
710 /* Returns true when the vector V is lexicographically positive, in
711 other words, when the first nonzero element is positive. */
712
713 static inline bool
714 lambda_vector_lexico_pos (lambda_vector v,
715 unsigned n)
716 {
717 unsigned i;
718 for (i = 0; i < n; i++)
719 {
720 if (v[i] == 0)
721 continue;
722 if (v[i] < 0)
723 return false;
724 if (v[i] > 0)
725 return true;
726 }
727 return true;
728 }
729
730 /* Return true if vector VEC1 of length SIZE is the zero vector. */
731
732 static inline bool
733 lambda_vector_zerop (lambda_vector vec1, int size)
734 {
735 int i;
736 for (i = 0; i < size; i++)
737 if (vec1[i] != 0)
738 return false;
739 return true;
740 }
741
742 /* Allocate a matrix of M rows x N cols. */
743
744 static inline lambda_matrix
745 lambda_matrix_new (int m, int n, struct obstack *lambda_obstack)
746 {
747 lambda_matrix mat;
748 int i;
749
750 mat = (lambda_matrix) obstack_alloc (lambda_obstack,
751 sizeof (lambda_vector *) * m);
752
753 for (i = 0; i < m; i++)
754 mat[i] = lambda_vector_new (n);
755
756 return mat;
757 }
758
608 #endif /* GCC_TREE_DATA_REF_H */ 759 #endif /* GCC_TREE_DATA_REF_H */