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