| Issue |
180645
|
| Summary |
[clang] no stack reuse for temporaries created without a `MaterializeTemporaryExpr`
|
| Labels |
clang:codegen,
missed-optimization
|
| Assignees |
|
| Reporter |
zygoloid
|
A [couple of testcases](https://godbolt.org/z/KrPejbhh1):
```c++
#include <string>
void g(std::string = {});
void f() {
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
g();
}
struct X {
X();
~X();
int data[32];
};
void h() {
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
X();
}
```
In both cases, the stack usage grows linearly with the number of times the body is repeated.
The problem appears to be that the logic in CodeGen for generating LLVM lifetime markers is part of the handling for `MaterializeTemporaryExpr`, but we don't create `MaterializeTemporaryExpr` nodes for the above constructs. Instead we get:
```
| | `-CXXBindTemporaryExpr <line:3:20, col:23> 'std::string':'std::basic_string<char>' (CXXTemporary 0x43009f70)
| | `-CXXConstructExpr <col:20, col:23> 'std::string':'std::basic_string<char>' 'void () noexcept(is_nothrow_default_constructible<std::allocator<char>>::value)' list
```
in the first case and
```
| `-CXXBindTemporaryExpr <col:3, col:5> 'X' (CXXTemporary 0x4300dc40)
| `-CXXTemporaryObjectExpr <col:3, col:5> 'X' 'void ()'
```
in the second case.
For the first case, we should probably create lifetime markers around the allocas we create for function parameters.
For the second case, we should probably create `MaterializeTemporaryExpr`s because [the language rules say a temporary materialization occurs here](https://eel.is/c++draft/expr.context#2.sentence-6).
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs