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]

Re: Loop stride inline hint


On Wed, Sep 12, 2012 at 11:53 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
> Hi,
> this patch makes inliner to realize that it is good idea to inline when loop
> stride becomes constant. This is mostly to help fortran testcases where
> it is important to inline to get array descriptors.

I think the same applies to upper/lower bounds.

Richard.

> Bootstrapped/regtested x86_64-linux, comitted.
>
> Honza
>
>         * ipa-inline-analysis.c (dump_inline_hints): Dump loop stride.
>         (set_hint_predicate): New function.
>         (reset_inline_summary): Reset loop stride.
>         (remap_predicate_after_duplication): New function.
>         (remap_hint_predicate_after_duplication): New function.
>         (inline_node_duplication_hook): Update.
>         (dump_inline_summary): Dump stride summaries.
>         (estimate_function_body_sizes): Compute strides.
>         (remap_hint_predicate): New function.
>         (inline_merge_summary): Use it.
>         (inline_read_section): Read stride.
>         (inline_write_summary): Write stride.
>         * ipa-inline.c (want_inline_small_function_p): Handle strides.
>         (edge_badness): Likewise.
>         * ipa-inline.h (inline_hints_vals): Add stride hint.
>         (inline_summary): Update stride.
>
>         * gcc.dg/ipa/inlinehint-2.c: New testcase.
> Index: ipa-inline.c
> ===================================================================
> *** ipa-inline.c        (revision 191228)
> --- ipa-inline.c        (working copy)
> *************** want_inline_small_function_p (struct cgr
> *** 481,487 ****
>         else if (DECL_DECLARED_INLINE_P (callee->symbol.decl)
>                && growth >= MAX_INLINE_INSNS_SINGLE
>                && !(hints & (INLINE_HINT_indirect_call
> !                            | INLINE_HINT_loop_iterations)))
>         {
>             e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
>           want_inline = false;
> --- 481,488 ----
>         else if (DECL_DECLARED_INLINE_P (callee->symbol.decl)
>                && growth >= MAX_INLINE_INSNS_SINGLE
>                && !(hints & (INLINE_HINT_indirect_call
> !                            | INLINE_HINT_loop_iterations
> !                            | INLINE_HINT_loop_stride)))
>         {
>             e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
>           want_inline = false;
> *************** want_inline_small_function_p (struct cgr
> *** 533,539 ****
>          inlining given function is very profitable.  */
>         else if (!DECL_DECLARED_INLINE_P (callee->symbol.decl)
>                && growth >= ((hints & (INLINE_HINT_indirect_call
> !                                      | INLINE_HINT_loop_iterations))
>                              ? MAX (MAX_INLINE_INSNS_AUTO,
>                                     MAX_INLINE_INSNS_SINGLE)
>                              : MAX_INLINE_INSNS_AUTO))
> --- 534,541 ----
>          inlining given function is very profitable.  */
>         else if (!DECL_DECLARED_INLINE_P (callee->symbol.decl)
>                && growth >= ((hints & (INLINE_HINT_indirect_call
> !                                      | INLINE_HINT_loop_iterations
> !                                      | INLINE_HINT_loop_stride))
>                              ? MAX (MAX_INLINE_INSNS_AUTO,
>                                     MAX_INLINE_INSNS_SINGLE)
>                              : MAX_INLINE_INSNS_AUTO))
> *************** edge_badness (struct cgraph_edge *edge,
> *** 866,872 ****
>             fprintf (dump_file, "Badness overflow\n");
>         }
>         if (hints & (INLINE_HINT_indirect_call
> !                  | INLINE_HINT_loop_iterations))
>         badness /= 8;
>         if (dump)
>         {
> --- 868,875 ----
>             fprintf (dump_file, "Badness overflow\n");
>         }
>         if (hints & (INLINE_HINT_indirect_call
> !                  | INLINE_HINT_loop_iterations
> !                  | INLINE_HINT_loop_stride))
>         badness /= 8;
>         if (dump)
>         {
> Index: ipa-inline.h
> ===================================================================
> *** ipa-inline.h        (revision 191228)
> --- ipa-inline.h        (working copy)
> *************** typedef struct GTY(()) condition
> *** 46,52 ****
>      They are represtented as bitmap of the following values.  */
>   enum inline_hints_vals {
>     INLINE_HINT_indirect_call = 1,
> !   INLINE_HINT_loop_iterations = 2
>   };
>   typedef int inline_hints;
>
> --- 46,53 ----
>      They are represtented as bitmap of the following values.  */
>   enum inline_hints_vals {
>     INLINE_HINT_indirect_call = 1,
> !   INLINE_HINT_loop_iterations = 2,
> !   INLINE_HINT_loop_stride = 4
>   };
>   typedef int inline_hints;
>
> *************** struct GTY(()) inline_summary
> *** 120,128 ****
>     conditions conds;
>     VEC(size_time_entry,gc) *entry;
>
> !   /* Predicate on when some loop in the function sbecomes to have known
>        bounds.   */
>     struct predicate * GTY((skip)) loop_iterations;
>   };
>
>
> --- 121,132 ----
>     conditions conds;
>     VEC(size_time_entry,gc) *entry;
>
> !   /* Predicate on when some loop in the function becomes to have known
>        bounds.   */
>     struct predicate * GTY((skip)) loop_iterations;
> +   /* Predicate on when some loop in the function becomes to have known
> +      stride.   */
> +   struct predicate * GTY((skip)) loop_stride;
>   };
>
>
> Index: ipa-inline-analysis.c
> ===================================================================
> *** ipa-inline-analysis.c       (revision 191228)
> --- ipa-inline-analysis.c       (working copy)
> *************** dump_inline_hints (FILE *f, inline_hints
> *** 634,639 ****
> --- 634,644 ----
>         hints &= ~INLINE_HINT_loop_iterations;
>         fprintf (f, " loop_iterations");
>       }
> +   if (hints & INLINE_HINT_loop_stride)
> +     {
> +       hints &= ~INLINE_HINT_loop_stride;
> +       fprintf (f, " loop_stride");
> +     }
>     gcc_assert (!hints);
>   }
>
> *************** edge_set_predicate (struct cgraph_edge *
> *** 719,724 ****
> --- 724,749 ----
>       }
>   }
>
> + /* Set predicate for hint *P.  */
> +
> + static void
> + set_hint_predicate (struct predicate **p, struct predicate new_predicate)
> + {
> +   if (false_predicate_p (&new_predicate)
> +       || true_predicate_p (&new_predicate))
> +     {
> +       if (*p)
> +       pool_free (edge_predicate_pool, *p);
> +       *p = NULL;
> +     }
> +   else
> +     {
> +       if (!*p)
> +       *p = (struct predicate *)pool_alloc (edge_predicate_pool);
> +       **p = new_predicate;
> +     }
> + }
> +
>
>   /* KNOWN_VALS is partial mapping of parameters of NODE to constant values.
>      KNOWN_AGGS is a vector of aggreggate jump functions for each parameter.
> *************** reset_inline_summary (struct cgraph_node
> *** 953,958 ****
> --- 978,988 ----
>         pool_free (edge_predicate_pool, info->loop_iterations);
>         info->loop_iterations = NULL;
>       }
> +   if (info->loop_stride)
> +     {
> +       pool_free (edge_predicate_pool, info->loop_stride);
> +       info->loop_stride = NULL;
> +     }
>     VEC_free (condition, gc, info->conds);
>     VEC_free (size_time_entry,gc, info->entry);
>     for (e = node->callees; e; e = e->next_callee)
> *************** inline_node_removal_hook (struct cgraph_
> *** 975,980 ****
> --- 1005,1056 ----
>     memset (info, 0, sizeof (inline_summary_t));
>   }
>
> + /* Remap predicate P of former function to be predicate of duplicated functoin.
> +    POSSIBLE_TRUTHS is clause of possible truths in the duplicated node,
> +    INFO is inline summary of the duplicated node.  */
> +
> + static struct predicate
> + remap_predicate_after_duplication (struct predicate *p,
> +                                  clause_t possible_truths,
> +                                  struct inline_summary *info)
> + {
> +   struct predicate new_predicate = true_predicate ();
> +   int j;
> +   for (j = 0; p->clause[j]; j++)
> +     if (!(possible_truths & p->clause[j]))
> +       {
> +       new_predicate = false_predicate ();
> +       break;
> +       }
> +     else
> +       add_clause (info->conds, &new_predicate,
> +                 possible_truths & p->clause[j]);
> +   return new_predicate;
> + }
> +
> + /* Same as remap_predicate_after_duplication but handle hint predicate *P.
> +    Additionally care about allocating new memory slot for updated predicate
> +    and set it to NULL when it becomes true or false (and thus uninteresting).
> +  */
> +
> + static void
> + remap_hint_predicate_after_duplication (struct predicate **p,
> +                                       clause_t possible_truths,
> +                                       struct inline_summary *info)
> + {
> +   struct predicate new_predicate;
> +
> +   if (!*p)
> +     return;
> +
> +   new_predicate = remap_predicate_after_duplication (*p,
> +                                                    possible_truths,
> +                                                    info);
> +   /* We do not want to free previous predicate; it is used by node origin.  */
> +   *p = NULL;
> +   set_hint_predicate (p, new_predicate);
> + }
> +
>
>   /* Hook that is called by cgraph.c when a node is duplicated.  */
>
> *************** inline_node_duplication_hook (struct cgr
> *** 1042,1057 ****
>          to be true.  */
>         for (i = 0; VEC_iterate (size_time_entry, entry, i, e); i++)
>         {
> !         struct predicate new_predicate = true_predicate ();
> !         for (j = 0; e->predicate.clause[j]; j++)
> !           if (!(possible_truths & e->predicate.clause[j]))
> !             {
> !               new_predicate = false_predicate ();
> !               break;
> !             }
> !           else
> !             add_clause (info->conds, &new_predicate,
> !                         possible_truths & e->predicate.clause[j]);
>           if (false_predicate_p (&new_predicate))
>             {
>               optimized_out_size += e->size;
> --- 1118,1127 ----
>          to be true.  */
>         for (i = 0; VEC_iterate (size_time_entry, entry, i, e); i++)
>         {
> !         struct predicate new_predicate;
> !         new_predicate = remap_predicate_after_duplication (&e->predicate,
> !                                                            possible_truths,
> !                                                            info);
>           if (false_predicate_p (&new_predicate))
>             {
>               optimized_out_size += e->size;
> *************** inline_node_duplication_hook (struct cgr
> *** 1065,1086 ****
>          Also copy constantness arrays.   */
>         for (edge = dst->callees; edge; edge = edge->next_callee)
>         {
> !         struct predicate new_predicate = true_predicate ();
>           struct inline_edge_summary *es = inline_edge_summary (edge);
>
>           if (!edge->inline_failed)
>             inlined_to_p = true;
>           if (!es->predicate)
>             continue;
> !         for (j = 0; es->predicate->clause[j]; j++)
> !           if (!(possible_truths & es->predicate->clause[j]))
> !             {
> !               new_predicate = false_predicate ();
> !               break;
> !             }
> !           else
> !             add_clause (info->conds, &new_predicate,
> !                         possible_truths & es->predicate->clause[j]);
>           if (false_predicate_p (&new_predicate)
>               && !false_predicate_p (es->predicate))
>             {
> --- 1135,1150 ----
>          Also copy constantness arrays.   */
>         for (edge = dst->callees; edge; edge = edge->next_callee)
>         {
> !         struct predicate new_predicate;
>           struct inline_edge_summary *es = inline_edge_summary (edge);
>
>           if (!edge->inline_failed)
>             inlined_to_p = true;
>           if (!es->predicate)
>             continue;
> !         new_predicate = remap_predicate_after_duplication (es->predicate,
> !                                                            possible_truths,
> !                                                            info);
>           if (false_predicate_p (&new_predicate)
>               && !false_predicate_p (es->predicate))
>             {
> *************** inline_node_duplication_hook (struct cgr
> *** 1097,1118 ****
>          Also copy constantness arrays.   */
>         for (edge = dst->indirect_calls; edge; edge = edge->next_callee)
>         {
> !         struct predicate new_predicate = true_predicate ();
>           struct inline_edge_summary *es = inline_edge_summary (edge);
>
> !         if (!edge->inline_failed)
> !           inlined_to_p = true;
>           if (!es->predicate)
>             continue;
> !         for (j = 0; es->predicate->clause[j]; j++)
> !           if (!(possible_truths & es->predicate->clause[j]))
> !             {
> !               new_predicate = false_predicate ();
> !               break;
> !             }
> !           else
> !             add_clause (info->conds, &new_predicate,
> !                         possible_truths & es->predicate->clause[j]);
>           if (false_predicate_p (&new_predicate)
>               && !false_predicate_p (es->predicate))
>             {
> --- 1161,1175 ----
>          Also copy constantness arrays.   */
>         for (edge = dst->indirect_calls; edge; edge = edge->next_callee)
>         {
> !         struct predicate new_predicate;
>           struct inline_edge_summary *es = inline_edge_summary (edge);
>
> !         gcc_checking_assert (edge->inline_failed);
>           if (!es->predicate)
>             continue;
> !         new_predicate = remap_predicate_after_duplication (es->predicate,
> !                                                            possible_truths,
> !                                                            info);
>           if (false_predicate_p (&new_predicate)
>               && !false_predicate_p (es->predicate))
>             {
> *************** inline_node_duplication_hook (struct cgr
> *** 1124,1151 ****
>             }
>           edge_set_predicate (edge, &new_predicate);
>         }
> !       if (info->loop_iterations)
> !       {
> !         struct predicate new_predicate = true_predicate ();
> !
> !         for (j = 0; info->loop_iterations->clause[j]; j++)
> !           if (!(possible_truths & info->loop_iterations->clause[j]))
> !             {
> !               new_predicate = false_predicate ();
> !               break;
> !             }
> !           else
> !             add_clause (info->conds, &new_predicate,
> !                         possible_truths & info->loop_iterations->clause[j]);
> !         if (false_predicate_p (&new_predicate)
> !             || true_predicate_p (&new_predicate))
> !           info->loop_iterations = NULL;
> !         else
> !           {
> !             info->loop_iterations = (struct predicate *)pool_alloc (edge_predicate_pool);
> !             *info->loop_iterations = new_predicate;
> !           }
> !       }
>
>         /* If inliner or someone after inliner will ever start producing
>          non-trivial clones, we will get trouble with lack of information
> --- 1181,1192 ----
>             }
>           edge_set_predicate (edge, &new_predicate);
>         }
> !       remap_hint_predicate_after_duplication (&info->loop_iterations,
> !                                             possible_truths,
> !                                             info);
> !       remap_hint_predicate_after_duplication (&info->loop_stride,
> !                                             possible_truths,
> !                                             info);
>
>         /* If inliner or someone after inliner will ever start producing
>          non-trivial clones, we will get trouble with lack of information
> *************** inline_node_duplication_hook (struct cgr
> *** 1175,1182 ****
>         if (info->loop_iterations)
>         {
>           predicate p = *info->loop_iterations;
> !         info->loop_iterations = (struct predicate *)pool_alloc (edge_predicate_pool);
> !         *info->loop_iterations = p;
>         }
>       }
>   }
> --- 1216,1229 ----
>         if (info->loop_iterations)
>         {
>           predicate p = *info->loop_iterations;
> !         info->loop_iterations = NULL;
> !         set_hint_predicate (&info->loop_iterations, p);
> !       }
> !       if (info->loop_stride)
> !       {
> !         predicate p = *info->loop_stride;
> !         info->loop_stride = NULL;
> !         set_hint_predicate (&info->loop_stride, p);
>         }
>       }
>   }
> *************** dump_inline_summary (FILE * f, struct cg
> *** 1355,1360 ****
> --- 1402,1412 ----
>           fprintf (f, "  loop iterations:");
>           dump_predicate (f, s->conds, s->loop_iterations);
>         }
> +       if (s->loop_stride)
> +       {
> +         fprintf (f, "  loop stride:");
> +         dump_predicate (f, s->conds, s->loop_stride);
> +       }
>         fprintf (f, "  calls:\n");
>         dump_inline_edge_summary (f, 4, node, s);
>         fprintf (f, "\n");
> *************** will_be_nonconstant_expr_predicate (stru
> *** 1851,1863 ****
>     if (TREE_CODE (expr) == SSA_NAME)
>       return VEC_index (predicate_t, nonconstant_names,
>                         SSA_NAME_VERSION (expr));
> !   if (BINARY_CLASS_P (expr))
>       {
> !       struct predicate p1 =  will_be_nonconstant_expr_predicate (info, summary, TREE_OPERAND (expr, 0), nonconstant_names);
>         struct predicate p2;
>         if (true_predicate_p (&p1))
>         return p1;
> !       p2 = will_be_nonconstant_expr_predicate (info, summary, TREE_OPERAND (expr, 0), nonconstant_names);
>         return or_predicates (summary->conds, &p1, &p2);
>       }
>     else
> --- 1903,1939 ----
>     if (TREE_CODE (expr) == SSA_NAME)
>       return VEC_index (predicate_t, nonconstant_names,
>                         SSA_NAME_VERSION (expr));
> !   if (BINARY_CLASS_P (expr)
> !       || COMPARISON_CLASS_P (expr))
> !     {
> !       struct predicate p1 = will_be_nonconstant_expr_predicate
> !                             (info, summary, TREE_OPERAND (expr, 0),
> !                              nonconstant_names);
> !       struct predicate p2;
> !       if (true_predicate_p (&p1))
> !       return p1;
> !       p2 = will_be_nonconstant_expr_predicate (info, summary,
> !                                              TREE_OPERAND (expr, 1),
> !                                              nonconstant_names);
> !       return or_predicates (summary->conds, &p1, &p2);
> !     }
> !   else if (TREE_CODE (expr) == COND_EXPR)
>       {
> !       struct predicate p1 = will_be_nonconstant_expr_predicate
> !                             (info, summary, TREE_OPERAND (expr, 0),
> !                              nonconstant_names);
>         struct predicate p2;
>         if (true_predicate_p (&p1))
>         return p1;
> !       p2 = will_be_nonconstant_expr_predicate (info, summary,
> !                                              TREE_OPERAND (expr, 1),
> !                                              nonconstant_names);
> !       if (true_predicate_p (&p2))
> !       return p2;
> !       p1 = or_predicates (summary->conds, &p1, &p2);
> !       p2 = will_be_nonconstant_expr_predicate (info, summary,
> !                                              TREE_OPERAND (expr, 2),
> !                                              nonconstant_names);
>         return or_predicates (summary->conds, &p1, &p2);
>       }
>     else
> *************** estimate_function_body_sizes (struct cgr
> *** 2390,2395 ****
> --- 2466,2472 ----
>         struct loop *loop;
>         loop_iterator li;
>         predicate loop_iterations = true_predicate ();
> +       predicate loop_stride = true_predicate ();
>
>         if (dump_file && (dump_flags & TDF_DETAILS))
>         flow_loops_dump (dump_file, NULL, 0);
> *************** estimate_function_body_sizes (struct cgr
> *** 2398,2405 ****
>         {
>             VEC (edge, heap) *exits;
>             edge ex;
> !         unsigned int j;
>           struct tree_niter_desc niter_desc;
>
>           exits = get_loop_exit_edges (loop);
>             FOR_EACH_VEC_ELT (edge, exits, j, ex)
> --- 2475,2483 ----
>         {
>             VEC (edge, heap) *exits;
>             edge ex;
> !         unsigned int j, i;
>           struct tree_niter_desc niter_desc;
> +         basic_block *body = get_loop_body (loop);
>
>           exits = get_loop_exit_edges (loop);
>             FOR_EACH_VEC_ELT (edge, exits, j, ex)
> *************** estimate_function_body_sizes (struct cgr
> *** 2416,2427 ****
>                   loop_iterations = and_predicates (info->conds, &loop_iterations, &will_be_nonconstant);
>               }
>             VEC_free (edge, heap, exits);
>         }
> !       if (!true_predicate_p (&loop_iterations))
> !       {
> !           inline_summary (node)->loop_iterations = (struct predicate *)pool_alloc (edge_predicate_pool);
> !           *inline_summary (node)->loop_iterations = loop_iterations;
> !       }
>         scev_finalize ();
>       }
>     inline_summary (node)->self_time = time;
> --- 2494,2532 ----
>                   loop_iterations = and_predicates (info->conds, &loop_iterations, &will_be_nonconstant);
>               }
>             VEC_free (edge, heap, exits);
> +
> +           for (i = 0; i < loop->num_nodes; i++)
> +           {
> +             gimple_stmt_iterator gsi;
> +             for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
> +               {
> +                 gimple stmt = gsi_stmt (gsi);
> +                 affine_iv iv;
> +                 ssa_op_iter iter;
> +                 tree use;
> +
> +                 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
> +                   {
> +                     predicate will_be_nonconstant;
> +
> +                     if (!simple_iv (loop, loop_containing_stmt (stmt), use, &iv, true)
> +                         || is_gimple_min_invariant (iv.step))
> +                       continue;
> +                     will_be_nonconstant
> +                      = will_be_nonconstant_expr_predicate (parms_info, info,
> +                                                            iv.step, nonconstant_names);
> +                     if (!true_predicate_p (&will_be_nonconstant)
> +                         && !false_predicate_p (&will_be_nonconstant))
> +                       /* This is slightly inprecise.  We may want to represent each loop with
> +                          independent predicate.  */
> +                       loop_stride = and_predicates (info->conds, &loop_stride, &will_be_nonconstant);
> +                   }
> +               }
> +           }
> +         free (body);
>         }
> !       set_hint_predicate (&inline_summary (node)->loop_iterations, loop_iterations);
> !       set_hint_predicate (&inline_summary (node)->loop_stride, loop_stride);
>         scev_finalize ();
>       }
>     inline_summary (node)->self_time = time;
> *************** estimate_node_size_and_time (struct cgra
> *** 2715,2720 ****
> --- 2820,2828 ----
>     if (info->loop_iterations
>         && !evaluate_predicate (info->loop_iterations, possible_truths))
>       hints |=INLINE_HINT_loop_iterations;
> +   if (info->loop_stride
> +       && !evaluate_predicate (info->loop_stride, possible_truths))
> +     hints |=INLINE_HINT_loop_stride;
>
>     if (time > MAX_TIME * INLINE_TIME_SCALE)
>       time = MAX_TIME * INLINE_TIME_SCALE;
> *************** remap_edge_summaries  (struct cgraph_edg
> *** 3011,3016 ****
> --- 3119,3155 ----
>       }
>   }
>
> + /* Same as remap_predicate, but set result into hint *HINT.  */
> +
> + static void
> + remap_hint_predicate (struct inline_summary *info,
> +                     struct inline_summary *callee_info,
> +                     struct predicate **hint,
> +                     VEC (int, heap) *operand_map,
> +                     VEC (int, heap) *offset_map,
> +                     clause_t possible_truths,
> +                     struct predicate *toplev_predicate)
> + {
> +   predicate p;
> +
> +   if (!*hint)
> +     return;
> +   p = remap_predicate (info, callee_info,
> +                      *hint,
> +                      operand_map, offset_map,
> +                      possible_truths,
> +                      toplev_predicate);
> +   if (!false_predicate_p (&p)
> +       && !true_predicate_p (&p))
> +     {
> +       if (!*hint)
> +       set_hint_predicate (hint, p);
> +       else
> +       **hint = and_predicates (info->conds,
> +                                *hint,
> +                                &p);
> +     }
> + }
>
>   /* We inlined EDGE.  Update summary of the function we inlined into.  */
>
> *************** inline_merge_summary (struct cgraph_edge
> *** 3102,3129 ****
>       }
>     remap_edge_summaries (edge, edge->callee, info, callee_info, operand_map,
>                         offset_map, clause, &toplev_predicate);
> !   if (callee_info->loop_iterations)
> !     {
> !       predicate p = remap_predicate (info, callee_info,
> !                                    callee_info->loop_iterations,
> !                                    operand_map, offset_map,
> !                                    clause,
> !                                    &toplev_predicate);
> !       if (!false_predicate_p (&p)
> !         && !true_predicate_p (&p))
> !       {
> !         if (!info->loop_iterations)
> !           {
> !             info->loop_iterations
> !                = (struct predicate *)pool_alloc (edge_predicate_pool);
> !             *info->loop_iterations = p;
> !           }
> !         else
> !           *info->loop_iterations = and_predicates (info->conds,
> !                                                    info->loop_iterations,
> !                                                    &p);
> !       }
> !     }
>
>     inline_update_callee_summaries (edge->callee,
>                                   inline_edge_summary (edge)->loop_depth);
> --- 3241,3254 ----
>       }
>     remap_edge_summaries (edge, edge->callee, info, callee_info, operand_map,
>                         offset_map, clause, &toplev_predicate);
> !   remap_hint_predicate (info, callee_info,
> !                       &callee_info->loop_iterations,
> !                       operand_map, offset_map,
> !                       clause, &toplev_predicate);
> !   remap_hint_predicate (info, callee_info,
> !                       &callee_info->loop_stride,
> !                       operand_map, offset_map,
> !                       clause, &toplev_predicate);
>
>     inline_update_callee_summaries (edge->callee,
>                                   inline_edge_summary (edge)->loop_depth);
> *************** inline_read_section (struct lto_file_dec
> *** 3595,3605 ****
>         }
>
>         p = read_predicate (&ib);
> !       if (!true_predicate_p (&p))
> !       {
> !         info->loop_iterations = (struct predicate *)pool_alloc (edge_predicate_pool);
> !         *info->loop_iterations = p;
> !       }
>         for (e = node->callees; e; e = e->next_callee)
>         read_inline_edge_summary (&ib, e);
>         for (e = node->indirect_calls; e; e = e->next_callee)
> --- 3720,3728 ----
>         }
>
>         p = read_predicate (&ib);
> !       set_hint_predicate (&info->loop_iterations, p);
> !       p = read_predicate (&ib);
> !       set_hint_predicate (&info->loop_stride, p);
>         for (e = node->callees; e; e = e->next_callee)
>         read_inline_edge_summary (&ib, e);
>         for (e = node->indirect_calls; e; e = e->next_callee)
> *************** inline_write_summary (void)
> *** 3747,3752 ****
> --- 3870,3876 ----
>               write_predicate (ob, &e->predicate);
>             }
>           write_predicate (ob, info->loop_iterations);
> +         write_predicate (ob, info->loop_stride);
>           for (edge = node->callees; edge; edge = edge->next_callee)
>             write_inline_edge_summary (ob, edge);
>           for (edge = node->indirect_calls; edge; edge = edge->next_callee)


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