Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-vect-stmts.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 /* Statement Analysis and Transformation for Vectorization | 1 /* Statement Analysis and Transformation 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 "cfglayout.h" | 37 #include "cfglayout.h" |
36 #include "expr.h" | 38 #include "expr.h" |
1132 vect_get_vec_defs (tree op0, tree op1, gimple stmt, | 1134 vect_get_vec_defs (tree op0, tree op1, gimple stmt, |
1133 VEC(tree,heap) **vec_oprnds0, VEC(tree,heap) **vec_oprnds1, | 1135 VEC(tree,heap) **vec_oprnds0, VEC(tree,heap) **vec_oprnds1, |
1134 slp_tree slp_node) | 1136 slp_tree slp_node) |
1135 { | 1137 { |
1136 if (slp_node) | 1138 if (slp_node) |
1137 vect_get_slp_defs (slp_node, vec_oprnds0, vec_oprnds1); | 1139 vect_get_slp_defs (slp_node, vec_oprnds0, vec_oprnds1, -1); |
1138 else | 1140 else |
1139 { | 1141 { |
1140 tree vec_oprnd; | 1142 tree vec_oprnd; |
1141 | 1143 |
1142 *vec_oprnds0 = VEC_alloc (tree, heap, 1); | 1144 *vec_oprnds0 = VEC_alloc (tree, heap, 1); |
1187 | 1189 |
1188 tree | 1190 tree |
1189 vectorizable_function (gimple call, tree vectype_out, tree vectype_in) | 1191 vectorizable_function (gimple call, tree vectype_out, tree vectype_in) |
1190 { | 1192 { |
1191 tree fndecl = gimple_call_fndecl (call); | 1193 tree fndecl = gimple_call_fndecl (call); |
1192 enum built_in_function code; | |
1193 | 1194 |
1194 /* We only handle functions that do not read or clobber memory -- i.e. | 1195 /* We only handle functions that do not read or clobber memory -- i.e. |
1195 const or novops ones. */ | 1196 const or novops ones. */ |
1196 if (!(gimple_call_flags (call) & (ECF_CONST | ECF_NOVOPS))) | 1197 if (!(gimple_call_flags (call) & (ECF_CONST | ECF_NOVOPS))) |
1197 return NULL_TREE; | 1198 return NULL_TREE; |
1199 if (!fndecl | 1200 if (!fndecl |
1200 || TREE_CODE (fndecl) != FUNCTION_DECL | 1201 || TREE_CODE (fndecl) != FUNCTION_DECL |
1201 || !DECL_BUILT_IN (fndecl)) | 1202 || !DECL_BUILT_IN (fndecl)) |
1202 return NULL_TREE; | 1203 return NULL_TREE; |
1203 | 1204 |
1204 code = DECL_FUNCTION_CODE (fndecl); | 1205 return targetm.vectorize.builtin_vectorized_function (fndecl, vectype_out, |
1205 return targetm.vectorize.builtin_vectorized_function (code, vectype_out, | |
1206 vectype_in); | 1206 vectype_in); |
1207 } | 1207 } |
1208 | 1208 |
1209 /* Function vectorizable_call. | 1209 /* Function vectorizable_call. |
1210 | 1210 |
1223 stmt_vec_info stmt_info = vinfo_for_stmt (stmt), prev_stmt_info; | 1223 stmt_vec_info stmt_info = vinfo_for_stmt (stmt), prev_stmt_info; |
1224 tree vectype_out, vectype_in; | 1224 tree vectype_out, vectype_in; |
1225 int nunits_in; | 1225 int nunits_in; |
1226 int nunits_out; | 1226 int nunits_out; |
1227 loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); | 1227 loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); |
1228 tree fndecl, new_temp, def, rhs_type, lhs_type; | 1228 tree fndecl, new_temp, def, rhs_type; |
1229 gimple def_stmt; | 1229 gimple def_stmt; |
1230 enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type}; | 1230 enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type}; |
1231 gimple new_stmt = NULL; | 1231 gimple new_stmt = NULL; |
1232 int ncopies, j; | 1232 int ncopies, j; |
1233 VEC(tree, heap) *vargs = NULL; | 1233 VEC(tree, heap) *vargs = NULL; |
1252 return false; | 1252 return false; |
1253 | 1253 |
1254 if (TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME) | 1254 if (TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME) |
1255 return false; | 1255 return false; |
1256 | 1256 |
1257 vectype_out = STMT_VINFO_VECTYPE (stmt_info); | |
1258 | |
1257 /* Process function arguments. */ | 1259 /* Process function arguments. */ |
1258 rhs_type = NULL_TREE; | 1260 rhs_type = NULL_TREE; |
1261 vectype_in = NULL_TREE; | |
1259 nargs = gimple_call_num_args (stmt); | 1262 nargs = gimple_call_num_args (stmt); |
1260 | 1263 |
1261 /* Bail out if the function has more than two arguments, we | 1264 /* Bail out if the function has more than two arguments, we |
1262 do not have interesting builtin functions to vectorize with | 1265 do not have interesting builtin functions to vectorize with |
1263 more than two arguments. No arguments is also not good. */ | 1266 more than two arguments. No arguments is also not good. */ |
1264 if (nargs == 0 || nargs > 2) | 1267 if (nargs == 0 || nargs > 2) |
1265 return false; | 1268 return false; |
1266 | 1269 |
1267 for (i = 0; i < nargs; i++) | 1270 for (i = 0; i < nargs; i++) |
1268 { | 1271 { |
1272 tree opvectype; | |
1273 | |
1269 op = gimple_call_arg (stmt, i); | 1274 op = gimple_call_arg (stmt, i); |
1270 | 1275 |
1271 /* We can only handle calls with arguments of the same type. */ | 1276 /* We can only handle calls with arguments of the same type. */ |
1272 if (rhs_type | 1277 if (rhs_type |
1273 && rhs_type != TREE_TYPE (op)) | 1278 && !types_compatible_p (rhs_type, TREE_TYPE (op))) |
1274 { | 1279 { |
1275 if (vect_print_dump_info (REPORT_DETAILS)) | 1280 if (vect_print_dump_info (REPORT_DETAILS)) |
1276 fprintf (vect_dump, "argument types differ."); | 1281 fprintf (vect_dump, "argument types differ."); |
1277 return false; | 1282 return false; |
1278 } | 1283 } |
1279 rhs_type = TREE_TYPE (op); | 1284 if (!rhs_type) |
1280 | 1285 rhs_type = TREE_TYPE (op); |
1281 if (!vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def, &dt[i])) | 1286 |
1287 if (!vect_is_simple_use_1 (op, loop_vinfo, NULL, | |
1288 &def_stmt, &def, &dt[i], &opvectype)) | |
1282 { | 1289 { |
1283 if (vect_print_dump_info (REPORT_DETAILS)) | 1290 if (vect_print_dump_info (REPORT_DETAILS)) |
1284 fprintf (vect_dump, "use not simple."); | 1291 fprintf (vect_dump, "use not simple."); |
1285 return false; | 1292 return false; |
1286 } | 1293 } |
1287 } | 1294 |
1288 | 1295 if (!vectype_in) |
1289 vectype_in = get_vectype_for_scalar_type (rhs_type); | 1296 vectype_in = opvectype; |
1297 else if (opvectype | |
1298 && opvectype != vectype_in) | |
1299 { | |
1300 if (vect_print_dump_info (REPORT_DETAILS)) | |
1301 fprintf (vect_dump, "argument vector types differ."); | |
1302 return false; | |
1303 } | |
1304 } | |
1305 /* If all arguments are external or constant defs use a vector type with | |
1306 the same size as the output vector type. */ | |
1290 if (!vectype_in) | 1307 if (!vectype_in) |
1291 return false; | 1308 vectype_in = get_same_sized_vectype (rhs_type, vectype_out); |
1309 if (vec_stmt) | |
1310 gcc_assert (vectype_in); | |
1311 if (!vectype_in) | |
1312 { | |
1313 if (vect_print_dump_info (REPORT_DETAILS)) | |
1314 { | |
1315 fprintf (vect_dump, "no vectype for scalar type "); | |
1316 print_generic_expr (vect_dump, rhs_type, TDF_SLIM); | |
1317 } | |
1318 | |
1319 return false; | |
1320 } | |
1321 | |
1322 /* FORNOW */ | |
1292 nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in); | 1323 nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in); |
1293 | |
1294 lhs_type = TREE_TYPE (gimple_call_lhs (stmt)); | |
1295 vectype_out = get_vectype_for_scalar_type (lhs_type); | |
1296 if (!vectype_out) | |
1297 return false; | |
1298 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); | 1324 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); |
1299 | |
1300 /* FORNOW */ | |
1301 if (nunits_in == nunits_out / 2) | 1325 if (nunits_in == nunits_out / 2) |
1302 modifier = NARROW; | 1326 modifier = NARROW; |
1303 else if (nunits_out == nunits_in) | 1327 else if (nunits_out == nunits_in) |
1304 modifier = NONE; | 1328 modifier = NONE; |
1305 else if (nunits_out == nunits_in / 2) | 1329 else if (nunits_out == nunits_in / 2) |
1546 stmt_vec_info prev_stmt_info; | 1570 stmt_vec_info prev_stmt_info; |
1547 int nunits_in; | 1571 int nunits_in; |
1548 int nunits_out; | 1572 int nunits_out; |
1549 tree vectype_out, vectype_in; | 1573 tree vectype_out, vectype_in; |
1550 int ncopies, j; | 1574 int ncopies, j; |
1551 tree rhs_type, lhs_type; | 1575 tree rhs_type; |
1552 tree builtin_decl; | 1576 tree builtin_decl; |
1553 enum { NARROW, NONE, WIDEN } modifier; | 1577 enum { NARROW, NONE, WIDEN } modifier; |
1554 int i; | 1578 int i; |
1555 VEC(tree,heap) *vec_oprnds0 = NULL; | 1579 VEC(tree,heap) *vec_oprnds0 = NULL; |
1556 tree vop0; | 1580 tree vop0; |
1557 tree integral_type; | |
1558 VEC(tree,heap) *dummy = NULL; | 1581 VEC(tree,heap) *dummy = NULL; |
1559 int dummy_int; | 1582 int dummy_int; |
1560 | 1583 |
1561 /* Is STMT a vectorizable conversion? */ | 1584 /* Is STMT a vectorizable conversion? */ |
1562 | 1585 |
1578 code = gimple_assign_rhs_code (stmt); | 1601 code = gimple_assign_rhs_code (stmt); |
1579 if (code != FIX_TRUNC_EXPR && code != FLOAT_EXPR) | 1602 if (code != FIX_TRUNC_EXPR && code != FLOAT_EXPR) |
1580 return false; | 1603 return false; |
1581 | 1604 |
1582 /* Check types of lhs and rhs. */ | 1605 /* Check types of lhs and rhs. */ |
1606 scalar_dest = gimple_assign_lhs (stmt); | |
1607 vectype_out = STMT_VINFO_VECTYPE (stmt_info); | |
1608 | |
1583 op0 = gimple_assign_rhs1 (stmt); | 1609 op0 = gimple_assign_rhs1 (stmt); |
1584 rhs_type = TREE_TYPE (op0); | 1610 rhs_type = TREE_TYPE (op0); |
1585 vectype_in = get_vectype_for_scalar_type (rhs_type); | 1611 /* Check the operands of the operation. */ |
1612 if (!vect_is_simple_use_1 (op0, loop_vinfo, NULL, | |
1613 &def_stmt, &def, &dt[0], &vectype_in)) | |
1614 { | |
1615 if (vect_print_dump_info (REPORT_DETAILS)) | |
1616 fprintf (vect_dump, "use not simple."); | |
1617 return false; | |
1618 } | |
1619 /* If op0 is an external or constant defs use a vector type of | |
1620 the same size as the output vector type. */ | |
1586 if (!vectype_in) | 1621 if (!vectype_in) |
1587 return false; | 1622 vectype_in = get_same_sized_vectype (rhs_type, vectype_out); |
1623 if (vec_stmt) | |
1624 gcc_assert (vectype_in); | |
1625 if (!vectype_in) | |
1626 { | |
1627 if (vect_print_dump_info (REPORT_DETAILS)) | |
1628 { | |
1629 fprintf (vect_dump, "no vectype for scalar type "); | |
1630 print_generic_expr (vect_dump, rhs_type, TDF_SLIM); | |
1631 } | |
1632 | |
1633 return false; | |
1634 } | |
1635 | |
1636 /* FORNOW */ | |
1588 nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in); | 1637 nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in); |
1589 | |
1590 scalar_dest = gimple_assign_lhs (stmt); | |
1591 lhs_type = TREE_TYPE (scalar_dest); | |
1592 vectype_out = get_vectype_for_scalar_type (lhs_type); | |
1593 if (!vectype_out) | |
1594 return false; | |
1595 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); | 1638 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); |
1596 | |
1597 /* FORNOW */ | |
1598 if (nunits_in == nunits_out / 2) | 1639 if (nunits_in == nunits_out / 2) |
1599 modifier = NARROW; | 1640 modifier = NARROW; |
1600 else if (nunits_out == nunits_in) | 1641 else if (nunits_out == nunits_in) |
1601 modifier = NONE; | 1642 modifier = NONE; |
1602 else if (nunits_out == nunits_in / 2) | 1643 else if (nunits_out == nunits_in / 2) |
1603 modifier = WIDEN; | 1644 modifier = WIDEN; |
1604 else | 1645 else |
1605 return false; | 1646 return false; |
1606 | 1647 |
1607 if (modifier == NONE) | |
1608 gcc_assert (STMT_VINFO_VECTYPE (stmt_info) == vectype_out); | |
1609 | |
1610 /* Bail out if the types are both integral or non-integral. */ | |
1611 if ((INTEGRAL_TYPE_P (rhs_type) && INTEGRAL_TYPE_P (lhs_type)) | |
1612 || (!INTEGRAL_TYPE_P (rhs_type) && !INTEGRAL_TYPE_P (lhs_type))) | |
1613 return false; | |
1614 | |
1615 integral_type = INTEGRAL_TYPE_P (rhs_type) ? vectype_in : vectype_out; | |
1616 | |
1617 if (modifier == NARROW) | 1648 if (modifier == NARROW) |
1618 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out; | 1649 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out; |
1619 else | 1650 else |
1620 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; | 1651 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; |
1621 | 1652 |
1626 | 1657 |
1627 /* Sanity check: make sure that at least one copy of the vectorized stmt | 1658 /* Sanity check: make sure that at least one copy of the vectorized stmt |
1628 needs to be generated. */ | 1659 needs to be generated. */ |
1629 gcc_assert (ncopies >= 1); | 1660 gcc_assert (ncopies >= 1); |
1630 | 1661 |
1631 /* Check the operands of the operation. */ | |
1632 if (!vect_is_simple_use (op0, loop_vinfo, NULL, &def_stmt, &def, &dt[0])) | |
1633 { | |
1634 if (vect_print_dump_info (REPORT_DETAILS)) | |
1635 fprintf (vect_dump, "use not simple."); | |
1636 return false; | |
1637 } | |
1638 | |
1639 /* Supportable by target? */ | 1662 /* Supportable by target? */ |
1640 if ((modifier == NONE | 1663 if ((modifier == NONE |
1641 && !targetm.vectorize.builtin_conversion (code, integral_type)) | 1664 && !targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in)) |
1642 || (modifier == WIDEN | 1665 || (modifier == WIDEN |
1643 && !supportable_widening_operation (code, stmt, vectype_in, | 1666 && !supportable_widening_operation (code, stmt, |
1667 vectype_out, vectype_in, | |
1644 &decl1, &decl2, | 1668 &decl1, &decl2, |
1645 &code1, &code2, | 1669 &code1, &code2, |
1646 &dummy_int, &dummy)) | 1670 &dummy_int, &dummy)) |
1647 || (modifier == NARROW | 1671 || (modifier == NARROW |
1648 && !supportable_narrowing_operation (code, stmt, vectype_in, | 1672 && !supportable_narrowing_operation (code, vectype_out, vectype_in, |
1649 &code1, &dummy_int, &dummy))) | 1673 &code1, &dummy_int, &dummy))) |
1650 { | 1674 { |
1651 if (vect_print_dump_info (REPORT_DETAILS)) | 1675 if (vect_print_dump_info (REPORT_DETAILS)) |
1652 fprintf (vect_dump, "conversion not supported by target."); | 1676 fprintf (vect_dump, "conversion not supported by target."); |
1653 return false; | 1677 return false; |
1654 } | 1678 } |
1655 | 1679 |
1656 if (modifier != NONE) | 1680 if (modifier != NONE) |
1657 { | 1681 { |
1658 STMT_VINFO_VECTYPE (stmt_info) = vectype_in; | |
1659 /* FORNOW: SLP not supported. */ | 1682 /* FORNOW: SLP not supported. */ |
1660 if (STMT_SLP_TYPE (stmt_info)) | 1683 if (STMT_SLP_TYPE (stmt_info)) |
1661 return false; | 1684 return false; |
1662 } | 1685 } |
1663 | 1686 |
1687 vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node); | 1710 vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node); |
1688 else | 1711 else |
1689 vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL); | 1712 vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL); |
1690 | 1713 |
1691 builtin_decl = | 1714 builtin_decl = |
1692 targetm.vectorize.builtin_conversion (code, integral_type); | 1715 targetm.vectorize.builtin_conversion (code, |
1716 vectype_out, vectype_in); | |
1693 for (i = 0; VEC_iterate (tree, vec_oprnds0, i, vop0); i++) | 1717 for (i = 0; VEC_iterate (tree, vec_oprnds0, i, vop0); i++) |
1694 { | 1718 { |
1695 /* Arguments are ready. create the new vector stmt. */ | 1719 /* Arguments are ready. create the new vector stmt. */ |
1696 new_stmt = gimple_build_call (builtin_decl, 1, vop0); | 1720 new_stmt = gimple_build_call (builtin_decl, 1, vop0); |
1697 new_temp = make_ssa_name (vec_dest, new_stmt); | 1721 new_temp = make_ssa_name (vec_dest, new_stmt); |
1718 { | 1742 { |
1719 if (j == 0) | 1743 if (j == 0) |
1720 vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL); | 1744 vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL); |
1721 else | 1745 else |
1722 vec_oprnd0 = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd0); | 1746 vec_oprnd0 = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd0); |
1723 | |
1724 STMT_VINFO_VECTYPE (stmt_info) = vectype_in; | |
1725 | 1747 |
1726 /* Generate first half of the widened result: */ | 1748 /* Generate first half of the widened result: */ |
1727 new_stmt | 1749 new_stmt |
1728 = vect_gen_widened_results_half (code1, decl1, | 1750 = vect_gen_widened_results_half (code1, decl1, |
1729 vec_oprnd0, vec_oprnd1, | 1751 vec_oprnd0, vec_oprnd1, |
1918 tree vec_dest; | 1940 tree vec_dest; |
1919 tree scalar_dest; | 1941 tree scalar_dest; |
1920 tree op0, op1 = NULL; | 1942 tree op0, op1 = NULL; |
1921 tree vec_oprnd1 = NULL_TREE; | 1943 tree vec_oprnd1 = NULL_TREE; |
1922 stmt_vec_info stmt_info = vinfo_for_stmt (stmt); | 1944 stmt_vec_info stmt_info = vinfo_for_stmt (stmt); |
1923 tree vectype = STMT_VINFO_VECTYPE (stmt_info); | 1945 tree vectype; |
1924 loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); | 1946 loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); |
1925 enum tree_code code; | 1947 enum tree_code code; |
1926 enum machine_mode vec_mode; | 1948 enum machine_mode vec_mode; |
1927 tree new_temp; | 1949 tree new_temp; |
1928 int op_type; | 1950 int op_type; |
1932 tree def; | 1954 tree def; |
1933 gimple def_stmt; | 1955 gimple def_stmt; |
1934 enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type}; | 1956 enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type}; |
1935 gimple new_stmt = NULL; | 1957 gimple new_stmt = NULL; |
1936 stmt_vec_info prev_stmt_info; | 1958 stmt_vec_info prev_stmt_info; |
1937 int nunits_in = TYPE_VECTOR_SUBPARTS (vectype); | 1959 int nunits_in; |
1938 int nunits_out; | 1960 int nunits_out; |
1939 tree vectype_out; | 1961 tree vectype_out; |
1940 int ncopies; | 1962 int ncopies; |
1941 int j, i; | 1963 int j, i; |
1942 VEC(tree,heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL; | 1964 VEC(tree,heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL; |
1944 unsigned int k; | 1966 unsigned int k; |
1945 bool scalar_shift_arg = false; | 1967 bool scalar_shift_arg = false; |
1946 bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info); | 1968 bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info); |
1947 int vf; | 1969 int vf; |
1948 | 1970 |
1949 if (loop_vinfo) | |
1950 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); | |
1951 else | |
1952 vf = 1; | |
1953 | |
1954 /* Multiple types in SLP are handled by creating the appropriate number of | |
1955 vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in | |
1956 case of SLP. */ | |
1957 if (slp_node) | |
1958 ncopies = 1; | |
1959 else | |
1960 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; | |
1961 | |
1962 gcc_assert (ncopies >= 1); | |
1963 | |
1964 if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo) | 1971 if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo) |
1965 return false; | 1972 return false; |
1966 | 1973 |
1967 if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def) | 1974 if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def) |
1968 return false; | 1975 return false; |
1970 /* Is STMT a vectorizable binary/unary operation? */ | 1977 /* Is STMT a vectorizable binary/unary operation? */ |
1971 if (!is_gimple_assign (stmt)) | 1978 if (!is_gimple_assign (stmt)) |
1972 return false; | 1979 return false; |
1973 | 1980 |
1974 if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME) | 1981 if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME) |
1975 return false; | |
1976 | |
1977 scalar_dest = gimple_assign_lhs (stmt); | |
1978 vectype_out = get_vectype_for_scalar_type (TREE_TYPE (scalar_dest)); | |
1979 if (!vectype_out) | |
1980 return false; | |
1981 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); | |
1982 if (nunits_out != nunits_in) | |
1983 return false; | 1982 return false; |
1984 | 1983 |
1985 code = gimple_assign_rhs_code (stmt); | 1984 code = gimple_assign_rhs_code (stmt); |
1986 | 1985 |
1987 /* For pointer addition, we should use the normal plus for | 1986 /* For pointer addition, we should use the normal plus for |
1996 if (vect_print_dump_info (REPORT_DETAILS)) | 1995 if (vect_print_dump_info (REPORT_DETAILS)) |
1997 fprintf (vect_dump, "num. args = %d (not unary/binary op).", op_type); | 1996 fprintf (vect_dump, "num. args = %d (not unary/binary op).", op_type); |
1998 return false; | 1997 return false; |
1999 } | 1998 } |
2000 | 1999 |
2000 scalar_dest = gimple_assign_lhs (stmt); | |
2001 vectype_out = STMT_VINFO_VECTYPE (stmt_info); | |
2002 | |
2001 op0 = gimple_assign_rhs1 (stmt); | 2003 op0 = gimple_assign_rhs1 (stmt); |
2002 if (!vect_is_simple_use (op0, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt[0])) | 2004 if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo, |
2005 &def_stmt, &def, &dt[0], &vectype)) | |
2003 { | 2006 { |
2004 if (vect_print_dump_info (REPORT_DETAILS)) | 2007 if (vect_print_dump_info (REPORT_DETAILS)) |
2005 fprintf (vect_dump, "use not simple."); | 2008 fprintf (vect_dump, "use not simple."); |
2006 return false; | 2009 return false; |
2007 } | 2010 } |
2011 /* If op0 is an external or constant def use a vector type with | |
2012 the same size as the output vector type. */ | |
2013 if (!vectype) | |
2014 vectype = get_same_sized_vectype (TREE_TYPE (op0), vectype_out); | |
2015 if (vec_stmt) | |
2016 gcc_assert (vectype); | |
2017 if (!vectype) | |
2018 { | |
2019 if (vect_print_dump_info (REPORT_DETAILS)) | |
2020 { | |
2021 fprintf (vect_dump, "no vectype for scalar type "); | |
2022 print_generic_expr (vect_dump, TREE_TYPE (op0), TDF_SLIM); | |
2023 } | |
2024 | |
2025 return false; | |
2026 } | |
2027 | |
2028 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); | |
2029 nunits_in = TYPE_VECTOR_SUBPARTS (vectype); | |
2030 if (nunits_out != nunits_in) | |
2031 return false; | |
2008 | 2032 |
2009 if (op_type == binary_op) | 2033 if (op_type == binary_op) |
2010 { | 2034 { |
2011 op1 = gimple_assign_rhs2 (stmt); | 2035 op1 = gimple_assign_rhs2 (stmt); |
2012 if (!vect_is_simple_use (op1, loop_vinfo, bb_vinfo, &def_stmt, &def, | 2036 if (!vect_is_simple_use (op1, loop_vinfo, bb_vinfo, &def_stmt, &def, |
2015 if (vect_print_dump_info (REPORT_DETAILS)) | 2039 if (vect_print_dump_info (REPORT_DETAILS)) |
2016 fprintf (vect_dump, "use not simple."); | 2040 fprintf (vect_dump, "use not simple."); |
2017 return false; | 2041 return false; |
2018 } | 2042 } |
2019 } | 2043 } |
2044 | |
2045 if (loop_vinfo) | |
2046 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); | |
2047 else | |
2048 vf = 1; | |
2049 | |
2050 /* Multiple types in SLP are handled by creating the appropriate number of | |
2051 vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in | |
2052 case of SLP. */ | |
2053 if (slp_node) | |
2054 ncopies = 1; | |
2055 else | |
2056 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; | |
2057 | |
2058 gcc_assert (ncopies >= 1); | |
2020 | 2059 |
2021 /* If this is a shift/rotate, determine whether the shift amount is a vector, | 2060 /* If this is a shift/rotate, determine whether the shift amount is a vector, |
2022 or scalar. If the shift/rotate amount is a vector, use the vector/vector | 2061 or scalar. If the shift/rotate amount is a vector, use the vector/vector |
2023 shift optabs. */ | 2062 shift optabs. */ |
2024 if (code == LSHIFT_EXPR || code == RSHIFT_EXPR || code == LROTATE_EXPR | 2063 if (code == LSHIFT_EXPR || code == RSHIFT_EXPR || code == LROTATE_EXPR |
2423 | 2462 |
2424 code = gimple_assign_rhs_code (stmt); | 2463 code = gimple_assign_rhs_code (stmt); |
2425 if (!CONVERT_EXPR_CODE_P (code)) | 2464 if (!CONVERT_EXPR_CODE_P (code)) |
2426 return false; | 2465 return false; |
2427 | 2466 |
2467 scalar_dest = gimple_assign_lhs (stmt); | |
2468 vectype_out = STMT_VINFO_VECTYPE (stmt_info); | |
2469 | |
2470 /* Check the operands of the operation. */ | |
2428 op0 = gimple_assign_rhs1 (stmt); | 2471 op0 = gimple_assign_rhs1 (stmt); |
2429 vectype_in = get_vectype_for_scalar_type (TREE_TYPE (op0)); | 2472 if (! ((INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest)) |
2473 && INTEGRAL_TYPE_P (TREE_TYPE (op0))) | |
2474 || (SCALAR_FLOAT_TYPE_P (TREE_TYPE (scalar_dest)) | |
2475 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (op0)) | |
2476 && CONVERT_EXPR_CODE_P (code)))) | |
2477 return false; | |
2478 if (!vect_is_simple_use_1 (op0, loop_vinfo, NULL, | |
2479 &def_stmt, &def, &dt[0], &vectype_in)) | |
2480 { | |
2481 if (vect_print_dump_info (REPORT_DETAILS)) | |
2482 fprintf (vect_dump, "use not simple."); | |
2483 return false; | |
2484 } | |
2485 /* If op0 is an external def use a vector type with the | |
2486 same size as the output vector type if possible. */ | |
2430 if (!vectype_in) | 2487 if (!vectype_in) |
2431 return false; | 2488 vectype_in = get_same_sized_vectype (TREE_TYPE (op0), vectype_out); |
2489 if (vec_stmt) | |
2490 gcc_assert (vectype_in); | |
2491 if (!vectype_in) | |
2492 { | |
2493 if (vect_print_dump_info (REPORT_DETAILS)) | |
2494 { | |
2495 fprintf (vect_dump, "no vectype for scalar type "); | |
2496 print_generic_expr (vect_dump, TREE_TYPE (op0), TDF_SLIM); | |
2497 } | |
2498 | |
2499 return false; | |
2500 } | |
2501 | |
2432 nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in); | 2502 nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in); |
2433 | |
2434 scalar_dest = gimple_assign_lhs (stmt); | |
2435 vectype_out = get_vectype_for_scalar_type (TREE_TYPE (scalar_dest)); | |
2436 if (!vectype_out) | |
2437 return false; | |
2438 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); | 2503 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); |
2439 if (nunits_in >= nunits_out) | 2504 if (nunits_in >= nunits_out) |
2440 return false; | 2505 return false; |
2441 | 2506 |
2442 /* Multiple types in SLP are handled by creating the appropriate number of | 2507 /* Multiple types in SLP are handled by creating the appropriate number of |
2446 ncopies = 1; | 2511 ncopies = 1; |
2447 else | 2512 else |
2448 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out; | 2513 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out; |
2449 gcc_assert (ncopies >= 1); | 2514 gcc_assert (ncopies >= 1); |
2450 | 2515 |
2451 if (! ((INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest)) | |
2452 && INTEGRAL_TYPE_P (TREE_TYPE (op0))) | |
2453 || (SCALAR_FLOAT_TYPE_P (TREE_TYPE (scalar_dest)) | |
2454 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (op0)) | |
2455 && CONVERT_EXPR_CODE_P (code)))) | |
2456 return false; | |
2457 | |
2458 /* Check the operands of the operation. */ | |
2459 if (!vect_is_simple_use (op0, loop_vinfo, NULL, &def_stmt, &def, &dt[0])) | |
2460 { | |
2461 if (vect_print_dump_info (REPORT_DETAILS)) | |
2462 fprintf (vect_dump, "use not simple."); | |
2463 return false; | |
2464 } | |
2465 | |
2466 /* Supportable by target? */ | 2516 /* Supportable by target? */ |
2467 if (!supportable_narrowing_operation (code, stmt, vectype_in, &code1, | 2517 if (!supportable_narrowing_operation (code, vectype_out, vectype_in, |
2468 &multi_step_cvt, &interm_types)) | 2518 &code1, &multi_step_cvt, &interm_types)) |
2469 return false; | 2519 return false; |
2470 | |
2471 STMT_VINFO_VECTYPE (stmt_info) = vectype_in; | |
2472 | 2520 |
2473 if (!vec_stmt) /* transformation not required. */ | 2521 if (!vec_stmt) /* transformation not required. */ |
2474 { | 2522 { |
2475 STMT_VINFO_TYPE (stmt_info) = type_demotion_vec_info_type; | 2523 STMT_VINFO_TYPE (stmt_info) = type_demotion_vec_info_type; |
2476 if (vect_print_dump_info (REPORT_DETAILS)) | 2524 if (vect_print_dump_info (REPORT_DETAILS)) |
2516 prev_stmt_info = NULL; | 2564 prev_stmt_info = NULL; |
2517 for (j = 0; j < ncopies; j++) | 2565 for (j = 0; j < ncopies; j++) |
2518 { | 2566 { |
2519 /* Handle uses. */ | 2567 /* Handle uses. */ |
2520 if (slp_node) | 2568 if (slp_node) |
2521 vect_get_slp_defs (slp_node, &vec_oprnds0, NULL); | 2569 vect_get_slp_defs (slp_node, &vec_oprnds0, NULL, -1); |
2522 else | 2570 else |
2523 { | 2571 { |
2524 VEC_free (tree, heap, vec_oprnds0); | 2572 VEC_free (tree, heap, vec_oprnds0); |
2525 vec_oprnds0 = VEC_alloc (tree, heap, | 2573 vec_oprnds0 = VEC_alloc (tree, heap, |
2526 (multi_step_cvt ? vect_pow2 (multi_step_cvt) * 2 : 2)); | 2574 (multi_step_cvt ? vect_pow2 (multi_step_cvt) * 2 : 2)); |
2693 code = gimple_assign_rhs_code (stmt); | 2741 code = gimple_assign_rhs_code (stmt); |
2694 if (!CONVERT_EXPR_CODE_P (code) | 2742 if (!CONVERT_EXPR_CODE_P (code) |
2695 && code != WIDEN_MULT_EXPR) | 2743 && code != WIDEN_MULT_EXPR) |
2696 return false; | 2744 return false; |
2697 | 2745 |
2746 scalar_dest = gimple_assign_lhs (stmt); | |
2747 vectype_out = STMT_VINFO_VECTYPE (stmt_info); | |
2748 | |
2749 /* Check the operands of the operation. */ | |
2698 op0 = gimple_assign_rhs1 (stmt); | 2750 op0 = gimple_assign_rhs1 (stmt); |
2699 vectype_in = get_vectype_for_scalar_type (TREE_TYPE (op0)); | 2751 if (! ((INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest)) |
2752 && INTEGRAL_TYPE_P (TREE_TYPE (op0))) | |
2753 || (SCALAR_FLOAT_TYPE_P (TREE_TYPE (scalar_dest)) | |
2754 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (op0)) | |
2755 && CONVERT_EXPR_CODE_P (code)))) | |
2756 return false; | |
2757 if (!vect_is_simple_use_1 (op0, loop_vinfo, NULL, | |
2758 &def_stmt, &def, &dt[0], &vectype_in)) | |
2759 { | |
2760 if (vect_print_dump_info (REPORT_DETAILS)) | |
2761 fprintf (vect_dump, "use not simple."); | |
2762 return false; | |
2763 } | |
2764 /* If op0 is an external or constant def use a vector type with | |
2765 the same size as the output vector type. */ | |
2700 if (!vectype_in) | 2766 if (!vectype_in) |
2701 return false; | 2767 vectype_in = get_same_sized_vectype (TREE_TYPE (op0), vectype_out); |
2768 if (vec_stmt) | |
2769 gcc_assert (vectype_in); | |
2770 if (!vectype_in) | |
2771 { | |
2772 if (vect_print_dump_info (REPORT_DETAILS)) | |
2773 { | |
2774 fprintf (vect_dump, "no vectype for scalar type "); | |
2775 print_generic_expr (vect_dump, TREE_TYPE (op0), TDF_SLIM); | |
2776 } | |
2777 | |
2778 return false; | |
2779 } | |
2780 | |
2702 nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in); | 2781 nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in); |
2703 | |
2704 scalar_dest = gimple_assign_lhs (stmt); | |
2705 vectype_out = get_vectype_for_scalar_type (TREE_TYPE (scalar_dest)); | |
2706 if (!vectype_out) | |
2707 return false; | |
2708 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); | 2782 nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); |
2709 if (nunits_in <= nunits_out) | 2783 if (nunits_in <= nunits_out) |
2710 return false; | 2784 return false; |
2711 | 2785 |
2712 /* Multiple types in SLP are handled by creating the appropriate number of | 2786 /* Multiple types in SLP are handled by creating the appropriate number of |
2717 else | 2791 else |
2718 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; | 2792 ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in; |
2719 | 2793 |
2720 gcc_assert (ncopies >= 1); | 2794 gcc_assert (ncopies >= 1); |
2721 | 2795 |
2722 if (! ((INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest)) | |
2723 && INTEGRAL_TYPE_P (TREE_TYPE (op0))) | |
2724 || (SCALAR_FLOAT_TYPE_P (TREE_TYPE (scalar_dest)) | |
2725 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (op0)) | |
2726 && CONVERT_EXPR_CODE_P (code)))) | |
2727 return false; | |
2728 | |
2729 /* Check the operands of the operation. */ | |
2730 if (!vect_is_simple_use (op0, loop_vinfo, NULL, &def_stmt, &def, &dt[0])) | |
2731 { | |
2732 if (vect_print_dump_info (REPORT_DETAILS)) | |
2733 fprintf (vect_dump, "use not simple."); | |
2734 return false; | |
2735 } | |
2736 | |
2737 op_type = TREE_CODE_LENGTH (code); | 2796 op_type = TREE_CODE_LENGTH (code); |
2738 if (op_type == binary_op) | 2797 if (op_type == binary_op) |
2739 { | 2798 { |
2740 op1 = gimple_assign_rhs2 (stmt); | 2799 op1 = gimple_assign_rhs2 (stmt); |
2741 if (!vect_is_simple_use (op1, loop_vinfo, NULL, &def_stmt, &def, &dt[1])) | 2800 if (!vect_is_simple_use (op1, loop_vinfo, NULL, &def_stmt, &def, &dt[1])) |
2745 return false; | 2804 return false; |
2746 } | 2805 } |
2747 } | 2806 } |
2748 | 2807 |
2749 /* Supportable by target? */ | 2808 /* Supportable by target? */ |
2750 if (!supportable_widening_operation (code, stmt, vectype_in, | 2809 if (!supportable_widening_operation (code, stmt, vectype_out, vectype_in, |
2751 &decl1, &decl2, &code1, &code2, | 2810 &decl1, &decl2, &code1, &code2, |
2752 &multi_step_cvt, &interm_types)) | 2811 &multi_step_cvt, &interm_types)) |
2753 return false; | 2812 return false; |
2754 | 2813 |
2755 /* Binary widening operation can only be supported directly by the | 2814 /* Binary widening operation can only be supported directly by the |
2756 architecture. */ | 2815 architecture. */ |
2757 gcc_assert (!(multi_step_cvt && op_type == binary_op)); | 2816 gcc_assert (!(multi_step_cvt && op_type == binary_op)); |
2758 | |
2759 STMT_VINFO_VECTYPE (stmt_info) = vectype_in; | |
2760 | 2817 |
2761 if (!vec_stmt) /* transformation not required. */ | 2818 if (!vec_stmt) /* transformation not required. */ |
2762 { | 2819 { |
2763 STMT_VINFO_TYPE (stmt_info) = type_promotion_vec_info_type; | 2820 STMT_VINFO_TYPE (stmt_info) = type_promotion_vec_info_type; |
2764 if (vect_print_dump_info (REPORT_DETAILS)) | 2821 if (vect_print_dump_info (REPORT_DETAILS)) |
2817 { | 2874 { |
2818 /* Handle uses. */ | 2875 /* Handle uses. */ |
2819 if (j == 0) | 2876 if (j == 0) |
2820 { | 2877 { |
2821 if (slp_node) | 2878 if (slp_node) |
2822 vect_get_slp_defs (slp_node, &vec_oprnds0, &vec_oprnds1); | 2879 vect_get_slp_defs (slp_node, &vec_oprnds0, &vec_oprnds1, -1); |
2823 else | 2880 else |
2824 { | 2881 { |
2825 vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL); | 2882 vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL); |
2826 VEC_quick_push (tree, vec_oprnds0, vec_oprnd0); | 2883 VEC_quick_push (tree, vec_oprnds0, vec_oprnd0); |
2827 if (op_type == binary_op) | 2884 if (op_type == binary_op) |
3029 *vec_stmt = NULL; | 3086 *vec_stmt = NULL; |
3030 return true; | 3087 return true; |
3031 } | 3088 } |
3032 | 3089 |
3033 if (slp) | 3090 if (slp) |
3034 strided_store = false; | 3091 { |
3035 | 3092 strided_store = false; |
3036 /* VEC_NUM is the number of vect stmts to be created for this group. */ | 3093 /* VEC_NUM is the number of vect stmts to be created for this |
3037 if (slp) | 3094 group. */ |
3038 vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); | 3095 vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); |
3096 first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0); | |
3097 first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt)); | |
3098 } | |
3039 else | 3099 else |
3100 /* VEC_NUM is the number of vect stmts to be created for this | |
3101 group. */ | |
3040 vec_num = group_size; | 3102 vec_num = group_size; |
3041 } | 3103 } |
3042 else | 3104 else |
3043 { | 3105 { |
3044 first_stmt = stmt; | 3106 first_stmt = stmt; |
3103 if (j == 0) | 3165 if (j == 0) |
3104 { | 3166 { |
3105 if (slp) | 3167 if (slp) |
3106 { | 3168 { |
3107 /* Get vectorized arguments for SLP_NODE. */ | 3169 /* Get vectorized arguments for SLP_NODE. */ |
3108 vect_get_slp_defs (slp_node, &vec_oprnds, NULL); | 3170 vect_get_slp_defs (slp_node, &vec_oprnds, NULL, -1); |
3109 | 3171 |
3110 vec_oprnd = VEC_index (tree, vec_oprnds, 0); | 3172 vec_oprnd = VEC_index (tree, vec_oprnds, 0); |
3111 } | 3173 } |
3112 else | 3174 else |
3113 { | 3175 { |
3863 if (!vect_is_simple_cond (cond_expr, loop_vinfo)) | 3925 if (!vect_is_simple_cond (cond_expr, loop_vinfo)) |
3864 return false; | 3926 return false; |
3865 | 3927 |
3866 /* We do not handle two different vector types for the condition | 3928 /* We do not handle two different vector types for the condition |
3867 and the values. */ | 3929 and the values. */ |
3868 if (TREE_TYPE (TREE_OPERAND (cond_expr, 0)) != TREE_TYPE (vectype)) | 3930 if (!types_compatible_p (TREE_TYPE (TREE_OPERAND (cond_expr, 0)), |
3931 TREE_TYPE (vectype))) | |
3869 return false; | 3932 return false; |
3870 | 3933 |
3871 if (TREE_CODE (then_clause) == SSA_NAME) | 3934 if (TREE_CODE (then_clause) == SSA_NAME) |
3872 { | 3935 { |
3873 gimple then_def_stmt = SSA_NAME_DEF_STMT (then_clause); | 3936 gimple then_def_stmt = SSA_NAME_DEF_STMT (then_clause); |
3943 { | 4006 { |
3944 stmt_vec_info stmt_info = vinfo_for_stmt (stmt); | 4007 stmt_vec_info stmt_info = vinfo_for_stmt (stmt); |
3945 bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info); | 4008 bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info); |
3946 enum vect_relevant relevance = STMT_VINFO_RELEVANT (stmt_info); | 4009 enum vect_relevant relevance = STMT_VINFO_RELEVANT (stmt_info); |
3947 bool ok; | 4010 bool ok; |
3948 HOST_WIDE_INT dummy; | |
3949 tree scalar_type, vectype; | 4011 tree scalar_type, vectype; |
3950 | 4012 |
3951 if (vect_print_dump_info (REPORT_DETAILS)) | 4013 if (vect_print_dump_info (REPORT_DETAILS)) |
3952 { | 4014 { |
3953 fprintf (vect_dump, "==> examining statement: "); | 4015 fprintf (vect_dump, "==> examining statement: "); |
4001 | 4063 |
4002 if (bb_vinfo) | 4064 if (bb_vinfo) |
4003 { | 4065 { |
4004 gcc_assert (PURE_SLP_STMT (stmt_info)); | 4066 gcc_assert (PURE_SLP_STMT (stmt_info)); |
4005 | 4067 |
4006 scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, &dummy); | 4068 scalar_type = TREE_TYPE (gimple_get_lhs (stmt)); |
4007 if (vect_print_dump_info (REPORT_DETAILS)) | 4069 if (vect_print_dump_info (REPORT_DETAILS)) |
4008 { | 4070 { |
4009 fprintf (vect_dump, "get vectype for scalar type: "); | 4071 fprintf (vect_dump, "get vectype for scalar type: "); |
4010 print_generic_expr (vect_dump, scalar_type, TDF_SLIM); | 4072 print_generic_expr (vect_dump, scalar_type, TDF_SLIM); |
4011 } | 4073 } |
4047 || vectorizable_operation (stmt, NULL, NULL, NULL) | 4109 || vectorizable_operation (stmt, NULL, NULL, NULL) |
4048 || vectorizable_assignment (stmt, NULL, NULL, NULL) | 4110 || vectorizable_assignment (stmt, NULL, NULL, NULL) |
4049 || vectorizable_load (stmt, NULL, NULL, NULL, NULL) | 4111 || vectorizable_load (stmt, NULL, NULL, NULL, NULL) |
4050 || vectorizable_call (stmt, NULL, NULL) | 4112 || vectorizable_call (stmt, NULL, NULL) |
4051 || vectorizable_store (stmt, NULL, NULL, NULL) | 4113 || vectorizable_store (stmt, NULL, NULL, NULL) |
4052 || vectorizable_reduction (stmt, NULL, NULL) | 4114 || vectorizable_reduction (stmt, NULL, NULL, NULL) |
4053 || vectorizable_condition (stmt, NULL, NULL, NULL, 0)); | 4115 || vectorizable_condition (stmt, NULL, NULL, NULL, 0)); |
4054 else | 4116 else |
4055 { | 4117 { |
4056 if (bb_vinfo) | 4118 if (bb_vinfo) |
4057 ok = (vectorizable_operation (stmt, NULL, NULL, node) | 4119 ok = (vectorizable_operation (stmt, NULL, NULL, node) |
4199 gcc_assert (!slp_node); | 4261 gcc_assert (!slp_node); |
4200 done = vectorizable_call (stmt, gsi, &vec_stmt); | 4262 done = vectorizable_call (stmt, gsi, &vec_stmt); |
4201 break; | 4263 break; |
4202 | 4264 |
4203 case reduc_vec_info_type: | 4265 case reduc_vec_info_type: |
4204 gcc_assert (!slp_node); | 4266 done = vectorizable_reduction (stmt, gsi, &vec_stmt, slp_node); |
4205 done = vectorizable_reduction (stmt, gsi, &vec_stmt); | |
4206 gcc_assert (done); | 4267 gcc_assert (done); |
4207 break; | 4268 break; |
4208 | 4269 |
4209 default: | 4270 default: |
4210 if (!STMT_VINFO_LIVE_P (stmt_info)) | 4271 if (!STMT_VINFO_LIVE_P (stmt_info)) |
4326 STMT_VINFO_BB_VINFO (res) = bb_vinfo; | 4387 STMT_VINFO_BB_VINFO (res) = bb_vinfo; |
4327 STMT_VINFO_RELEVANT (res) = vect_unused_in_scope; | 4388 STMT_VINFO_RELEVANT (res) = vect_unused_in_scope; |
4328 STMT_VINFO_LIVE_P (res) = false; | 4389 STMT_VINFO_LIVE_P (res) = false; |
4329 STMT_VINFO_VECTYPE (res) = NULL; | 4390 STMT_VINFO_VECTYPE (res) = NULL; |
4330 STMT_VINFO_VEC_STMT (res) = NULL; | 4391 STMT_VINFO_VEC_STMT (res) = NULL; |
4392 STMT_VINFO_VECTORIZABLE (res) = true; | |
4331 STMT_VINFO_IN_PATTERN_P (res) = false; | 4393 STMT_VINFO_IN_PATTERN_P (res) = false; |
4332 STMT_VINFO_RELATED_STMT (res) = NULL; | 4394 STMT_VINFO_RELATED_STMT (res) = NULL; |
4333 STMT_VINFO_DATA_REF (res) = NULL; | 4395 STMT_VINFO_DATA_REF (res) = NULL; |
4334 | 4396 |
4335 STMT_VINFO_DR_BASE_ADDRESS (res) = NULL; | 4397 STMT_VINFO_DR_BASE_ADDRESS (res) = NULL; |
4403 | 4465 |
4404 tree | 4466 tree |
4405 get_vectype_for_scalar_type (tree scalar_type) | 4467 get_vectype_for_scalar_type (tree scalar_type) |
4406 { | 4468 { |
4407 enum machine_mode inner_mode = TYPE_MODE (scalar_type); | 4469 enum machine_mode inner_mode = TYPE_MODE (scalar_type); |
4408 int nbytes = GET_MODE_SIZE (inner_mode); | 4470 unsigned int nbytes = GET_MODE_SIZE (inner_mode); |
4409 int nunits; | 4471 int nunits; |
4410 tree vectype; | 4472 tree vectype; |
4411 | 4473 |
4412 if (nbytes == 0 || nbytes >= UNITS_PER_SIMD_WORD (inner_mode)) | 4474 if (nbytes == 0 || nbytes >= UNITS_PER_SIMD_WORD (inner_mode)) |
4475 return NULL_TREE; | |
4476 | |
4477 /* We can't build a vector type of elements with alignment bigger than | |
4478 their size. */ | |
4479 if (nbytes < TYPE_ALIGN_UNIT (scalar_type)) | |
4480 return NULL_TREE; | |
4481 | |
4482 /* If we'd build a vector type of elements whose mode precision doesn't | |
4483 match their types precision we'll get mismatched types on vector | |
4484 extracts via BIT_FIELD_REFs. This effectively means we disable | |
4485 vectorization of bool and/or enum types in some languages. */ | |
4486 if (INTEGRAL_TYPE_P (scalar_type) | |
4487 && GET_MODE_BITSIZE (inner_mode) != TYPE_PRECISION (scalar_type)) | |
4413 return NULL_TREE; | 4488 return NULL_TREE; |
4414 | 4489 |
4415 /* FORNOW: Only a single vector size per mode (UNITS_PER_SIMD_WORD) | 4490 /* FORNOW: Only a single vector size per mode (UNITS_PER_SIMD_WORD) |
4416 is expected. */ | 4491 is expected. */ |
4417 nunits = UNITS_PER_SIMD_WORD (inner_mode) / nbytes; | 4492 nunits = UNITS_PER_SIMD_WORD (inner_mode) / nbytes; |
4439 fprintf (vect_dump, "mode not supported by target."); | 4514 fprintf (vect_dump, "mode not supported by target."); |
4440 return NULL_TREE; | 4515 return NULL_TREE; |
4441 } | 4516 } |
4442 | 4517 |
4443 return vectype; | 4518 return vectype; |
4519 } | |
4520 | |
4521 /* Function get_same_sized_vectype | |
4522 | |
4523 Returns a vector type corresponding to SCALAR_TYPE of size | |
4524 VECTOR_TYPE if supported by the target. */ | |
4525 | |
4526 tree | |
4527 get_same_sized_vectype (tree scalar_type, tree vector_type ATTRIBUTE_UNUSED) | |
4528 { | |
4529 return get_vectype_for_scalar_type (scalar_type); | |
4444 } | 4530 } |
4445 | 4531 |
4446 /* Function vect_is_simple_use. | 4532 /* Function vect_is_simple_use. |
4447 | 4533 |
4448 Input: | 4534 Input: |
4574 } | 4660 } |
4575 | 4661 |
4576 return true; | 4662 return true; |
4577 } | 4663 } |
4578 | 4664 |
4665 /* Function vect_is_simple_use_1. | |
4666 | |
4667 Same as vect_is_simple_use_1 but also determines the vector operand | |
4668 type of OPERAND and stores it to *VECTYPE. If the definition of | |
4669 OPERAND is vect_uninitialized_def, vect_constant_def or | |
4670 vect_external_def *VECTYPE will be set to NULL_TREE and the caller | |
4671 is responsible to compute the best suited vector type for the | |
4672 scalar operand. */ | |
4673 | |
4674 bool | |
4675 vect_is_simple_use_1 (tree operand, loop_vec_info loop_vinfo, | |
4676 bb_vec_info bb_vinfo, gimple *def_stmt, | |
4677 tree *def, enum vect_def_type *dt, tree *vectype) | |
4678 { | |
4679 if (!vect_is_simple_use (operand, loop_vinfo, bb_vinfo, def_stmt, def, dt)) | |
4680 return false; | |
4681 | |
4682 /* Now get a vector type if the def is internal, otherwise supply | |
4683 NULL_TREE and leave it up to the caller to figure out a proper | |
4684 type for the use stmt. */ | |
4685 if (*dt == vect_internal_def | |
4686 || *dt == vect_induction_def | |
4687 || *dt == vect_reduction_def | |
4688 || *dt == vect_double_reduction_def | |
4689 || *dt == vect_nested_cycle) | |
4690 { | |
4691 stmt_vec_info stmt_info = vinfo_for_stmt (*def_stmt); | |
4692 if (STMT_VINFO_IN_PATTERN_P (stmt_info)) | |
4693 stmt_info = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info)); | |
4694 *vectype = STMT_VINFO_VECTYPE (stmt_info); | |
4695 gcc_assert (*vectype != NULL_TREE); | |
4696 } | |
4697 else if (*dt == vect_uninitialized_def | |
4698 || *dt == vect_constant_def | |
4699 || *dt == vect_external_def) | |
4700 *vectype = NULL_TREE; | |
4701 else | |
4702 gcc_unreachable (); | |
4703 | |
4704 return true; | |
4705 } | |
4706 | |
4579 | 4707 |
4580 /* Function supportable_widening_operation | 4708 /* Function supportable_widening_operation |
4581 | 4709 |
4582 Check whether an operation represented by the code CODE is a | 4710 Check whether an operation represented by the code CODE is a |
4583 widening operation that is supported by the target platform in | 4711 widening operation that is supported by the target platform in |
4584 vector form (i.e., when operating on arguments of type VECTYPE). | 4712 vector form (i.e., when operating on arguments of type VECTYPE_IN |
4713 producing a result of type VECTYPE_OUT). | |
4585 | 4714 |
4586 Widening operations we currently support are NOP (CONVERT), FLOAT | 4715 Widening operations we currently support are NOP (CONVERT), FLOAT |
4587 and WIDEN_MULT. This function checks if these operations are supported | 4716 and WIDEN_MULT. This function checks if these operations are supported |
4588 by the target platform either directly (via vector tree-codes), or via | 4717 by the target platform either directly (via vector tree-codes), or via |
4589 target builtins. | 4718 target builtins. |
4599 MULTI_STEP_CVT will be 1). | 4728 MULTI_STEP_CVT will be 1). |
4600 - INTERM_TYPES contains the intermediate type required to perform the | 4729 - INTERM_TYPES contains the intermediate type required to perform the |
4601 widening operation (short in the above example). */ | 4730 widening operation (short in the above example). */ |
4602 | 4731 |
4603 bool | 4732 bool |
4604 supportable_widening_operation (enum tree_code code, gimple stmt, tree vectype, | 4733 supportable_widening_operation (enum tree_code code, gimple stmt, |
4734 tree vectype_out, tree vectype_in, | |
4605 tree *decl1, tree *decl2, | 4735 tree *decl1, tree *decl2, |
4606 enum tree_code *code1, enum tree_code *code2, | 4736 enum tree_code *code1, enum tree_code *code2, |
4607 int *multi_step_cvt, | 4737 int *multi_step_cvt, |
4608 VEC (tree, heap) **interm_types) | 4738 VEC (tree, heap) **interm_types) |
4609 { | 4739 { |
4612 struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info); | 4742 struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info); |
4613 bool ordered_p; | 4743 bool ordered_p; |
4614 enum machine_mode vec_mode; | 4744 enum machine_mode vec_mode; |
4615 enum insn_code icode1, icode2; | 4745 enum insn_code icode1, icode2; |
4616 optab optab1, optab2; | 4746 optab optab1, optab2; |
4617 tree type = gimple_expr_type (stmt); | 4747 tree vectype = vectype_in; |
4618 tree wide_vectype = get_vectype_for_scalar_type (type); | 4748 tree wide_vectype = vectype_out; |
4619 enum tree_code c1, c2; | 4749 enum tree_code c1, c2; |
4620 | 4750 |
4621 /* The result of a vectorized widening operation usually requires two vectors | 4751 /* The result of a vectorized widening operation usually requires two vectors |
4622 (because the widened results do not fit int one vector). The generated | 4752 (because the widened results do not fit int one vector). The generated |
4623 vector results would normally be expected to be generated in the same | 4753 vector results would normally be expected to be generated in the same |
4712 } | 4842 } |
4713 | 4843 |
4714 if (code == FIX_TRUNC_EXPR) | 4844 if (code == FIX_TRUNC_EXPR) |
4715 { | 4845 { |
4716 /* The signedness is determined from output operand. */ | 4846 /* The signedness is determined from output operand. */ |
4717 optab1 = optab_for_tree_code (c1, type, optab_default); | 4847 optab1 = optab_for_tree_code (c1, vectype_out, optab_default); |
4718 optab2 = optab_for_tree_code (c2, type, optab_default); | 4848 optab2 = optab_for_tree_code (c2, vectype_out, optab_default); |
4719 } | 4849 } |
4720 else | 4850 else |
4721 { | 4851 { |
4722 optab1 = optab_for_tree_code (c1, vectype, optab_default); | 4852 optab1 = optab_for_tree_code (c1, vectype, optab_default); |
4723 optab2 = optab_for_tree_code (c2, vectype, optab_default); | 4853 optab2 = optab_for_tree_code (c2, vectype, optab_default); |
4795 | 4925 |
4796 /* Function supportable_narrowing_operation | 4926 /* Function supportable_narrowing_operation |
4797 | 4927 |
4798 Check whether an operation represented by the code CODE is a | 4928 Check whether an operation represented by the code CODE is a |
4799 narrowing operation that is supported by the target platform in | 4929 narrowing operation that is supported by the target platform in |
4800 vector form (i.e., when operating on arguments of type VECTYPE). | 4930 vector form (i.e., when operating on arguments of type VECTYPE_IN |
4931 and producing a result of type VECTYPE_OUT). | |
4801 | 4932 |
4802 Narrowing operations we currently support are NOP (CONVERT) and | 4933 Narrowing operations we currently support are NOP (CONVERT) and |
4803 FIX_TRUNC. This function checks if these operations are supported by | 4934 FIX_TRUNC. This function checks if these operations are supported by |
4804 the target platform directly via vector tree-codes. | 4935 the target platform directly via vector tree-codes. |
4805 | 4936 |
4812 - INTERM_TYPES contains the intermediate type required to perform the | 4943 - INTERM_TYPES contains the intermediate type required to perform the |
4813 narrowing operation (short in the above example). */ | 4944 narrowing operation (short in the above example). */ |
4814 | 4945 |
4815 bool | 4946 bool |
4816 supportable_narrowing_operation (enum tree_code code, | 4947 supportable_narrowing_operation (enum tree_code code, |
4817 const_gimple stmt, tree vectype, | 4948 tree vectype_out, tree vectype_in, |
4818 enum tree_code *code1, int *multi_step_cvt, | 4949 enum tree_code *code1, int *multi_step_cvt, |
4819 VEC (tree, heap) **interm_types) | 4950 VEC (tree, heap) **interm_types) |
4820 { | 4951 { |
4821 enum machine_mode vec_mode; | 4952 enum machine_mode vec_mode; |
4822 enum insn_code icode1; | 4953 enum insn_code icode1; |
4823 optab optab1, interm_optab; | 4954 optab optab1, interm_optab; |
4824 tree type = gimple_expr_type (stmt); | 4955 tree vectype = vectype_in; |
4825 tree narrow_vectype = get_vectype_for_scalar_type (type); | 4956 tree narrow_vectype = vectype_out; |
4826 enum tree_code c1; | 4957 enum tree_code c1; |
4827 tree intermediate_type, prev_type; | 4958 tree intermediate_type, prev_type; |
4828 int i; | 4959 int i; |
4829 | 4960 |
4830 switch (code) | 4961 switch (code) |
4846 gcc_unreachable (); | 4977 gcc_unreachable (); |
4847 } | 4978 } |
4848 | 4979 |
4849 if (code == FIX_TRUNC_EXPR) | 4980 if (code == FIX_TRUNC_EXPR) |
4850 /* The signedness is determined from output operand. */ | 4981 /* The signedness is determined from output operand. */ |
4851 optab1 = optab_for_tree_code (c1, type, optab_default); | 4982 optab1 = optab_for_tree_code (c1, vectype_out, optab_default); |
4852 else | 4983 else |
4853 optab1 = optab_for_tree_code (c1, vectype, optab_default); | 4984 optab1 = optab_for_tree_code (c1, vectype, optab_default); |
4854 | 4985 |
4855 if (!optab1) | 4986 if (!optab1) |
4856 return false; | 4987 return false; |