This is an archive of the discontinued LLVM Phabricator instance.

[CodeGen] guarantee templated static variables are initialized in the reverse instantiation order
ClosedPublic

Authored by ychen on Jun 7 2022, 3:35 PM.

Details

Summary

Based on Richard's suggestion in D126341:
`If we can actually describe a rule that we provide for initialization
order of instantiated variables, and we can easily implement that rule
and be confident we won't want to substantially weaken it later, and we
can thereby assure our users that we will satisfy that rule, then I
think that could be interesting, but anything less than that doesn't
seem worthwhile to me.`

I'm giving it try here. IMHO the implementation is pretty simple and
does not change behavior for unrelated constructs like the timing when
instantiated variables are passed to CodeGen.

This is based on the same ordering guarantee needed for inline variables D127233.
To provide this guarantee, we also need to
emit DeferredDeclsToEmit in the DFS order. https://github.com/llvm/llvm-project/commit/e5df59ff78faebd897e81907606ce6074aac0df6
originally supported this but it is not exactly DFS order for cases like
the one in cwg362. For the example of Fib<5>, it triggers the instantiation
of Fib<4> and Fib<3>. However, due to the way GlobalEagerInstantiationScope
is implemented, Fib<4> does not actually trigger Fib<3> instantiation
since it is already triggered by Fib<5>. This breaks the guarantee.

This patch makes sure DeferredDeclsToEmit is emitted in DFS order by moving
DeferredDeclsToEmit storage from the call stack to an explicit stack-like
data structure. Then the DFS order could be enforced.

Diff Detail

Event Timeline

ychen created this revision.Jun 7 2022, 3:35 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 7 2022, 3:35 PM
ychen requested review of this revision.Jun 7 2022, 3:35 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 7 2022, 3:35 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
ychen edited the summary of this revision. (Show Details)Jun 7 2022, 3:46 PM

gentle ping..

I think Richard had some concerns in the other review that this may not be enough to really guarantee initialization order within the TU. I couldn't say either way, I shouldn't review this code. Conceptually, this change seems small enough to me. Can we ask @aaron.ballman to take a look?

ychen added a comment.Jun 16 2022, 3:18 PM

I think Richard had some concerns in the other review that this may not be enough to really guarantee initialization order within the TU. I couldn't say either way, I shouldn't review this code. Conceptually, this change seems small enough to me. Can we ask @aaron.ballman to take a look?

@rnk, thanks. @rsmith, please correct me if I'm wrong. I think the current approach is relying on two things: partial ordering in llvm.global_ctors entries (this is also needed to fix https://github.com/llvm/llvm-project/issues/55804, D127233, I could submit a follow-up patch to either make IR verifier check the order is not unexpected changed or simply check the order is maintained by GlobalOpt) and a linker that picks the *first* COMDAT consistently (this is not guaranteed but generally true for major linkers for a long time). The alternative is to coalesce llvm.global_ctors entries with order requirements into a single dynamic initialization function, however, as already being discussed, this has code size and startup time overhead. We could discuss the partial ordering in llvm.global_ctors entries in D127233.

tchatow removed a subscriber: tchatow.
tchatow added a subscriber: tchatow.
ychen planned changes to this revision.Aug 23 2022, 12:13 PM

I'll do a compile-time impact measurement.

erichkeane accepted this revision.Feb 27 2023, 12:23 PM
erichkeane added a subscriber: erichkeane.

I don't see much compile-time concerns myself, and this seems to fix a pretty serious regression, I think this is acceptable once Aaron and the author think so as well.

ychen updated this revision to Diff 502068.Mar 3 2023, 12:11 AM
  • rebase
This revision is now accepted and ready to land.Mar 3 2023, 12:11 AM
This revision was landed with ongoing or failed builds.Mar 3 2023, 12:13 AM
This revision was automatically updated to reflect the committed changes.
shafik added a subscriber: shafik.Mar 3 2023, 7:57 AM
shafik added inline comments.
clang/lib/Sema/SemaExpr.cpp
19385

Doesn't this invalidate the iterators?