zahiraam added inline comments.

================
Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:572
     PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
+  } else if (D->hasConstantInitialization() && !(D->hasAttr<ConstInitAttr>())) 
{
+    OrderGlobalInitsOrStermFinalizers Key(201,
----------------
efriedma wrote:
> zahiraam wrote:
> > efriedma wrote:
> > > zahiraam wrote:
> > > > efriedma wrote:
> > > > > zahiraam wrote:
> > > > > > efriedma wrote:
> > > > > > > zahiraam wrote:
> > > > > > > > efriedma wrote:
> > > > > > > > > How is ConstInitAttr relevant here?
> > > > > > > > This change made (without the !(D->hasAttr<ConstInitAttr>()) 
> > > > > > > > made the LIT behavior of aix-static-init.cpp. The IR generated 
> > > > > > > > for 
> > > > > > > > namespace test3 {
> > > > > > > >   struct Test3 {
> > > > > > > >     constexpr Test3() {};
> > > > > > > >     ~Test3() {};
> > > > > > > >   };
> > > > > > > > 
> > > > > > > >   constinit Test3 t;
> > > > > > > > } // namespace test3
> > > > > > > > 
> > > > > > > > was different. I would have thought that the change we made for 
> > > > > > > > constexpr wouldn't affter constinit? 
> > > > > > > I think the significant bit there isn't the use of constinit; 
> > > > > > > it's the non-trivial destructor.  I think the priority 
> > > > > > > modification should only affect constructors, not destructors.  
> > > > > > > (Not sure how to make that work, at first glance.)
> > > > > > Let's see if this is an acceptable solution.
> > > > > To fake constant initialization, we need to initialize the variable 
> > > > > before anything else runs.  But the rearranged prioritization isn't 
> > > > > supposed to affect the destructor.  From [basic.start.term]: "If an 
> > > > > object is initialized statically, the object is destroyed in the same 
> > > > > order as if the object was dynamically initialized."
> > > > > 
> > > > > What you're doing here isn't exactly implementing that.  What you're 
> > > > > doing here is delaying both the initialization and the destruction if 
> > > > > the variable has a non-trivial destructor.  We need to separate the 
> > > > > two to get the behavior we want.
> > > > Could we consider adding a field to EvaluatedStmt called 
> > > > "HasTrivialDestrutor" and only perform the prioritization change when 
> > > > !D->HasTrivialDesctructor?  Instead of using the test for 
> > > > D->hasConstantInitialization(). This seems to be englobing to many 
> > > > cases.
> > > > 
> > > > I considered returning null for HasConstantInitialization in case of 
> > > > var has a non-trivial destructor but that doesn't seem to work.
> > > Once you separate out the initialization from the destruction, the rest 
> > > should come together naturally, I think? I'm not sure what other cases 
> > > could be caught by hasConstantInitialization().
> > Does this change accomplish this? Thanks.
> When a global variable is dynamically initialized, there are two parts to the 
> initialization:
> 
> - Constructing the variable (calling the constructor, or equivalent)
> - Registering the destructor with the runtime (atexit on Windows)
> 
> If an object is initialized statically, the two parts are separated: the 
> variable is emitted already initialized by the compiler.  But we still 
> register the destructor at the same time, in the same way.
> 
> If a dllimport object is initialized statically, we need to make it appear to 
> user code that the same thing happened.  So we need to initialize the object 
> early, but we need to register the destructor at the same time we would have 
> otherwise registered it.  To make this work, we need two separate initializer 
> functions with different priorities.
Thanks for the clarification. I am slowly getting it, I think.

In terms of IR, for example for this:
  struct Test3 {
    constexpr Test3() {};
    ~Test3() {};
  };

  constinit Test3 t;

Are we looking for something like this (partial IR):

  @t = global %struct.Test3 undef
  @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, 
ptr } { i32 **201**, ptr @_GLOBAL__I_000201, ptr null }]
  @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, 
ptr } { i32 **65535**, ptr @_GLOBAL__D_a, ptr null }]
  define internal void @__cxx_global_var_init() {
  entry:
    call void @_ZN5Test3C1Ev(ptr noundef nonnull align 1 dereferenceable(1) @t)
    %0 = call i32 @atexit(ptr @__dtor_t) 
    ret void
  }
  define internal void @__finalize_t() {
   %0 = call i32 @unatexit(ptr @__dtor_t) 
   %needs_destruct = icmp eq i32 %0, 0
   br i1 %needs_destruct, label %destruct.call, label %destruct.end

  destruct.call:  
    call void @__dtor_t()
  .....}
  }

Or

  define internal void @__cxx_global_var_init()  {
  entry:
    call void @_ZN5Test3C1Ev(ptr noundef nonnull align 1 dereferenceable(1) @t)
    ret void
  }
  define internal void @__finalize_t()  {
  %0 = call i32 @atexit(ptr @__dtor_t) 
  }


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137107/new/

https://reviews.llvm.org/D137107

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to