comparison gcc/tree-vect-data-refs.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
comparison
equal deleted inserted replaced
56:3c8a44c06a95 63:b7f97abdc517
1 /* Data References Analysis and Manipulation Utilities for Vectorization. 1 /* Data References Analysis and Manipulation Utilities for Vectorization.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Foundation, Inc. 3 Free Software Foundation, Inc.
4 Contributed by Dorit Naishlos <dorit@il.ibm.com> 4 Contributed by Dorit Naishlos <dorit@il.ibm.com>
5 and Ira Rosen <irar@il.ibm.com> 5 and Ira Rosen <irar@il.ibm.com>
6 6
7 This file is part of GCC. 7 This file is part of GCC.
8 8
27 #include "ggc.h" 27 #include "ggc.h"
28 #include "tree.h" 28 #include "tree.h"
29 #include "target.h" 29 #include "target.h"
30 #include "basic-block.h" 30 #include "basic-block.h"
31 #include "diagnostic.h" 31 #include "diagnostic.h"
32 #include "tree-pretty-print.h"
33 #include "gimple-pretty-print.h"
32 #include "tree-flow.h" 34 #include "tree-flow.h"
33 #include "tree-dump.h" 35 #include "tree-dump.h"
34 #include "cfgloop.h" 36 #include "cfgloop.h"
35 #include "expr.h" 37 #include "expr.h"
36 #include "optabs.h" 38 #include "optabs.h"
292 Check if OFFSET1 and OFFSET2 are identical expressions. */ 294 Check if OFFSET1 and OFFSET2 are identical expressions. */
293 295
294 static bool 296 static bool
295 vect_equal_offsets (tree offset1, tree offset2) 297 vect_equal_offsets (tree offset1, tree offset2)
296 { 298 {
297 bool res0, res1; 299 bool res;
298 300
299 STRIP_NOPS (offset1); 301 STRIP_NOPS (offset1);
300 STRIP_NOPS (offset2); 302 STRIP_NOPS (offset2);
301 303
302 if (offset1 == offset2) 304 if (offset1 == offset2)
303 return true; 305 return true;
304 306
305 if (TREE_CODE (offset1) != TREE_CODE (offset2) 307 if (TREE_CODE (offset1) != TREE_CODE (offset2)
306 || !BINARY_CLASS_P (offset1) 308 || (!BINARY_CLASS_P (offset1) && !UNARY_CLASS_P (offset1)))
307 || !BINARY_CLASS_P (offset2))
308 return false; 309 return false;
309 310
310 res0 = vect_equal_offsets (TREE_OPERAND (offset1, 0), 311 res = vect_equal_offsets (TREE_OPERAND (offset1, 0),
311 TREE_OPERAND (offset2, 0)); 312 TREE_OPERAND (offset2, 0));
312 res1 = vect_equal_offsets (TREE_OPERAND (offset1, 1), 313
313 TREE_OPERAND (offset2, 1)); 314 if (!res || !BINARY_CLASS_P (offset1))
314 315 return res;
315 return (res0 && res1); 316
317 res = vect_equal_offsets (TREE_OPERAND (offset1, 1),
318 TREE_OPERAND (offset2, 1));
319
320 return res;
316 } 321 }
317 322
318 323
319 /* Function vect_check_interleaving. 324 /* Function vect_check_interleaving.
320 325
482 487
483 /* Function vect_analyze_data_ref_dependence. 488 /* Function vect_analyze_data_ref_dependence.
484 489
485 Return TRUE if there (might) exist a dependence between a memory-reference 490 Return TRUE if there (might) exist a dependence between a memory-reference
486 DRA and a memory-reference DRB. When versioning for alias may check a 491 DRA and a memory-reference DRB. When versioning for alias may check a
487 dependence at run-time, return FALSE. */ 492 dependence at run-time, return FALSE. Adjust *MAX_VF according to
493 the data dependence. */
488 494
489 static bool 495 static bool
490 vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, 496 vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
491 loop_vec_info loop_vinfo) 497 loop_vec_info loop_vinfo, int *max_vf)
492 { 498 {
493 unsigned int i; 499 unsigned int i;
494 struct loop *loop = NULL; 500 struct loop *loop = NULL;
495 int vectorization_factor = 0;
496 struct data_reference *dra = DDR_A (ddr); 501 struct data_reference *dra = DDR_A (ddr);
497 struct data_reference *drb = DDR_B (ddr); 502 struct data_reference *drb = DDR_B (ddr);
498 stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); 503 stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
499 stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb)); 504 stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
500 int dra_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dra))));
501 int drb_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (drb))));
502 lambda_vector dist_v; 505 lambda_vector dist_v;
503 unsigned int loop_depth; 506 unsigned int loop_depth;
507
508 /* Don't bother to analyze statements marked as unvectorizable. */
509 if (!STMT_VINFO_VECTORIZABLE (stmtinfo_a)
510 || !STMT_VINFO_VECTORIZABLE (stmtinfo_b))
511 return false;
504 512
505 if (DDR_ARE_DEPENDENT (ddr) == chrec_known) 513 if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
506 { 514 {
507 /* Independent data accesses. */ 515 /* Independent data accesses. */
508 vect_check_interleaving (dra, drb); 516 vect_check_interleaving (dra, drb);
509 return false; 517 return false;
510 } 518 }
511 519
512 if (loop_vinfo) 520 if (loop_vinfo)
513 { 521 loop = LOOP_VINFO_LOOP (loop_vinfo);
514 loop = LOOP_VINFO_LOOP (loop_vinfo);
515 vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
516 }
517 522
518 if ((DR_IS_READ (dra) && DR_IS_READ (drb) && loop_vinfo) || dra == drb) 523 if ((DR_IS_READ (dra) && DR_IS_READ (drb) && loop_vinfo) || dra == drb)
519 return false; 524 return false;
520 525
521 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know) 526 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
546 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM); 551 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
547 fprintf (vect_dump, " and "); 552 fprintf (vect_dump, " and ");
548 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM); 553 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
549 } 554 }
550 555
551 return true; 556 /* Mark the statements as unvectorizable. */
557 STMT_VINFO_VECTORIZABLE (stmtinfo_a) = false;
558 STMT_VINFO_VECTORIZABLE (stmtinfo_b) = false;
559
560 return false;
552 } 561 }
553 562
554 /* Versioning for alias is not yet supported for basic block SLP, and 563 /* Versioning for alias is not yet supported for basic block SLP, and
555 dependence distance is unapplicable, hence, in case of known data 564 dependence distance is unapplicable, hence, in case of known data
556 dependence, basic block vectorization is impossible for now. */ 565 dependence, basic block vectorization is impossible for now. */
590 int dist = dist_v[loop_depth]; 599 int dist = dist_v[loop_depth];
591 600
592 if (vect_print_dump_info (REPORT_DR_DETAILS)) 601 if (vect_print_dump_info (REPORT_DR_DETAILS))
593 fprintf (vect_dump, "dependence distance = %d.", dist); 602 fprintf (vect_dump, "dependence distance = %d.", dist);
594 603
595 /* Same loop iteration. */ 604 if (dist == 0)
596 if (dist % vectorization_factor == 0 && dra_size == drb_size)
597 { 605 {
598 /* Two references with distance zero have the same alignment. */
599 VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
600 VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
601 if (vect_print_dump_info (REPORT_ALIGNMENT))
602 fprintf (vect_dump, "accesses have the same alignment.");
603 if (vect_print_dump_info (REPORT_DR_DETAILS)) 606 if (vect_print_dump_info (REPORT_DR_DETAILS))
604 { 607 {
605 fprintf (vect_dump, "dependence distance modulo vf == 0 between "); 608 fprintf (vect_dump, "dependence distance == 0 between ");
606 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM); 609 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
607 fprintf (vect_dump, " and "); 610 fprintf (vect_dump, " and ");
608 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM); 611 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
609 } 612 }
610 613
616 { 619 {
617 if (DR_IS_READ (drb)) 620 if (DR_IS_READ (drb))
618 DR_GROUP_READ_WRITE_DEPENDENCE (stmtinfo_b) = true; 621 DR_GROUP_READ_WRITE_DEPENDENCE (stmtinfo_b) = true;
619 } 622 }
620 623
621 continue; 624 continue;
622 } 625 }
623 626
624 if (abs (dist) >= vectorization_factor 627 if (dist > 0 && DDR_REVERSED_P (ddr))
625 || (dist > 0 && DDR_REVERSED_P (ddr))) 628 {
629 /* If DDR_REVERSED_P the order of the data-refs in DDR was
630 reversed (to make distance vector positive), and the actual
631 distance is negative. */
632 if (vect_print_dump_info (REPORT_DR_DETAILS))
633 fprintf (vect_dump, "dependence distance negative.");
634 continue;
635 }
636
637 if (abs (dist) >= 2
638 && abs (dist) < *max_vf)
639 {
640 /* The dependence distance requires reduction of the maximal
641 vectorization factor. */
642 *max_vf = abs (dist);
643 if (vect_print_dump_info (REPORT_DR_DETAILS))
644 fprintf (vect_dump, "adjusting maximal vectorization factor to %i",
645 *max_vf);
646 }
647
648 if (abs (dist) >= *max_vf)
626 { 649 {
627 /* Dependence distance does not create dependence, as far as 650 /* Dependence distance does not create dependence, as far as
628 vectorization is concerned, in this case. If DDR_REVERSED_P the 651 vectorization is concerned, in this case. */
629 order of the data-refs in DDR was reversed (to make distance
630 vector positive), and the actual distance is negative. */
631 if (vect_print_dump_info (REPORT_DR_DETAILS)) 652 if (vect_print_dump_info (REPORT_DR_DETAILS))
632 fprintf (vect_dump, "dependence distance >= VF or negative."); 653 fprintf (vect_dump, "dependence distance >= VF.");
633 continue; 654 continue;
634 } 655 }
635 656
636 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) 657 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
637 { 658 {
649 } 670 }
650 671
651 /* Function vect_analyze_data_ref_dependences. 672 /* Function vect_analyze_data_ref_dependences.
652 673
653 Examine all the data references in the loop, and make sure there do not 674 Examine all the data references in the loop, and make sure there do not
654 exist any data dependences between them. */ 675 exist any data dependences between them. Set *MAX_VF according to
676 the maximum vectorization factor the data dependences allow. */
655 677
656 bool 678 bool
657 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo, 679 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo,
658 bb_vec_info bb_vinfo) 680 bb_vec_info bb_vinfo, int *max_vf)
659 { 681 {
660 unsigned int i; 682 unsigned int i;
661 VEC (ddr_p, heap) *ddrs = NULL; 683 VEC (ddr_p, heap) *ddrs = NULL;
662 struct data_dependence_relation *ddr; 684 struct data_dependence_relation *ddr;
663 685
668 ddrs = LOOP_VINFO_DDRS (loop_vinfo); 690 ddrs = LOOP_VINFO_DDRS (loop_vinfo);
669 else 691 else
670 ddrs = BB_VINFO_DDRS (bb_vinfo); 692 ddrs = BB_VINFO_DDRS (bb_vinfo);
671 693
672 for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++) 694 for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
673 if (vect_analyze_data_ref_dependence (ddr, loop_vinfo)) 695 if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, max_vf))
674 return false; 696 return false;
675 697
676 return true; 698 return true;
677 } 699 }
678 700
838 datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); 860 datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
839 else 861 else
840 datarefs = BB_VINFO_DATAREFS (bb_vinfo); 862 datarefs = BB_VINFO_DATAREFS (bb_vinfo);
841 863
842 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++) 864 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
843 if (!vect_compute_data_ref_alignment (dr)) 865 if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr)))
844 return false; 866 && !vect_compute_data_ref_alignment (dr))
867 {
868 if (bb_vinfo)
869 {
870 /* Mark unsupported statement as unvectorizable. */
871 STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
872 continue;
873 }
874 else
875 return false;
876 }
845 877
846 return true; 878 return true;
847 } 879 }
848 880
849 881
926 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++) 958 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
927 { 959 {
928 gimple stmt = DR_STMT (dr); 960 gimple stmt = DR_STMT (dr);
929 stmt_vec_info stmt_info = vinfo_for_stmt (stmt); 961 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
930 962
931 /* For interleaving, only the alignment of the first access matters. */ 963 /* For interleaving, only the alignment of the first access matters.
932 if (STMT_VINFO_STRIDED_ACCESS (stmt_info) 964 Skip statements marked as not vectorizable. */
933 && DR_GROUP_FIRST_DR (stmt_info) != stmt) 965 if ((STMT_VINFO_STRIDED_ACCESS (stmt_info)
966 && DR_GROUP_FIRST_DR (stmt_info) != stmt)
967 || !STMT_VINFO_VECTORIZABLE (stmt_info))
934 continue; 968 continue;
935 969
936 supportable_dr_alignment = vect_supportable_dr_alignment (dr); 970 supportable_dr_alignment = vect_supportable_dr_alignment (dr);
937 if (!supportable_dr_alignment) 971 if (!supportable_dr_alignment)
938 { 972 {
942 fprintf (vect_dump, 976 fprintf (vect_dump,
943 "not vectorized: unsupported unaligned load."); 977 "not vectorized: unsupported unaligned load.");
944 else 978 else
945 fprintf (vect_dump, 979 fprintf (vect_dump,
946 "not vectorized: unsupported unaligned store."); 980 "not vectorized: unsupported unaligned store.");
981
982 print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
947 } 983 }
948 return false; 984 return false;
949 } 985 }
950 if (supportable_dr_alignment != dr_aligned 986 if (supportable_dr_alignment != dr_aligned
951 && vect_print_dump_info (REPORT_ALIGNMENT)) 987 && vect_print_dump_info (REPORT_ALIGNMENT))
1405 stat = vect_verify_datarefs_alignment (loop_vinfo, NULL); 1441 stat = vect_verify_datarefs_alignment (loop_vinfo, NULL);
1406 return stat; 1442 return stat;
1407 } 1443 }
1408 1444
1409 1445
1446 /* Function vect_find_same_alignment_drs.
1447
1448 Update group and alignment relations according to the chosen
1449 vectorization factor. */
1450
1451 static void
1452 vect_find_same_alignment_drs (struct data_dependence_relation *ddr,
1453 loop_vec_info loop_vinfo)
1454 {
1455 unsigned int i;
1456 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1457 int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1458 struct data_reference *dra = DDR_A (ddr);
1459 struct data_reference *drb = DDR_B (ddr);
1460 stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
1461 stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
1462 int dra_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dra))));
1463 int drb_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (drb))));
1464 lambda_vector dist_v;
1465 unsigned int loop_depth;
1466
1467 if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
1468 return;
1469
1470 if ((DR_IS_READ (dra) && DR_IS_READ (drb)) || dra == drb)
1471 return;
1472
1473 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
1474 return;
1475
1476 /* Loop-based vectorization and known data dependence. */
1477 if (DDR_NUM_DIST_VECTS (ddr) == 0)
1478 return;
1479
1480 loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr));
1481 for (i = 0; VEC_iterate (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v); i++)
1482 {
1483 int dist = dist_v[loop_depth];
1484
1485 if (vect_print_dump_info (REPORT_DR_DETAILS))
1486 fprintf (vect_dump, "dependence distance = %d.", dist);
1487
1488 /* Same loop iteration. */
1489 if (dist == 0
1490 || (dist % vectorization_factor == 0 && dra_size == drb_size))
1491 {
1492 /* Two references with distance zero have the same alignment. */
1493 VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
1494 VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
1495 if (vect_print_dump_info (REPORT_ALIGNMENT))
1496 fprintf (vect_dump, "accesses have the same alignment.");
1497 if (vect_print_dump_info (REPORT_DR_DETAILS))
1498 {
1499 fprintf (vect_dump, "dependence distance modulo vf == 0 between ");
1500 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1501 fprintf (vect_dump, " and ");
1502 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1503 }
1504 }
1505 }
1506 }
1507
1508
1410 /* Function vect_analyze_data_refs_alignment 1509 /* Function vect_analyze_data_refs_alignment
1411 1510
1412 Analyze the alignment of the data-references in the loop. 1511 Analyze the alignment of the data-references in the loop.
1413 Return FALSE if a data reference is found that cannot be vectorized. */ 1512 Return FALSE if a data reference is found that cannot be vectorized. */
1414 1513
1416 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo, 1515 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo,
1417 bb_vec_info bb_vinfo) 1516 bb_vec_info bb_vinfo)
1418 { 1517 {
1419 if (vect_print_dump_info (REPORT_DETAILS)) 1518 if (vect_print_dump_info (REPORT_DETAILS))
1420 fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ==="); 1519 fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ===");
1520
1521 /* Mark groups of data references with same alignment using
1522 data dependence information. */
1523 if (loop_vinfo)
1524 {
1525 VEC (ddr_p, heap) *ddrs = LOOP_VINFO_DDRS (loop_vinfo);
1526 struct data_dependence_relation *ddr;
1527 unsigned int i;
1528
1529 for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
1530 vect_find_same_alignment_drs (ddr, loop_vinfo);
1531 }
1421 1532
1422 if (!vect_compute_data_refs_alignment (loop_vinfo, bb_vinfo)) 1533 if (!vect_compute_data_refs_alignment (loop_vinfo, bb_vinfo))
1423 { 1534 {
1424 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) 1535 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1425 fprintf (vect_dump, 1536 fprintf (vect_dump,
1476 fprintf (vect_dump, " step "); 1587 fprintf (vect_dump, " step ");
1477 print_generic_expr (vect_dump, step, TDF_SLIM); 1588 print_generic_expr (vect_dump, step, TDF_SLIM);
1478 } 1589 }
1479 return true; 1590 return true;
1480 } 1591 }
1592
1481 if (vect_print_dump_info (REPORT_DETAILS)) 1593 if (vect_print_dump_info (REPORT_DETAILS))
1482 fprintf (vect_dump, "not consecutive access"); 1594 {
1595 fprintf (vect_dump, "not consecutive access ");
1596 print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
1597 }
1598
1599 if (bb_vinfo)
1600 {
1601 /* Mark the statement as unvectorizable. */
1602 STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
1603 return true;
1604 }
1605
1483 return false; 1606 return false;
1484 } 1607 }
1485 1608
1486 if (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) == stmt) 1609 if (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) == stmt)
1487 { 1610 {
1748 datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); 1871 datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1749 else 1872 else
1750 datarefs = BB_VINFO_DATAREFS (bb_vinfo); 1873 datarefs = BB_VINFO_DATAREFS (bb_vinfo);
1751 1874
1752 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++) 1875 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1753 if (!vect_analyze_data_ref_access (dr)) 1876 if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr)))
1877 && !vect_analyze_data_ref_access (dr))
1754 { 1878 {
1755 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) 1879 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1756 fprintf (vect_dump, "not vectorized: complicated access pattern."); 1880 fprintf (vect_dump, "not vectorized: complicated access pattern.");
1757 return false; 1881
1882 if (bb_vinfo)
1883 {
1884 /* Mark the statement as not vectorizable. */
1885 STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
1886 continue;
1887 }
1888 else
1889 return false;
1758 } 1890 }
1759 1891
1760 return true; 1892 return true;
1761 } 1893 }
1762 1894
1847 4- vect_analyze_drs_access(): check that ref_stmt.step is ok. 1979 4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
1848 1980
1849 */ 1981 */
1850 1982
1851 bool 1983 bool
1852 vect_analyze_data_refs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) 1984 vect_analyze_data_refs (loop_vec_info loop_vinfo,
1985 bb_vec_info bb_vinfo,
1986 int *min_vf)
1853 { 1987 {
1854 struct loop *loop = NULL; 1988 struct loop *loop = NULL;
1855 basic_block bb = NULL; 1989 basic_block bb = NULL;
1856 unsigned int i; 1990 unsigned int i;
1857 VEC (data_reference_p, heap) *datarefs; 1991 VEC (data_reference_p, heap) *datarefs;
1858 struct data_reference *dr; 1992 struct data_reference *dr;
1859 tree scalar_type; 1993 tree scalar_type;
1994 bool res;
1860 1995
1861 if (vect_print_dump_info (REPORT_DETAILS)) 1996 if (vect_print_dump_info (REPORT_DETAILS))
1862 fprintf (vect_dump, "=== vect_analyze_data_refs ===\n"); 1997 fprintf (vect_dump, "=== vect_analyze_data_refs ===\n");
1863 1998
1864 if (loop_vinfo) 1999 if (loop_vinfo)
1865 { 2000 {
1866 loop = LOOP_VINFO_LOOP (loop_vinfo); 2001 loop = LOOP_VINFO_LOOP (loop_vinfo);
1867 compute_data_dependences_for_loop (loop, true, 2002 res = compute_data_dependences_for_loop
1868 &LOOP_VINFO_DATAREFS (loop_vinfo), 2003 (loop, true, &LOOP_VINFO_DATAREFS (loop_vinfo),
1869 &LOOP_VINFO_DDRS (loop_vinfo)); 2004 &LOOP_VINFO_DDRS (loop_vinfo));
2005
2006 if (!res)
2007 {
2008 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
2009 fprintf (vect_dump, "not vectorized: loop contains function calls"
2010 " or data references that cannot be analyzed");
2011 return false;
2012 }
2013
1870 datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); 2014 datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1871 } 2015 }
1872 else 2016 else
1873 { 2017 {
1874 bb = BB_VINFO_BB (bb_vinfo); 2018 bb = BB_VINFO_BB (bb_vinfo);
1875 compute_data_dependences_for_bb (bb, true, 2019 res = compute_data_dependences_for_bb (bb, true,
1876 &BB_VINFO_DATAREFS (bb_vinfo), 2020 &BB_VINFO_DATAREFS (bb_vinfo),
1877 &BB_VINFO_DDRS (bb_vinfo)); 2021 &BB_VINFO_DDRS (bb_vinfo));
2022 if (!res)
2023 {
2024 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
2025 fprintf (vect_dump, "not vectorized: basic block contains function"
2026 " calls or data references that cannot be analyzed");
2027 return false;
2028 }
2029
1878 datarefs = BB_VINFO_DATAREFS (bb_vinfo); 2030 datarefs = BB_VINFO_DATAREFS (bb_vinfo);
1879 } 2031 }
1880 2032
1881 /* Go through the data-refs, check that the analysis succeeded. Update pointer 2033 /* Go through the data-refs, check that the analysis succeeded. Update pointer
1882 from stmt_vec_info struct to DR and vectype. */ 2034 from stmt_vec_info struct to DR and vectype. */
1884 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++) 2036 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1885 { 2037 {
1886 gimple stmt; 2038 gimple stmt;
1887 stmt_vec_info stmt_info; 2039 stmt_vec_info stmt_info;
1888 tree base, offset, init; 2040 tree base, offset, init;
2041 int vf;
1889 2042
1890 if (!dr || !DR_REF (dr)) 2043 if (!dr || !DR_REF (dr))
1891 { 2044 {
1892 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) 2045 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1893 fprintf (vect_dump, "not vectorized: unhandled data-ref "); 2046 fprintf (vect_dump, "not vectorized: unhandled data-ref ");
1904 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) 2057 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1905 { 2058 {
1906 fprintf (vect_dump, "not vectorized: data ref analysis failed "); 2059 fprintf (vect_dump, "not vectorized: data ref analysis failed ");
1907 print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); 2060 print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
1908 } 2061 }
1909 return false; 2062
2063 if (bb_vinfo)
2064 {
2065 /* Mark the statement as not vectorizable. */
2066 STMT_VINFO_VECTORIZABLE (stmt_info) = false;
2067 continue;
2068 }
2069 else
2070 return false;
1910 } 2071 }
1911 2072
1912 if (TREE_CODE (DR_BASE_ADDRESS (dr)) == INTEGER_CST) 2073 if (TREE_CODE (DR_BASE_ADDRESS (dr)) == INTEGER_CST)
1913 { 2074 {
1914 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) 2075 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1915 fprintf (vect_dump, "not vectorized: base addr of dr is a " 2076 fprintf (vect_dump, "not vectorized: base addr of dr is a "
1916 "constant"); 2077 "constant");
1917 return false; 2078 if (bb_vinfo)
2079 {
2080 /* Mark the statement as not vectorizable. */
2081 STMT_VINFO_VECTORIZABLE (stmt_info) = false;
2082 continue;
2083 }
2084 else
2085 return false;
1918 } 2086 }
1919 2087
1920 base = unshare_expr (DR_BASE_ADDRESS (dr)); 2088 base = unshare_expr (DR_BASE_ADDRESS (dr));
1921 offset = unshare_expr (DR_OFFSET (dr)); 2089 offset = unshare_expr (DR_OFFSET (dr));
1922 init = unshare_expr (DR_INIT (dr)); 2090 init = unshare_expr (DR_INIT (dr));
2054 "not vectorized: no vectype for stmt: "); 2222 "not vectorized: no vectype for stmt: ");
2055 print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); 2223 print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
2056 fprintf (vect_dump, " scalar_type: "); 2224 fprintf (vect_dump, " scalar_type: ");
2057 print_generic_expr (vect_dump, scalar_type, TDF_DETAILS); 2225 print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
2058 } 2226 }
2059 return false; 2227
2228 if (bb_vinfo)
2229 {
2230 /* Mark the statement as not vectorizable. */
2231 STMT_VINFO_VECTORIZABLE (stmt_info) = false;
2232 continue;
2233 }
2234 else
2235 return false;
2060 } 2236 }
2237
2238 /* Adjust the minimal vectorization factor according to the
2239 vector type. */
2240 vf = TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info));
2241 if (vf > *min_vf)
2242 *min_vf = vf;
2061 } 2243 }
2062 2244
2063 return true; 2245 return true;
2064 } 2246 }
2065 2247