This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Extended if-conversion for loops marked with pragma omp simd.


Hi All,

We implemented additional support for pragma omp simd in part of
extended if-conversion loops with such pragma. These extensions
include:

1. All extensions are performed only if considered loop or its outer
   loop was marked with pragma omp simd (force_vectorize); For ordinary
   loops behavior was not changed.
2. Took off cfg restriction on basic block which can have more than 2
   predecessors.
3. Put additional restriction on phi nodes which was missed in current design:
   all phi nodes must be in non-predicated basic block to conform
   semantic of COND_EXPR which is used for transformation.
4. Extend predication of phi nodes: phi may have more than 2 arguments
with some limitations:
   - for phi nodes which have more than 2 arguments, but only two
   arguments are different and one of them has the only occurence,
transformation to  single COND_EXPR can be done.
   - if phi node has more different arguments and all edge predicates
   correspondent to phi-arguments are disjoint, a chain of COND_EXPR
   will be generated for it. In current design very simple check is used:
   check starting from end that two edges correspondent to neighbor
arguments have common predecessor which is used for further check
with next edge.
 These guarantee that phi predication will produce the correct result.

Here is example of such extended predication (compile with -march=core-avx2):
#pragma omp simd safelen(8)
  for (i=0; i<512; i++)
  {
    float t = a[i];
    if (t > 0 & t < 1.0e+17f)
      if (c[i] != 0)
res += 1;
  }
  <bb 4>:
  # res_15 = PHI <res_1(5), 0(3)>
  # i_16 = PHI <i_11(5), 0(3)>
  # ivtmp_17 = PHI <ivtmp_14(5), 512(3)>
  t_5 = a[i_16];
  _6 = t_5 > 0.0;
  _7 = t_5 < 9.9999998430674944e+16;
  _8 = _7 & _6;
  _ifc__28 = (unsigned int) _8;
  _10 = &c[i_16];
  _ifc__36 = _ifc__28 != 0 ? 4294967295 : 0;
  _9 = MASK_LOAD (_10, 0B, _ifc__36);
  _ifc__29 = _ifc__28 != 0 ? 1 : 0;
  _ifc__30 = (int) _ifc__29;
  _ifc__31 = _9 != 0 ? _ifc__30 : 0;
  _ifc__32 = _ifc__28 != 0 ? 1 : 0;
  _ifc__33 = (int) _ifc__32;
  _ifc__34 = _9 == 0 ? _ifc__33 : 0;
  _ifc__35 = _ifc__31 != 0 ? 1 : 0;
  res_1 = res_15 + _ifc__35;
  i_11 = i_16 + 1;
  ivtmp_14 = ivtmp_17 - 1;
  if (ivtmp_14 != 0)
    goto <bb 4>;

Bootstrap and regression testing did not show any new failures.

gcc/ChageLog

2014-06-25  Yuri Rumyantsev  <ysrumyan@gmail.com>

* tree-if-conv.c (flag_force_vectorize): New variable.
(struct bb_predicate_s): Add negate_predicate field.
(bb_negate_predicate): New function.
(set_bb_negate_predicate): New function.
(bb_copy_predicate): New function.
(add_stmt_to_bb_predicate_gimplified_stmts): New function.
(init_bb_predicate): Add initialization of negate_predicate field.
(reset_bb_predicate): Reset negate_predicate to NULL_TREE.
(convert_name_to_cmp): New function.
(get_type_for_cond): New function.
(convert_bool_predicate): New function.
(predicate_disjunction): New function.
(predicate_conjunction): New function.
(add_to_predicate_list): Add convert_bool argument.
Add call of predicate_disjunction if convert_bool argument is true.
(add_to_dst_predicate_list): Add convert_bool argument.
Add early function exit if edge target block is always executed.
Add call of predicate_conjunction if convert_bool argument is true.
Pass convert_bool argument for add_to_predicate_list.
(equal_phi_args): New function.
(phi_has_two_different_args): New function.
(phi_args_disjoint): New function.
(if_convertible_phi_p): Accept phi nodes with more than two args
for loops marked with pragma omp simd. Add check that phi nodes are
in non-predicated basic blocks.
(ifcvt_can_use_mask_load_store): Use flag_force_vectorize.
(all_edges_are_critical): New function.
(if_convertible_bb_p): Allow bb has more than two predecessors if
flag_force_vectorize was setup. Use call of all_edges_are_critical
to reject block if-conversion with imcoming critical edges only if
flag_force_vectorize was not setup.
(walk_cond_tree): New function.
(vect_bool_pattern_is_applicable): New function.
(predicate_bbs): Add convert_bool argument that is used to transform
comparison expressions of boolean type into conditional expressions
with integral operands. If bool_conv argument is false or both
outgoing edges are not critical old algorithm of predicate assignments
is used, otherwise the following code was added: check on applicable
of vect-bool-pattern recognition and trnasformation of
(bool) x != 0  --> y = (int) x; x != 0;
compute predicates for both outgoing edges one of which is critical
one using 'normal' edge, i.e. compute true and false predicates using
normal outgoing edge only; evaluated predicates are stored in
predicate and negate_predicate fields of struct bb_predicate_s and
negate_predicate of normal edge conatins predicate of critical edge,
but generated gimplified statements are stored in their destination
block fields. Additional argument 'convert_bool" is passed to
add_to_dst_predicate_list and add_to_predicate_list.
(if_convertible_loop_p_1): Call predicate_bbs with additional argument
equal to false.
(find_phi_replacement_condition): Extend function interface:
it returns NULL if given phi node must be handled by means of
extended phi node predication. If number of predecessors of phi-block
is equal 2 and atleast one incoming edge is not critical original
algorithm is used.
(is_cond_scalar_reduction): Add 'extended' argument which signals that
both phi arguments must be evaluated through phi_has_two_different_args.
(predicate_scalar_phi): Add invoÑation of convert_name_to_cmp if cond
is SSA_NAME. Add 'false' argument to call of is_cond_scalar_reduction.
(get_predicate_for_edge): New function.
(find_insertion_point): New function.
(predicate_phi_disjoint_args): New function.
(predicate_extended_scalar_phi): New function.
(predicate_all_scalar_phis): Add code to set-up gimple statement
iterator for predication of extended scalar phi's for insertion.
(insert_gimplified_predicates): Add test for non-predicated basic
blocks that there are no gimplified statements to insert. Insert
predicates at the block begining for extended if-conversion.
(predicate_mem_writes): Invoke convert_name_to_cmp for extended
predication to build mask.
(combine_blocks): Pass flag_force_vectorize to predicate_bbs.
(split_crit_edge): New function.
(tree_if_conversion): Initialize flag_force_vectorize from current
loop or outer loop (to support pragma omp declare). Invoke
split_crit_edge for extended predication. Do loop versioning for
innermost loop marked with pragma omp simd.

Attachment: patch
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]