<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/96728>96728</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [Modules] Unncessary compilations due to use of "same" lambda signatures
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:modules
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          ChuanqiXu9
      </td>
    </tr>
</table>

<pre>
    I found this when measuring compilation time with modules.

Minimal reproducer:

```
export module f;
export inline auto f() {
 return [](auto file){};
}
export inline auto g() {
    return [](auto file){};
}
```

```
import f;
void test() {
 g()(3);
}
```

And to observe the bug, we need to insert codes to https://github.com/llvm/llvm-project/blob/9253ac24aac0198371260762838758f587fa3f9d/clang/lib/CodeGen/CodeGenAction.cpp#L225-L226

```
 if (D.begin() != D.end()) {
      llvm::errs() << "Handling interesting decl:\n";
      (*D.begin())->dump();
 }
```

and let's compile the user, we will see:

```
Handling interesting decl:
FunctionDecl 0x812b200 </home/chuanqi.xcq/llvm-project-for-work/build/test_lambda/f.cppm:5:8, line:7:1> line:5:20 imported in f hidden used g '(lambda at /home/chuanqi.xcq/llvm-project-for-work/build/test_lambda/f.cppm:6:12) ()' inline
`-CompoundStmt 0x812bda8 <col:24, line:7:1>
  `-ReturnStmt 0x812bd98 <line:6:5, col:26>
    `-LambdaExpr 0x812bd70 <col:12, col:26> '(lambda at /home/chuanqi.xcq/llvm-project-for-work/build/test_lambda/f.cppm:6:12)'
 |-CXXRecordDecl 0x812b390 <col:12> col:12 imported in f hidden implicit <undeserialized declarations> class definition
      | `-DefinitionData generic lambda pass_in_registers empty standard_layout trivially_copyable trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
 |   |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
      |   |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
      | |-MoveConstructor exists simple trivial needs_implicit
      | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
      |   |-MoveAssignment exists simple trivial needs_implicit
      |   `-Destructor simple irrelevant trivial constexpr
      `-CompoundStmt 0x812bdc0 <col:25, col:26>
Handling interesting decl:
CXXMethodDecl 0x812b9f8 </home/chuanqi.xcq/llvm-project-for-work/build/test_lambda/f.cppm:6:24, col:26> col:12 imported in f hidden constexpr operator() 'auto (auto) const' inline
|-ParmVarDecl 0x812b650 <col:15, col:20> col:20 imported in f hidden file 'auto'
`-CompoundStmt 0x812bdc0 <col:25, col:26>
```

It shows that the unused function `f()` got emitted in CodeGen! It is terrible since it implies that other entities referenced in `f()` will be deserialized and maybe generated too. This is a chain reaction.

>From my debugging, the reason may be that we would find the redeclaration of the compiler generated function `__invoke` for lambdas and so that it triggers many deserilizations. The happens  in `https://github.com/llvm/llvm-project/blob/89d8df12015ac3440190d372a8d439614027dc2c/clang/lib/Serialization/ASTReader.cpp#L7585`.

I believe this happens with clang header modules too. @ilya-biryukov 

Luckily this wouldn't cause any run time effects since LLVM will "optimize" the generated IR automatically. But this is absolute not good for modules.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8V91u47oRfhr6ZmBDpmxLuvCF1163CyRAsXt6kDuDIkcWuxSpQ1JOvE9fkJJtOcmm7banQBBLFPnNzDfD-WHOyaNGXJPlJ7LcTVjna2PX27pj-g_51BWT0ojz-gtUptMCfC0dPNeooUHmOiv1EbhpWqmYl0aDlw3Cs_Q1NEZ0Ct2MJDuSbPr_j1LLhimw2FojOo6WpJvxBrJKhr_4ii-tsX6Agoqkn-7WpVZSI7DOG6gIzQktgGTDHrDoO6uht4vQvN8mFRJahF3Z7ooXnn8GfHwDDPBL2K9se3dRNlH-zdKTkQI8Ov9Gi0EvQvM0_Px74jbBhQZM6dCeEHyNUHZHQrfwjKAR41epHVoP3Ah04b32vnXBUXRP6P4ofd2VM24aQvdKnS4_09aafyD3hO5LZUpC9wVdpozTBWM8mRd5ms3pKslWNE_zbJlXyzyrWFoVgtA9V0wfA5AMB7dG4F9Q3542PATXjLctoekDpcvpA6WrD3gEWQGh-W5W4lHqC3d0TtId7GaoxYW8V34FiBalG5Ju0Fp3OZluSboFQulfmRYqBL3UHi06H54FchXOLLeaUHp1RQ8YITZ3mhBaTEn6WXRNOyxcj3zsPqYFKPSEZm64db0PO4d2cOKzVAoc4scX60Mz4o59pyPpO-QKkpd8TkuaJJEJuq9Ng8FrfZKYvfA_XgXBtDJ2-mzs9xANnVTBxyGKD4o1pWCE7qvgzcD0kqSbPCgfrhxJNxlJN3OSfr68h-80gf5moACpoYJaCoE62C3gCIRmhOY9NDAP_2MNV0Ej2kdQ775syBBXbqdb07QhQX7zjR_oEiwPdHETSKWLd0y8hEkA-Bozyvh4EY8PR1aRCbqFAW41Ot4DPES9P7-09gKQJTf5Qf-7w_830oKcS2xvp9unp6_IjRWjuEqLe0XTz3B5ft_tsmmV5NKHU50W6NBKpuQPFDGGmY21yEUgxZwDgZXUMize3cxsG5nbXb_umGdwRI1WchioaZlzB6kPFo_SebQOsGn9GZxnWjArDoqdTefBW3mSTKnzgZv2zMpwNfslUNKjZQpq5g7caOfxpbUHbXTcemjMCQ_cGwuc6X7DQWDFOuUPQbEbfb3SQeHwcRt22i6exBfpvLtKvEqJSd0drowNuCgOcqTLa1Z6MVvTnscyXEC5WXW15tAyy5rXki4Ph1f73ngg204fzQnfseaVwHsB7-EEjTexoWlQ-z9JYbiqPBL1KxrDEH2vCZbWosIT0_6tP-8wfpJ3-Og60feTxr_O_9unp0f0tRlf1KLK_4QCsLqmx3F6-jgD3OLbtGiZN_Za47PYiw09WViKe9_k7Gw7_Ruzze_MjgxcLceZaExdctPpZ8UotH8X-dek91_46N0O4IsHV5tnB75mvq_9OlbBaqjXISqGXpisEjgaD9hIPyh77azm8MWDdODRWhlylZOaI1yuAQ4CjK_RAmovfVizWKFFzXuwe0mx8SgR7tJxaFgadi6xz6rMxw7TzOC3MEdIBwx4zaQGi6zv8cbG7q1poDmDwLI7HqWOjWqw2SJzRgfkIDFqGlof0ykBlYxjStg0KgZgqrg4dE12pM-YucNB6pP5jsGgytihBrhohzO9JBmv5fEYSkHD9HmwWMkffdkJxiHUrG1ROxiI-tUeOi9ELqo5TeZLxtPFIpkXiUgzynKxSIvVfJHQTHDK3_TQ3wYnRJ0I3W--_fYVmUB76aKzZb4kq-SO8C9QopIYJwPprjbEeS7CQx0xLsNd70uySKQ6s2kp7bn7bk4whnzo-HepzsPgGDykCc08cNY5hECf7YaxEasKeUyiIRQfHn5_7IOKUGpaLxv5Awml0Y037335Gse0hnnJQ_WdwadQjC_hVTqjOo-gjYejMSJ69TKaTsQ6FUVasAmu59m8SLN0OU8m9ZqJRT5frNJFUqYJz2iS82I15xmWrEyRzydyTRO6SFZ0laSL5TyZpemSsmrO0lKIPCsLskiwYVLNgltnxh4n0rkO18Uqo_lEsRKViyM3pb3f0s2gVZgglruJXceAKLujI4tEhepyw_LSqzixPw5nljv4u9YcnWP2PB7IHYgOwxAX2DZhKKKONZHHob8JJYz5zqKbdFat_-NAjXa5MO5F005r-s8AAAD__1I_Iyc">