comparison gcc/tree-vect-generic.c @ 67:f6334be47118

update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Mar 2011 17:18:12 +0900
parents b7f97abdc517
children 04ced10e8804
comparison
equal deleted inserted replaced
65:65488c3d617d 67:f6334be47118
1 /* Lower vector operations to scalar operations. 1 /* Lower vector operations to scalar operations.
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it 7 GCC is free software; you can redistribute it and/or modify it
21 #include "config.h" 21 #include "config.h"
22 #include "system.h" 22 #include "system.h"
23 #include "coretypes.h" 23 #include "coretypes.h"
24 #include "tree.h" 24 #include "tree.h"
25 #include "tm.h" 25 #include "tm.h"
26 #include "expr.h"
27 #include "insn-codes.h"
28 #include "diagnostic.h"
29 #include "optabs.h"
30 #include "machmode.h"
31 #include "langhooks.h" 26 #include "langhooks.h"
32 #include "tree-flow.h" 27 #include "tree-flow.h"
33 #include "gimple.h" 28 #include "gimple.h"
34 #include "tree-iterator.h" 29 #include "tree-iterator.h"
35 #include "tree-pass.h" 30 #include "tree-pass.h"
36 #include "flags.h" 31 #include "flags.h"
37 #include "ggc.h" 32 #include "ggc.h"
38 33
34 /* Need to include rtl.h, expr.h, etc. for optabs. */
35 #include "expr.h"
36 #include "optabs.h"
39 37
40 /* Build a constant of type TYPE, made of VALUE's bits replicated 38 /* Build a constant of type TYPE, made of VALUE's bits replicated
41 every TYPE_SIZE (INNER_TYPE) bits to fit TYPE's precision. */ 39 every TYPE_SIZE (INNER_TYPE) bits to fit TYPE's precision. */
42 static tree 40 static tree
43 build_replicated_const (tree type, tree inner_type, HOST_WIDE_INT value) 41 build_replicated_const (tree type, tree inner_type, HOST_WIDE_INT value)
282 type, a, b, code); 280 type, a, b, code);
283 else 281 else
284 return expand_vector_piecewise (gsi, f, 282 return expand_vector_piecewise (gsi, f,
285 type, TREE_TYPE (type), 283 type, TREE_TYPE (type),
286 a, b, code); 284 a, b, code);
285 }
286
287 /* Check if vector VEC consists of all the equal elements and
288 that the number of elements corresponds to the type of VEC.
289 The function returns first element of the vector
290 or NULL_TREE if the vector is not uniform. */
291 static tree
292 uniform_vector_p (tree vec)
293 {
294 tree first, t, els;
295 unsigned i;
296
297 if (vec == NULL_TREE)
298 return NULL_TREE;
299
300 if (TREE_CODE (vec) == VECTOR_CST)
301 {
302 els = TREE_VECTOR_CST_ELTS (vec);
303 first = TREE_VALUE (els);
304 els = TREE_CHAIN (els);
305
306 for (t = els; t; t = TREE_CHAIN (t))
307 if (!operand_equal_p (first, TREE_VALUE (t), 0))
308 return NULL_TREE;
309
310 return first;
311 }
312
313 else if (TREE_CODE (vec) == CONSTRUCTOR)
314 {
315 first = error_mark_node;
316
317 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (vec), i, t)
318 {
319 if (i == 0)
320 {
321 first = t;
322 continue;
323 }
324 if (!operand_equal_p (first, t, 0))
325 return NULL_TREE;
326 }
327 if (i != TYPE_VECTOR_SUBPARTS (TREE_TYPE (vec)))
328 return NULL_TREE;
329
330 return first;
331 }
332
333 return NULL_TREE;
287 } 334 }
288 335
289 static tree 336 static tree
290 expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type, 337 expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type,
291 gimple assign, enum tree_code code) 338 gimple assign, enum tree_code code)
368 mode = MIN_MODE_VECTOR_INT; 415 mode = MIN_MODE_VECTOR_INT;
369 416
370 for (; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) 417 for (; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
371 if (GET_MODE_INNER (mode) == inner_mode 418 if (GET_MODE_INNER (mode) == inner_mode
372 && GET_MODE_NUNITS (mode) > best_nunits 419 && GET_MODE_NUNITS (mode) > best_nunits
373 && optab_handler (op, mode)->insn_code != CODE_FOR_nothing) 420 && optab_handler (op, mode) != CODE_FOR_nothing)
374 best_mode = mode, best_nunits = GET_MODE_NUNITS (mode); 421 best_mode = mode, best_nunits = GET_MODE_NUNITS (mode);
375 422
376 if (best_mode == VOIDmode) 423 if (best_mode == VOIDmode)
377 return NULL_TREE; 424 return NULL_TREE;
378 else 425 else
392 { 439 {
393 gimple stmt = gsi_stmt (*gsi); 440 gimple stmt = gsi_stmt (*gsi);
394 tree lhs, rhs1, rhs2 = NULL, type, compute_type; 441 tree lhs, rhs1, rhs2 = NULL, type, compute_type;
395 enum tree_code code; 442 enum tree_code code;
396 enum machine_mode compute_mode; 443 enum machine_mode compute_mode;
397 optab op; 444 optab op = NULL;
398 enum gimple_rhs_class rhs_class; 445 enum gimple_rhs_class rhs_class;
399 tree new_rhs; 446 tree new_rhs;
400 447
401 if (gimple_code (stmt) != GIMPLE_ASSIGN) 448 if (gimple_code (stmt) != GIMPLE_ASSIGN)
402 return; 449 return;
434 if (code == LSHIFT_EXPR 481 if (code == LSHIFT_EXPR
435 || code == RSHIFT_EXPR 482 || code == RSHIFT_EXPR
436 || code == LROTATE_EXPR 483 || code == LROTATE_EXPR
437 || code == RROTATE_EXPR) 484 || code == RROTATE_EXPR)
438 { 485 {
439 /* If the 2nd argument is vector, we need a vector/vector shift */ 486 bool vector_scalar_shift;
487 op = optab_for_tree_code (code, type, optab_scalar);
488
489 /* Vector/Scalar shift is supported. */
490 vector_scalar_shift = (op && (optab_handler (op, TYPE_MODE (type))
491 != CODE_FOR_nothing));
492
493 /* If the 2nd argument is vector, we need a vector/vector shift.
494 Except all the elements in the second vector are the same. */
440 if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs2)))) 495 if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs2))))
441 op = optab_for_tree_code (code, type, optab_vector); 496 {
442 else 497 tree first;
498 gimple def_stmt;
499
500 /* Check whether we have vector <op> {x,x,x,x} where x
501 could be a scalar variable or a constant. Transform
502 vector <op> {x,x,x,x} ==> vector <op> scalar. */
503 if (vector_scalar_shift
504 && ((TREE_CODE (rhs2) == VECTOR_CST
505 && (first = uniform_vector_p (rhs2)) != NULL_TREE)
506 || (TREE_CODE (rhs2) == SSA_NAME
507 && (def_stmt = SSA_NAME_DEF_STMT (rhs2))
508 && gimple_assign_single_p (def_stmt)
509 && (first = uniform_vector_p
510 (gimple_assign_rhs1 (def_stmt))) != NULL_TREE)))
511 {
512 gimple_assign_set_rhs2 (stmt, first);
513 update_stmt (stmt);
514 rhs2 = first;
515 }
516 else
517 op = optab_for_tree_code (code, type, optab_vector);
518 }
519
520 /* Try for a vector/scalar shift, and if we don't have one, see if we
521 have a vector/vector shift */
522 else if (!vector_scalar_shift)
443 { 523 {
444 /* Try for a vector/scalar shift, and if we don't have one, see if we 524 op = optab_for_tree_code (code, type, optab_vector);
445 have a vector/vector shift */ 525
446 op = optab_for_tree_code (code, type, optab_scalar); 526 if (op && (optab_handler (op, TYPE_MODE (type))
447 if (!op 527 != CODE_FOR_nothing))
448 || (op->handlers[(int) TYPE_MODE (type)].insn_code 528 {
449 == CODE_FOR_nothing)) 529 /* Transform vector <op> scalar => vector <op> {x,x,x,x}. */
450 op = optab_for_tree_code (code, type, optab_vector); 530 int n_parts = TYPE_VECTOR_SUBPARTS (type);
531 int part_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (type)), 1);
532 tree part_type = lang_hooks.types.type_for_size (part_size, 1);
533 tree vect_type = build_vector_type (part_type, n_parts);
534
535 rhs2 = fold_convert (part_type, rhs2);
536 rhs2 = build_vector_from_val (vect_type, rhs2);
537 gimple_assign_set_rhs2 (stmt, rhs2);
538 update_stmt (stmt);
539 }
451 } 540 }
452 } 541 }
453 else 542 else
454 op = optab_for_tree_code (code, type, optab_default); 543 op = optab_for_tree_code (code, type, optab_default);
455 544
498 || GET_MODE_CLASS (compute_mode) == MODE_VECTOR_FRACT 587 || GET_MODE_CLASS (compute_mode) == MODE_VECTOR_FRACT
499 || GET_MODE_CLASS (compute_mode) == MODE_VECTOR_UFRACT 588 || GET_MODE_CLASS (compute_mode) == MODE_VECTOR_UFRACT
500 || GET_MODE_CLASS (compute_mode) == MODE_VECTOR_ACCUM 589 || GET_MODE_CLASS (compute_mode) == MODE_VECTOR_ACCUM
501 || GET_MODE_CLASS (compute_mode) == MODE_VECTOR_UACCUM) 590 || GET_MODE_CLASS (compute_mode) == MODE_VECTOR_UACCUM)
502 && op != NULL 591 && op != NULL
503 && optab_handler (op, compute_mode)->insn_code != CODE_FOR_nothing) 592 && optab_handler (op, compute_mode) != CODE_FOR_nothing)
504 return; 593 return;
505 else 594 else
506 /* There is no operation in hardware, so fall back to scalars. */ 595 /* There is no operation in hardware, so fall back to scalars. */
507 compute_type = TREE_TYPE (type); 596 compute_type = TREE_TYPE (type);
508 } 597 }
515 604
516 /* NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One 605 /* NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One
517 way to do it is change expand_vector_operation and its callees to 606 way to do it is change expand_vector_operation and its callees to
518 return a tree_code, RHS1 and RHS2 instead of a tree. */ 607 return a tree_code, RHS1 and RHS2 instead of a tree. */
519 gimple_assign_set_rhs_from_tree (gsi, new_rhs); 608 gimple_assign_set_rhs_from_tree (gsi, new_rhs);
520 609 update_stmt (gsi_stmt (*gsi));
521 gimple_set_modified (gsi_stmt (*gsi), true);
522 } 610 }
523 611
524 /* Use this to lower vector operations introduced by the vectorizer, 612 /* Use this to lower vector operations introduced by the vectorizer,
525 if it may need the bit-twiddling tricks implemented in this file. */ 613 if it may need the bit-twiddling tricks implemented in this file. */
526 614
533 static unsigned int 621 static unsigned int
534 expand_vector_operations (void) 622 expand_vector_operations (void)
535 { 623 {
536 gimple_stmt_iterator gsi; 624 gimple_stmt_iterator gsi;
537 basic_block bb; 625 basic_block bb;
626 bool cfg_changed = false;
538 627
539 FOR_EACH_BB (bb) 628 FOR_EACH_BB (bb)
540 { 629 {
541 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 630 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
542 { 631 {
543 expand_vector_operations_1 (&gsi); 632 expand_vector_operations_1 (&gsi);
544 update_stmt_if_modified (gsi_stmt (gsi)); 633 /* ??? If we do not cleanup EH then we will ICE in
634 verification. But in reality we have created wrong-code
635 as we did not properly transition EH info and edges to
636 the piecewise computations. */
637 if (maybe_clean_eh_stmt (gsi_stmt (gsi))
638 && gimple_purge_dead_eh_edges (bb))
639 cfg_changed = true;
545 } 640 }
546 } 641 }
547 return 0; 642
643 return cfg_changed ? TODO_cleanup_cfg : 0;
548 } 644 }
549 645
550 struct gimple_opt_pass pass_lower_vector = 646 struct gimple_opt_pass pass_lower_vector =
551 { 647 {
552 { 648 {
560 TV_NONE, /* tv_id */ 656 TV_NONE, /* tv_id */
561 PROP_cfg, /* properties_required */ 657 PROP_cfg, /* properties_required */
562 0, /* properties_provided */ 658 0, /* properties_provided */
563 0, /* properties_destroyed */ 659 0, /* properties_destroyed */
564 0, /* todo_flags_start */ 660 0, /* todo_flags_start */
565 TODO_dump_func | TODO_ggc_collect 661 TODO_dump_func | TODO_update_ssa /* todo_flags_finish */
566 | TODO_verify_stmts /* todo_flags_finish */ 662 | TODO_verify_ssa
663 | TODO_verify_stmts | TODO_verify_flow
567 } 664 }
568 }; 665 };
569 666
570 struct gimple_opt_pass pass_lower_vector_ssa = 667 struct gimple_opt_pass pass_lower_vector_ssa =
571 { 668 {