Mercurial > hg > CbC > CbC_gcc
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 */ |