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. > >