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;