<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="mpark/wg21" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <meta name="dcterms.date" content="2023-11-21" />
  <title>Two finer-grained compilation model for named modules</title>
  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
      div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
      ul.task-list{list-style: none;}
      pre > code.sourceCode { white-space: pre; position: relative; }
      pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
      pre > code.sourceCode > span:empty { height: 1.2em; }
      code.sourceCode > span { color: inherit; text-decoration: inherit; }
      div.sourceCode { margin: 1em 0; }
      pre.sourceCode { margin: 0; }
      @media screen {
      div.sourceCode { overflow: auto; }
      }
      @media print {
      pre > code.sourceCode { white-space: pre-wrap; }
      pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
      }
      pre.numberSource code
        { counter-reset: source-line 0; }
      pre.numberSource code > span
        { position: relative; left: -4em; counter-increment: source-line; }
      pre.numberSource code > span > a:first-child::before
        { content: counter(source-line);
          position: relative; left: -1em; text-align: right; vertical-align: baseline;
          border: none; display: inline-block;
          -webkit-touch-callout: none; -webkit-user-select: none;
          -khtml-user-select: none; -moz-user-select: none;
          -ms-user-select: none; user-select: none;
          padding: 0 4px; width: 4em;
          color: #aaaaaa;
        }
      pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
      div.sourceCode
        {  background-color: #f6f8fa; }
      @media screen {
      pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
      }
      code span. { } /* Normal */
      code span.al { color: #ff0000; } /* Alert */
      code span.an { } /* Annotation */
      code span.at { } /* Attribute */
      code span.bn { color: #9f6807; } /* BaseN */
      code span.bu { color: #9f6807; } /* BuiltIn */
      code span.cf { color: #00607c; } /* ControlFlow */
      code span.ch { color: #9f6807; } /* Char */
      code span.cn { } /* Constant */
      code span.co { color: #008000; font-style: italic; } /* Comment */
      code span.cv { color: #008000; font-style: italic; } /* CommentVar */
      code span.do { color: #008000; } /* Documentation */
      code span.dt { color: #00607c; } /* DataType */
      code span.dv { color: #9f6807; } /* DecVal */
      code span.er { color: #ff0000; font-weight: bold; } /* Error */
      code span.ex { } /* Extension */
      code span.fl { color: #9f6807; } /* Float */
      code span.fu { } /* Function */
      code span.im { } /* Import */
      code span.in { color: #008000; } /* Information */
      code span.kw { color: #00607c; } /* Keyword */
      code span.op { color: #af1915; } /* Operator */
      code span.ot { } /* Other */
      code span.pp { color: #6f4e37; } /* Preprocessor */
      code span.re { } /* RegionMarker */
      code span.sc { color: #9f6807; } /* SpecialChar */
      code span.ss { color: #9f6807; } /* SpecialString */
      code span.st { color: #9f6807; } /* String */
      code span.va { } /* Variable */
      code span.vs { color: #9f6807; } /* VerbatimString */
      code span.wa { color: #008000; font-weight: bold; } /* Warning */
      code.diff {color: #898887}
      code.diff span.va {color: #006e28}
      code.diff span.st {color: #bf0303}
  </style>
  <style type="text/css">
body {
margin: 5em;
font-family: serif;

hyphens: auto;
line-height: 1.35;
text-align: justify;
font-size: 135%;
}
@media screen and (max-width: 30em) {
body {
margin: 1.5em;
}
}
div.wrapper {
max-width: 60em;
margin: auto;
}
ul {
list-style-type: none;
padding-left: 2em;
margin-top: -0.2em;
margin-bottom: -0.2em;
}
a {
text-decoration: none;
color: #4183C4;
}
a.hidden_link {
text-decoration: none;
color: inherit;
}
li {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
h1, h2, h3, h4 {
position: relative;
line-height: 1;
}
a.self-link {
position: absolute;
top: 0;
left: calc(-1 * (3.5rem - 26px));
width: calc(3.5rem - 26px);
height: 2em;
text-align: center;
border: none;
transition: opacity .2s;
opacity: .5;
font-family: sans-serif;
font-weight: normal;
font-size: 83%;
}
a.self-link:hover { opacity: 1; }
a.self-link::before { content: "§"; }
ul > li:before {
content: "\2014";
position: absolute;
margin-left: -1.5em;
}
:target { background-color: #C9FBC9; }
:target .codeblock { background-color: #C9FBC9; }
:target ul { background-color: #C9FBC9; }
.abbr_ref { float: right; }
.folded_abbr_ref { float: right; }
:target .folded_abbr_ref { display: none; }
:target .unfolded_abbr_ref { float: right; display: inherit; }
.unfolded_abbr_ref { display: none; }
.secnum { display: inline-block; min-width: 35pt; }
.header-section-number { display: inline-block; min-width: 35pt; }
.annexnum { display: block; }
div.sourceLinkParent {
float: right;
}
a.sourceLink {
position: absolute;
opacity: 0;
margin-left: 10pt;
}
a.sourceLink:hover {
opacity: 1;
}
a.itemDeclLink {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
opacity: 0;
}
a.itemDeclLink:hover { opacity: 1; }
span.marginalizedparent {
position: relative;
left: -5em;
}
li span.marginalizedparent { left: -7em; }
li ul > li span.marginalizedparent { left: -9em; }
li ul > li ul > li span.marginalizedparent { left: -11em; }
li ul > li ul > li ul > li span.marginalizedparent { left: -13em; }
div.footnoteNumberParent {
position: relative;
left: -4.7em;
}
a.marginalized {
position: absolute;
font-size: 75%;
text-align: right;
width: 5em;
}
a.enumerated_item_num {
position: relative;
left: -3.5em;
display: inline-block;
margin-right: -3em;
text-align: right;
width: 3em;
}
div.para { margin-bottom: 0.6em; margin-top: 0.6em; text-align: justify; }
div.section { text-align: justify; }
div.sentence { display: inline; }
span.indexparent {
display: inline;
position: relative;
float: right;
right: -1em;
}
a.index {
position: absolute;
display: none;
}
a.index:before { content: "⟵"; }

a.index:target {
display: inline;
}
.indexitems {
margin-left: 2em;
text-indent: -2em;
}
div.itemdescr {
margin-left: 3em;
}
.bnf {
font-family: serif;
margin-left: 40pt;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.ncbnf {
font-family: serif;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
}
.ncsimplebnf {
font-family: serif;
font-style: italic;
margin-top: 0.5em;
margin-bottom: 0.5em;
margin-left: 40pt;
background: inherit; 
}
span.textnormal {
font-style: normal;
font-family: serif;
white-space: normal;
display: inline-block;
}
span.rlap {
display: inline-block;
width: 0px;
}
span.descr { font-style: normal; font-family: serif; }
span.grammarterm { font-style: italic; }
span.term { font-style: italic; }
span.terminal { font-family: monospace; font-style: normal; }
span.nonterminal { font-style: italic; }
span.tcode { font-family: monospace; font-style: normal; }
span.textbf { font-weight: bold; }
span.textsc { font-variant: small-caps; }
a.nontermdef { font-style: italic; font-family: serif; }
span.emph { font-style: italic; }
span.techterm { font-style: italic; }
span.mathit { font-style: italic; }
span.mathsf { font-family: sans-serif; }
span.mathrm { font-family: serif; font-style: normal; }
span.textrm { font-family: serif; }
span.textsl { font-style: italic; }
span.mathtt { font-family: monospace; font-style: normal; }
span.mbox { font-family: serif; font-style: normal; }
span.ungap { display: inline-block; width: 2pt; }
span.textit { font-style: italic; }
span.texttt { font-family: monospace; }
span.tcode_in_codeblock { font-family: monospace; font-style: normal; }
span.phantom { color: white; }

span.math { font-style: normal; }
span.mathblock {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 1.2em;
margin-bottom: 1.2em;
text-align: center;
}
span.mathalpha {
font-style: italic;
}
span.synopsis {
font-weight: bold;
margin-top: 0.5em;
display: block;
}
span.definition {
font-weight: bold;
display: block;
}
.codeblock {
margin-left: 1.2em;
line-height: 127%;
}
.outputblock {
margin-left: 1.2em;
line-height: 127%;
}
div.itemdecl {
margin-top: 2ex;
}
code.itemdeclcode {
white-space: pre;
display: block;
}
span.textsuperscript {
vertical-align: super;
font-size: smaller;
line-height: 0;
}
.footnotenum { vertical-align: super; font-size: smaller; line-height: 0; }
.footnote {
font-size: small;
margin-left: 2em;
margin-right: 2em;
margin-top: 0.6em;
margin-bottom: 0.6em;
}
div.minipage {
display: inline-block;
margin-right: 3em;
}
div.numberedTable {
text-align: center;
margin: 2em;
}
div.figure {
text-align: center;
margin: 2em;
}
table {
border: 1px solid black;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
margin-top: 0.8em;
text-align: left;
hyphens: none; 
}
td, th {
padding-left: 1em;
padding-right: 1em;
vertical-align: top;
}
td.empty {
padding: 0px;
padding-left: 1px;
}
td.left {
text-align: left;
}
td.right {
text-align: right;
}
td.center {
text-align: center;
}
td.justify {
text-align: justify;
}
td.border {
border-left: 1px solid black;
}
tr.rowsep, td.cline {
border-top: 1px solid black;
}
tr.even, tr.odd {
border-bottom: 1px solid black;
}
tr.capsep {
border-top: 3px solid black;
border-top-style: double;
}
tr.header {
border-bottom: 3px solid black;
border-bottom-style: double;
}
th {
border-bottom: 1px solid black;
}
span.centry {
font-weight: bold;
}
div.table {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
width: 90%;
}
span.indented {
display: block;
margin-left: 2em;
margin-bottom: 1em;
margin-top: 1em;
}
ol.enumeratea { list-style-type: none; background: inherit; }
ol.enumerate { list-style-type: none; background: inherit; }

code.sourceCode > span { display: inline; }
</style>
  <link href="data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAVoJEAN6CRADegkQAWIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wCCRAAAgkQAAIJEAACCRAAsgkQAvoJEAP+CRAD/gkQA/4JEAP+CRADAgkQALoJEAACCRAAAgkQAAP///wD///8AgkQAAIJEABSCRACSgkQA/IJEAP99PQD/dzMA/3czAP99PQD/gkQA/4JEAPyCRACUgkQAFIJEAAD///8A////AHw+AFiBQwDqgkQA/4BBAP9/PxP/uZd6/9rJtf/bybX/upd7/39AFP+AQQD/gkQA/4FDAOqAQgBc////AP///wDKklv4jlEa/3o7AP+PWC//8+3o///////////////////////z7un/kFox/35AAP+GRwD/mVYA+v///wD///8A0Zpk+NmibP+0d0T/8evj///////+/fv/1sKz/9bCs//9/fr//////+/m2/+NRwL/nloA/5xYAPj///8A////ANKaZPjRmGH/5cKh////////////k149/3UwAP91MQD/lmQ//86rhv+USg3/m1YA/5hSAP+bVgD4////AP///wDSmmT4zpJY/+/bx///////8+TV/8mLT/+TVx//gkIA/5lVAP+VTAD/x6B//7aEVv/JpH7/s39J+P///wD///8A0ppk+M6SWP/u2sf///////Pj1f/Nj1T/2KFs/8mOUv+eWhD/lEsA/8aee/+0glT/x6F7/7J8Rvj///8A////ANKaZPjRmGH/48Cf///////+/v7/2qt//82PVP/OkFX/37KJ/86siv+USg7/mVQA/5hRAP+bVgD4////AP///wDSmmT40ppk/9CVXP/69O////////7+/v/x4M//8d/P//7+/f//////9u7n/6tnJf+XUgD/nFgA+P///wD///8A0ppk+NKaZP/RmWL/1qNy//r07///////////////////////+vXw/9akdP/Wnmn/y5FY/6JfFvj///8A////ANKaZFTSmmTo0ppk/9GYYv/Ql1//5cWm//Hg0P/x4ND/5cWm/9GXYP/RmGH/0ppk/9KaZOjVnmpY////AP///wDSmmQA0ppkEtKaZI7SmmT60ppk/9CWX//OkVb/zpFW/9CWX//SmmT/0ppk/NKaZJDSmmQS0ppkAP///wD///8A0ppkANKaZADSmmQA0ppkKtKaZLrSmmT/0ppk/9KaZP/SmmT/0ppkvNKaZCrSmmQA0ppkANKaZAD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkUtKaZNzSmmTc0ppkVNKaZADSmmQA0ppkANKaZADSmmQA////AP5/AAD4HwAA4AcAAMADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMADAADgBwAA+B8AAP5/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAyCRACMgkQA6oJEAOqCRACQgkQAEIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRABigkQA5oJEAP+CRAD/gkQA/4JEAP+CRADqgkQAZoJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAA4gkQAwoJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQAxIJEADyCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAAgkQAAP///wD///8A////AP///wCCRAAAgkQAAIJEAACCRAAAgkQAAIJEAACCRAAWgkQAmIJEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAJyCRAAYgkQAAIJEAACCRAAAgkQAAIJEAACCRAAA////AP///wD///8A////AIJEAACCRAAAgkQAAIJEAACCRAAAgkQAdIJEAPCCRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAP+CRAD/gkQA/4JEAPSCRAB4gkQAAIJEAACCRAAAgkQAAIJEAAD///8A////AP///wD///8AgkQAAIJEAACCRAAAgkQASoJEANKCRAD/gkQA/4JEAP+CRAD/g0YA/39AAP9zLgD/bSQA/2shAP9rIQD/bSQA/3MuAP9/PwD/g0YA/4JEAP+CRAD/gkQA/4JEAP+CRADUgkQAToJEAACCRAAAgkQAAP///wD///8A////AP///wB+PwAAgkUAIoJEAKiCRAD/gkQA/4JEAP+CRAD/hEcA/4BBAP9sIwD/dTAA/5RfKv+viF7/vp56/76ee/+wiF7/lWAr/3YxAP9sIwD/f0AA/4RHAP+CRAD/gkQA/4JEAP+CRAD/gkQArIJEACaBQwAA////AP///wD///8A////AIBCAEBzNAD6f0EA/4NFAP+CRAD/gkQA/4VIAP92MwD/bSUA/6N1Tv/ezsL/////////////////////////////////38/D/6V3Uv9uJgD/dTEA/4VJAP+CRAD/gkQA/4JEAP+BQwD/fUAA/4FDAEj///8A////AP///wD///8AzJRd5qBlKf91NgD/dDUA/4JEAP+FSQD/cy4A/3YyAP/PuKP//////////////////////////////////////////////////////9K7qP94NQD/ciwA/4VJAP+CRAD/fkEA/35BAP+LSwD/mlYA6v///wD///8A////AP///wDdpnL/4qx3/8KJUv+PUhf/cTMA/3AsAP90LgD/4dK+/////////////////////////////////////////////////////////////////+TYxf91MAD/dTIA/31CAP+GRwD/llQA/6FcAP+gWwD8////AP///wD///8A////ANGZY/LSm2X/4ap3/92mcP+wdT3/byQA/8mwj////////////////////////////////////////////////////////////////////////////+LYxv9zLgP/jUoA/59bAP+hXAD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/RmWL/1p9q/9ubXv/XqXj////////////////////////////7+fD/vZyG/6BxS/+gcUr/vJuE//r37f//////////////////////3MOr/5dQBf+dVQD/nVkA/5xYAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmWP/yohJ//jo2P//////////////////////4NTG/4JDFf9lGAD/bSQA/20kAP9kGAD/fz8S/+Xb0f//////5NG9/6txN/+LOgD/m1QA/51aAP+cWAD/m1cA/5xYAP+cWADy////AP///wD///8A////ANKaZPLSmmT/0ppk/8+TWf/Unmv//v37//////////////////////+TWRr/VwsA/35AAP+ERgD/g0UA/4JGAP9lHgD/kFga/8KXX/+TRwD/jT4A/49CAP+VTQD/n10A/5xYAP+OQQD/lk4A/55cAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/y4tO/92yiP//////////////////////8NnE/8eCQP+rcTT/ez0A/3IyAP98PgD/gEMA/5FSAP+USwD/jj8A/5lUAP+JNwD/yqV2/694Mf+HNQD/jkAA/82rf/+laBj/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/LiUr/4byY///////////////////////gupX/0I5P/+Wuev/Lklz/l1sj/308AP+QSwD/ol0A/59aAP+aVQD/k0oA/8yoh///////+fXv/6pwO//Lp3v///////Pr4f+oay7y////AP///wD///8A////ANKaZPLSmmT/0ppk/8uJSv/hvJj//////////////////////+G7l//Jhkb/0ppk/96nc//fqXX/x4xO/6dkFP+QSQD/llEA/5xXAP+USgD/yaOA///////38uv/qG05/8ijdv//////8efb/6ZpLPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/zIxO/9yxh///////////////////////7dbA/8iEQf/Sm2X/0Zlj/9ScZv/eqHf/2KJv/7yAQf+XTgD/iToA/5lSAP+JNgD/yKFv/611LP+HNQD/jT8A/8qmeP+kZRT/jT4A8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/Pk1n/1J5q//78+//////////////////+/fv/1aFv/8iEQv/Tm2b/0ppl/9GZY//Wn2z/1pZc/9eldf/Bl2b/kUcA/4w9AP+OQAD/lUwA/59eAP+cWQD/jT8A/5ZOAP+eXADy////AP///wD///8A////ANKaZPLSmmT/0ppk/9KZY//KiEn/8d/P///////////////////////47+f/05tm/8iCP//KiEj/yohJ/8eCP//RmGH//vfy///////n1sP/rXQ7/4k4AP+TTAD/nVoA/5xYAP+cVwD/nFgA/5xYAPL///8A////AP///wD///8A0ppk8tKaZP/SmmT/0ptl/8uLTf/aq37////////////////////////////+/fz/6c2y/961jv/etY7/6Myx//78+v//////////////////////3MWv/5xXD/+ORAD/mFQA/51ZAP+cWAD/nFgA8v///wD///8A////AP///wDSmmTy0ppk/9KaZP/SmmT/0ppk/8mFRP/s1b//////////////////////////////////////////////////////////////////////////////+PD/0JFU/7NzMv+WUQD/kUsA/5tXAP+dWQDy////AP///wD///8A////ANKaZP/SmmT/0ppk/9KaZP/Sm2X/z5NZ/8yMT//z5NX/////////////////////////////////////////////////////////////////9Ofa/8yNUP/UmGH/36p5/8yTWv+qaSD/kksA/5ROAPz///8A////AP///wD///8A0ppk5NKaZP/SmmT/0ppk/9KaZP/TnGf/zY9T/82OUv/t1sD//////////////////////////////////////////////////////+7Yw//OkFX/zI5R/9OcZ//SmmP/26V0/9ymdf/BhUf/ol8R6P///wD///8A////AP///wDSmmQ80ppk9tKaZP/SmmT/0ppk/9KaZP/TnGj/zpFW/8qJSv/dson/8uHS//////////////////////////////////Lj0//etIv/y4lL/86QVf/TnGj/0ppk/9KaZP/RmWP/05xn/9ymdfjUnWdC////AP///wD///8A////ANKaZADSmmQc0ppkotKaZP/SmmT/0ppk/9KaZP/Tm2b/0Zli/8qJSf/NjlH/16Z3/+G8mP/myKr/5siq/+G8mP/Xp3f/zY5S/8qISf/RmGH/05tm/9KaZP/SmmT/0ppk/9KaZP/SmmSm0pljINWdaQD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkQtKaZMrSmmT/0ppk/9KaZP/SmmT/0ptl/9GYYf/Nj1P/y4lL/8qISP/KiEj/y4lK/82PU//RmGH/0ptl/9KaZP/SmmT/0ppk/9KaZP/SmmTO0ppkRtKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZGzSmmTu0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmTw0ppkcNKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZBLSmmSQ0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppklNKaZBTSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP///wD///8A0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQy0ppkutKaZP/SmmT/0ppk/9KaZP/SmmT/0ppk/9KaZP/SmmT/0ppkvtKaZDbSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkAP///wD///8A////AP///wDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkXNKaZODSmmT/0ppk/9KaZP/SmmT/0ppk5NKaZGDSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA////AP///wD///8A////ANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkBtKaZIbSmmTo0ppk6tKaZIrSmmQK0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZADSmmQA0ppkANKaZAD///8A////AP/8P///+B///+AH//+AAf//AAD//AAAP/AAAA/gAAAHwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA+AAAAfwAAAP/AAAP/8AAP//gAH//+AH///4H////D//" rel="icon" />
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  
</head>
<body>
<div class="wrapper">
<header id="title-block-header">
<h1 class="title" style="text-align:center">Two finer-grained compilation model for named modules</h1>

<table style="border:none;float:right">
  <tr>
    <td>Document #:</td>
    <td>P3057R0</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>2023-11-21</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Project:</td>
    <td>Programming Language C++</td>
  </tr>
  <tr>
    <td style="vertical-align:top">Audience:</td>
    <td>
      SG15<br>
    </td>
  </tr>
  <tr>
    <td style="vertical-align:top">Reply-to:</td>
    <td>
      Chuanqi Xu<br>&lt;<a href="mailto:chuanqi.xcq@alibaba-inc.com" class="email">chuanqi.xcq@alibaba-inc.com</a>&gt;<br>
    </td>
  </tr>
</table>

</header>
<div style="clear:both">
<div id="TOC" role="doc-toc">
<h1 id="toctitle">Contents</h1>
<ul>
<li><a href="#abstract"><span class="toc-section-number">1</span> Abstract<span></span></a></li>
<li><a href="#proposed-solutions"><span class="toc-section-number">2</span> Proposed solutions<span></span></a>
<ul>
<li><a href="#used-files-based-solution"><span class="toc-section-number">2.1</span> Used Files based solution<span></span></a>
<ul>
<li><a href="#foo-and-bar-example"><span class="toc-section-number">2.1.1</span> foo and bar example<span></span></a></li>
<li><a href="#hello-world-example"><span class="toc-section-number">2.1.2</span> Hello World Example<span></span></a></li>
</ul></li>
<li><a href="#hash-of-declarations-solution"><span class="toc-section-number">2.2</span> Hash of declarations solution<span></span></a>
<ul>
<li><a href="#example"><span class="toc-section-number">2.2.1</span> Example<span></span></a></li>
<li><a href="#for-the-format-of-the-output"><span class="toc-section-number">2.2.2</span> For the format of the output<span></span></a></li>
</ul></li>
</ul></li>
<li><a href="#demo"><span class="toc-section-number">3</span> Demo<span></span></a></li>
<li><a href="#summary"><span class="toc-section-number">4</span> Summary<span></span></a></li>
</ul>
</div>
<h1 data-number="1" id="abstract"><span class="header-section-number">1</span> Abstract<a href="#abstract" class="self-link"></a></h1>
<p>One of the major concerns for adopting named modules is that named modules will bring a lot dependencies altogether. So that the incremental build within modules may compile more files if we changed one of the module interfaces or the included headers. To solve/mitigate this issue, this paper presents two new compilation models for named modules with finer-grained dependency management. The demo tools needed in the compiler side are provided.</p>
<h1 data-number="2" id="proposed-solutions"><span class="header-section-number">2</span> Proposed solutions<a href="#proposed-solutions" class="self-link"></a></h1>
<p>We propose 2 potential solutions in this paper. One is based on the files used during the compilation. Another is based on the hash values of declarations used during the compilation.</p>
<p>We can find tools and the command line options used in this section in <a href="#demo">Demo</a> section.</p>
<h2 data-number="2.1" id="used-files-based-solution"><span class="header-section-number">2.1</span> Used Files based solution<a href="#used-files-based-solution" class="self-link"></a></h2>
<p>For a specific source file, we can collect used files from modules during the compilation of the source file. Then we can try to rebuild the source file if all the recorded used files doesn’t change.</p>
<h3 data-number="2.1.1" id="foo-and-bar-example"><span class="header-section-number">2.1.1</span> foo and bar example<a href="#foo-and-bar-example" class="self-link"></a></h3>
<div class="sourceCode" id="cb1"><pre class="sourceCode c++"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="co">//--- foo.h</span></span>
<span id="cb1-2"><a href="#cb1-2"></a><span class="kw">inline</span> <span class="dt">int</span> foo() {</span>
<span id="cb1-3"><a href="#cb1-3"></a>    <span class="cf">return</span> <span class="dv">43</span>;</span>
<span id="cb1-4"><a href="#cb1-4"></a>}</span>
<span id="cb1-5"><a href="#cb1-5"></a></span>
<span id="cb1-6"><a href="#cb1-6"></a><span class="co">//--- bar.h</span></span>
<span id="cb1-7"><a href="#cb1-7"></a><span class="kw">inline</span> <span class="dt">int</span> bar() {</span>
<span id="cb1-8"><a href="#cb1-8"></a>    <span class="cf">return</span> <span class="dv">43</span>;</span>
<span id="cb1-9"><a href="#cb1-9"></a>}</span>
<span id="cb1-10"><a href="#cb1-10"></a></span>
<span id="cb1-11"><a href="#cb1-11"></a><span class="co">//--- foo.cppm</span></span>
<span id="cb1-12"><a href="#cb1-12"></a><span class="kw">module</span>;</span>
<span id="cb1-13"><a href="#cb1-13"></a><span class="pp">#include </span><span class="im">&quot;foo.h&quot;</span></span>
<span id="cb1-14"><a href="#cb1-14"></a><span class="pp">#include </span><span class="im">&quot;bar.h&quot;</span></span>
<span id="cb1-15"><a href="#cb1-15"></a><span class="kw">export</span> <span class="kw">module</span> foo;</span>
<span id="cb1-16"><a href="#cb1-16"></a><span class="kw">export</span> <span class="kw">using</span> ::foo;</span>
<span id="cb1-17"><a href="#cb1-17"></a><span class="kw">export</span> <span class="kw">using</span> ::bar;</span>
<span id="cb1-18"><a href="#cb1-18"></a></span>
<span id="cb1-19"><a href="#cb1-19"></a><span class="co">//--- use.cpp</span></span>
<span id="cb1-20"><a href="#cb1-20"></a><span class="kw">import</span> foo;</span>
<span id="cb1-21"><a href="#cb1-21"></a><span class="dt">int</span> use() {</span>
<span id="cb1-22"><a href="#cb1-22"></a>    <span class="cf">return</span> bar();</span>
<span id="cb1-23"><a href="#cb1-23"></a>}</span></code></pre></div>
<p>We can compile normally <code class="sourceCode default">use.cpp</code> and get the used files from modules.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb1-1"><a href="#cb1-1"></a>$ clang++ -std=c++20 use.cpp -c -o use.o -fplugin=&lt;path/to&gt;/ClangGetUsedFilesFromModulesPlugin.so  -fplugin-arg-get_used_files_from_modules-output=used_files -fmodule-file=foo=foo.pcm</span>
<span id="cb1-2"><a href="#cb1-2"></a></span>
<span id="cb1-3"><a href="#cb1-3"></a>$ cat used_files</span>
<span id="cb1-4"><a href="#cb1-4"></a>foo.cppm</span>
<span id="cb1-5"><a href="#cb1-5"></a>bar.h</span></code></pre></div>
<p>We can find that <code class="sourceCode default">foo.h</code> is not included in the list. Since the declarations in <code class="sourceCode default">foo.h</code> doesn’t contribute to the compilation process of <code class="sourceCode default">use.cpp</code>.</p>
<p>So the build system can use the information to avoid recompiling <code class="sourceCode default">use.cpp</code> in case only <code class="sourceCode default">foo.h</code> changes.</p>
<p>Note that here the term <code class="sourceCode default">change</code> means the change in the file systems instead of in the tranditional dependency analysis. Since <code class="sourceCode default">foo.cppm</code> includes <code class="sourceCode default">foo.h</code> and <code class="sourceCode default">foo.cppm</code> will always change if <code class="sourceCode default">foo.h</code> changes in the tranditional dependency analysis.</p>
<h3 data-number="2.1.2" id="hello-world-example"><span class="header-section-number">2.1.2</span> Hello World Example<a href="#hello-world-example" class="self-link"></a></h3>
<div class="sourceCode" id="cb2"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb2-1"><a href="#cb2-1"></a>// Hello.cppm</span>
<span id="cb2-2"><a href="#cb2-2"></a>module;</span>
<span id="cb2-3"><a href="#cb2-3"></a>#include &lt;iostream&gt;</span>
<span id="cb2-4"><a href="#cb2-4"></a>export module Hello;</span>
<span id="cb2-5"><a href="#cb2-5"></a></span>
<span id="cb2-6"><a href="#cb2-6"></a>class Hello {</span>
<span id="cb2-7"><a href="#cb2-7"></a>public:</span>
<span id="cb2-8"><a href="#cb2-8"></a>    void hello() {</span>
<span id="cb2-9"><a href="#cb2-9"></a>        std::cout &lt;&lt; &quot;Hello World&quot; &lt;&lt; &quot;\n&quot;;</span>
<span id="cb2-10"><a href="#cb2-10"></a>        std::cout &lt;&lt; &quot;Hello &quot; &lt;&lt; &quot;\n&quot;;</span>
<span id="cb2-11"><a href="#cb2-11"></a>    }</span>
<span id="cb2-12"><a href="#cb2-12"></a>};</span>
<span id="cb2-13"><a href="#cb2-13"></a></span>
<span id="cb2-14"><a href="#cb2-14"></a>export void hello() {</span>
<span id="cb2-15"><a href="#cb2-15"></a>    Hello h;</span>
<span id="cb2-16"><a href="#cb2-16"></a>    h.hello();</span>
<span id="cb2-17"><a href="#cb2-17"></a>    h.hello();</span>
<span id="cb2-18"><a href="#cb2-18"></a>}</span>
<span id="cb2-19"><a href="#cb2-19"></a></span>
<span id="cb2-20"><a href="#cb2-20"></a>// Use.cpp</span>
<span id="cb2-21"><a href="#cb2-21"></a>import Hello;</span>
<span id="cb2-22"><a href="#cb2-22"></a>int main() {</span>
<span id="cb2-23"><a href="#cb2-23"></a>    hello();</span>
<span id="cb2-24"><a href="#cb2-24"></a>}</span></code></pre></div>
<p>Let’s get the used files for <code class="sourceCode default">Use.cpp</code> by:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb3-1"><a href="#cb3-1"></a>$ clang++ -std=c++20 Use.cpp -c -o Use.o -fplugin=&lt;path/to&gt;/ClangGetUsedFilesFromModulesPlugin.so  -fplugin-arg-get_used_files_from_modules-output=used_files -fmodule-file=Hello=Hello.pcm</span>
<span id="cb3-2"><a href="#cb3-2"></a></span>
<span id="cb3-3"><a href="#cb3-3"></a>$ cat used_files</span>
<span id="cb3-4"><a href="#cb3-4"></a>/usr/include/bits/types/struct_FILE.h</span>
<span id="cb3-5"><a href="#cb3-5"></a>/usr/include/bits/types/__FILE.h</span>
<span id="cb3-6"><a href="#cb3-6"></a>/usr/include/bits/types/FILE.h</span>
<span id="cb3-7"><a href="#cb3-7"></a>&lt;path/to&gt;/Hello.cppm</span></code></pre></div>
<p>Note that <code class="sourceCode default">&lt;iostream&gt;</code> is not included in the list! The reason is the declarations in <code class="sourceCode default">&lt;iostream&gt;</code> doesn’t contribute to the compilation.</p>
<p>We can verify this by converting both <code class="sourceCode default">hello()</code> and <code class="sourceCode default">Hello::hello()</code> to inline explicitly. It is necessary to convert <code class="sourceCode default">Hello::hello()</code> too since in-class member definition is no longer implicitly inline in module purview.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c++"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">module</span>;</span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="pp">#include </span><span class="im">&lt;iostream&gt;</span></span>
<span id="cb2-3"><a href="#cb2-3"></a><span class="kw">export</span> <span class="kw">module</span> Hello;</span>
<span id="cb2-4"><a href="#cb2-4"></a></span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="kw">export</span> <span class="kw">class</span> Hello {</span>
<span id="cb2-6"><a href="#cb2-6"></a><span class="kw">public</span>:</span>
<span id="cb2-7"><a href="#cb2-7"></a>    <span class="kw">inline</span> <span class="dt">void</span> hello() {</span>
<span id="cb2-8"><a href="#cb2-8"></a>        <span class="bu">std::</span>cout &lt;&lt; <span class="st">&quot;Hello World&quot;</span> &lt;&lt; <span class="st">&quot;</span><span class="sc">\n</span><span class="st">&quot;</span>;</span>
<span id="cb2-9"><a href="#cb2-9"></a>        <span class="bu">std::</span>cout &lt;&lt; <span class="st">&quot;Hello &quot;</span> &lt;&lt; <span class="st">&quot;</span><span class="sc">\n</span><span class="st">&quot;</span>;</span>
<span id="cb2-10"><a href="#cb2-10"></a>    }</span>
<span id="cb2-11"><a href="#cb2-11"></a>};</span>
<span id="cb2-12"><a href="#cb2-12"></a></span>
<span id="cb2-13"><a href="#cb2-13"></a><span class="kw">export</span> <span class="kw">inline</span> <span class="dt">int</span> hello() {</span>
<span id="cb2-14"><a href="#cb2-14"></a>    Hello h;</span>
<span id="cb2-15"><a href="#cb2-15"></a>    h.hello();</span>
<span id="cb2-16"><a href="#cb2-16"></a>    h.hello();</span>
<span id="cb2-17"><a href="#cb2-17"></a>}</span></code></pre></div>
<p>After we converted them, the output of used files becomes to:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb4-1"><a href="#cb4-1"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/uniform_int_dist.h</span>
<span id="cb4-2"><a href="#cb4-2"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/limits</span>
<span id="cb4-3"><a href="#cb4-3"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/basic_ios.tcc</span>
<span id="cb4-4"><a href="#cb4-4"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/basic_string.tcc</span>
<span id="cb4-5"><a href="#cb4-5"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_pair.h</span>
<span id="cb4-6"><a href="#cb4-6"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/cstdint</span>
<span id="cb4-7"><a href="#cb4-7"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_heap.h</span>
<span id="cb4-8"><a href="#cb4-8"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/nested_exception.h</span>
<span id="cb4-9"><a href="#cb4-9"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/ostream.tcc</span>
<span id="cb4-10"><a href="#cb4-10"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/exception.h</span>
<span id="cb4-11"><a href="#cb4-11"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/move.h</span>
<span id="cb4-12"><a href="#cb4-12"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/exception</span>
<span id="cb4-13"><a href="#cb4-13"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/backward/binders.h</span>
<span id="cb4-14"><a href="#cb4-14"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/cstdlib</span>
<span id="cb4-15"><a href="#cb4-15"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/streambuf</span>
<span id="cb4-16"><a href="#cb4-16"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/type_traits</span>
<span id="cb4-17"><a href="#cb4-17"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_algo.h</span>
<span id="cb4-18"><a href="#cb4-18"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/ios_base.h</span>
<span id="cb4-19"><a href="#cb4-19"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/string_view.tcc</span>
<span id="cb4-20"><a href="#cb4-20"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/range_access.h</span>
<span id="cb4-21"><a href="#cb4-21"></a>&lt;path/to&gt;/Hello.cppm</span>
<span id="cb4-22"><a href="#cb4-22"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/streambuf.tcc</span>
<span id="cb4-23"><a href="#cb4-23"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/ostream</span>
<span id="cb4-24"><a href="#cb4-24"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/x86_64-redhat-linux/bits/c++config.h</span>
<span id="cb4-25"><a href="#cb4-25"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/iosfwd</span>
<span id="cb4-26"><a href="#cb4-26"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/ostream_insert.h</span>
<span id="cb4-27"><a href="#cb4-27"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stringfwd.h</span>
<span id="cb4-28"><a href="#cb4-28"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/memoryfwd.h</span>
<span id="cb4-29"><a href="#cb4-29"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/iostream</span>
<span id="cb4-30"><a href="#cb4-30"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/cxxabi_init_exception.h</span>
<span id="cb4-31"><a href="#cb4-31"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/basic_ios.h</span>
<span id="cb4-32"><a href="#cb4-32"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/localefwd.h</span>
<span id="cb4-33"><a href="#cb4-33"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/x86_64-redhat-linux/bits/c++locale.h</span>
<span id="cb4-34"><a href="#cb4-34"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_iterator_base_types.h</span>
<span id="cb4-35"><a href="#cb4-35"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/char_traits.h</span>
<span id="cb4-36"><a href="#cb4-36"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_algobase.h</span>
<span id="cb4-37"><a href="#cb4-37"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/postypes.h</span>
<span id="cb4-38"><a href="#cb4-38"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/cwchar</span>
<span id="cb4-39"><a href="#cb4-39"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/exception_ptr.h</span>
<span id="cb4-40"><a href="#cb4-40"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/functexcept.h</span>
<span id="cb4-41"><a href="#cb4-41"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/cpp_type_traits.h</span>
<span id="cb4-42"><a href="#cb4-42"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/basic_string.h</span>
<span id="cb4-43"><a href="#cb4-43"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_function.h</span>
<span id="cb4-44"><a href="#cb4-44"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_iterator_base_funcs.h</span>
<span id="cb4-45"><a href="#cb4-45"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/typeinfo</span>
<span id="cb4-46"><a href="#cb4-46"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/string_view</span>
<span id="cb4-47"><a href="#cb4-47"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/hash_bytes.h</span>
<span id="cb4-48"><a href="#cb4-48"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_tempbuf.h</span>
<span id="cb4-49"><a href="#cb4-49"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/clocale</span>
<span id="cb4-50"><a href="#cb4-50"></a>/usr/include/bits/types/struct_FILE.h</span>
<span id="cb4-51"><a href="#cb4-51"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/x86_64-redhat-linux/bits/ctype_base.h</span>
<span id="cb4-52"><a href="#cb4-52"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/alloc_traits.h</span>
<span id="cb4-53"><a href="#cb4-53"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/functional_hash.h</span>
<span id="cb4-54"><a href="#cb4-54"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/locale_facets.h</span>
<span id="cb4-55"><a href="#cb4-55"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_construct.h</span>
<span id="cb4-56"><a href="#cb4-56"></a>/usr/include/bits/types/__FILE.h</span>
<span id="cb4-57"><a href="#cb4-57"></a>/usr/include/bits/types/FILE.h</span>
<span id="cb4-58"><a href="#cb4-58"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/locale_classes.tcc</span>
<span id="cb4-59"><a href="#cb4-59"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/istream</span>
<span id="cb4-60"><a href="#cb4-60"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/streambuf_iterator.h</span>
<span id="cb4-61"><a href="#cb4-61"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new</span>
<span id="cb4-62"><a href="#cb4-62"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/ptr_traits.h</span>
<span id="cb4-63"><a href="#cb4-63"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/cctype</span>
<span id="cb4-64"><a href="#cb4-64"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/stl_iterator.h</span>
<span id="cb4-65"><a href="#cb4-65"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/debug/debug.h</span>
<span id="cb4-66"><a href="#cb4-66"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/std_abs.h</span>
<span id="cb4-67"><a href="#cb4-67"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/x86_64-redhat-linux/bits/ctype_inline.h</span>
<span id="cb4-68"><a href="#cb4-68"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/cwctype</span>
<span id="cb4-69"><a href="#cb4-69"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/stdexcept</span>
<span id="cb4-70"><a href="#cb4-70"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/cstdio</span>
<span id="cb4-71"><a href="#cb4-71"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/istream.tcc</span>
<span id="cb4-72"><a href="#cb4-72"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/system_error</span>
<span id="cb4-73"><a href="#cb4-73"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/x86_64-redhat-linux/bits/error_constants.h</span>
<span id="cb4-74"><a href="#cb4-74"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/locale_facets.tcc</span>
<span id="cb4-75"><a href="#cb4-75"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/algorithmfwd.h</span>
<span id="cb4-76"><a href="#cb4-76"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/initializer_list</span>
<span id="cb4-77"><a href="#cb4-77"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/locale_classes.h</span>
<span id="cb4-78"><a href="#cb4-78"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/string</span>
<span id="cb4-79"><a href="#cb4-79"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/bits/allocator.h</span>
<span id="cb4-80"><a href="#cb4-80"></a>/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/x86_64-redhat-linux/bits/c++allocator.h</span></code></pre></div>
<p>This feature is pretty helpful if the header is a first-party header. Then we can avoid compiling <code class="sourceCode default">Use.cpp</code> if only the header changes.</p>
<p>Sadly, we still need to recompile <code class="sourceCode default">Use.cpp</code> if the implementation of <code class="sourceCode default">Hello::hello()</code> changes or the class <code class="sourceCode default">Hello</code> adds new members. Although we can workaround the issue by putting class <code class="sourceCode default">Hello</code> to a partition or even another plain text and include it here, it is not so convenient.</p>
<p>Luckily, it is possible solve the issue by another solution presented here. The hash of declarations based solution.</p>
<h2 data-number="2.2" id="hash-of-declarations-solution"><span class="header-section-number">2.2</span> Hash of declarations solution<a href="#hash-of-declarations-solution" class="self-link"></a></h2>
<p>During the compilation of a specific file, we can record the declarations used in modules. Then when the module file updates, we can query and compare these declarations. Then we can skip recompiling the file if no used declarations changes.</p>
<p>I heard the idea from Mathias Stearn for the first time.</p>
<h3 data-number="2.2.1" id="example"><span class="header-section-number">2.2.1</span> Example<a href="#example" class="self-link"></a></h3>
<div class="sourceCode" id="cb3"><pre class="sourceCode c++"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="co">/// a.cppm</span></span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="kw">export</span> <span class="kw">module</span> a;</span>
<span id="cb3-3"><a href="#cb3-3"></a></span>
<span id="cb3-4"><a href="#cb3-4"></a><span class="kw">export</span> <span class="dt">int</span> a() {</span>
<span id="cb3-5"><a href="#cb3-5"></a>    <span class="cf">return</span> <span class="dv">43</span>;</span>
<span id="cb3-6"><a href="#cb3-6"></a>}</span>
<span id="cb3-7"><a href="#cb3-7"></a></span>
<span id="cb3-8"><a href="#cb3-8"></a><span class="kw">namespace</span> nn {</span>
<span id="cb3-9"><a href="#cb3-9"></a>    <span class="kw">export</span> <span class="dt">int</span> a(<span class="dt">int</span> x, <span class="dt">int</span> y) {</span>
<span id="cb3-10"><a href="#cb3-10"></a>        <span class="cf">return</span> x + y;</span>
<span id="cb3-11"><a href="#cb3-11"></a>    }</span>
<span id="cb3-12"><a href="#cb3-12"></a>}</span>
<span id="cb3-13"><a href="#cb3-13"></a></span>
<span id="cb3-14"><a href="#cb3-14"></a><span class="kw">export</span> <span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;</span>
<span id="cb3-15"><a href="#cb3-15"></a><span class="kw">class</span> Templ {</span>
<span id="cb3-16"><a href="#cb3-16"></a><span class="kw">public</span>:</span>
<span id="cb3-17"><a href="#cb3-17"></a>    T get() { <span class="cf">return</span> T(<span class="dv">43</span>); }</span>
<span id="cb3-18"><a href="#cb3-18"></a>};</span>
<span id="cb3-19"><a href="#cb3-19"></a></span>
<span id="cb3-20"><a href="#cb3-20"></a><span class="kw">export</span> <span class="kw">class</span> C {</span>
<span id="cb3-21"><a href="#cb3-21"></a><span class="kw">public</span>:</span>
<span id="cb3-22"><a href="#cb3-22"></a>    <span class="dt">void</span> member_function() {}</span>
<span id="cb3-23"><a href="#cb3-23"></a>};</span>
<span id="cb3-24"><a href="#cb3-24"></a></span>
<span id="cb3-25"><a href="#cb3-25"></a><span class="co">// b.cpp</span></span>
<span id="cb3-26"><a href="#cb3-26"></a><span class="pp">#include </span><span class="im">&lt;iostream&gt;</span></span>
<span id="cb3-27"><a href="#cb3-27"></a><span class="kw">import</span> a;</span>
<span id="cb3-28"><a href="#cb3-28"></a></span>
<span id="cb3-29"><a href="#cb3-29"></a><span class="dt">int</span> main() {</span>
<span id="cb3-30"><a href="#cb3-30"></a>    <span class="bu">std::</span>cout &lt;&lt; a() &lt;&lt; <span class="bu">std::</span>endl;</span>
<span id="cb3-31"><a href="#cb3-31"></a>    Templ&lt;<span class="dt">int</span>&gt; t;</span>
<span id="cb3-32"><a href="#cb3-32"></a>    <span class="bu">std::</span>cout &lt;&lt; t.get() &lt;&lt; <span class="bu">std::</span>endl;</span>
<span id="cb3-33"><a href="#cb3-33"></a>}</span></code></pre></div>
<p>When compiling <code class="sourceCode default">b.cpp</code>, we can query the used decls during the compilation model by another plugin <code class="sourceCode default">ClangGetDeclsInModulesPlugin</code>:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb5-1"><a href="#cb5-1"></a>$clang++ -std=c++20 b.cpp -fmodule-file=a=a.pcm -c -o b.o -fplugin=&lt;path/to&gt;/ClangGetDeclsInModulesPlugin.so -fplugin-arg-decls_query_from_modules-output=b.json</span>
<span id="cb5-2"><a href="#cb5-2"></a></span>
<span id="cb5-3"><a href="#cb5-3"></a>$ cat b.json</span>
<span id="cb5-4"><a href="#cb5-4"></a></span>
<span id="cb5-5"><a href="#cb5-5"></a>[</span>
<span id="cb5-6"><a href="#cb5-6"></a>  {</span>
<span id="cb5-7"><a href="#cb5-7"></a>    &quot;decls&quot;: [</span>
<span id="cb5-8"><a href="#cb5-8"></a>      {</span>
<span id="cb5-9"><a href="#cb5-9"></a>        &quot;a&quot;: {</span>
<span id="cb5-10"><a href="#cb5-10"></a>          &quot;Hash&quot;: 3379170117,</span>
<span id="cb5-11"><a href="#cb5-11"></a>          &quot;col&quot;: 12,</span>
<span id="cb5-12"><a href="#cb5-12"></a>          &quot;kind&quot;: &quot;Function&quot;,</span>
<span id="cb5-13"><a href="#cb5-13"></a>          &quot;line&quot;: 3,</span>
<span id="cb5-14"><a href="#cb5-14"></a>          &quot;source File Name&quot;: &quot;/home/chuanqi.xcq/llvm-project-for-work/build/ModulesDatabase/a.cppm&quot;</span>
<span id="cb5-15"><a href="#cb5-15"></a>        }</span>
<span id="cb5-16"><a href="#cb5-16"></a>      },</span>
<span id="cb5-17"><a href="#cb5-17"></a>      {</span>
<span id="cb5-18"><a href="#cb5-18"></a>        &quot;Templ&quot;: {</span>
<span id="cb5-19"><a href="#cb5-19"></a>          &quot;Hash&quot;: 222160723,</span>
<span id="cb5-20"><a href="#cb5-20"></a>          &quot;col&quot;: 7,</span>
<span id="cb5-21"><a href="#cb5-21"></a>          &quot;kind&quot;: &quot;ClassTemplate&quot;,</span>
<span id="cb5-22"><a href="#cb5-22"></a>          &quot;line&quot;: 26,</span>
<span id="cb5-23"><a href="#cb5-23"></a>          &quot;source File Name&quot;: &quot;/home/chuanqi.xcq/llvm-project-for-work/build/ModulesDatabase/a.cppm&quot;</span>
<span id="cb5-24"><a href="#cb5-24"></a>        }</span>
<span id="cb5-25"><a href="#cb5-25"></a>      },</span>
<span id="cb5-26"><a href="#cb5-26"></a>      {</span>
<span id="cb5-27"><a href="#cb5-27"></a>        &quot;Templ::get&quot;: {</span>
<span id="cb5-28"><a href="#cb5-28"></a>          &quot;Hash&quot;: 3343854614,</span>
<span id="cb5-29"><a href="#cb5-29"></a>          &quot;col&quot;: 7,</span>
<span id="cb5-30"><a href="#cb5-30"></a>          &quot;kind&quot;: &quot;CXXMethod&quot;,</span>
<span id="cb5-31"><a href="#cb5-31"></a>          &quot;line&quot;: 28,</span>
<span id="cb5-32"><a href="#cb5-32"></a>          &quot;source File Name&quot;: &quot;/home/chuanqi.xcq/llvm-project-for-work/build/ModulesDatabase/a.cppm&quot;</span>
<span id="cb5-33"><a href="#cb5-33"></a>        }</span>
<span id="cb5-34"><a href="#cb5-34"></a>      }</span>
<span id="cb5-35"><a href="#cb5-35"></a>    ],</span>
<span id="cb5-36"><a href="#cb5-36"></a>    &quot;module&quot;: &quot;a&quot;</span>
<span id="cb5-37"><a href="#cb5-37"></a>  }</span>
<span id="cb5-38"><a href="#cb5-38"></a>]</span></code></pre></div>
<p>Then when <code class="sourceCode default">a.pcm</code> changes and we’re trying to recompile <code class="sourceCode default">b.cpp</code>, we can query these declarations in <code class="sourceCode default">a.pcm</code> by:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode default"><code class="sourceCode default"><span id="cb6-1"><a href="#cb6-1"></a>$clang-named-modules-querier a.pcm -- a nn::a Templ::get</span>
<span id="cb6-2"><a href="#cb6-2"></a>[</span>
<span id="cb6-3"><a href="#cb6-3"></a>  {</span>
<span id="cb6-4"><a href="#cb6-4"></a>    &quot;a&quot;: {</span>
<span id="cb6-5"><a href="#cb6-5"></a>      &quot;Hash&quot;: 3379170117,</span>
<span id="cb6-6"><a href="#cb6-6"></a>      &quot;col&quot;: 12,</span>
<span id="cb6-7"><a href="#cb6-7"></a>      &quot;kind&quot;: &quot;Function&quot;,</span>
<span id="cb6-8"><a href="#cb6-8"></a>      &quot;line&quot;: 3,</span>
<span id="cb6-9"><a href="#cb6-9"></a>      &quot;source File Name&quot;: &quot;&lt;path/to&gt;/a.cppm&quot;</span>
<span id="cb6-10"><a href="#cb6-10"></a>    }</span>
<span id="cb6-11"><a href="#cb6-11"></a>  },</span>
<span id="cb6-12"><a href="#cb6-12"></a>  {</span>
<span id="cb6-13"><a href="#cb6-13"></a>    &quot;nn::a&quot;: {</span>
<span id="cb6-14"><a href="#cb6-14"></a>      &quot;Hash&quot;: 1071306246,</span>
<span id="cb6-15"><a href="#cb6-15"></a>      &quot;col&quot;: 16,</span>
<span id="cb6-16"><a href="#cb6-16"></a>      &quot;kind&quot;: &quot;Function&quot;,</span>
<span id="cb6-17"><a href="#cb6-17"></a>      &quot;line&quot;: 20,</span>
<span id="cb6-18"><a href="#cb6-18"></a>      &quot;source File Name&quot;: &quot;&lt;path/to&gt;/a.cppm&quot;</span>
<span id="cb6-19"><a href="#cb6-19"></a>    }</span>
<span id="cb6-20"><a href="#cb6-20"></a>  },</span>
<span id="cb6-21"><a href="#cb6-21"></a>  {</span>
<span id="cb6-22"><a href="#cb6-22"></a>    &quot;Templ::get&quot;: {</span>
<span id="cb6-23"><a href="#cb6-23"></a>      &quot;Hash&quot;: 3343854614,</span>
<span id="cb6-24"><a href="#cb6-24"></a>      &quot;col&quot;: 7,</span>
<span id="cb6-25"><a href="#cb6-25"></a>      &quot;kind&quot;: &quot;CXXMethod&quot;,</span>
<span id="cb6-26"><a href="#cb6-26"></a>      &quot;line&quot;: 28,</span>
<span id="cb6-27"><a href="#cb6-27"></a>      &quot;source File Name&quot;: &quot;&lt;path/to&gt;/a.cppm&quot;</span>
<span id="cb6-28"><a href="#cb6-28"></a>    }</span>
<span id="cb6-29"><a href="#cb6-29"></a>  }</span>
<span id="cb6-30"><a href="#cb6-30"></a>]</span></code></pre></div>
<p>(unqualified name are treated as if they are under global namespace)</p>
<p>We can find that all these used declarations are not changed. So we’re allowed to skip the compiltion for <code class="sourceCode default">b.cpp</code>.</p>
<h3 data-number="2.2.2" id="for-the-format-of-the-output"><span class="header-section-number">2.2.2</span> For the format of the output<a href="#for-the-format-of-the-output" class="self-link"></a></h3>
<p>The format of the informations of declarations is not decided yet. This is still an open area and we can try to experiment and discuss.</p>
<p>Further more, maybe we’re possible to define DSL for programmers/build systems/static analyzers to query the informations they want. It implies that we may treat the BMIs as databases!</p>
<h1 data-number="3" id="demo"><span class="header-section-number">3</span> Demo<a href="#demo" class="self-link"></a></h1>
<p>We can find the demo to help to implement these strategies in https://github.com/llvm/llvm-project/pull/72956. These implementations are not polished. We can push it further if people are interested. Also it will be highly appreciated if build systems vendors are willing to make experiments with them.</p>
<h1 data-number="4" id="summary"><span class="header-section-number">4</span> Summary<a href="#summary" class="self-link"></a></h1>
<p>This paper presents 2 more finer-grained compilation model for named modules. To allow the build systems/users to understand what is used in the module file during the compilation. So that we may skip some unnecessary recompilations.</p>
<p>Both of the compilation model have a demo implementation in the compiler side.</p>
<p>The hash value based solution looks pretty appealing while it is hard to implement both for build systems and compilers (I believe the current implementation is not production ready). Also the cost of computing hashes and comparing a lot of declarations is a concern too. But it should still worth to give it a try.</p>
<p>The used files solution should be much more stable and easier to implement. Maybe we can choose this solution as a first step to optimize the compilation of modules.</p>
</div>
</div>
</body>
</html>
