r276159 - [modules] Don't emit initializers for VarDecls within a module eagerly whenever

2016-07-20 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Wed Jul 20 14:10:16 2016
New Revision: 276159

URL: http://llvm.org/viewvc/llvm-project?rev=276159&view=rev
Log:
[modules] Don't emit initializers for VarDecls within a module eagerly whenever
we first touch any part of that module. Instead, defer them until the first
time that module is (transitively) imported. The initializer step for a module
then recursively initializes modules that its own headers imported.

For example, this avoids running the  global initializer in programs
that don't actually use iostreams, but do use other parts of the standard
library.

Added:
cfe/trunk/test/Modules/Inputs/unused-global-init/
  - copied from r275623, cfe/trunk/test/Modules/Inputs/unused-global-init/
cfe/trunk/test/Modules/unused-global-init.cpp
  - copied, changed from r275623, 
cfe/trunk/test/Modules/unused-global-init.cpp
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/include/clang/Serialization/ASTBitCodes.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
cfe/trunk/test/Modules/Inputs/unused-global-init/used.h
cfe/trunk/test/Modules/odr.cpp
cfe/trunk/test/Modules/templates.mm

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=276159&r1=276158&r2=276159&view=diff
==
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 20 14:10:16 2016
@@ -312,6 +312,18 @@ class ASTContext : public RefCountedBase
   /// definitions of that entity.
   llvm::DenseMap> MergedDefModules;
 
+  /// \brief Initializers for a module, in order. Each Decl will be either
+  /// something that has a semantic effect on startup (such as a variable with
+  /// a non-constant initializer), or an ImportDecl (which recursively triggers
+  /// initialization of another module).
+  struct PerModuleInitializers {
+llvm::SmallVector Initializers;
+llvm::SmallVector LazyInitializers;
+
+void resolve(ASTContext &Ctx);
+  };
+  llvm::DenseMap ModuleInitializers;
+
 public:
   /// \brief A type synonym for the TemplateOrInstantiation mapping.
   typedef llvm::PointerUnion
@@ -883,6 +895,17 @@ public:
 return MergedIt->second;
   }
 
+  /// Add a declaration to the list of declarations that are initialized
+  /// for a module. This will typically be a global variable (with internal
+  /// linkage) that runs module initializers, such as the iostream initializer,
+  /// or an ImportDecl nominating another module that has initializers.
+  void addModuleInitializer(Module *M, Decl *Init);
+
+  void addLazyModuleInitializers(Module *M, ArrayRef IDs);
+
+  /// Get the initializations to perform when importing a module, if any.
+  ArrayRef getModuleInitializers(Module *M);
+
   TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
 
   ExternCContextDecl *getExternCContextDecl() const;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=276159&r1=276158&r2=276159&view=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Jul 20 14:10:16 2016
@@ -1390,8 +1390,14 @@ private:
   bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
TypeDiagnoser *Diagnoser);
 
+  struct ModuleScope {
+clang::Module *Module;
+VisibleModuleSet OuterVisibleModules;
+  };
+  /// The modules we're currently parsing.
+  llvm::SmallVector ModuleScopes;
+
   VisibleModuleSet VisibleModules;
-  llvm::SmallVector VisibleModulesStack;
 
   Module *CachedFakeTopLevelModule;
 

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=276159&r1=276158&r2=276159&view=diff
==
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Jul 20 14:10:16 2016
@@ -684,6 +684,9 @@ namespace clang {
   /// \brief Specifies a header that is private to this submodule but
   /// must be textually included.
   SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15,
+  /// \brief Specifies some declarations with initializers that must be
+  /// emitted to initialize the module.
+  SUBMODULE_INITIALIZERS = 16,
 };
 
 /// \brief Record types used within a comme

Re: r276159 - [modules] Don't emit initializers for VarDecls within a module eagerly whenever

2016-10-13 Thread Manman via cfe-commits
Hi Richard,

I committed a follow-up patch in r284142 to fix issues with C/ObjC.

Let me know if you see any problem.

Manman

> On Jul 20, 2016, at 12:10 PM, Richard Smith via cfe-commits 
>  wrote:
> 
> Author: rsmith
> Date: Wed Jul 20 14:10:16 2016
> New Revision: 276159
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=276159&view=rev
> Log:
> [modules] Don't emit initializers for VarDecls within a module eagerly 
> whenever
> we first touch any part of that module. Instead, defer them until the first
> time that module is (transitively) imported. The initializer step for a module
> then recursively initializes modules that its own headers imported.
> 
> For example, this avoids running the  global initializer in programs
> that don't actually use iostreams, but do use other parts of the standard
> library.
> 
> Added:
>cfe/trunk/test/Modules/Inputs/unused-global-init/
>  - copied from r275623, cfe/trunk/test/Modules/Inputs/unused-global-init/
>cfe/trunk/test/Modules/unused-global-init.cpp
>  - copied, changed from r275623, 
> cfe/trunk/test/Modules/unused-global-init.cpp
> Modified:
>cfe/trunk/include/clang/AST/ASTContext.h
>cfe/trunk/include/clang/Sema/Sema.h
>cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>cfe/trunk/lib/AST/ASTContext.cpp
>cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>cfe/trunk/lib/Sema/SemaDecl.cpp
>cfe/trunk/lib/Sema/SemaLookup.cpp
>cfe/trunk/lib/Serialization/ASTReader.cpp
>cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
>cfe/trunk/lib/Serialization/ASTWriter.cpp
>cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
>cfe/trunk/test/Modules/Inputs/unused-global-init/used.h
>cfe/trunk/test/Modules/odr.cpp
>cfe/trunk/test/Modules/templates.mm
> 
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=276159&r1=276158&r2=276159&view=diff
> ==
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 20 14:10:16 2016
> @@ -312,6 +312,18 @@ class ASTContext : public RefCountedBase
>   /// definitions of that entity.
>   llvm::DenseMap> MergedDefModules;
> 
> +  /// \brief Initializers for a module, in order. Each Decl will be either
> +  /// something that has a semantic effect on startup (such as a variable 
> with
> +  /// a non-constant initializer), or an ImportDecl (which recursively 
> triggers
> +  /// initialization of another module).
> +  struct PerModuleInitializers {
> +llvm::SmallVector Initializers;
> +llvm::SmallVector LazyInitializers;
> +
> +void resolve(ASTContext &Ctx);
> +  };
> +  llvm::DenseMap ModuleInitializers;
> +
> public:
>   /// \brief A type synonym for the TemplateOrInstantiation mapping.
>   typedef llvm::PointerUnion
> @@ -883,6 +895,17 @@ public:
> return MergedIt->second;
>   }
> 
> +  /// Add a declaration to the list of declarations that are initialized
> +  /// for a module. This will typically be a global variable (with internal
> +  /// linkage) that runs module initializers, such as the iostream 
> initializer,
> +  /// or an ImportDecl nominating another module that has initializers.
> +  void addModuleInitializer(Module *M, Decl *Init);
> +
> +  void addLazyModuleInitializers(Module *M, ArrayRef IDs);
> +
> +  /// Get the initializations to perform when importing a module, if any.
> +  ArrayRef getModuleInitializers(Module *M);
> +
>   TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
> 
>   ExternCContextDecl *getExternCContextDecl() const;
> 
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=276159&r1=276158&r2=276159&view=diff
> ==
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Wed Jul 20 14:10:16 2016
> @@ -1390,8 +1390,14 @@ private:
>   bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
>TypeDiagnoser *Diagnoser);
> 
> +  struct ModuleScope {
> +clang::Module *Module;
> +VisibleModuleSet OuterVisibleModules;
> +  };
> +  /// The modules we're currently parsing.
> +  llvm::SmallVector ModuleScopes;
> +
>   VisibleModuleSet VisibleModules;
> -  llvm::SmallVector VisibleModulesStack;
> 
>   Module *CachedFakeTopLevelModule;
> 
> 
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=276159&r1=276158&r2=276159&view=diff
> ==
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Jul 20 14:10:16 
> 2016
> @@ -684,6 +

Re: r276159 - [modules] Don't emit initializers for VarDecls within a module eagerly whenever

2016-10-13 Thread Richard Smith via cfe-commits
On Thu, Oct 13, 2016 at 11:52 AM, Manman via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Hi Richard,
>
> I committed a follow-up patch in r284142 to fix issues with C/ObjC.
>
> Let me know if you see any problem.
>

Looks good, thank you!


> Manman
>
> > On Jul 20, 2016, at 12:10 PM, Richard Smith via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
> >
> > Author: rsmith
> > Date: Wed Jul 20 14:10:16 2016
> > New Revision: 276159
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=276159&view=rev
> > Log:
> > [modules] Don't emit initializers for VarDecls within a module eagerly
> whenever
> > we first touch any part of that module. Instead, defer them until the
> first
> > time that module is (transitively) imported. The initializer step for a
> module
> > then recursively initializes modules that its own headers imported.
> >
> > For example, this avoids running the  global initializer in
> programs
> > that don't actually use iostreams, but do use other parts of the standard
> > library.
> >
> > Added:
> >cfe/trunk/test/Modules/Inputs/unused-global-init/
> >  - copied from r275623, cfe/trunk/test/Modules/Inputs/
> unused-global-init/
> >cfe/trunk/test/Modules/unused-global-init.cpp
> >  - copied, changed from r275623, cfe/trunk/test/Modules/unused-
> global-init.cpp
> > Modified:
> >cfe/trunk/include/clang/AST/ASTContext.h
> >cfe/trunk/include/clang/Sema/Sema.h
> >cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> >cfe/trunk/lib/AST/ASTContext.cpp
> >cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> >cfe/trunk/lib/Sema/SemaDecl.cpp
> >cfe/trunk/lib/Sema/SemaLookup.cpp
> >cfe/trunk/lib/Serialization/ASTReader.cpp
> >cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
> >cfe/trunk/lib/Serialization/ASTWriter.cpp
> >cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
> >cfe/trunk/test/Modules/Inputs/unused-global-init/used.h
> >cfe/trunk/test/Modules/odr.cpp
> >cfe/trunk/test/Modules/templates.mm
> >
> > Modified: cfe/trunk/include/clang/AST/ASTContext.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/AST/ASTContext.h?rev=276159&r1=276158&r2=276159&view=diff
> > 
> ==
> > --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> > +++ cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 20 14:10:16 2016
> > @@ -312,6 +312,18 @@ class ASTContext : public RefCountedBase
> >   /// definitions of that entity.
> >   llvm::DenseMap>
> MergedDefModules;
> >
> > +  /// \brief Initializers for a module, in order. Each Decl will be
> either
> > +  /// something that has a semantic effect on startup (such as a
> variable with
> > +  /// a non-constant initializer), or an ImportDecl (which recursively
> triggers
> > +  /// initialization of another module).
> > +  struct PerModuleInitializers {
> > +llvm::SmallVector Initializers;
> > +llvm::SmallVector LazyInitializers;
> > +
> > +void resolve(ASTContext &Ctx);
> > +  };
> > +  llvm::DenseMap ModuleInitializers;
> > +
> > public:
> >   /// \brief A type synonym for the TemplateOrInstantiation mapping.
> >   typedef llvm::PointerUnion MemberSpecializationInfo *>
> > @@ -883,6 +895,17 @@ public:
> > return MergedIt->second;
> >   }
> >
> > +  /// Add a declaration to the list of declarations that are initialized
> > +  /// for a module. This will typically be a global variable (with
> internal
> > +  /// linkage) that runs module initializers, such as the iostream
> initializer,
> > +  /// or an ImportDecl nominating another module that has initializers.
> > +  void addModuleInitializer(Module *M, Decl *Init);
> > +
> > +  void addLazyModuleInitializers(Module *M, ArrayRef IDs);
> > +
> > +  /// Get the initializations to perform when importing a module, if
> any.
> > +  ArrayRef getModuleInitializers(Module *M);
> > +
> >   TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
> >
> >   ExternCContextDecl *getExternCContextDecl() const;
> >
> > Modified: cfe/trunk/include/clang/Sema/Sema.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Sema/Sema.h?rev=276159&r1=276158&r2=276159&view=diff
> > 
> ==
> > --- cfe/trunk/include/clang/Sema/Sema.h (original)
> > +++ cfe/trunk/include/clang/Sema/Sema.h Wed Jul 20 14:10:16 2016
> > @@ -1390,8 +1390,14 @@ private:
> >   bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
> >TypeDiagnoser *Diagnoser);
> >
> > +  struct ModuleScope {
> > +clang::Module *Module;
> > +VisibleModuleSet OuterVisibleModules;
> > +  };
> > +  /// The modules we're currently parsing.
> > +  llvm::SmallVector ModuleScopes;
> > +
> >   VisibleModuleSet VisibleModules;
> > -  llvm::SmallVector VisibleModulesStack;
> >
> >   Module *CachedFakeTopLevelModule;
> >
> >
> > Modified: cfe/trunk/include/clang/Serialization

Re: r276159 - [modules] Don't emit initializers for VarDecls within a module eagerly whenever

2016-10-14 Thread Manman via cfe-commits
Hi Richard,

Another follow-up commit r284263.

When we import the top-level module with “@import X;”, all the initializers in 
the submodule should be emitted.

Let me know if you see any problem,
Manman

> On Oct 13, 2016, at 4:03 PM, Richard Smith  wrote:
> 
> On Thu, Oct 13, 2016 at 11:52 AM, Manman via cfe-commits 
> mailto:cfe-commits@lists.llvm.org>> wrote:
> Hi Richard,
> 
> I committed a follow-up patch in r284142 to fix issues with C/ObjC.
> 
> Let me know if you see any problem.
> 
> Looks good, thank you!
>  
> Manman
> 
> > On Jul 20, 2016, at 12:10 PM, Richard Smith via cfe-commits 
> > mailto:cfe-commits@lists.llvm.org>> wrote:
> >
> > Author: rsmith
> > Date: Wed Jul 20 14:10:16 2016
> > New Revision: 276159
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=276159&view=rev 
> > 
> > Log:
> > [modules] Don't emit initializers for VarDecls within a module eagerly 
> > whenever
> > we first touch any part of that module. Instead, defer them until the first
> > time that module is (transitively) imported. The initializer step for a 
> > module
> > then recursively initializes modules that its own headers imported.
> >
> > For example, this avoids running the  global initializer in 
> > programs
> > that don't actually use iostreams, but do use other parts of the standard
> > library.
> >
> > Added:
> >cfe/trunk/test/Modules/Inputs/unused-global-init/
> >  - copied from r275623, 
> > cfe/trunk/test/Modules/Inputs/unused-global-init/
> >cfe/trunk/test/Modules/unused-global-init.cpp
> >  - copied, changed from r275623, 
> > cfe/trunk/test/Modules/unused-global-init.cpp
> > Modified:
> >cfe/trunk/include/clang/AST/ASTContext.h
> >cfe/trunk/include/clang/Sema/Sema.h
> >cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> >cfe/trunk/lib/AST/ASTContext.cpp
> >cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> >cfe/trunk/lib/Sema/SemaDecl.cpp
> >cfe/trunk/lib/Sema/SemaLookup.cpp
> >cfe/trunk/lib/Serialization/ASTReader.cpp
> >cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
> >cfe/trunk/lib/Serialization/ASTWriter.cpp
> >cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
> >cfe/trunk/test/Modules/Inputs/unused-global-init/used.h
> >cfe/trunk/test/Modules/odr.cpp
> >cfe/trunk/test/Modules/templates.mm 
> >
> > Modified: cfe/trunk/include/clang/AST/ASTContext.h
> > URL: 
> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=276159&r1=276158&r2=276159&view=diff
> >  
> > 
> > ==
> > --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> > +++ cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 20 14:10:16 2016
> > @@ -312,6 +312,18 @@ class ASTContext : public RefCountedBase
> >   /// definitions of that entity.
> >   llvm::DenseMap> MergedDefModules;
> >
> > +  /// \brief Initializers for a module, in order. Each Decl will be either
> > +  /// something that has a semantic effect on startup (such as a variable 
> > with
> > +  /// a non-constant initializer), or an ImportDecl (which recursively 
> > triggers
> > +  /// initialization of another module).
> > +  struct PerModuleInitializers {
> > +llvm::SmallVector Initializers;
> > +llvm::SmallVector LazyInitializers;
> > +
> > +void resolve(ASTContext &Ctx);
> > +  };
> > +  llvm::DenseMap ModuleInitializers;
> > +
> > public:
> >   /// \brief A type synonym for the TemplateOrInstantiation mapping.
> >   typedef llvm::PointerUnion
> > @@ -883,6 +895,17 @@ public:
> > return MergedIt->second;
> >   }
> >
> > +  /// Add a declaration to the list of declarations that are initialized
> > +  /// for a module. This will typically be a global variable (with internal
> > +  /// linkage) that runs module initializers, such as the iostream 
> > initializer,
> > +  /// or an ImportDecl nominating another module that has initializers.
> > +  void addModuleInitializer(Module *M, Decl *Init);
> > +
> > +  void addLazyModuleInitializers(Module *M, ArrayRef IDs);
> > +
> > +  /// Get the initializations to perform when importing a module, if any.
> > +  ArrayRef getModuleInitializers(Module *M);
> > +
> >   TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
> >
> >   ExternCContextDecl *getExternCContextDecl() const;
> >
> > Modified: cfe/trunk/include/clang/Sema/Sema.h
> > URL: 
> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=276159&r1=276158&r2=276159&view=diff
> >  
> > 
> > ==
> > --- cfe/trunk/include/clang/Sema/Sema.h (original)
> > +++ cfe/trunk/include

Regression caused by r276159 - [modules] Don't emit initializers for VarDecls within a module eagerly whenever

2016-12-14 Thread Manman via cfe-commits

> On Jul 20, 2016, at 12:10 PM, Richard Smith via cfe-commits 
>  wrote:
> 
> Author: rsmith
> Date: Wed Jul 20 14:10:16 2016
> New Revision: 276159
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=276159&view=rev
> Log:
> [modules] Don't emit initializers for VarDecls within a module eagerly 
> whenever
> we first touch any part of that module. Instead, defer them until the first
> time that module is (transitively) imported. The initializer step for a module
> then recursively initializes modules that its own headers imported.
> 
> For example, this avoids running the  global initializer in programs
> that don't actually use iostreams, but do use other parts of the standard
> library.
> 
> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=276159&r1=276158&r2=276159&view=diff
> ==
> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Jul 20 14:10:16 2016
> @@ -1017,6 +1017,7 @@ void ASTWriter::WriteBlockInfoBlock() {
>   RECORD(SUBMODULE_PRIVATE_HEADER);
>   RECORD(SUBMODULE_TEXTUAL_HEADER);
>   RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER);
> +  RECORD(SUBMODULE_INITIALIZERS);
> 
>   // Comments Block.
>   BLOCK(COMMENTS_BLOCK);
> @@ -2417,7 +2418,9 @@ unsigned ASTWriter::getLocalOrImportedSu
>   if (Known != SubmoduleIDs.end())
> return Known->second;
> 
> -  if (Mod->getTopLevelModule() != WritingModule)
> +  auto *Top = Mod->getTopLevelModule();
> +  if (Top != WritingModule &&
> +  !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule)))
> return 0;
> 
>   return SubmoduleIDs[Mod] = NextSubmoduleID++;
> @@ -2649,6 +2652,13 @@ void ASTWriter::WriteSubmodules(Module *
>   Stream.EmitRecordWithBlob(ConfigMacroAbbrev, Record, CM);
> }
> 
> +// Emit the initializers, if any.
> +RecordData Inits;
> +for (Decl *D : Context->getModuleInitializers(Mod))
> +  Inits.push_back(GetDeclRef(D));
> +if (!Inits.empty())
> +  Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits);
> +
> // Queue up the submodules of this module.
> for (auto *M : Mod->submodules())
>   Q.push(M);
> @@ -4514,6 +4524,17 @@ uint64_t ASTWriter::WriteASTCore(Sema &S
>   // If we're emitting a module, write out the submodule information.  
>   if (WritingModule)
> WriteSubmodules(WritingModule);
> +  else if (!getLangOpts().CurrentModule.empty()) {
> +// If we're building a PCH in the implementation of a module, we may need
> +// the description of the current module.

Hi Richard,

Sorry to dig up this old commit. We are seeing a regression with the following 
simplified testing case.
cat test.h 
#include "A.h"
cat test.m 
#include "C.h"
cat run.sh 
rm -rf tmp
clang -cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=tmp -I Inputs 
-emit-pch -o tmp-A.pch test.h -fmodule-name=Contacts -x objective-c-header
clang -cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=tmp -I Inputs 
-include-pch tmp-A.pch test.m -fsyntax-only -fmodule-name=Contacts
test.m:1:2: fatal error: module 'Contacts' is defined in both 
'/Users/Ren/projects/module/screen/r29542516/tmp/2BSZ9VNPW89EZ/Contacts-389KKPMFZ1XO7.pcm'
 and 'tmp-A.pch'
#include "C.h"
 ^
test.m:1:2: note: imported by module 'CloudKit' in 
'/Users/Ren/projects/module/screen/r29542516/tmp/2BSZ9VNPW89EZ/CloudKit-389KKPMFZ1XO7.pcm'
1 error generated.

cat Inputs/module.modulemap 
module CloudKit {
  header "C.h"
  export *
}

module Contacts {
  header "D.h"
  export *
}
cat Inputs/A.h
// in pch
cat Inputs/C.h
#include "D.h"
cat Inputs/D.h
//empty

We used to have a different option "-fmodule-implementation-of" which was 
unified with "-fmodule-name”.

When building the pch, we pass in “-fmodule-implementation-of Contacts”, 
because of this part of the commit, we will say the pch defines module Contacts.
The TU also pulls in module CloudKit, which imports module Contacts. Thus we 
have this error:
module 'Contacts' is defined in both 
'/Users/Ren/projects/module/screen/r29542516/tmp/2BSZ9VNPW89EZ/Contacts-389KKPMFZ1XO7.pcm'
 and 'tmp-A.pch’

I wonder why we want to say that a pch defines a module. Is this related to 
lazily evaluating initializers?

Thanks,
Manman

> +//
> +// FIXME: We may need other modules that we did not load from an AST 
> file,
> +// such as if a module declares a 'conflicts' on a different module.
> +Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule(
> +getLangOpts().CurrentModule);
> +if (M && !M->IsFromModuleFile)
> +  WriteSubmodules(M);
> +  }
> 
>   Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
> 
> 

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


Re: Regression caused by r276159 - [modules] Don't emit initializers for VarDecls within a module eagerly whenever

2016-12-19 Thread Manman via cfe-commits

> On Dec 14, 2016, at 1:20 PM, Manman  wrote:
> 
> 
>> On Jul 20, 2016, at 12:10 PM, Richard Smith via cfe-commits 
>>  wrote:
>> 
>> Author: rsmith
>> Date: Wed Jul 20 14:10:16 2016
>> New Revision: 276159
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=276159&view=rev
>> Log:
>> [modules] Don't emit initializers for VarDecls within a module eagerly 
>> whenever
>> we first touch any part of that module. Instead, defer them until the first
>> time that module is (transitively) imported. The initializer step for a 
>> module
>> then recursively initializes modules that its own headers imported.
>> 
>> For example, this avoids running the  global initializer in 
>> programs
>> that don't actually use iostreams, but do use other parts of the standard
>> library.
>> 
>> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
>> URL: 
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=276159&r1=276158&r2=276159&view=diff
>> ==
>> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Jul 20 14:10:16 2016
>> @@ -1017,6 +1017,7 @@ void ASTWriter::WriteBlockInfoBlock() {
>>  RECORD(SUBMODULE_PRIVATE_HEADER);
>>  RECORD(SUBMODULE_TEXTUAL_HEADER);
>>  RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER);
>> +  RECORD(SUBMODULE_INITIALIZERS);
>> 
>>  // Comments Block.
>>  BLOCK(COMMENTS_BLOCK);
>> @@ -2417,7 +2418,9 @@ unsigned ASTWriter::getLocalOrImportedSu
>>  if (Known != SubmoduleIDs.end())
>>return Known->second;
>> 
>> -  if (Mod->getTopLevelModule() != WritingModule)
>> +  auto *Top = Mod->getTopLevelModule();
>> +  if (Top != WritingModule &&
>> +  !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule)))
>>return 0;
>> 
>>  return SubmoduleIDs[Mod] = NextSubmoduleID++;
>> @@ -2649,6 +2652,13 @@ void ASTWriter::WriteSubmodules(Module *
>>  Stream.EmitRecordWithBlob(ConfigMacroAbbrev, Record, CM);
>>}
>> 
>> +// Emit the initializers, if any.
>> +RecordData Inits;
>> +for (Decl *D : Context->getModuleInitializers(Mod))
>> +  Inits.push_back(GetDeclRef(D));
>> +if (!Inits.empty())
>> +  Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits);
>> +
>>// Queue up the submodules of this module.
>>for (auto *M : Mod->submodules())
>>  Q.push(M);
>> @@ -4514,6 +4524,17 @@ uint64_t ASTWriter::WriteASTCore(Sema &S
>>  // If we're emitting a module, write out the submodule information.  
>>  if (WritingModule)
>>WriteSubmodules(WritingModule);
>> +  else if (!getLangOpts().CurrentModule.empty()) {
>> +// If we're building a PCH in the implementation of a module, we may 
>> need
>> +// the description of the current module.
> 
> Hi Richard,
> 
> Sorry to dig up this old commit. We are seeing a regression with the 
> following simplified testing case.
> cat test.h 
> #include "A.h"
> cat test.m 
> #include "C.h"
> cat run.sh 
> rm -rf tmp
> clang -cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=tmp -I 
> Inputs -emit-pch -o tmp-A.pch test.h -fmodule-name=Contacts -x 
> objective-c-header
> clang -cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=tmp -I 
> Inputs -include-pch tmp-A.pch test.m -fsyntax-only -fmodule-name=Contacts
> test.m:1:2: fatal error: module 'Contacts' is defined in both 
> '/Users/Ren/projects/module/screen/r29542516/tmp/2BSZ9VNPW89EZ/Contacts-389KKPMFZ1XO7.pcm'
>  and 'tmp-A.pch'
> #include "C.h"
> ^
> test.m:1:2: note: imported by module 'CloudKit' in 
> '/Users/Ren/projects/module/screen/r29542516/tmp/2BSZ9VNPW89EZ/CloudKit-389KKPMFZ1XO7.pcm'
> 1 error generated.
> 
> cat Inputs/module.modulemap 
> module CloudKit {
>  header "C.h"
>  export *
> }
> 
> module Contacts {
>  header "D.h"
>  export *
> }
> cat Inputs/A.h
> // in pch
> cat Inputs/C.h
> #include "D.h"
> cat Inputs/D.h
> //empty
> 
> We used to have a different option "-fmodule-implementation-of" which was 
> unified with "-fmodule-name”.
> 
> When building the pch, we pass in “-fmodule-implementation-of Contacts”, 
> because of this part of the commit, we will say the pch defines module 
> Contacts.
> The TU also pulls in module CloudKit, which imports module Contacts. Thus we 
> have this error:
> module 'Contacts' is defined in both 
> '/Users/Ren/projects/module/screen/r29542516/tmp/2BSZ9VNPW89EZ/Contacts-389KKPMFZ1XO7.pcm'
>  and 'tmp-A.pch’
> 
> I wonder why we want to say that a pch defines a module. Is this related to 
> lazily evaluating initializers?

Hi Richard,

Can you comment on why we want to say that a PCH defines a module? Any 
suggestion on fixing this regression?

Manman

> 
> Thanks,
> Manman
> 
>> +//
>> +// FIXME: We may need other modules that we did not load from an AST 
>> file,
>> +// such as if a module declares a 'conflicts' on a different module.
>> +Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule(
>> +getLangOpts().CurrentModule);