Thanks for the comments.

Regards,
Wei.

On Thu, Nov 21, 2013 at 12:48 AM, Bin.Cheng <amker.ch...@gmail.com> wrote:
> I don't know very much about the problem but willing to study since I
> am looking into IVO recently :)
>
>> --- tree-ssa-loop-ivopts.c      (revision 204792)
>> +++ tree-ssa-loop-ivopts.c      (working copy)
>> @@ -135,6 +135,8 @@ struct iv
>>    tree ssa_name;       /* The ssa name with the value.  */
>>    bool biv_p;          /* Is it a biv?  */
>>    bool have_use_for;   /* Do we already have a use for it?  */
>> +  bool builtin_mem_param; /* Used as param of a builtin, so it could not be
>> +                            removed by remove_unused_ivs.  */
>
> As comment below, address parameter may be not limited to builtin
> function only, how about a variable name more generic?

Ok, I will change it to a different name.

>
>>    unsigned use_id;     /* The identifier in the use if it is the case.  */
>>  };
>>
>> @@ -952,6 +954,7 @@ alloc_iv (tree base, tree step)
>>    iv->step = step;
>>    iv->biv_p = false;
>>    iv->have_use_for = false;
>> +  iv->builtin_mem_param = false;
>>    iv->use_id = 0;
>>    iv->ssa_name = NULL_TREE;
>>
>> @@ -1874,13 +1877,36 @@ find_invariants_stmt (struct ivopts_data
>>      }
>>  }
>>
>> +/* Find whether the Ith param of the BUILTIN is a mem
>> +   reference. If I is -1, it returns whether the BUILTIN
>> +   contains any mem reference type param.  */
>> +
>> +static bool
>> +builtin_has_mem_ref_p (gimple builtin, int i)
>> +{
>> +  tree fndecl = gimple_call_fndecl (builtin);
>> +  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
>> +    {
>> +      switch (DECL_FUNCTION_CODE (fndecl))
>> +       {
>> +       case BUILT_IN_PREFETCH:
>> +         if (i == -1 || i == 0)
>> +            return true;
>> +       }
> This switch looks strange, could be refactored I think.
>

I am not sure if there will be more builtins coming in the func, so I
use switch case here.

>> +    }
>> +  else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
>> +    return targetm.builtin_has_mem_ref_p ((int) DECL_FUNCTION_CODE
>> (fndecl), i);
>> +
>> +  return false;
>> +}
>> +
>>  /* Finds interesting uses of induction variables in the statement STMT.  */
>>
>>  static void
>>  find_interesting_uses_stmt (struct ivopts_data *data, gimple stmt)
>>  {
>>    struct iv *iv;
>> -  tree op, *lhs, *rhs;
>> +  tree op, *lhs, *rhs, callee;
>>    ssa_op_iter iter;
>>    use_operand_p use_p;
>>    enum tree_code code;
>> @@ -1937,6 +1963,74 @@ find_interesting_uses_stmt (struct ivopt
>>
>>          call (memory).  */
>>      }
>> +  else if (is_gimple_call (stmt)
>> +          && (callee = gimple_call_fndecl (stmt))
>> +          && is_builtin_fn (callee)
>> +          && builtin_has_mem_ref_p (stmt, -1))
>> +    {
>
> I noticed the preceding comments about call(memory), is your change a
> specific case of the mention one?
>

Yes, I will fix it.

>> +      size_t i;
>> +      for (i = 0; i < gimple_call_num_args (stmt); i++)
>> +       {
>> +         if (builtin_has_mem_ref_p (stmt, i))
>> +           {
>> +             gimple def, g;
>> +             gimple_seq seq = NULL;
>> +             tree type, mem, addr, rhs;
>> +             tree *arg = gimple_call_arg_ptr (stmt, i);
>> +              location_t loc = gimple_location (stmt);
>> +             gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
>> +
>> +              if (TREE_CODE (*arg) != SSA_NAME)
>> +               continue;
>> +
>> +             def = SSA_NAME_DEF_STMT (*arg);
>> +             gcc_assert (gimple_code (def) == GIMPLE_PHI
>> +                         || is_gimple_assign (def));
>> +             /* Suppose we have the case:
>> +                  arg = expr;
>> +                  call (arg)
>> +                If the expr is not like the form: &MEM(...), change it to:
>> +                  arg = expr;
>> +                  tmp = &MEM(arg);
>> +                  call(tmp);
>> +                then try to find interesting uses address in MEM(arg).  */
>> +             if (is_gimple_assign (def)
>> +                 && (rhs = gimple_assign_rhs1(def))
>> +                 && TREE_CODE (rhs) == ADDR_EXPR
>> +                 && REFERENCE_CLASS_P (TREE_OPERAND (rhs, 0)))
>> +               {
>> +                 iv = get_iv (data, *arg);
>> +                 if (iv && !iv->builtin_mem_param)
>> +                   iv->builtin_mem_param = true;
>> +
>> +                 find_interesting_uses_address (data, def,
>> +                                                &TREE_OPERAND (rhs, 0));
>> +               }
>> +             else
>> +               {
>> +                 mem = build2 (MEM_REF, TREE_TYPE (*arg), *arg,
>> +                               build_int_cst (TREE_TYPE (*arg), 0));
>> +                 type = build_pointer_type (TREE_TYPE (*arg));
>> +                 addr = build1 (ADDR_EXPR, type, mem);
>> +                 g = gimple_build_assign_with_ops (ADDR_EXPR,
>> +                                                   make_ssa_name (type, 
>> NULL),
>> +                                                   addr, NULL);
>> +                 gimple_call_set_arg (stmt, i, gimple_assign_lhs (g));
>> +                 update_stmt (stmt);
>> +                 gimple_set_location (g, loc);
>> +                 gimple_seq_add_stmt_without_update (&seq, g);
>> +                 gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
>> +                 find_interesting_uses_address (data, g,
>> &TREE_OPERAND (addr, 0));
>
> This would be the only code changes gimple before iv use rewriting and
> seems not a good practice.

Yes. Zdenek mentioned the same. I will think how to fix it.

>
>> +               }
>> +           }
>> +         else
>> +           {
>> +             tree arg = gimple_call_arg (stmt, i);
>> +             find_interesting_uses_op (data, arg);
>> +           }
>> +       }
>> +      return;
>> +    }
>>
>>    if (gimple_code (stmt) == GIMPLE_PHI
>>        && gimple_bb (stmt) == data->current_loop->header)
>> @@ -6507,10 +6601,10 @@ remove_unused_ivs (struct ivopts_data *d
>>           && !integer_zerop (info->iv->step)
>>           && !info->inv_id
>>           && !info->iv->have_use_for
>> +         && !info->iv->builtin_mem_param
>>           && !info->preserve_biv)
>>         {
>
> Thanks,
> bin
>
> --
> Best Regards.

Reply via email to