On Tue, Dec 1, 2020 at 8:49 PM Qing Zhao <qing.z...@oracle.com> wrote:
>
> Hi, Richard,
>
> Could you please comment on the following approach:
>
> Instead of adding the zero-initializer quite late at the pass “pass_expand”, 
> we can add it as early as during gimplification.
> However, we will mark these new added zero-initializers as “artificial”. And 
> passing this “artificial” information to
> “pass_early_warn_uninitialized” and “pass_late_warn_uninitialized”, in these 
> two uninitialized variable analysis passes,
> (i.e., in tree-sea-uninit.c) We will update the checking on 
> “ssa_undefined_value_p”  to consider “artificial” zero-initializers.
> (i.e, if the def_stmt is marked with “artificial”, then it’s a undefined 
> value).
>
> With such approach, we should be able to address all those conflicts.
>
> Do you see any obvious issue with this approach?

Yes, DSE will happily elide an explicit zero-init following the
artificial one leading to false uninit diagnostics.

What's the intended purpose of the zero-init?

Richard.

> Thanks a lot for your help.
>
> Qing
>
>
> On Nov 25, 2020, at 3:11 AM, Richard Biener <richard.guent...@gmail.com> 
> wrote:
>
>
>
> I am planing to add a new phase immediately after 
> “pass_late_warn_uninitialized” to initialize all auto-variables that are
> not explicitly initialized in the declaration, the basic idea is following:
>
> ** The proposal:
>
> A. add a new GCC option: (same name and meaning as CLANG)
> -ftrivial-auto-var-init=[pattern|zero], similar pattern init as CLANG;
>
> B. add a new attribute for variable:
> __attribute((uninitialized)
> the marked variable is uninitialized intentionaly for performance purpose.
>
> C. The implementation needs to keep the current static warning on 
> uninitialized
> variables untouched in order to avoid "forking the language".
>
>
> ** The implementation:
>
> There are two major requirements for the implementation:
>
> 1. all auto-variables that do not have an explicit initializer should be 
> initialized to
> zero by this option.  (Same behavior as CLANG)
>
> 2. keep the current static warning on uninitialized variables untouched.
>
> In order to satisfy 1, we should check whether an auto-variable has 
> initializer
> or not;
> In order to satisfy 2, we should add this new transformation after
> "pass_late_warn_uninitialized".
>
> So, we should be able to check whether an auto-variable has initializer or 
> not after “pass_late_warn_uninitialized”,
> If Not, then insert an initialization for it.
>
> For this purpose, I guess that “FOR_EACH_LOCAL_DECL” might be better?
>
>
> I think both as long as they are source-level auto-variables. Then which one 
> is better?
>
>
> Another issue is, in order to check whether an auto-variable has initializer, 
> I plan to add a new bit in “decl_common” as:
> /* In a VAR_DECL, this is DECL_IS_INITIALIZED.  */
> unsigned decl_is_initialized :1;
>
> /* IN VAR_DECL, set when the decl is initialized at the declaration.  */
> #define DECL_IS_INITIALIZED(NODE) \
> (DECL_COMMON_CHECK (NODE)->decl_common.decl_is_initialized)
>
> set this bit when setting DECL_INITIAL for the variables in FE. then keep it
> even though DECL_INITIAL might be NULLed.
>
>
> For locals it would be more reliable to set this flag-Wmaybe-uninitialized.
>
>
>
> You mean I can set the flag “DECL_IS_INITIALIZED (decl)”  inside the routine 
> “gimpley_decl_expr” (gimplify.c) as following:
>
>  if (VAR_P (decl) && !DECL_EXTERNAL (decl))
>    {
>      tree init = DECL_INITIAL (decl);
> ...
>      if (init && init != error_mark_node)
>        {
>          if (!TREE_STATIC (decl))
>    {
>      DECL_IS_INITIALIZED(decl) = 1;
>    }
>
> Is this enough for all Frontends? Are there other places that I need to 
> maintain this bit?
>
>
>
> Do you have any comment and suggestions?
>
>
> As said above - do you want to cover registers as well as locals?
>
>
> All the locals from the source-code point of view should be covered.   (From 
> my study so far,  looks like that Clang adds that phase in FE).
> If GCC adds this phase in FE, then the following design requirement
>
> C. The implementation needs to keep the current static warning on 
> uninitialized
> variables untouched in order to avoid "forking the language”.
>
> cannot be satisfied.  Since gcc’s uninitialized variables analysis is applied 
> quite late.
>
> So, we have to add this new phase after “pass_late_warn_uninitialized”.
>
> I'd do
> the actual zeroing during RTL expansion instead since otherwise you
> have to figure youself whether a local is actually used (see 
> expand_stack_vars)
>
>
> Adding  this new transformation during RTL expansion is okay.  I will check 
> on this in more details to see how to add it to RTL expansion phase.
>
>
> Note that optimization will already made have use of "uninitialized" state
> of locals so depending on what the actual goal is here "late" may be too late.
>
>
> This is a really good point…
>
> In order to avoid optimization  to use the “uninitialized” state of locals, 
> we should add the zeroing phase as early as possible (adding it in FE might 
> be best
> for this issue). However, if we have to met the following requirement:
>
>
> So is optimization supposed to pick up zero or is it supposed to act
> as if the initializer
> is unknown?
>
> C. The implementation needs to keep the current static warning on 
> uninitialized
> variables untouched in order to avoid "forking the language”.
>
> We have to move the new phase after all the uninitialized analysis is done in 
> order to avoid “forking the language”.
>
> So, this is a problem that is not easy to resolve.
>
>
> Indeed, those are conflicting goals.
>
> Do you have suggestion on this?
>
>
> No, not any easy ones.  Doing more of the uninit analysis early (there
> is already an early
> uninit pass) which would mean doing IPA analysis turing GCC into more
> of a static analysis
> tool.  Theres the analyzer now, not sure if that can employ an early
> LTO phase for example.
>
>
>
>
> Richard.
>
>

Reply via email to