@@ -520,6 +520,112 @@ is attached to the global module fragments. For example:
520
520
521
521
Now the linkage name of ``NS::foo() `` will be ``_ZN2NS3fooEv ``.
522
522
523
+ Reduced BMI
524
+ -----------
525
+
526
+ To support the 2 phase compilation model, Clang chose to put everything needed to
527
+ produce an object into the BMI. But every consumer of the BMI, except itself, doesn't
528
+ need such informations. It makes the BMI to larger and so may introduce unnecessary
529
+ dependencies into the BMI. To mitigate the problem, we decided to reduce the information
530
+ contained in the BMI.
531
+
532
+ To be clear, we call the default BMI as Full BMI and the new introduced BMI as Reduced
533
+ BMI.
534
+
535
+ Users can use ``-fexperimental-modules-reduced-bmi `` flag to enable the Reduced BMI.
536
+
537
+ For one phase compilation model (CMake implements this model), with
538
+ ``-fexperimental-modules-reduced-bmi ``, the generated BMI will be Reduced BMI automatically.
539
+ (The output path of the BMI is specified by ``-fmodule-output= `` as usual one phase
540
+ compilation model).
541
+
542
+ It is still possible to support Reduced BMI in two phase compilation model. With
543
+ ``-fexperimental-modules-reduced-bmi ``, ``--precompile `` and ``-fmodule-output= `` specified,
544
+ the generated BMI specified by ``-o `` will be full BMI and the BMI specified by
545
+ ``-fmodule-output= `` will be Reduced BMI. The dependency graph may be:
546
+
547
+ .. code-block :: none
548
+
549
+ module-unit.cppm --> module-unit.full.pcm -> module-unit.o
550
+ |
551
+ -> module-unit.reduced.pcm -> consumer1.cpp
552
+ -> consumer2.cpp
553
+ -> ...
554
+ -> consumer_n.cpp
555
+
556
+ We don't emit diagnostics if ``-fexperimental-modules-reduced-bmi `` is used with a non-module
557
+ unit. This design helps the end users of one phase compilation model to perform experiments
558
+ early without asking for the help of build systems. The users of build systems which supports
559
+ two phase compilation model still need helps from build systems.
560
+
561
+ Within Reduced BMI, we won't write unreachable entities from GMF, definitions of non-inline
562
+ functions and non-inline variables. This may not be a transparent change.
563
+ `[module.global.frag]ex2 <https://eel.is/c++draft/module.global.frag#example-2 >`_ may be a good
564
+ example:
565
+
566
+ .. code-block :: c++
567
+
568
+ // foo.h
569
+ namespace N {
570
+ struct X {};
571
+ int d();
572
+ int e();
573
+ inline int f(X, int = d()) { return e(); }
574
+ int g(X);
575
+ int h(X);
576
+ }
577
+
578
+ // M.cppm
579
+ module;
580
+ #include "foo.h"
581
+ export module M;
582
+ template<typename T> int use_f() {
583
+ N::X x; // N::X, N, and :: are decl-reachable from use_f
584
+ return f(x, 123); // N::f is decl-reachable from use_f,
585
+ // N::e is indirectly decl-reachable from use_f
586
+ // because it is decl-reachable from N::f, and
587
+ // N::d is decl-reachable from use_f
588
+ // because it is decl-reachable from N::f
589
+ // even though it is not used in this call
590
+ }
591
+ template<typename T> int use_g() {
592
+ N::X x; // N::X, N, and :: are decl-reachable from use_g
593
+ return g((T(), x)); // N::g is not decl-reachable from use_g
594
+ }
595
+ template<typename T> int use_h() {
596
+ N::X x; // N::X, N, and :: are decl-reachable from use_h
597
+ return h((T(), x)); // N::h is not decl-reachable from use_h, but
598
+ // N::h is decl-reachable from use_h<int>
599
+ }
600
+ int k = use_h<int>();
601
+ // use_h<int> is decl-reachable from k, so
602
+ // N::h is decl-reachable from k
603
+
604
+ // M-impl.cpp
605
+ module M;
606
+ int a = use_f<int>(); // OK
607
+ int b = use_g<int>(); // error: no viable function for call to g;
608
+ // g is not decl-reachable from purview of
609
+ // module M's interface, so is discarded
610
+ int c = use_h<int>(); // OK
611
+
612
+ In the above example, the function definition of ``N::g `` is elided from the Reduced
613
+ BMI of ``M.cppm ``. Then the use of ``use_g<int> `` in ``M-impl.cpp `` fails
614
+ to instantiate. For such issues, users can add references to ``N::g `` in the module purview
615
+ of ``M.cppm `` to make sure it is reachable, e.g., ``using N::g; ``.
616
+
617
+ We think the Reduced BMI is the correct direction. But given it is a drastic change,
618
+ we'd like to make it experimental first to avoid breaking existing users. The roadmap
619
+ of Reduced BMI may be:
620
+
621
+ 1. ``-fexperimental-modules-reduced-bmi `` is opt in for 1~2 releases. The period depends
622
+ on testing feedbacks.
623
+ 2. We would announce Reduced BMI is not experimental and introduce ``-fmodules-reduced-bmi ``.
624
+ and suggest users to enable this mode. This may takes 1~2 releases too.
625
+ 3. Finally we will enable this by default. When that time comes, the term BMI will refer to
626
+ the reduced BMI today and the Full BMI will only be meaningful to build systems which
627
+ loves to support two phase compilations.
628
+
523
629
Performance Tips
524
630
----------------
525
631
0 commit comments