[libunwind] df9a23e - [libunwind] Use `_dl_find_object` if available

2022-08-09 Thread Adrian Vogelsgesang via cfe-commits

Author: Adrian Vogelsgesang
Date: 2022-08-09T16:19:13-07:00
New Revision: df9a23e2feda18f0308b6d4dbd591ebe6b605aa4

URL: 
https://github.com/llvm/llvm-project/commit/df9a23e2feda18f0308b6d4dbd591ebe6b605aa4
DIFF: 
https://github.com/llvm/llvm-project/commit/df9a23e2feda18f0308b6d4dbd591ebe6b605aa4.diff

LOG: [libunwind] Use `_dl_find_object` if available

As shown in P2544R0 [1] and the accompanying benchmark [2], the
current unwinding logic does not scale for multi-threaded programs.
This is because `dl_iterate_phdr` takes a global lock.

glibc 2.35 added `_dl_find_object` which directly returns the unwind
info for a given target address. `_dl_find_object` is fully lock-free
and hence allows parallel exception unwinding on multiple threads.

With this commit, libunwind now takes advantage of `_dl_find_object`.
Thereby, this commit improves libunwind's performance on benchmark [2]
for unwinding exception on 20 threads from 1103ms to 78ms.
(measured on Intel Xeon Silver 4114 with 20 physical cores)

[1] https://isocpp.org/files/papers/P2544R0.html
[2] https://github.com/neumannt/exceptionperformance

Detailed performance numbers from the benchmark:

Before:
> Testing unwinding performance: sqrt computation with occasional errors
>
> testing baseline using 1 2 4 8 16 20 threads
> failure rate 0%: 34 35 34 35 35 36
> testing exceptions using 1 2 4 8 16 20 threads
> failure rate 0%: 16 32 33 34 35 36
> failure rate 0.1%: 16 32 34 36 35 36
> failure rate 1%: 20 40 40 43 90 113
> failure rate 10%: 59 92 140 304 880 1103
> [...]
>
> Testing invocation overhead: recursive fib with occasional errors
>
> testing exceptions using 1 2 4 8 16 20 threads
> failure rate 0%: 19 32 37 38 39 36
> failure rate 0.1%: 22 32 40 40 39 34
> failure rate 1%: 20 28 38 39 48 40
> failure rate 10%: 25 39 44 50 92 113

After:
> Testing unwinding performance: sqrt computation with occasional errors
>
> testing baseline using 1 2 4 8 16 20 threads
> failure rate 0%: 19 30 35 38 39 35
> testing baseline using 1 2 4 8 16 20 threads
> failure rate 0%: 32 35 33 34 34 36
> testing exceptions using 1 2 4 8 16 20 threads
> failure rate 0%: 16 35 33 37 35 35
> failure rate 0.1%: 16 32 36 33 34 37
> failure rate 1%: 21 37 39 40 40 41
> failure rate 10%: 72 75 76 80 80 78
> [...]
>
> Testing invocation overhead: recursive fib with occasional errors
>
> testing baseline using 1 2 4 8 16 20 threads
> failure rate 0%: 18 35 37 34 38 37
> testing exceptions using 1 2 4 8 16 20 threads
> failure rate 0%: 19 33 40 40 41 39
> failure rate 0.1%: 21 33 39 38 39 38
> failure rate 1%: 20 36 39 40 41 40
> failure rate 10%: 25 45 41 42 44 43

Differential Revision: https://reviews.llvm.org/D130668

Added: 


Modified: 
libunwind/src/AddressSpace.hpp

Removed: 




diff  --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp
index 36c9f5a9e36f9..f1ba94ed732e3 100644
--- a/libunwind/src/AddressSpace.hpp
+++ b/libunwind/src/AddressSpace.hpp
@@ -601,6 +601,61 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t 
targetAddr,
   if (info.arm_section && info.arm_section_length)
 return true;
 #elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
+  // Use DLFO_STRUCT_HAS_EH_DBASE to determine the existence of
+  // `_dl_find_object`. Use _LIBUNWIND_SUPPORT_DWARF_INDEX, because libunwind
+  // support for _dl_find_object on other unwind formats is not implemented,
+  // yet.
+#if defined(DLFO_STRUCT_HAS_EH_DBASE) & defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
+  // We expect to run on a platform which does not use a base address for
+  // exception information.
+#if DLFO_STRUCT_HAS_EH_DBASE
+#error dlfo_eh_dbase is not supported for DWARF-based unwinding
+#endif
+  // We expect `_dl_find_object` to return PT_GNU_EH_FRAME.
+#if DLFO_EH_SEGMENT_TYPE != PT_GNU_EH_FRAME
+#error _dl_find_object retrieves an unexpected section type
+#endif
+  // We look-up `dl_find_object` dynamically at runtime to ensure backwards
+  // compatibility with earlier version of glibc not yet providing it. On older
+  // systems, we gracefully fallback to `dl_iterate_phdr`. Cache the pointer
+  // so we only look it up once. Do manual lock to avoid _cxa_guard_acquire.
+  static decltype(_dl_find_object) *dlFindObject;
+  static bool dlFindObjectChecked = false;
+  if (!dlFindObjectChecked) {
+dlFindObject = reinterpret_cast(
+dlsym(RTLD_DEFAULT, "_dl_find_object"));
+dlFindObjectChecked = true;
+  }
+  // Try to find the unwind info using `dl_find_object`
+  dl_find_object findResult;
+  if (dlFindObject && dlFindObject((void *)targetAddr, &findResult) == 0) {
+if (findResult.dlfo_eh_frame == nullptr) {
+  // Found an entry for `targetAddr`, but there is no unwind info.
+  return false;
+}
+info.dso_base = reinterpret_cast(findResult.dlfo_map_start);
+info.text_segment_length = static_cast(
+(char *)findResult.dlfo_map_end - (char *)findRes

[clang] 9138900 - [LLDB] Add data formatter for std::coroutine_handle

2022-08-24 Thread Adrian Vogelsgesang via cfe-commits

Author: Adrian Vogelsgesang
Date: 2022-08-24T14:40:53-07:00
New Revision: 91389000abe8ef5d06d98cbbefd3fa03ac7e4480

URL: 
https://github.com/llvm/llvm-project/commit/91389000abe8ef5d06d98cbbefd3fa03ac7e4480
DIFF: 
https://github.com/llvm/llvm-project/commit/91389000abe8ef5d06d98cbbefd3fa03ac7e4480.diff

LOG: [LLDB] Add data formatter for std::coroutine_handle

This patch adds a formatter for `std::coroutine_handle`, both for libc++
and libstdc++. For the type-erased `coroutine_handle<>`, it shows the
`resume` and `destroy` function pointers. For a non-type-erased
`coroutine_handle` it also shows the `promise` value.

With this change, executing the `v t` command on the example from
https://clang.llvm.org/docs/DebuggingCoroutines.html now outputs

```
(task) t = {
  handle = coro frame = 0xb2a0 {
resume = 0x5a10 (a.out`coro_task(int, int) at 
llvm-example.cpp:36)
destroy = 0x6090 (a.out`coro_task(int, int) at 
llvm-example.cpp:36)
  }
}
```

instead of just

```
(task) t = {
  handle = {
__handle_ = 0xb2a0
  }
}
```

Note, how the symbols for the `resume` and `destroy` function pointer
reveal which coroutine is stored inside the `std::coroutine_handle`.
A follow-up commit will use this fact to infer the coroutine's promise
type and the representation of its internal coroutine state based on
the `resume` and `destroy` pointers.

The same formatter is used for both libc++ and libstdc++. It would
also work for MSVC's standard library, however it is not registered
for MSVC, given that lldb does not provide pretty printers for other
MSVC types, either.

The formatter is in a newly added  `Coroutines.{h,cpp}` file because there
does not seem to be an already existing place where we could share
formatters across libc++ and libstdc++. Also, I expect this code to grow
as we improve debugging experience for coroutines further.

**Testing**

* Added API test

Differential Revision: https://reviews.llvm.org/D132415

Added: 
lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
lldb/source/Plugins/Language/CPlusPlus/Coroutines.h

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/Makefile

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py

lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/main.cpp

Modified: 
clang/docs/tools/clang-formatted-files.txt
lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/packages/Python/lldbsuite/test/lldbutil.py
lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Removed: 




diff  --git a/clang/docs/tools/clang-formatted-files.txt 
b/clang/docs/tools/clang-formatted-files.txt
index f89e19ca7cd3a..c49acfaec58aa 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -4180,6 +4180,8 @@ 
lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
 lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h
 lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
 lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h
+lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+lldb/source/Plugins/Language/CPlusPlus/Coroutines.h
 lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
 lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
 lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h

diff  --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py 
b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 69bb5ac5629e4..1c090395e6c4c 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -292,8 +292,12 @@ def check_value(self, test_base, val, error_msg=None):
 test_base.assertEqual(self.expect_type, val.GetDisplayTypeName(),
   this_error_msg)
 if self.expect_summary:
-test_base.assertEqual(self.expect_summary, val.GetSummary(),
-  this_error_msg)
+if isinstance(self.expect_summary, re.Pattern):
+test_base.assertRegex(val.GetSummary(), self.expect_summary,
+  this_error_msg)
+else:
+test_base.assertEqual(self.expect_summary, val.GetSummary(),
+  this_error_msg)
 if self.children is not None:
 self.check_value_children(test_base, val, error_msg)
 

diff  --git a/lldb/packages/Python/lldbsuite/test/lldbutil.py 
b/lldb/packages/Python/lldbsuite/test/lldbutil.py
index 8bd49c742cb04..7e64afb3639cd 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbutil.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbutil.py
@@ -988,6 +988,21 @@ def continue_to_breakpoin

[libunwind] c9cffdd - [libunwind] Fix usage of `_dl_find_object` on 32-bit x86

2022-09-16 Thread Adrian Vogelsgesang via cfe-commits

Author: Adrian Vogelsgesang
Date: 2022-09-16T06:29:49-07:00
New Revision: c9cffdde393f646acf62d6160e7fa6613e038508

URL: 
https://github.com/llvm/llvm-project/commit/c9cffdde393f646acf62d6160e7fa6613e038508
DIFF: 
https://github.com/llvm/llvm-project/commit/c9cffdde393f646acf62d6160e7fa6613e038508.diff

LOG: [libunwind] Fix usage of `_dl_find_object` on 32-bit x86

On 32-bit x86, `_dl_find_object` also returns a `dlfo_eh_dbase` address.
So far, compiling against a version of `_dl_find_object` which returns a
`dlfo_eh_dbase` was blocked using a `#if` + `#error`. This commit now
removes this compile time assertion and simply ignores the returned
`dlfo_eh_dbase`. All test cases are passing on a 32-bit build now.

According to 
https://www.gnu.org/software/libc/manual/html_node/Dynamic-Linker-Introspection.html,
`dlfo_eh_dbase` should be the base address for all DW_EH_PE_datarel
relocations. However, glibc/elf/dl-find_object.h says that eh_dbase
is the relocated DT_PLTGOT value. I don't understand how those two
statements fit together, but to fix 32-bit x86, ignoring `dlfo_eh_dbase`
seems to be good enough.

Fixes #57733

Differential Revision: https://reviews.llvm.org/D133846

Added: 


Modified: 
libunwind/src/AddressSpace.hpp

Removed: 




diff  --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp
index 315289cd4211b..b0135b0c0519c 100644
--- a/libunwind/src/AddressSpace.hpp
+++ b/libunwind/src/AddressSpace.hpp
@@ -584,11 +584,6 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t 
targetAddr,
   // support for _dl_find_object on other unwind formats is not implemented,
   // yet.
 #if defined(DLFO_STRUCT_HAS_EH_DBASE) & defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
-  // We expect to run on a platform which does not use a base address for
-  // exception information.
-#if DLFO_STRUCT_HAS_EH_DBASE
-#error dlfo_eh_dbase is not supported for DWARF-based unwinding
-#endif
   // We expect `_dl_find_object` to return PT_GNU_EH_FRAME.
 #if DLFO_EH_SEGMENT_TYPE != PT_GNU_EH_FRAME
 #error _dl_find_object retrieves an unexpected section type



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


[clang-tools-extra] fda7778 - [clang-tidy] Update tests to include C++23 and C++26

2023-08-07 Thread Adrian Vogelsgesang via cfe-commits

Author: Adrian Vogelsgesang
Date: 2023-08-07T21:25:22Z
New Revision: fda777849b0088ba83e28683c53c5c8321ef2558

URL: 
https://github.com/llvm/llvm-project/commit/fda777849b0088ba83e28683c53c5c8321ef2558
DIFF: 
https://github.com/llvm/llvm-project/commit/fda777849b0088ba83e28683c53c5c8321ef2558.diff

LOG: [clang-tidy] Update tests to include C++23 and C++26

This commit changes the `c++xx-or-later` definitions to also include
C++23 and the upcoming C++26.
`readability/container-contains.cpp` to also test newer C++ versions.

Also, this commit adjusts a couple of test cases slightly:
* `container-contains.cpp` now also tests newer C++ versions.
  Restricting it to C++20 was an oversight of mine when originally
  writing this check.
* `unconventional-assign-operator.cpp`: The `return rhs` raised
  a "non-const lvalue reference to type 'BadReturnStatement' cannot
  bind to a temporary" error in C++23. The issue is circumenvented
  by writing `return *&rhs`.
* `const-correctness-values.cpp` was also running into the same error
  in C++23. The troublesome test cases were moved to a separate file.

Differential Revision: https://reviews.llvm.org/D157246

Added: 

clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values-before-cxx23.cpp

Modified: 
clang-tools-extra/test/clang-tidy/check_clang_tidy.py
clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp

clang-tools-extra/test/clang-tidy/checkers/misc/unconventional-assign-operator.cpp

clang-tools-extra/test/clang-tidy/checkers/readability/container-contains.cpp

Removed: 




diff  --git a/clang-tools-extra/test/clang-tidy/check_clang_tidy.py 
b/clang-tools-extra/test/clang-tidy/check_clang_tidy.py
index a78996a0fce3b0..53ffca0bad8d06 100755
--- a/clang-tools-extra/test/clang-tidy/check_clang_tidy.py
+++ b/clang-tools-extra/test/clang-tidy/check_clang_tidy.py
@@ -265,15 +265,17 @@ def run(self):
 
 def expand_std(std):
 if std == "c++98-or-later":
-return ["c++98", "c++11", "c++14", "c++17", "c++20"]
+return ["c++98", "c++11", "c++14", "c++17", "c++20", "c++23", "c++2c"]
 if std == "c++11-or-later":
-return ["c++11", "c++14", "c++17", "c++20"]
+return ["c++11", "c++14", "c++17", "c++20", "c++23", "c++2c"]
 if std == "c++14-or-later":
-return ["c++14", "c++17", "c++20"]
+return ["c++14", "c++17", "c++20", "c++23", "c++2c"]
 if std == "c++17-or-later":
-return ["c++17", "c++20"]
+return ["c++17", "c++20", "c++23", "c++2c"]
 if std == "c++20-or-later":
-return ["c++20"]
+return ["c++20", "c++23", "c++2c"]
+if std == "c++23-or-later":
+return ["c++23", "c++2c"]
 return [std]
 
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values-before-cxx23.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values-before-cxx23.cpp
new file mode 100644
index 00..3547ec080911eb
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values-before-cxx23.cpp
@@ -0,0 +1,20 @@
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17,c++20 %s 
misc-const-correctness %t -- \
+// RUN:   -config="{CheckOptions: {\
+// RUN: misc-const-correctness.TransformValues: true, \
+// RUN: misc-const-correctness.WarnPointersAsValues: false, \
+// RUN: misc-const-correctness.TransformPointersAsValues: false \
+// RUN:   }}" -- -fno-delayed-template-parsing
+
+
+double &non_const_ref_return() {
+  double p_local0 = 0.0;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 
'double' can be declared 'const'
+  // CHECK-FIXES: double const p_local0
+  double np_local0 = 42.42;
+  return np_local0;
+}
+
+double *&return_non_const_pointer_ref() {
+  double *np_local0 = nullptr;
+  return np_local0;
+}

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
index 88f40462003e88..186e3cf5a179b2 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp
@@ -1,9 +1,9 @@
 // RUN: %check_clang_tidy %s misc-const-correctness %t -- \
 // RUN:   -config="{CheckOptions: {\
-// RUN:   misc-const-correctness.TransformValues: true, \
-// RUN:   misc-const-correctness.WarnPointersAsValues: false, \
-// RUN:   misc-const-correctness.TransformPointersAsValues: false} \
-// RUN:   }" -- -fno-delayed-template-parsing
+// RUN: misc-const-correctness.TransformValues: true, \
+// RUN: misc-const-correctness.WarnPointersAsValues: false, \
+// RUN: misc-const-correctness.TransformPointersAsValues: false \
+// RUN:   }}" -- -fno-delayed-template-parsing
 
 // --- Provide test samples for primitive builtins

[clang] [llvm] [Clang][Coroutines] Introducing the `[[clang::coro_inplace_task]]` attribute (PR #94693)

2024-06-17 Thread Adrian Vogelsgesang via cfe-commits


@@ -0,0 +1,84 @@
+// This file tests the coro_structured_concurrency attribute semantics. 
+// RUN: %clang_cc1 -std=c++20 -disable-llvm-passes -emit-llvm %s -o - | 
FileCheck %s
+
+#include "Inputs/coroutine.h"
+#include "Inputs/utility.h"
+
+template 
+struct [[clang::coro_structured_concurrency]] Task {

vogelsgesang wrote:

Afaict, this particular `Task` can also be annotated using 
`coro_only_destroy_when_complete`?

I guess many libraries would want to use both `coro_structured_concurrency` / 
`coro_inplace_task` and `coro_only_destroy_when_complete`. Do those 
optimizations interact well with each other? Does it make sense to add a test 
case which tests both attributes together?

https://github.com/llvm/llvm-project/pull/94693
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][Coroutines] Introducing the `[[clang::coro_inplace_task]]` attribute (PR #94693)

2024-06-18 Thread Adrian Vogelsgesang via cfe-commits


@@ -0,0 +1,84 @@
+// This file tests the coro_structured_concurrency attribute semantics. 
+// RUN: %clang_cc1 -std=c++20 -disable-llvm-passes -emit-llvm %s -o - | 
FileCheck %s
+
+#include "Inputs/coroutine.h"
+#include "Inputs/utility.h"
+
+template 
+struct [[clang::coro_structured_concurrency]] Task {

vogelsgesang wrote:

> through a handle you smuggled with the task, which this type does not allow 
> to do

that's the point I am getting at. Most `task` types do not allow smuggling 
handles out of the wrappers types. As such, I expect that many task types would 
be annotated with both `coro_structured_concurrency` / `coro_inplace_task` and 
`coro_only_destroy_when_complete`. I guess we should have a test case that both 
attributes interact nicely with each other?

https://github.com/llvm/llvm-project/pull/94693
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][Coroutines] Introducing the `[[clang::coro_inplace_task]]` attribute (PR #94693)

2024-06-18 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/94693
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][Coroutines] Introducing the `[[clang::coro_inplace_task]]` attribute (PR #94693)

2024-06-18 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/94693
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_await_elidable]] (PR #99282)

2024-07-19 Thread Adrian Vogelsgesang via cfe-commits


@@ -825,6 +826,32 @@ ExprResult Sema::BuildOperatorCoawaitLookupExpr(Scope *S, 
SourceLocation Loc) {
   return CoawaitOp;
 }
 
+static bool isAttributedCoroInplaceTask(const QualType &QT) {
+  auto *Record = QT->getAsCXXRecordDecl();
+  return Record && Record->hasAttr();
+}
+
+static bool isCoroInplaceCall(Expr *Operand) {
+  if (!Operand->isPRValue()) {
+return false;
+  }
+
+  return isAttributedCoroInplaceTask(Operand->getType());
+}
+
+template 
+DesiredExpr *getExprWrappedByTemporary(Expr *E) {

vogelsgesang wrote:

seems unused?

https://github.com/llvm/llvm-project/pull/99282
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_await_elidable]] (PR #99282)

2024-07-19 Thread Adrian Vogelsgesang via cfe-commits


@@ -8108,6 +8108,24 @@ but do not pass them to the underlying coroutine or pass 
them by value.
 }];
 }
 
+def CoroAwaitElidableDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The ``[[clang::coro_await_elidable]]`` is a class attribute which can be 
applied
+to a coroutine return type.
+
+When a coroutine function that returns such a type calls another coroutine 
function,
+the compiler performs heap allocation elision when the following conditions 
are all met:
+- callee coroutine function returns a type that is annotated with 
``[[clang::coro_await_elidable]]``.
+- In caller coroutine, the return value of the callee is a prvalue or an 
xvalue, and
+- The temporary expression containing the callee coroutine object is 
immediately co_awaited.
+
+The behavior is undefined if any of the following condition was met:
+- the caller coroutine is destroyed earlier than the callee coroutine.

vogelsgesang wrote:

Are we expecting this list to contain more than one entry soon? Otherwise, I 
think we can simplify this

```suggestion
The behavior is undefined if the caller coroutine is destroyed earlier than the 
callee coroutine.
```

https://github.com/llvm/llvm-project/pull/99282
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_await_elidable]] (PR #99282)

2024-07-19 Thread Adrian Vogelsgesang via cfe-commits


@@ -8108,6 +8108,24 @@ but do not pass them to the underlying coroutine or pass 
them by value.
 }];
 }
 
+def CoroAwaitElidableDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The ``[[clang::coro_await_elidable]]`` is a class attribute which can be 
applied
+to a coroutine return type.
+
+When a coroutine function that returns such a type calls another coroutine 
function,
+the compiler performs heap allocation elision when the following conditions 
are all met:
+- callee coroutine function returns a type that is annotated with 
``[[clang::coro_await_elidable]]``.
+- In caller coroutine, the return value of the callee is a prvalue or an 
xvalue, and
+- The temporary expression containing the callee coroutine object is 
immediately co_awaited.

vogelsgesang wrote:

```suggestion
- The callee coroutine function returns a type that is annotated with 
``[[clang::coro_await_elidable]]``.
- In the caller coroutine, the return value of the callee is a prvalue or an 
xvalue.
- The temporary expression containing the callee coroutine object is 
immediately co_awaited.
```

(why remove the "and" in the 2nd bullet point? For consistency. Because 
otherwise, the 1st bullet point is also a self-contained sentence with a dot at 
its end)

https://github.com/llvm/llvm-project/pull/99282
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang] C++20 Coroutines: Introduce Frontend Attribute [[clang::coro_await_elidable]] (PR #99282)

2024-07-22 Thread Adrian Vogelsgesang via cfe-commits


@@ -1217,6 +1217,14 @@ def CoroDisableLifetimeBound : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def CoroAwaitElidable : InheritableAttr {

vogelsgesang wrote:

does this also warrant an entry in `clang/docs/ReleaseNotes.rst`?

https://github.com/llvm/llvm-project/pull/99282
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Implement C++26 Attributes for Structured Bindings (P0609R3) (PR #89906)

2024-04-29 Thread Adrian Vogelsgesang via cfe-commits


@@ -187,7 +187,7 @@ C++2c implementation status
  
   Trivial infinite loops are not Undefined Behavior
   https://wg21.link/P2809R3";>P2809R3 (DR)
-  No
+  Clang 19

vogelsgesang wrote:

the wrong paper was marked as implemented

https://github.com/llvm/llvm-project/pull/89906
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Address post commit feedbacks in #89906 (PR #90495)

2024-04-29 Thread Adrian Vogelsgesang via cfe-commits


@@ -177,7 +177,7 @@ C++2c implementation status
  
   Attributes for Structured Bindings
   https://wg21.link/P0609R3";>P0609R3
-  No
+  Clang 19

vogelsgesang wrote:

none -> unreleased

But maybe just fix this together when landing #90066...

https://github.com/llvm/llvm-project/pull/90495
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Address post commit feedbacks in #89906 (PR #90495)

2024-04-29 Thread Adrian Vogelsgesang via cfe-commits


@@ -187,7 +187,7 @@ C++2c implementation status
  
   Trivial infinite loops are not Undefined Behavior
   https://wg21.link/P2809R3";>P2809R3 (DR)
-  Clang 19
+  No

vogelsgesang wrote:

unreleased -> none

https://github.com/llvm/llvm-project/pull/90495
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Implement C++26 P2748R5 "Disallow Binding a Returned Glvalue to a Temporary" (PR #89942)

2024-04-30 Thread Adrian Vogelsgesang via cfe-commits


@@ -167,7 +167,7 @@ C++2c implementation status
  
   Disallow Binding a Returned Glvalue to a Temporary
   https://wg21.link/P2748R5";>P2748R5
-  No
+  Clang 19

vogelsgesang wrote:

Should be `class="unreleased"` instead of `class="full"`

https://github.com/llvm/llvm-project/pull/89942
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Implement C++26 P2748R5 "Disallow Binding a Returned Glvalue to a Temporary" (PR #89942)

2024-04-30 Thread Adrian Vogelsgesang via cfe-commits


@@ -167,7 +167,7 @@ C++2c implementation status
  
   Disallow Binding a Returned Glvalue to a Temporary
   https://wg21.link/P2748R5";>P2748R5
-  No
+  Clang 19

vogelsgesang wrote:

Ah, I just saw this was already fixed in the meantime - nevermind 🙂 

https://github.com/llvm/llvm-project/pull/89942
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Introduce -defer-thinlto-prelink-coro-split that skips Coro passes in ThinLTO pre-link pipeline (PR #107153)

2024-09-13 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

My 2cts:

I think it would be best for clang-users, if HALO / coroutine optimizations 
work out-of-the-box in as many cases as possible.

Unfortunately, it seems we have an "either-or" decision here. Either, the 
"thin-lto + HALO" work out-of-the-box or the llc-code-generation works 
out-of-the-box. Afaict, thin-lto is the more common use case compared to 
calling llc directly. At least there seems to be documentation for 
[thin-lto](https://clang.llvm.org/docs/ThinLTO.html) but not for the llc use 
case?

As a normal C++ programmer and clang user, I doubt that I would ever find the 
`-defer-thinlto-prelink-coro-split` setting, in particular given that this 
commit does not add any documentation for it. As such, I would be stuck without 
cross-TU link-time HALO optimizations. At the same time, I would expect people 
which use custom llc-based compilation to be more experienced with setting up 
an LLVM toolchain, and more enabled to figure out about the existince of the 
flag.

All of this is to say: I think the default should be flipped. **By default, 
coro-split should be deferred to post-link** (such that the more common 
thin-lto setup can apply HALO out-of-the-box). More advanced users, who call 
llc directly, can still use a flag to defer coro-split.

In addition, some documentation would be great (e.g. mentioning the newly 
introduced flag in https://clang.llvm.org/docs/ThinLTO.html and 
https://llvm.org/docs/Coroutines.html

https://github.com/llvm/llvm-project/pull/107153
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] Introduce -defer-thinlto-prelink-coro-split that skips Coro passes in ThinLTO pre-link pipeline (PR #107153)

2024-09-13 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

> Unfortunately, it seems we have an "either-or" decision here

Although... Is this even an either-or decision?

Could we add coro-split to the llc unconditionally, also for non-thin-lto 
pipelines? Afaict, coro-split is a no-op pass if coroutines were already split 
previously. Hence, codegen would simply work, even if a thin-lto-prelink 
pipeline is combined with a non-thin-lto post-link step.

Doing so, I think we wouldn't need to introduce a flag at all?

https://github.com/llvm/llvm-project/pull/107153
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -249,7 +249,10 @@ Attribute Changes in Clang
   (#GH106864)
 
 - Introduced a new attribute ``[[clang::coro_await_elidable]]`` on coroutine 
return types
-  to express elideability at call sites where the coroutine is co_awaited as a 
prvalue.
+  to express elideability at call sites where the coroutine is invoked under a 
safe elide context.
+
+- Introduced a new attribute ``[[clang::coro_must_await]]`` on function 
parameters to

vogelsgesang wrote:

What do you think about `[[clang::coro_await_elideable_argument]]`? I would 
slightly prefer this over `[[clang::coro_elideable_await_argument]]` because it 
is more similar to its sibling argument `[[clang::coro_await_elideable]]`, and 
the duality between the two arguments becomes more obvious already from their 
names.

I think we should particularly try to avoid any name with `must` in its name. 
To me, `must` expresses a guarantee given by the compiler to the programmer 
(such as for the `[[musttail]]` attribute which will fail compilation in case 
the call cannot be tail-called), enforced by the compiler. However, this 
attribute behaves the other way around: It expresses a guarantee given by the 
programmer to the compiler, the compiler does nothing to check or enforce the 
correctness of it.

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -8281,8 +8288,62 @@ Example:
 co_await t;
   }
 
-The behavior is undefined if the caller coroutine is destroyed earlier than the
-callee coroutine.
+Such elision replaces the heap allocated activation frame of the callee 
coroutine
+with a local variable within the enclosing braces in the caller's stack frame.
+The local variable, like other variables in coroutines, may be collected into 
the
+coroutine frame, which may be allocated on the heap. The behavior is undefined
+if the caller coroutine is destroyed earlier than the callee coroutine.
+
+}];
+}
+
+def CoroMustAwaitDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+
+The ``[[clang::coro_must_await]]`` is a function parameter attribute. It works
+in conjunction with ``[[clang::coro_await_elidable]]`` to propagate a safe 
elide
+context to a parameter or parameter pack if the function is called under a safe
+elide context.
+
+This is sometimes necessary on utility functions whose role is to compose or
+modify the behavior of a callee coroutine.

vogelsgesang wrote:

```suggestion
This is sometimes necessary on utility functions used to compose or
modify the behavior of a callee coroutine.
```

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -8261,12 +8261,19 @@ def CoroAwaitElidableDoc : Documentation {
 The ``[[clang::coro_await_elidable]]`` is a class attribute which can be 
applied
 to a coroutine return type.
 
-When a coroutine function that returns such a type calls another coroutine 
function,
-the compiler performs heap allocation elision when the call to the coroutine 
function
-is immediately co_awaited as a prvalue. In this case, the coroutine frame for 
the
-callee will be a local variable within the enclosing braces in the caller's 
stack
-frame. And the local variable, like other variables in coroutines, may be 
collected
-into the coroutine frame, which may be allocated on the heap.
+When a coroutine function returns such a type, a direct call expression therein
+that returns a prvalue of a type attributed ``[[clang::coro_await_elidable]]``
+is said to be under a safe elide context if one of the following is true:

vogelsgesang wrote:

> When a coroutine function returns such a type, a direct call expression 
> therein that returns a prvalue of a type attributed 
> ``[[clang::coro_await_elidable]]`` [...]

If I am reading the code correctly, it is not actually a requirement that the 
containing / callee coroutine itself is also annotated as 
`coro_await_elidable`. Only the called coroutine needs to be annotated as 
`coro_await_elidable`.

I.e., we would also apply HALO for something like

```
  class [[clang::coro_await_elidable]] ElidableTask { ... };
  class NonElidableTask { ... };

  ElidableTask foo();
  NonElidableTask bar() {
co_await foo(); // foo()'s coroutine frame on this line is elidable
  }
```

Or did I misread the code?

Assuming I understood code correctly, I would propose something like

```
A call to a coroutine function returning such a type is said to be safe-to-elide
if one of the following is true:
- it is the immediate right-hand side operand to a co_await expression.
- it is an argument to a [[clang::coro_must_await]] parameter or parameter pack
   of another safe-to-elide function call.

Do note that the safe-to-elide context applies only to the call expression 
itself,
and the context does not transitively include any of its subexpressions unless
``[[clang::coro_must_await]]`` is used to opt-in to transivitely applying 
safe-to-elide.

The compiler performs heap allocation elision on call expressions on 
safe-to-elide
calls, if the callee is a coroutine.
```

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -8281,8 +8288,62 @@ Example:
 co_await t;
   }
 
-The behavior is undefined if the caller coroutine is destroyed earlier than the
-callee coroutine.
+Such elision replaces the heap allocated activation frame of the callee 
coroutine
+with a local variable within the enclosing braces in the caller's stack frame.
+The local variable, like other variables in coroutines, may be collected into 
the
+coroutine frame, which may be allocated on the heap. The behavior is undefined
+if the caller coroutine is destroyed earlier than the callee coroutine.
+
+}];
+}
+
+def CoroMustAwaitDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+
+The ``[[clang::coro_must_await]]`` is a function parameter attribute. It works
+in conjunction with ``[[clang::coro_await_elidable]]`` to propagate a safe 
elide
+context to a parameter or parameter pack if the function is called under a safe
+elide context.
+
+This is sometimes necessary on utility functions whose role is to compose or
+modify the behavior of a callee coroutine.
+
+Example:
+
+.. code-block:: c++
+
+  template 
+  class [[clang::coro_await_elidable]] Task { ... };
+
+  template 
+  class [[clang::coro_await_elidable]] WhenAll { ... };
+
+  // `when_all` is a utility function that compose coroutines. It does not need

vogelsgesang wrote:

```suggestion
  // `when_all` is a utility function that composes coroutines. It does not need
```

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -8281,8 +8288,62 @@ Example:
 co_await t;
   }
 
-The behavior is undefined if the caller coroutine is destroyed earlier than the
-callee coroutine.
+Such elision replaces the heap allocated activation frame of the callee 
coroutine
+with a local variable within the enclosing braces in the caller's stack frame.
+The local variable, like other variables in coroutines, may be collected into 
the
+coroutine frame, which may be allocated on the heap. The behavior is undefined
+if the caller coroutine is destroyed earlier than the callee coroutine.
+
+}];
+}
+
+def CoroMustAwaitDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+
+The ``[[clang::coro_must_await]]`` is a function parameter attribute. It works
+in conjunction with ``[[clang::coro_await_elidable]]`` to propagate a safe 
elide
+context to a parameter or parameter pack if the function is called under a safe
+elide context.
+
+This is sometimes necessary on utility functions whose role is to compose or
+modify the behavior of a callee coroutine.
+
+Example:
+
+.. code-block:: c++
+
+  template 
+  class [[clang::coro_await_elidable]] Task { ... };
+
+  template 
+  class [[clang::coro_await_elidable]] WhenAll { ... };
+
+  // `when_all` is a utility function that compose coroutines. It does not need
+  // to be a coroutine to propagate.
+  template 
+  WhenAll when_all([[clang::coro_must_await]] Task tasks...);
+
+  Task foo();
+  Task bar();
+  Task example1() {
+// `when_all``, `foo``, and `bar` are all elide safe because `when_all` is
+// under a safe elide context and propagated such contexts to foo and bar.

vogelsgesang wrote:

```suggestion
// under a safe elide context and, thanks to the [[coro_must_await]] 
attribute,
// this context is propagated to foo and bar.
```

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -8261,12 +8261,19 @@ def CoroAwaitElidableDoc : Documentation {
 The ``[[clang::coro_await_elidable]]`` is a class attribute which can be 
applied
 to a coroutine return type.

vogelsgesang wrote:

```suggestion
to a coroutine return type. It provides a hint to the compiler to apply Heap 
Allocation Elision
more aggressively.
```

I like it if the first paragraph of any documentation immediately gives me a 
high-level picture, so I know if I should keep reading the rest of its 
documentation or skip it. By immediately mentioning Heap Allocation Elision in 
the first paragraph, the reader also gets more context when read the rest of 
the paragraph, so he will hopefully be able to understand the following 
paragraphs more easily

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -84,4 +84,35 @@ Task nonelidable() {
   co_return 1;
 }
 
+// CHECK-LABEL: define{{.*}} @_Z8addTasksO4TaskIiES1_{{.*}} {
+Task addTasks([[clang::coro_must_await]] Task &&t1, Task &&t2) {
+  int i1 = co_await t1;
+  int i2 = co_await t2;
+  co_return i1 + i2;
+}
+
+// CHECK-LABEL: define{{.*}} @_Z10returnSamei{{.*}} {
+Task returnSame(int i) {
+  co_return i;
+}
+
+// CHECK-LABEL: define{{.*}} @_Z21elidableWithMustAwaitv{{.*}} {
+Task elidableWithMustAwait() {
+  // CHECK: call void @_Z10returnSamei(ptr {{.*}}, i32 noundef 2) 
#[[ELIDE_SAFE]]
+  // CHECK-NOT: call void @_Z10returnSamei(ptr {{.*}}, i32 noundef 3) 
#[[ELIDE_SAFE]]
+  co_return co_await addTasks(returnSame(2), returnSame(3));
+}
+
+template 
+Task sumAll([[clang::coro_must_await]] Args && ... tasks);
+
+// CHECK-LABEL: define{{.*}} @_Z16elidableWithPackv{{.*}} {
+Task elidableWithPack() {

vogelsgesang wrote:

maybe also add a test case for recursive elision? I.e. for something like

```
co_await sumAll(addTasks(returnSame(1), returnSame(2)), returnSame(3));
```

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -84,4 +84,35 @@ Task nonelidable() {
   co_return 1;
 }
 
+// CHECK-LABEL: define{{.*}} @_Z8addTasksO4TaskIiES1_{{.*}} {
+Task addTasks([[clang::coro_must_await]] Task &&t1, Task &&t2) {
+  int i1 = co_await t1;
+  int i2 = co_await t2;
+  co_return i1 + i2;
+}
+
+// CHECK-LABEL: define{{.*}} @_Z10returnSamei{{.*}} {
+Task returnSame(int i) {
+  co_return i;
+}
+
+// CHECK-LABEL: define{{.*}} @_Z21elidableWithMustAwaitv{{.*}} {
+Task elidableWithMustAwait() {
+  // CHECK: call void @_Z10returnSamei(ptr {{.*}}, i32 noundef 2) 
#[[ELIDE_SAFE]]
+  // CHECK-NOT: call void @_Z10returnSamei(ptr {{.*}}, i32 noundef 3) 
#[[ELIDE_SAFE]]

vogelsgesang wrote:

Can we somehow turn this into a positive test? Negative tests can easily 
regress, e.g. if something else in the line would change.

Can we use a `$` (or some other mechanism) to check for the end of the line, 
and there by explicitly check that a call to `_Z10returnSamei(ptr {{.*}}, i32 
noundef 3)` does exist, but does not have the ELIDE_SAFE annotation?

```suggestion
  // CHECK: call void @_Z10returnSamei(ptr {{.*}}, i32 noundef 3)$
```

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -880,14 +898,12 @@ ExprResult 
Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
   }
 
   auto *RD = Promise->getType()->getAsCXXRecordDecl();
-  bool AwaitElidable =
-  isCoroAwaitElidableCall(Operand) &&
-  isAttributedCoroAwaitElidable(
-  getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());
-
-  if (AwaitElidable)
-if (auto *Call = dyn_cast(Operand->IgnoreImplicit()))
-  Call->setCoroElideSafe();
+
+  bool CurFnAwaitElidable = isAttributedCoroAwaitElidable(
+  getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());

vogelsgesang wrote:

shouldn't we actually check if the return type of àwait_transform` is marked as 
elideable, instead of the immediate argument to `co_await`? Or maybe we should 
check that both the immediate argument and the transformed awaitable are 
annotated?

(Not really related to this commit. I just noticed this as I was reviewing this 
code change here. Fell free to ship this PR without addressing this comment. In 
case this is actually something we want to change, we should probably do so in 
a separate PR, anyway...)

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -8261,12 +8261,19 @@ def CoroAwaitElidableDoc : Documentation {
 The ``[[clang::coro_await_elidable]]`` is a class attribute which can be 
applied
 to a coroutine return type.
 
-When a coroutine function that returns such a type calls another coroutine 
function,
-the compiler performs heap allocation elision when the call to the coroutine 
function
-is immediately co_awaited as a prvalue. In this case, the coroutine frame for 
the
-callee will be a local variable within the enclosing braces in the caller's 
stack
-frame. And the local variable, like other variables in coroutines, may be 
collected
-into the coroutine frame, which may be allocated on the heap.
+When a coroutine function returns such a type, a direct call expression therein
+that returns a prvalue of a type attributed ``[[clang::coro_await_elidable]]``
+is said to be under a safe elide context if one of the following is true:
+- it is the immediate right-hand side operand to a co_await expression.
+- it is an argument to a [[clang::coro_must_await]] parameter or parameter pack

vogelsgesang wrote:

```suggestion
- it is an argument to a ``[[clang::coro_must_await]]`` parameter or parameter 
pack
```

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang commented:

Thanks for implementing this! Looking forward to using it 🙂 

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-14 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-15 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-16 Thread Adrian Vogelsgesang via cfe-commits


@@ -880,14 +898,12 @@ ExprResult 
Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
   }
 
   auto *RD = Promise->getType()->getAsCXXRecordDecl();
-  bool AwaitElidable =
-  isCoroAwaitElidableCall(Operand) &&
-  isAttributedCoroAwaitElidable(
-  getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());
-
-  if (AwaitElidable)
-if (auto *Call = dyn_cast(Operand->IgnoreImplicit()))
-  Call->setCoroElideSafe();
+
+  bool CurFnAwaitElidable = isAttributedCoroAwaitElidable(
+  getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());

vogelsgesang wrote:

ah, I see. So after this patch, we could actually check `await_transform` and 
also `operator co_await` and thereby get rid of the `CurFnAwaitElidable` check? 
Such that a `ElideableTask` coawaited within a NonElidableTask (as discussed in 
the other thread) would become elideable?

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_must_await]] (PR #108474)

2024-09-16 Thread Adrian Vogelsgesang via cfe-commits


@@ -8261,12 +8261,19 @@ def CoroAwaitElidableDoc : Documentation {
 The ``[[clang::coro_await_elidable]]`` is a class attribute which can be 
applied
 to a coroutine return type.
 
-When a coroutine function that returns such a type calls another coroutine 
function,
-the compiler performs heap allocation elision when the call to the coroutine 
function
-is immediately co_awaited as a prvalue. In this case, the coroutine frame for 
the
-callee will be a local variable within the enclosing braces in the caller's 
stack
-frame. And the local variable, like other variables in coroutines, may be 
collected
-into the coroutine frame, which may be allocated on the heap.
+When a coroutine function returns such a type, a direct call expression therein
+that returns a prvalue of a type attributed ``[[clang::coro_await_elidable]]``
+is said to be under a safe elide context if one of the following is true:

vogelsgesang wrote:

Ah, right. I misread the code.

In general: Is checking if the callee coroutine is annotated actually 
necessary? To my understanding from the other thread, so far it was necessary 
because of `await_transform` and `operator co_await`. After we make this 
checking more fine-granular, are there any other reasons why we would still 
need to check if the callee coroutine is annotated?

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_await_elidable_argument]] (PR #108474)

2024-09-16 Thread Adrian Vogelsgesang via cfe-commits


@@ -880,14 +898,12 @@ ExprResult 
Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
   }
 
   auto *RD = Promise->getType()->getAsCXXRecordDecl();
-  bool AwaitElidable =
-  isCoroAwaitElidableCall(Operand) &&
-  isAttributedCoroAwaitElidable(
-  getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());
-
-  if (AwaitElidable)
-if (auto *Call = dyn_cast(Operand->IgnoreImplicit()))
-  Call->setCoroElideSafe();
+
+  bool CurFnAwaitElidable = isAttributedCoroAwaitElidable(
+  getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());

vogelsgesang wrote:

👍 

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Propagate elide safe context through [[clang::coro_await_elidable_argument]] (PR #108474)

2024-09-17 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang commented:

Looks good to me, but at the same time: I am not experienced in the 
clang-frontend, so please wait for an approval of a more experienced 
clang-frontend contributor

https://github.com/llvm/llvm-project/pull/108474
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-05-29 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-03 Thread Adrian Vogelsgesang via cfe-commits


@@ -124,7 +124,7 @@ static void resolveTopLevelMetadata(llvm::Function *Fn,
   auto *DIS = Fn->getSubprogram();
   if (!DIS)
 return;
-  auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());
+  auto *NewDIS = llvm::MDNode::replaceWithDistinct(DIS->clone());

vogelsgesang wrote:

Yep, drive-by. I was looking up how others used the clone method, and was 
initially confused by this place here, because it called a static method via an 
object pointer.

Will update the commit message to mention that this is a drive by NFC

https://github.com/llvm/llvm-project/pull/141889
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-03 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

CC @iains @ArsenArsen, since from the gcc commit look, it seems you are working 
on coroutine support in gcc. Would be great if clang/LLVM and gcc could agree 
on a common approach to emit debug info for coroutine suspension points 🙂 

See 
https://discourse.llvm.org/t/rfc-debug-info-for-coroutine-suspension-locations-take-2/86606
 for the actual discussion

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-03 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

> Since the change is almost about swift, CC @adrian-prantl

Note that this change should be a NFC for Swift. Changing the 
`DISubprogram::get` call to `Decl->clone() + replaceLinkageName` just 
simplifies the code, but does not change its semantics.

This PR primarily enables the same behavior which already existed in Swift also 
for C++.

https://github.com/llvm/llvm-project/pull/141889
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)

2025-06-23 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

@hokein @ChuanqiXu9 @yuxuanchen1997 friendly ping 🙂 


https://github.com/llvm/llvm-project/pull/142651
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Transforms] Implement always_specialize attribute lowering (PR #143983)

2025-06-14 Thread Adrian Vogelsgesang via cfe-commits


@@ -0,0 +1,324 @@
+//===- AlwaysSpecializer.cpp - implementation of always_specialize 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Function specialisation under programmer control.
+//
+// Specifically, function parameters are marked [[always_specialize]], then 
call
+// sites which pass a constant argument are rewritten to call specialisations.
+//
+// The difficult parts of function specialisation are the cost model, ensuring
+// termination and specialisation to the anticipated extent.
+//
+// Cost model is under programmer control, exactly like always_inline.
+//
+// Termination follows from the implementation following a phased structure:
+// 1. Functions are identifed in the input IR
+// 2. Calls that exist in the input IR are identified
+// Those constitute the complete set of specialisations that will be created.
+//
+// This pass does the _minimum_ specialisation, in the sense that only call
+// sites in the input will lead to cloning. A specialised function will call
+// another specialised function iff there was a call site with the same
+// argument vector in the input.
+//
+// Running the identifyCalls + createClones sequence N times will behave
+// as expected, specialising recursively to that depth. This patch has N=1
+// in the first instance, with no commandline argument to override.
+// Similarly variadic functions are not yet handled.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/AlwaysSpecializer.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/IR/Module.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/IPO/FunctionSpecialization.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "always-specialize"
+
+namespace {
+
+class AlwaysSpecializer : public ModulePass {
+public:
+  static char ID;
+
+  AlwaysSpecializer() : ModulePass(ID) {}
+  StringRef getPassName() const override { return "Always specializer"; }
+
+  // One constant for each argument, nullptr if that one is non-constant
+  using ArgVector = SmallVector;
+
+  // A map from the ArgVector to the matching specialisation
+  using FunctionSpecializations = MapVector;
+
+  // The four mini-passes populate and then use a map:
+  // 1. identifyFunctions writes all keys, with default initialised values.
+  // 2. identifyCalls writes all the ArgVector keys in the values of SpecList.
+  // 3. createClones writes the Function* values at the leaves.
+  // 4. replaceCalls walks the map doing the trivial rewrite.
+
+  // Conceptually a Map but a vector suffices.
+  using SpecListTy =
+  SmallVector, 4>;
+
+  SpecListTy identifyFunctions(Module &M);
+  bool identifyCalls(Module &M, Function *F, FunctionSpecializations &);
+  bool createClones(Module &M, Function *F, FunctionSpecializations &);
+  bool replaceCalls(Module &M, Function *F, FunctionSpecializations &);
+
+  bool runOnModule(Module &M) override {
+bool Changed = false;
+
+// Sets all the keys in the structure used in this invocation.
+SpecListTy SpecList = identifyFunctions(M);
+size_t Count = SpecList.size();
+if (Count == 0) {
+  return false;
+}
+
+// Record distinct call sites as vector -> nullptr
+for (auto &[F, spec] : SpecList)
+  Changed |= identifyCalls(M, F, spec);
+
+// Create and record the clones. Note that call sites within the clones
+// cannot trigger creating more clones so no termination risk.
+for (auto &[F, spec] : SpecList)
+  Changed |= createClones(M, F, spec);
+
+// Replacing calls as the final phase means no need to track
+// partially-specialised calls and no creating further clones.
+for (auto &[F, spec] : SpecList)
+  Changed |= replaceCalls(M, F, spec);
+
+return Changed;
+  }
+
+  static bool isCandidateFunction(const Function &F);
+  static bool callEligible(const Function &F, const CallBase *CB,
+   ArgVector &Out);
+  static Function *cloneCandidateFunction(Module &M, Function *F,
+  const ArgVector &C);
+
+  // Only a member variable to reuse the allocation. Short lived.
+  ArgVector ArgVec;
+};
+
+AlwaysSpecializer::SpecListTy AlwaysSpecializer::identifyFunctions(Module &M) {
+  SpecListTy SpecList;
+  for (Function &F : M) {
+if (isCandidateFunction(F)) {
+  SpecList.push_back(std::make_pair(&F, FunctionSpecializations()));
+}
+  }
+  return SpecList;
+}
+
+bool AlwaysSpecializer::identifyCalls(Module &M, Function *F,
+  FunctionSpec

[clang] [C++][Modules] A module directive may only appear as the first preprocessing tokens in a file (PR #144233)

2025-06-14 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

Should this commit also mark the papers as implemented on 
https://clang.llvm.org/cxx_status.html?

https://github.com/llvm/llvm-project/pull/144233
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-26 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/141937

>From 8fe2bd74609cf0c14466ff82a9c966c07eecd6c8 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 27 May 2025 19:36:42 +
Subject: [PATCH 1/4] [debuginfo][coro] Emit debug info labels for coroutine
 resume points

With this commit, we add `DILabel` debug infos (lowering to DW_TAG_label
in DWARF) to the various resume points of a coroutine. Those labels use
the naming convention `__coro_resume_` where `` is the suspension
point id.

That way, debugging scripts can figure out the exact line / column at
which a coroutine was suspended by looking up current `__coro_index`
value inside the coroutines frame, and then searching for the
corresponding `__coro_resume_` inside the coroutine's resume
function.

While this is an artificial compiler-generated label, I did not apply
the DW_AT_artificial tag to it. The DWARFv5 standard only allows that
tag on type and variable definitions, but not on labels.

In gdb, those line numebers can then be looked up using the command
`info line -function my_coroutine -label __coro_resume_1`.

LLDB unfortunately does not parse DW_TAG_label debug information, yet. As
such, this debug information is currently not useful in LLDB.
---
 clang/docs/DebuggingCoroutines.rst   | 24 ++--
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp |  6 ++--
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 29 +++-
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index 80df321340724..9fc3785a0622b 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -311,17 +311,25 @@ variables in the C++ source.
 Get the suspended points
 
 
-An important requirement for debugging coroutines is to understand suspended
-points, which are where the coroutine is currently suspended and awaiting.
+An important requirement for debugging coroutines is to understand at which
+point a coroutine is currently suspended and awaiting.
 
-For simple cases like the above, inspecting the value of the `__coro_index`
-variable in the coroutine frame works well.
+The value of the `__coro_index` inside a couroutine frame indicates the current
+suspension point. To map this id back to a source code location, you can lookup
+the source location of a special, compiler-generated label 
`__coro_suspend_`.
 
-However, it is not quite so simple in really complex situations. In these
-cases, it is necessary to use the coroutine libraries to insert the
-line-number.
+::
 
-For example:
+  (gdb) info line -function coro_task -label __coro_resume_2
+  Line 45 of "llvm-example.cpp" starts at address 0x1b1b 
<_ZL9coro_taski.resume+555> and ends at 0x1b46 <_ZL9coro_taski.resume+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x201b 
<_ZL9coro_taski.destroy+555> and ends at 0x2046 <_ZL9coro_taski.destroy+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x253b 
<_ZL9coro_taski.cleanup+555> and ends at 0x2566 <_ZL9coro_taski.cleanup+598>.
+
+Older versions of LLVM/clang might not yet emit those labels, though. For
+simple cases, you might still be able to guess the suspension point correctly.
+
+Alternatively, you might also want to modify your coroutine library to store
+the line number of the current suspension point in the promise:
 
 .. code-block:: c++
 
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp 
b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 1acd9139fe26e..42f8bf91118ae 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -688,9 +688,9 @@ static DIType *solveDIType(DIBuilder &Builder, Type *Ty,
 static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
 FrameDataInfo &FrameData) {
   DISubprogram *DIS = F.getSubprogram();
-  // If there is no DISubprogram for F, it implies the Function are not 
compiled
-  // with debug info. So we also don't need to generate debug info for the 
frame
-  // neither.
+  // If there is no DISubprogram for F, it implies the function is compiled
+  // without debug info. So we also don't generate debug info for the frame,
+  // either.
   if (!DIS || !DIS->getUnit() ||
   !dwarf::isCPlusPlus(
   (dwarf::SourceLanguage)DIS->getUnit()->getSourceLanguage()) ||
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp 
b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 8813f91e9060c..1348d785f4f85 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -42,6 +42,7 @@
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -302,7 +303,7 @@ static void replaceFallthrou

[clang] [llvm] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-26 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-26 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/141937

>From 8fe2bd74609cf0c14466ff82a9c966c07eecd6c8 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 27 May 2025 19:36:42 +
Subject: [PATCH 1/5] [debuginfo][coro] Emit debug info labels for coroutine
 resume points

With this commit, we add `DILabel` debug infos (lowering to DW_TAG_label
in DWARF) to the various resume points of a coroutine. Those labels use
the naming convention `__coro_resume_` where `` is the suspension
point id.

That way, debugging scripts can figure out the exact line / column at
which a coroutine was suspended by looking up current `__coro_index`
value inside the coroutines frame, and then searching for the
corresponding `__coro_resume_` inside the coroutine's resume
function.

While this is an artificial compiler-generated label, I did not apply
the DW_AT_artificial tag to it. The DWARFv5 standard only allows that
tag on type and variable definitions, but not on labels.

In gdb, those line numebers can then be looked up using the command
`info line -function my_coroutine -label __coro_resume_1`.

LLDB unfortunately does not parse DW_TAG_label debug information, yet. As
such, this debug information is currently not useful in LLDB.
---
 clang/docs/DebuggingCoroutines.rst   | 24 ++--
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp |  6 ++--
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 29 +++-
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index 80df321340724..9fc3785a0622b 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -311,17 +311,25 @@ variables in the C++ source.
 Get the suspended points
 
 
-An important requirement for debugging coroutines is to understand suspended
-points, which are where the coroutine is currently suspended and awaiting.
+An important requirement for debugging coroutines is to understand at which
+point a coroutine is currently suspended and awaiting.
 
-For simple cases like the above, inspecting the value of the `__coro_index`
-variable in the coroutine frame works well.
+The value of the `__coro_index` inside a couroutine frame indicates the current
+suspension point. To map this id back to a source code location, you can lookup
+the source location of a special, compiler-generated label 
`__coro_suspend_`.
 
-However, it is not quite so simple in really complex situations. In these
-cases, it is necessary to use the coroutine libraries to insert the
-line-number.
+::
 
-For example:
+  (gdb) info line -function coro_task -label __coro_resume_2
+  Line 45 of "llvm-example.cpp" starts at address 0x1b1b 
<_ZL9coro_taski.resume+555> and ends at 0x1b46 <_ZL9coro_taski.resume+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x201b 
<_ZL9coro_taski.destroy+555> and ends at 0x2046 <_ZL9coro_taski.destroy+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x253b 
<_ZL9coro_taski.cleanup+555> and ends at 0x2566 <_ZL9coro_taski.cleanup+598>.
+
+Older versions of LLVM/clang might not yet emit those labels, though. For
+simple cases, you might still be able to guess the suspension point correctly.
+
+Alternatively, you might also want to modify your coroutine library to store
+the line number of the current suspension point in the promise:
 
 .. code-block:: c++
 
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp 
b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 1acd9139fe26e..42f8bf91118ae 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -688,9 +688,9 @@ static DIType *solveDIType(DIBuilder &Builder, Type *Ty,
 static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
 FrameDataInfo &FrameData) {
   DISubprogram *DIS = F.getSubprogram();
-  // If there is no DISubprogram for F, it implies the Function are not 
compiled
-  // with debug info. So we also don't need to generate debug info for the 
frame
-  // neither.
+  // If there is no DISubprogram for F, it implies the function is compiled
+  // without debug info. So we also don't generate debug info for the frame,
+  // either.
   if (!DIS || !DIS->getUnit() ||
   !dwarf::isCPlusPlus(
   (dwarf::SourceLanguage)DIS->getUnit()->getSourceLanguage()) ||
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp 
b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 8813f91e9060c..1348d785f4f85 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -42,6 +42,7 @@
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -302,7 +303,7 @@ static void replaceFallthrou

[clang] [llvm] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-26 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-26 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/141937

>From 8fe2bd74609cf0c14466ff82a9c966c07eecd6c8 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 27 May 2025 19:36:42 +
Subject: [PATCH 1/4] [debuginfo][coro] Emit debug info labels for coroutine
 resume points

With this commit, we add `DILabel` debug infos (lowering to DW_TAG_label
in DWARF) to the various resume points of a coroutine. Those labels use
the naming convention `__coro_resume_` where `` is the suspension
point id.

That way, debugging scripts can figure out the exact line / column at
which a coroutine was suspended by looking up current `__coro_index`
value inside the coroutines frame, and then searching for the
corresponding `__coro_resume_` inside the coroutine's resume
function.

While this is an artificial compiler-generated label, I did not apply
the DW_AT_artificial tag to it. The DWARFv5 standard only allows that
tag on type and variable definitions, but not on labels.

In gdb, those line numebers can then be looked up using the command
`info line -function my_coroutine -label __coro_resume_1`.

LLDB unfortunately does not parse DW_TAG_label debug information, yet. As
such, this debug information is currently not useful in LLDB.
---
 clang/docs/DebuggingCoroutines.rst   | 24 ++--
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp |  6 ++--
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 29 +++-
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index 80df321340724..9fc3785a0622b 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -311,17 +311,25 @@ variables in the C++ source.
 Get the suspended points
 
 
-An important requirement for debugging coroutines is to understand suspended
-points, which are where the coroutine is currently suspended and awaiting.
+An important requirement for debugging coroutines is to understand at which
+point a coroutine is currently suspended and awaiting.
 
-For simple cases like the above, inspecting the value of the `__coro_index`
-variable in the coroutine frame works well.
+The value of the `__coro_index` inside a couroutine frame indicates the current
+suspension point. To map this id back to a source code location, you can lookup
+the source location of a special, compiler-generated label 
`__coro_suspend_`.
 
-However, it is not quite so simple in really complex situations. In these
-cases, it is necessary to use the coroutine libraries to insert the
-line-number.
+::
 
-For example:
+  (gdb) info line -function coro_task -label __coro_resume_2
+  Line 45 of "llvm-example.cpp" starts at address 0x1b1b 
<_ZL9coro_taski.resume+555> and ends at 0x1b46 <_ZL9coro_taski.resume+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x201b 
<_ZL9coro_taski.destroy+555> and ends at 0x2046 <_ZL9coro_taski.destroy+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x253b 
<_ZL9coro_taski.cleanup+555> and ends at 0x2566 <_ZL9coro_taski.cleanup+598>.
+
+Older versions of LLVM/clang might not yet emit those labels, though. For
+simple cases, you might still be able to guess the suspension point correctly.
+
+Alternatively, you might also want to modify your coroutine library to store
+the line number of the current suspension point in the promise:
 
 .. code-block:: c++
 
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp 
b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 1acd9139fe26e..42f8bf91118ae 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -688,9 +688,9 @@ static DIType *solveDIType(DIBuilder &Builder, Type *Ty,
 static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
 FrameDataInfo &FrameData) {
   DISubprogram *DIS = F.getSubprogram();
-  // If there is no DISubprogram for F, it implies the Function are not 
compiled
-  // with debug info. So we also don't need to generate debug info for the 
frame
-  // neither.
+  // If there is no DISubprogram for F, it implies the function is compiled
+  // without debug info. So we also don't generate debug info for the frame,
+  // either.
   if (!DIS || !DIS->getUnit() ||
   !dwarf::isCPlusPlus(
   (dwarf::SourceLanguage)DIS->getUnit()->getSourceLanguage()) ||
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp 
b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 8813f91e9060c..1348d785f4f85 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -42,6 +42,7 @@
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -302,7 +303,7 @@ static void replaceFallthrou

[clang] [llvm] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-26 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

Could you review clang and the coroutine-specific pieces? I think the DWARF and 
`DILabel` aspects @dwblaikie might be able to give feedback?

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-26 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/141937

>From 8fe2bd74609cf0c14466ff82a9c966c07eecd6c8 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 27 May 2025 19:36:42 +
Subject: [PATCH 1/5] [debuginfo][coro] Emit debug info labels for coroutine
 resume points

With this commit, we add `DILabel` debug infos (lowering to DW_TAG_label
in DWARF) to the various resume points of a coroutine. Those labels use
the naming convention `__coro_resume_` where `` is the suspension
point id.

That way, debugging scripts can figure out the exact line / column at
which a coroutine was suspended by looking up current `__coro_index`
value inside the coroutines frame, and then searching for the
corresponding `__coro_resume_` inside the coroutine's resume
function.

While this is an artificial compiler-generated label, I did not apply
the DW_AT_artificial tag to it. The DWARFv5 standard only allows that
tag on type and variable definitions, but not on labels.

In gdb, those line numebers can then be looked up using the command
`info line -function my_coroutine -label __coro_resume_1`.

LLDB unfortunately does not parse DW_TAG_label debug information, yet. As
such, this debug information is currently not useful in LLDB.
---
 clang/docs/DebuggingCoroutines.rst   | 24 ++--
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp |  6 ++--
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 29 +++-
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index 80df321340724..9fc3785a0622b 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -311,17 +311,25 @@ variables in the C++ source.
 Get the suspended points
 
 
-An important requirement for debugging coroutines is to understand suspended
-points, which are where the coroutine is currently suspended and awaiting.
+An important requirement for debugging coroutines is to understand at which
+point a coroutine is currently suspended and awaiting.
 
-For simple cases like the above, inspecting the value of the `__coro_index`
-variable in the coroutine frame works well.
+The value of the `__coro_index` inside a couroutine frame indicates the current
+suspension point. To map this id back to a source code location, you can lookup
+the source location of a special, compiler-generated label 
`__coro_suspend_`.
 
-However, it is not quite so simple in really complex situations. In these
-cases, it is necessary to use the coroutine libraries to insert the
-line-number.
+::
 
-For example:
+  (gdb) info line -function coro_task -label __coro_resume_2
+  Line 45 of "llvm-example.cpp" starts at address 0x1b1b 
<_ZL9coro_taski.resume+555> and ends at 0x1b46 <_ZL9coro_taski.resume+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x201b 
<_ZL9coro_taski.destroy+555> and ends at 0x2046 <_ZL9coro_taski.destroy+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x253b 
<_ZL9coro_taski.cleanup+555> and ends at 0x2566 <_ZL9coro_taski.cleanup+598>.
+
+Older versions of LLVM/clang might not yet emit those labels, though. For
+simple cases, you might still be able to guess the suspension point correctly.
+
+Alternatively, you might also want to modify your coroutine library to store
+the line number of the current suspension point in the promise:
 
 .. code-block:: c++
 
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp 
b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 1acd9139fe26e..42f8bf91118ae 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -688,9 +688,9 @@ static DIType *solveDIType(DIBuilder &Builder, Type *Ty,
 static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
 FrameDataInfo &FrameData) {
   DISubprogram *DIS = F.getSubprogram();
-  // If there is no DISubprogram for F, it implies the Function are not 
compiled
-  // with debug info. So we also don't need to generate debug info for the 
frame
-  // neither.
+  // If there is no DISubprogram for F, it implies the function is compiled
+  // without debug info. So we also don't generate debug info for the frame,
+  // either.
   if (!DIS || !DIS->getUnit() ||
   !dwarf::isCPlusPlus(
   (dwarf::SourceLanguage)DIS->getUnit()->getSourceLanguage()) ||
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp 
b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 8813f91e9060c..1348d785f4f85 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -42,6 +42,7 @@
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -302,7 +303,7 @@ static void replaceFallthrou

[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)

2025-06-03 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang unassigned 
https://github.com/llvm/llvm-project/pull/142651
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)

2025-06-03 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang unassigned 
https://github.com/llvm/llvm-project/pull/142651
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)

2025-06-03 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang ready_for_review 
https://github.com/llvm/llvm-project/pull/142651
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang][DebugInfo] Add symbol for debugger with VTable information. (PR #130255)

2025-06-06 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

Afaict, the issue is not that the address gets optimized out, but rather that 
we are setting `LineNo` to 0:

```
  DBuilder.createGlobalVariableExpression(
  TheCU, SymbolName, VTable->getName(), Unit, /*LineNo=*/0,
  getOrCreateType(VoidPtr, Unit), VTable->hasLocalLinkage(),
  /*isDefined=*/true, nullptr, DT, /*TemplateParameters=*/nullptr,
  PAlign);
```

I think this can be solved by setting the line number to the line number of, 
e.g., the `class` / `struct` keyword or the line number of the class name, or 
whatever is easily available

https://github.com/llvm/llvm-project/pull/130255
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lldb] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-10 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

@ChuanqiXu9 do you want to take another look? (given that this is a NFC for 
Swift, and primarily changes C++ behavior)
Alternatively, is it fine by you if I ship this based on @Michael137's approval?

https://github.com/llvm/llvm-project/pull/141889
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lldb] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-10 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/141889

>From 700c1c465ff7f29dc980356f36844a12d580 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 27 May 2025 23:50:18 +
Subject: [PATCH 1/3] [debuginfo][coro] Fix linkage name for clones of coro
 functions

So far, the `DW_AT_linkage_name` of the coroutine `resume`, `destroy`,
`cleanup` and `noalloc` functions were incorrectly set to the original
function name instead of the updated function names.

With this commit, we now update the `DW_AT_linkage_name` to the correct
name. This has multiple benefits:
1. it's easier for me (and other developers) to understand the output of
   `llvm-dwarf-dump` when coroutines are involved.
2. When hitting a breakpoint, both LLDB and GDB now tell you which clone
   of the function you are in. E.g., GDB now prints
   "Breakpoint 1.2, coro_func(int) [clone .resume] (v=43) at ..."
   instead of
   "Breakpoint 1.2, coro_func(int) (v=43) at ...".
3. GDB's `info line coro_func` command now allows you to distinguish the
   multiple different clones of the function.

In Swift, the linkage names of the clones were already updated. The
comment right above the relevant code in `CoroSplit.cpp` already hinted
that the linkage name should probably also be updated in C++. This
commit was added in commit 6ce76ff7eb7640, and back then the
corresponding `DW_AT_specification` (i.e., `SP->getDeclaration()`) was
not updated, yet, which led to problems for C++. In the meantime, commit
ca1a5b37c7236d added code to also update `SP->getDeclaration`, as such
there is no reason anymore to not update the linkage name for C++.

Note that most test cases used inconsistent function names for the LLVM
function vs. the DISubprogram linkage name. clang would never emit such
LLVM IR. This confused me initially, and hence I fixed it while updating
the test case.
---
 clang/lib/CodeGen/CGVTables.cpp   |  2 +-
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp  | 31 +--
 ...coro-debug-dbg.values-not_used_in_frame.ll |  6 ++--
 .../Coroutines/coro-debug-dbg.values.ll   | 10 +++---
 .../Coroutines/coro-debug-frame-variable.ll   | 10 +++---
 llvm/test/Transforms/Coroutines/coro-debug.ll | 18 +--
 6 files changed, 31 insertions(+), 46 deletions(-)

diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index c7447273a42fa..2897ccdf88660 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -124,7 +124,7 @@ static void resolveTopLevelMetadata(llvm::Function *Fn,
   auto *DIS = Fn->getSubprogram();
   if (!DIS)
 return;
-  auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());
+  auto *NewDIS = llvm::MDNode::replaceWithDistinct(DIS->clone());
   VMap.MD()[DIS].reset(NewDIS);
 
   // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp 
b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index f9a6c70fedc2d..07d888a10eb7f 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -912,29 +912,14 @@ void coro::BaseCloner::create() {
 assert(SP != OrigF.getSubprogram() && SP->isDistinct());
 updateScopeLine(ActiveSuspend, *SP);
 
-// Update the linkage name to reflect the modified symbol name. It
-// is necessary to update the linkage name in Swift, since the
-// mangling changes for resume functions. It might also be the
-// right thing to do in C++, but due to a limitation in LLVM's
-// AsmPrinter we can only do this if the function doesn't have an
-// abstract specification, since the DWARF backend expects the
-// abstract specification to contain the linkage name and asserts
-// that they are identical.
-if (SP->getUnit() &&
-SP->getUnit()->getSourceLanguage() == dwarf::DW_LANG_Swift) {
-  SP->replaceLinkageName(MDString::get(Context, NewF->getName()));
-  if (auto *Decl = SP->getDeclaration()) {
-auto *NewDecl = DISubprogram::get(
-Decl->getContext(), Decl->getScope(), Decl->getName(),
-NewF->getName(), Decl->getFile(), Decl->getLine(), Decl->getType(),
-Decl->getScopeLine(), Decl->getContainingType(),
-Decl->getVirtualIndex(), Decl->getThisAdjustment(),
-Decl->getFlags(), Decl->getSPFlags(), Decl->getUnit(),
-Decl->getTemplateParams(), nullptr, Decl->getRetainedNodes(),
-Decl->getThrownTypes(), Decl->getAnnotations(),
-Decl->getTargetFuncName());
-SP->replaceDeclaration(NewDecl);
-  }
+// Update the linkage name and the functaion name to reflect the modified
+// name.
+MDString *NewLinkageName = MDString::get(Context, NewF->getName());
+SP->replaceLinkageName(NewLinkageName);
+if (DISubprogram *Decl = SP->getDeclaration()) {
+  TempDISubprogram NewDecl = Decl->clone();
+  NewDecl->repla

[clang] [lldb] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-10 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

> The LLDB test failure seems expected. The demangled frame name changed

Good catch. I updated the LLDB test expectations just now

https://github.com/llvm/llvm-project/pull/141889
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lldb] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-11 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141889
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lldb] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-11 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang closed 
https://github.com/llvm/llvm-project/pull/141889
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lldb] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-11 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141889
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lldb] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-11 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141889
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [lldb] [llvm] [debuginfo][coro] Fix linkage name for clones of coro functions (PR #141889)

2025-06-11 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141889
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix a typo in documentation (PR #147128)

2025-07-05 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/147128
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/141937

>From 185be04e482344ce2f76eeb02859162e1838150e Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 27 May 2025 19:36:42 +
Subject: [PATCH 1/6] [debuginfo][coro] Emit debug info labels for coroutine
 resume points

With this commit, we add `DILabel` debug infos (lowering to DW_TAG_label
in DWARF) to the various resume points of a coroutine. Those labels use
the naming convention `__coro_resume_` where `` is the suspension
point id.

That way, debugging scripts can figure out the exact line / column at
which a coroutine was suspended by looking up current `__coro_index`
value inside the coroutines frame, and then searching for the
corresponding `__coro_resume_` inside the coroutine's resume
function.

While this is an artificial compiler-generated label, I did not apply
the DW_AT_artificial tag to it. The DWARFv5 standard only allows that
tag on type and variable definitions, but not on labels.

In gdb, those line numebers can then be looked up using the command
`info line -function my_coroutine -label __coro_resume_1`.

LLDB unfortunately does not parse DW_TAG_label debug information, yet. As
such, this debug information is currently not useful in LLDB.
---
 clang/docs/DebuggingCoroutines.rst   | 23 
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp |  6 ++--
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 29 +++-
 3 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index c47579bc62e51..c221b2ec9c19b 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -209,9 +209,24 @@ important. This member identifies the suspension point at 
which the coroutine
 is currently suspended.
 
 However, it is non-trivial to map this number back to a source code location.
-In simple cases, one might correctly guess the source code location. In more
-complex cases, we can modify the C++ code to store additional information in
-the promise type:
+The compiler emits debug info labels for the suspension points. This allows us
+to map the suspension point index back to a source code location. In gdb, we
+can use the ``info line`` command to get the source code location of the
+suspension point.
+
+::
+
+  (gdb) info line -function coro_task -label __coro_resume_2
+  Line 45 of "llvm-example.cpp" starts at address 0x1b1b 
<_ZL9coro_taski.resume+555> and ends at 0x1b46 <_ZL9coro_taski.resume+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x201b 
<_ZL9coro_taski.destroy+555> and ends at 0x2046 <_ZL9coro_taski.destroy+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x253b 
<_ZL9coro_taski.cleanup+555> and ends at 0x2566 <_ZL9coro_taski.cleanup+598>.
+
+LLDB does not support looking up labels. Furthmore, those labels are only 
emitted
+starting with clang 21.0.
+
+For simple cases, you might still be able to guess the suspension point 
correctly.
+Alternatively, you might also want to modify your coroutine library to store
+the line number of the current suspension point in the promise:
 
 .. code-block:: c++
 
@@ -221,8 +236,6 @@ the promise type:
 void* _coro_return_address = nullptr;
   };
 
-  #include 
-
   // For all the awaiter types we need:
   class awaiter {
 ...
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp 
b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 1acd9139fe26e..42f8bf91118ae 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -688,9 +688,9 @@ static DIType *solveDIType(DIBuilder &Builder, Type *Ty,
 static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
 FrameDataInfo &FrameData) {
   DISubprogram *DIS = F.getSubprogram();
-  // If there is no DISubprogram for F, it implies the Function are not 
compiled
-  // with debug info. So we also don't need to generate debug info for the 
frame
-  // neither.
+  // If there is no DISubprogram for F, it implies the function is compiled
+  // without debug info. So we also don't generate debug info for the frame,
+  // either.
   if (!DIS || !DIS->getUnit() ||
   !dwarf::isCPlusPlus(
   (dwarf::SourceLanguage)DIS->getUnit()->getSourceLanguage()) ||
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp 
b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 8813f91e9060c..1348d785f4f85 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -42,6 +42,7 @@
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -302,7 +303,7 @@ static void replaceFallthroughCoroEnd(AnyCoroEndInst *End,
 }
 
 // Mark a coroutine as done, which implies that 

[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits


@@ -0,0 +1,148 @@
+; Tests that we add DILabels for the suspend points.
+;
+; We check both the generated LLVM:
+; RUN: opt < %s -passes='cgscc(coro-split)' -S | FileCheck %s
+;
+; And the debug info:
+; RUN: opt < %s -passes='cgscc(coro-split),coro-cleanup' \
+; RUN:   | llc -O0 -filetype=obj -o - \
+; RUN:   | llvm-dwarfdump - \
+; RUN:   | FileCheck %s -check-prefix=DWARF
+
+source_filename = "coro.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"

vogelsgesang wrote:

Is there any way to mark only the second "RUN" command as `x86_64`, but keep 
the first "RUN" working for all systems? I guess not?

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/141937

>From 185be04e482344ce2f76eeb02859162e1838150e Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 27 May 2025 19:36:42 +
Subject: [PATCH 1/6] [debuginfo][coro] Emit debug info labels for coroutine
 resume points

With this commit, we add `DILabel` debug infos (lowering to DW_TAG_label
in DWARF) to the various resume points of a coroutine. Those labels use
the naming convention `__coro_resume_` where `` is the suspension
point id.

That way, debugging scripts can figure out the exact line / column at
which a coroutine was suspended by looking up current `__coro_index`
value inside the coroutines frame, and then searching for the
corresponding `__coro_resume_` inside the coroutine's resume
function.

While this is an artificial compiler-generated label, I did not apply
the DW_AT_artificial tag to it. The DWARFv5 standard only allows that
tag on type and variable definitions, but not on labels.

In gdb, those line numebers can then be looked up using the command
`info line -function my_coroutine -label __coro_resume_1`.

LLDB unfortunately does not parse DW_TAG_label debug information, yet. As
such, this debug information is currently not useful in LLDB.
---
 clang/docs/DebuggingCoroutines.rst   | 23 
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp |  6 ++--
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 29 +++-
 3 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index c47579bc62e51..c221b2ec9c19b 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -209,9 +209,24 @@ important. This member identifies the suspension point at 
which the coroutine
 is currently suspended.
 
 However, it is non-trivial to map this number back to a source code location.
-In simple cases, one might correctly guess the source code location. In more
-complex cases, we can modify the C++ code to store additional information in
-the promise type:
+The compiler emits debug info labels for the suspension points. This allows us
+to map the suspension point index back to a source code location. In gdb, we
+can use the ``info line`` command to get the source code location of the
+suspension point.
+
+::
+
+  (gdb) info line -function coro_task -label __coro_resume_2
+  Line 45 of "llvm-example.cpp" starts at address 0x1b1b 
<_ZL9coro_taski.resume+555> and ends at 0x1b46 <_ZL9coro_taski.resume+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x201b 
<_ZL9coro_taski.destroy+555> and ends at 0x2046 <_ZL9coro_taski.destroy+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x253b 
<_ZL9coro_taski.cleanup+555> and ends at 0x2566 <_ZL9coro_taski.cleanup+598>.
+
+LLDB does not support looking up labels. Furthmore, those labels are only 
emitted
+starting with clang 21.0.
+
+For simple cases, you might still be able to guess the suspension point 
correctly.
+Alternatively, you might also want to modify your coroutine library to store
+the line number of the current suspension point in the promise:
 
 .. code-block:: c++
 
@@ -221,8 +236,6 @@ the promise type:
 void* _coro_return_address = nullptr;
   };
 
-  #include 
-
   // For all the awaiter types we need:
   class awaiter {
 ...
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp 
b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 1acd9139fe26e..42f8bf91118ae 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -688,9 +688,9 @@ static DIType *solveDIType(DIBuilder &Builder, Type *Ty,
 static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
 FrameDataInfo &FrameData) {
   DISubprogram *DIS = F.getSubprogram();
-  // If there is no DISubprogram for F, it implies the Function are not 
compiled
-  // with debug info. So we also don't need to generate debug info for the 
frame
-  // neither.
+  // If there is no DISubprogram for F, it implies the function is compiled
+  // without debug info. So we also don't generate debug info for the frame,
+  // either.
   if (!DIS || !DIS->getUnit() ||
   !dwarf::isCPlusPlus(
   (dwarf::SourceLanguage)DIS->getUnit()->getSourceLanguage()) ||
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp 
b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 8813f91e9060c..1348d785f4f85 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -42,6 +42,7 @@
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -302,7 +303,7 @@ static void replaceFallthroughCoroEnd(AnyCoroEndInst *End,
 }
 
 // Mark a coroutine as done, which implies that 

[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits


@@ -0,0 +1,148 @@
+; Tests that we add DILabels for the suspend points.
+;
+; We check both the generated LLVM:
+; RUN: opt < %s -passes='cgscc(coro-split)' -S | FileCheck %s
+;
+; And the debug info:
+; RUN: opt < %s -passes='cgscc(coro-split),coro-cleanup' \
+; RUN:   | llc -O0 -filetype=obj -o - \
+; RUN:   | llvm-dwarfdump - \
+; RUN:   | FileCheck %s -check-prefix=DWARF
+
+source_filename = "coro.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"

vogelsgesang wrote:

Could I simply delete

```
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
```

from this file, and this would work? At least 
`llvm/test/DebugInfo/Generic/debug-label.ll` is doing so. Afaict, this should 
make this test case system-independent, and would be preferable?

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits


@@ -1133,6 +1133,7 @@ Error 
MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
 ++NumMDRecordLoaded;
 if (Expected MaybeCode =
 Stream.readRecord(Entry.ID, Record, &Blob)) {
+  // Crashes called from here!

vogelsgesang wrote:

indeed. This was a left-over note from some debugging I had to do

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits


@@ -715,6 +715,7 @@ static void printExtendedName(raw_ostream &OS, const DINode 
*Node,
 Res = V->getName();
 Line = V->getLine();
   } else if (const auto *L = dyn_cast(Node)) {
+// XXX what are we doing here? Adjust it?

vogelsgesang wrote:

yes. I came to the conclusion that this is only debug output, and that printing 
column / coro-suspend-idx here would probably only hurt the readability of the 
debug output. As such, this code should stay unchanged.

Forgot the comment, though :/ Fixed now.

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits


@@ -2240,14 +2242,28 @@ Error 
MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
 break;
   }
   case bitc::METADATA_LABEL: {
-if (Record.size() != 5)
+if (Record.size() < 5 || Record.size() > 7)
   return error("Invalid record");
 
 IsDistinct = Record[0] & 1;
+uint64_t Line = Record[4];
+uint64_t Column = Record.size() > 5 ? Record[5] : 0;
+bool IsArtificial = Record[0] & 2;
+std::optional CoroSuspendIdx;
+if (Record.size() > 6) {
+  unsigned RawSuspendIdx = Record[6];
+  if (RawSuspendIdx != std::numeric_limits::max()) {
+if (RawSuspendIdx > (uint64_t)std::numeric_limits::max())
+  return error("CoroSuspendIdx value is too large");

vogelsgesang wrote:

indeed, RawSuspendIdx should have been uint64_t, and I should have checked for 
numeric_limits::max here. Fixed. Thanks for catching this! :)

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits


@@ -2344,11 +2344,15 @@ void ModuleBitcodeWriter::writeDILocalVariable(
 void ModuleBitcodeWriter::writeDILabel(
 const DILabel *N, SmallVectorImpl &Record,
 unsigned Abbrev) {
-  Record.push_back((uint64_t)N->isDistinct());
+  uint64_t IsArtificialFlag = uint64_t(N->isArtificial()) << 1;
+  Record.push_back((uint64_t)N->isDistinct() | IsArtificialFlag);
   Record.push_back(VE.getMetadataOrNullID(N->getScope()));
   Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
   Record.push_back(VE.getMetadataOrNullID(N->getFile()));
   Record.push_back(N->getLine());
+  Record.push_back(N->getColumn());
+  Record.push_back(
+  N->getCoroSuspendIdx().value_or(std::numeric_limits::max()));

vogelsgesang wrote:

fixed `MetaDataLoader.cpp` to read this correctly. The writing code here was 
already as intended

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-01 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang edited 
https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-28 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

Note that this also influences Swift. The new labels will also be available in 
Swift. I hope this might also be useful for Swift to improve debugging 
experience, and hence is actually a good thing?

Not sure, though. If you want, I could also skip emitting those labels for 
Swift.

CC @adrian-prantl

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)

2025-06-28 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang closed 
https://github.com/llvm/llvm-project/pull/142651
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)

2025-06-28 Thread Adrian Vogelsgesang via cfe-commits


@@ -8,470 +8,966 @@ Debugging C++ Coroutines
 Introduction
 
 
-For performance and other architectural reasons, the C++ Coroutines feature in
-the Clang compiler is implemented in two parts of the compiler.  Semantic
-analysis is performed in Clang, and Coroutine construction and optimization
-takes place in the LLVM middle-end.

vogelsgesang wrote:

I merged this now, since I want to be able to point people to the documentation 
from a discourse thread. Let me know if I missed anything. Happy to update this 
further also post-commit

https://github.com/llvm/llvm-project/pull/142651
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)

2025-06-29 Thread Adrian Vogelsgesang via cfe-commits


@@ -301,177 +735,284 @@ optimized to the equivalent of:
 std::cout << a+5 << "\n";
   }
 
-It should now be obvious why the value of `__int_32_0` remains unchanged
-throughout the function. It is important to recognize that `__int_32_0`
-does not directly correspond to `a`, but is instead a variable generated
-to assist the compiler in code generation. The variables in an optimized
-coroutine frame should not be thought of as directly representing the
-variables in the C++ source.
-
-Get the suspended points
-
-
-An important requirement for debugging coroutines is to understand suspended
-points, which are where the coroutine is currently suspended and awaiting.
-
-For simple cases like the above, inspecting the value of the `__coro_index`
-variable in the coroutine frame works well.
+It should now be obvious why the value of ``__int_32_0`` remains unchanged
+throughout the function. It is important to recognize that ``__int_32_0`` does
+not directly correspond to ``a``, but is instead a variable generated to assist
+the compiler in code generation. The variables in an optimized coroutine frame
+should not be thought of as directly representing the variables in the C++
+source.
 
-However, it is not quite so simple in really complex situations. In these
-cases, it is necessary to use the coroutine libraries to insert the
-line-number.
 
-For example:
-
-.. code-block:: c++
+Resources
+=
 
-  // For all the promise_type we want:
-  class promise_type {
-...
-  +  unsigned line_number = 0x;
-  };
+.. _lldb-script:
 
-  #include 
+LLDB Debugger Script
+
 
-  // For all the awaiter types we need:
-  class awaiter {
-...
-template 
-void await_suspend(std::coroutine_handle handle,
-   std::source_location sl = 
std::source_location::current()) {
-  ...
-  handle.promise().line_number = sl.line();
-}
-  };
+The following script provides the ``coro bt`` and ``coro in-flight`` commands
+discussed above. It can be loaded into LLDB using ``command script import
+lldb_coro_debugging.py``. To load this by default, add this command to your
+``~/.lldbinit`` file.
 
-In this case, we use `std::source_location` to store the line number of the
-await inside the `promise_type`.  Since we can locate the coroutine function
-from the address of the coroutine, we can identify suspended points this way
-as well.
+Note that this script requires LLDB 21.0 or newer.
 
-The downside here is that this comes at the price of additional runtime cost.
-This is consistent with the C++ philosophy of "Pay for what you use".
-
-Get the asynchronous stack
-==
-
-Another important requirement to debug a coroutine is to print the asynchronous
-stack to identify the asynchronous caller of the coroutine.  As many
-implementations of coroutine types store `std::coroutine_handle<> continuation`
-in the promise type, identifying the caller should be trivial.  The
-`continuation` is typically the awaiting coroutine for the current coroutine.
-That is, the asynchronous parent.
-
-Since the `promise_type` is obtainable from the address of a coroutine and
-contains the corresponding continuation (which itself is a coroutine with a
-`promise_type`), it should be trivial to print the entire asynchronous stack.
-
-This logic should be quite easily captured in a debugger script.
-
-Examples to print asynchronous stack
-
-
-Here is an example to print the asynchronous stack for the normal task 
implementation.
+.. code-block:: python
 
-.. code-block:: c++
+  # lldb_coro_debugging.py
+  import lldb
+  from lldb.plugins.parsed_cmd import ParsedCommand
+
+  def _get_first_var_path(v, paths):
+  """
+  Tries multiple variable paths via `GetValueForExpressionPath`
+  and returns the first one that succeeds, or None if none succeed.
+  """
+  for path in paths:
+  var = v.GetValueForExpressionPath(path)
+  if var.error.Success():
+  return var
+  return None
+
+
+  def _print_async_bt(coro_hdl, result, *, curr_idx, start, limit, 
continuation_paths, prefix=""):
+  """
+  Prints a backtrace for an async coroutine stack starting from `coro_hdl`,
+  using the given `continuation_paths` to get the next coroutine from the 
promise.
+  """
+  target = coro_hdl.GetTarget()
+  while curr_idx < limit and coro_hdl is not None and 
coro_hdl.error.Success():
+  # Print the stack frame, if in range
+  if curr_idx >= start:
+  # Figure out the function name
+  destroy_func_var = coro_hdl.GetValueForExpressionPath(".destroy")
+  destroy_addr = 
target.ResolveLoadAddress(destroy_func_var.GetValueAsAddress())
+  func_name = destroy_addr.function.name
+  # Figure out the line entry to show
+  suspension_addr_var = 
coro_hdl.

[clang] [NFC][docs][coro] Fix syntax & typos (PR #146282)

2025-06-29 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang created 
https://github.com/llvm/llvm-project/pull/146282

Follow-up fixes to #142651

>From 21f5dad37ecae2465e9c135e70bec6c040449823 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sun, 29 Jun 2025 17:07:29 +
Subject: [PATCH] [NFC][docs][coro] Fix syntax & typos

Follow-up fixes to #142651
---
 clang/docs/DebuggingCoroutines.rst | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index c47579bc62e51..0ae03380807c2 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -24,7 +24,7 @@ still improving their support for coroutines. As such, we 
recommend using the
 latest available version of your toolchain.
 
 This document focuses on clang and lldb. The screenshots show
-[lldb-dap](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.lldb-dap)
+`lldb-dap 
`_
 in combination with VS Code. The same techniques can also be used in other
 IDEs.
 
@@ -913,7 +913,7 @@ Note that this script requires LLDB 21.0 or newer.
   continuation_paths = continuation_paths)
 
 
-  class Coroin-flightCommand(ParsedCommand):
+  class CoroInflightCommand(ParsedCommand):
   def get_short_help(self):
   return "Identify all in-flight coroutines"
 
@@ -993,7 +993,7 @@ Note that this script requires LLDB 21.0 or newer.
   def __lldb_init_module(debugger, internal_dict):
   debugger.HandleCommand("command container add -h 'Debugging utilities 
for C++20 coroutines' coro")
   debugger.HandleCommand(f"command script add -o -p -c 
{__name__}.CoroBacktraceCommand coro bt")
-  debugger.HandleCommand(f"command script add -o -p -c 
{__name__}.Coroin-flightCommand coro in-flight")
+  debugger.HandleCommand(f"command script add -o -p -c 
{__name__}.CoroInflightCommand coro in-flight")
   print("Coro debugging utilities installed. Use `help coro` to see 
available commands.")
 
   if __name__ == '__main__':
@@ -1012,7 +1012,7 @@ For GDB, the following script provides a couple of useful 
commands:
 
 .. code-block:: python
 
-# debugging-helper.py
+  # debugging-helper.py
   import gdb
   from gdb.FrameDecorator import FrameDecorator
 
@@ -1160,11 +1160,11 @@ Further Reading
 
 The authors of the Folly libraries wrote a blog post series on how they debug 
coroutines:
 
-* [Async stack traces in folly: 
Introduction](https://developers.facebook.com/blog/post/2021/09/16/async-stack-traces-folly-Introduction/)
-* [Async stack traces in folly: Synchronous and asynchronous stack 
traces](https://developers.facebook.com/blog/post/2021/09/23/async-stack-traces-folly-synchronous-asynchronous-stack-traces/)
-* [Async stack traces in folly: Forming an async stack from individual 
frames](https://developers.facebook.com/blog/post/2021/09/30/async-stack-traces-folly-forming-async-stack-individual-frames/)
-* [Async Stack Traces for C++ Coroutines in Folly: Walking the async 
stack](https://developers.facebook.com/blog/post/2021/10/14/async-stack-traces-c-plus-plus-coroutines-folly-walking-async-stack/)
-* [Async stack traces in folly: Improving debugging in the developer 
lifecycle](https://developers.facebook.com/blog/post/2021/10/21/async-stack-traces-folly-improving-debugging-developer-lifecycle/)
+* `Async stack traces in folly: Introduction 
`_
+* `Async stack traces in folly: Synchronous and asynchronous stack traces 
`_
+* `Async stack traces in folly: Forming an async stack from individual frames 
`_
+* `Async Stack Traces for C++ Coroutines in Folly: Walking the async stack 
`_
+* `Async stack traces in folly: Improving debugging in the developer lifecycle 
`_
 
 Besides some topics also covered here (stack traces from the debugger), 
Folly's blog post series also covers
 more additional topics, such as capturing async strack traces in performance 
profiles via eBPF filters

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


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-27 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

> I don't feel there are coroutine specific things

What I would have had in mind: The integration in the `CoroSplit` pass and the 
test case changes

> I can accept this

Thanks! I will still wait for a 2nd review from someone with debuginfo 
expertise. We still have 3 weeks before the branch cut for clang-21, so we are 
not in a hurry :)

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [docs][coroutines] Revamp "Debugging C++ coroutines" (PR #142651)

2025-06-29 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

Thanks for reporting. I actually ended up feeding this document to AI and asked 
it to do a proof-read. It found a couple more smaller issues. Those are fixed 
in #146282 now

https://github.com/llvm/llvm-project/pull/142651
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [NFC][docs][coro] Fix syntax & typos (PR #146282)

2025-06-29 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/146282

>From b547ef22612bdd66abc8076df40924074230c9e3 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Sun, 29 Jun 2025 17:07:29 +
Subject: [PATCH] [NFC][docs][coro] Fix syntax & typos

Follow-up fixes to #142651
---
 clang/docs/DebuggingCoroutines.rst | 42 +++---
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index c47579bc62e51..ef44a865bfd96 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -24,7 +24,7 @@ still improving their support for coroutines. As such, we 
recommend using the
 latest available version of your toolchain.
 
 This document focuses on clang and lldb. The screenshots show
-[lldb-dap](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.lldb-dap)
+`lldb-dap 
`_
 in combination with VS Code. The same techniques can also be used in other
 IDEs.
 
@@ -44,7 +44,7 @@ Debugging generators
 
 One of the two major use cases for coroutines in C++ are generators, i.e.,
 functions which can produce values via ``co_yield``. Values are produced
-lazily, on-demand. For that purpose, every time a new value is requested the
+lazily, on-demand. For this purpose, every time a new value is requested, the
 coroutine gets resumed. As soon as it reaches a ``co_yield`` and thereby
 returns the requested value, the coroutine is suspended again.
 
@@ -134,7 +134,7 @@ Inspecting variables in a coroutine
 ---
 
 If you hit a breakpoint inside the ``fibonacci`` function, you should be able
-to inspect all local variables (``prev```, ``current```, ``next``) just like in
+to inspect all local variables (``prev``, ``current``, ``next``) just like in
 a regular function.
 
 .. image:: ./coro-generator-variables.png
@@ -215,7 +215,7 @@ the promise type:
 
 .. code-block:: c++
 
-  // For all promise_types we need a new `line_number variable`:
+  // For all promise_types we need a new `_coro_return_address` variable:
   class promise_type {
 ...
 void* _coro_return_address = nullptr;
@@ -240,8 +240,8 @@ type used below for asynchronous programming.
 
 Alternatively, we can modify the C++ code to store the line number in the
 promise type. We can use a ``std::source_location`` to get the line number of
-the await and store it inside the ``promise_type``. Since we can get the
-promise of a suspended coroutine, we thereby get access to the line_number.
+the await and store it inside the ``promise_type``. In the debugger, we can
+then read the line number from the promise of the suspended coroutine.
 
 .. code-block:: c++
 
@@ -351,8 +351,8 @@ Note how the ``task::promise_type`` has a member variable
 ``std::coroutine_handle<> continuation``. This is the handle of the coroutine
 that will be resumed when the current coroutine is finished executing (see
 ``final_suspend``). In a sense, this is the "return address" of the coroutine.
-It is as soon as the caller coroutine ``co_await`` on the called coroutine in
-``operator co_await``.
+It is set inside ``operator co_await`` when another coroutine calls our
+generator and awaits for the next value to be produced.
 
 The result value is returned via the ``int result`` member. It is written in
 ``return_value`` and read by ``Awaiter::await_resume``. Usually, the result
@@ -425,7 +425,7 @@ script, we can run ``coro bt`` to get the following stack 
trace:
 
 Note how the frames #1 and #2 are async frames.
 
-The ``coro bt`` frame already includes logic to identify the exact suspension
+The ``coro bt`` command already includes logic to identify the exact suspension
 point of each frame based on the ``_coro_suspension_point_addr`` stored inside
 the promise.
 
@@ -900,7 +900,7 @@ Note that this script requires LLDB 21.0 or newer.
   coro_hdl = frame.EvaluateExpression(expr)
   if not coro_hdl.error.Success():
   result.AppendMessage(
-  f'error: expression failed {expr} => {async_root.error}'
+  f'error: expression failed {expr} => {coro_hdl.error}'
   )
   result.SetError(f"Expression `{expr}` failed to evaluate")
   return
@@ -913,7 +913,7 @@ Note that this script requires LLDB 21.0 or newer.
   continuation_paths = continuation_paths)
 
 
-  class Coroin-flightCommand(ParsedCommand):
+  class CoroInflightCommand(ParsedCommand):
   def get_short_help(self):
   return "Identify all in-flight coroutines"
 
@@ -974,7 +974,7 @@ Note that this script requires LLDB 21.0 or newer.
   return
   all_coros.append(entry)
 
-  # Remove all coroutines that have are currently waiting for other 
corouti

[clang] [NFC][docs][coro] Fix syntax & typos (PR #146282)

2025-06-29 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang closed 
https://github.com/llvm/llvm-project/pull/146282
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-06-28 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/141937

>From 185be04e482344ce2f76eeb02859162e1838150e Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 27 May 2025 19:36:42 +
Subject: [PATCH 1/5] [debuginfo][coro] Emit debug info labels for coroutine
 resume points

With this commit, we add `DILabel` debug infos (lowering to DW_TAG_label
in DWARF) to the various resume points of a coroutine. Those labels use
the naming convention `__coro_resume_` where `` is the suspension
point id.

That way, debugging scripts can figure out the exact line / column at
which a coroutine was suspended by looking up current `__coro_index`
value inside the coroutines frame, and then searching for the
corresponding `__coro_resume_` inside the coroutine's resume
function.

While this is an artificial compiler-generated label, I did not apply
the DW_AT_artificial tag to it. The DWARFv5 standard only allows that
tag on type and variable definitions, but not on labels.

In gdb, those line numebers can then be looked up using the command
`info line -function my_coroutine -label __coro_resume_1`.

LLDB unfortunately does not parse DW_TAG_label debug information, yet. As
such, this debug information is currently not useful in LLDB.
---
 clang/docs/DebuggingCoroutines.rst   | 23 
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp |  6 ++--
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 29 +++-
 3 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index c47579bc62e51..c221b2ec9c19b 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -209,9 +209,24 @@ important. This member identifies the suspension point at 
which the coroutine
 is currently suspended.
 
 However, it is non-trivial to map this number back to a source code location.
-In simple cases, one might correctly guess the source code location. In more
-complex cases, we can modify the C++ code to store additional information in
-the promise type:
+The compiler emits debug info labels for the suspension points. This allows us
+to map the suspension point index back to a source code location. In gdb, we
+can use the ``info line`` command to get the source code location of the
+suspension point.
+
+::
+
+  (gdb) info line -function coro_task -label __coro_resume_2
+  Line 45 of "llvm-example.cpp" starts at address 0x1b1b 
<_ZL9coro_taski.resume+555> and ends at 0x1b46 <_ZL9coro_taski.resume+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x201b 
<_ZL9coro_taski.destroy+555> and ends at 0x2046 <_ZL9coro_taski.destroy+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x253b 
<_ZL9coro_taski.cleanup+555> and ends at 0x2566 <_ZL9coro_taski.cleanup+598>.
+
+LLDB does not support looking up labels. Furthmore, those labels are only 
emitted
+starting with clang 21.0.
+
+For simple cases, you might still be able to guess the suspension point 
correctly.
+Alternatively, you might also want to modify your coroutine library to store
+the line number of the current suspension point in the promise:
 
 .. code-block:: c++
 
@@ -221,8 +236,6 @@ the promise type:
 void* _coro_return_address = nullptr;
   };
 
-  #include 
-
   // For all the awaiter types we need:
   class awaiter {
 ...
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp 
b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 1acd9139fe26e..42f8bf91118ae 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -688,9 +688,9 @@ static DIType *solveDIType(DIBuilder &Builder, Type *Ty,
 static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
 FrameDataInfo &FrameData) {
   DISubprogram *DIS = F.getSubprogram();
-  // If there is no DISubprogram for F, it implies the Function are not 
compiled
-  // with debug info. So we also don't need to generate debug info for the 
frame
-  // neither.
+  // If there is no DISubprogram for F, it implies the function is compiled
+  // without debug info. So we also don't generate debug info for the frame,
+  // either.
   if (!DIS || !DIS->getUnit() ||
   !dwarf::isCPlusPlus(
   (dwarf::SourceLanguage)DIS->getUnit()->getSourceLanguage()) ||
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp 
b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 8813f91e9060c..1348d785f4f85 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -42,6 +42,7 @@
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -302,7 +303,7 @@ static void replaceFallthroughCoroEnd(AnyCoroEndInst *End,
 }
 
 // Mark a coroutine as done, which implies that 

[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-03 Thread Adrian Vogelsgesang via cfe-commits

https://github.com/vogelsgesang updated 
https://github.com/llvm/llvm-project/pull/141937

>From 185be04e482344ce2f76eeb02859162e1838150e Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang 
Date: Tue, 27 May 2025 19:36:42 +
Subject: [PATCH 1/9] [debuginfo][coro] Emit debug info labels for coroutine
 resume points

With this commit, we add `DILabel` debug infos (lowering to DW_TAG_label
in DWARF) to the various resume points of a coroutine. Those labels use
the naming convention `__coro_resume_` where `` is the suspension
point id.

That way, debugging scripts can figure out the exact line / column at
which a coroutine was suspended by looking up current `__coro_index`
value inside the coroutines frame, and then searching for the
corresponding `__coro_resume_` inside the coroutine's resume
function.

While this is an artificial compiler-generated label, I did not apply
the DW_AT_artificial tag to it. The DWARFv5 standard only allows that
tag on type and variable definitions, but not on labels.

In gdb, those line numebers can then be looked up using the command
`info line -function my_coroutine -label __coro_resume_1`.

LLDB unfortunately does not parse DW_TAG_label debug information, yet. As
such, this debug information is currently not useful in LLDB.
---
 clang/docs/DebuggingCoroutines.rst   | 23 
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp |  6 ++--
 llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 29 +++-
 3 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/clang/docs/DebuggingCoroutines.rst 
b/clang/docs/DebuggingCoroutines.rst
index c47579bc62e51..c221b2ec9c19b 100644
--- a/clang/docs/DebuggingCoroutines.rst
+++ b/clang/docs/DebuggingCoroutines.rst
@@ -209,9 +209,24 @@ important. This member identifies the suspension point at 
which the coroutine
 is currently suspended.
 
 However, it is non-trivial to map this number back to a source code location.
-In simple cases, one might correctly guess the source code location. In more
-complex cases, we can modify the C++ code to store additional information in
-the promise type:
+The compiler emits debug info labels for the suspension points. This allows us
+to map the suspension point index back to a source code location. In gdb, we
+can use the ``info line`` command to get the source code location of the
+suspension point.
+
+::
+
+  (gdb) info line -function coro_task -label __coro_resume_2
+  Line 45 of "llvm-example.cpp" starts at address 0x1b1b 
<_ZL9coro_taski.resume+555> and ends at 0x1b46 <_ZL9coro_taski.resume+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x201b 
<_ZL9coro_taski.destroy+555> and ends at 0x2046 <_ZL9coro_taski.destroy+598>.
+  Line 45 of "llvm-example.cpp" starts at address 0x253b 
<_ZL9coro_taski.cleanup+555> and ends at 0x2566 <_ZL9coro_taski.cleanup+598>.
+
+LLDB does not support looking up labels. Furthmore, those labels are only 
emitted
+starting with clang 21.0.
+
+For simple cases, you might still be able to guess the suspension point 
correctly.
+Alternatively, you might also want to modify your coroutine library to store
+the line number of the current suspension point in the promise:
 
 .. code-block:: c++
 
@@ -221,8 +236,6 @@ the promise type:
 void* _coro_return_address = nullptr;
   };
 
-  #include 
-
   // For all the awaiter types we need:
   class awaiter {
 ...
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp 
b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 1acd9139fe26e..42f8bf91118ae 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -688,9 +688,9 @@ static DIType *solveDIType(DIBuilder &Builder, Type *Ty,
 static void buildFrameDebugInfo(Function &F, coro::Shape &Shape,
 FrameDataInfo &FrameData) {
   DISubprogram *DIS = F.getSubprogram();
-  // If there is no DISubprogram for F, it implies the Function are not 
compiled
-  // with debug info. So we also don't need to generate debug info for the 
frame
-  // neither.
+  // If there is no DISubprogram for F, it implies the function is compiled
+  // without debug info. So we also don't generate debug info for the frame,
+  // either.
   if (!DIS || !DIS->getUnit() ||
   !dwarf::isCPlusPlus(
   (dwarf::SourceLanguage)DIS->getUnit()->getSourceLanguage()) ||
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp 
b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 8813f91e9060c..1348d785f4f85 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -42,6 +42,7 @@
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -302,7 +303,7 @@ static void replaceFallthroughCoroEnd(AnyCoroEndInst *End,
 }
 
 // Mark a coroutine as done, which implies that 

[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-04 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

Thanks for pinpointing this - https://github.com/llvm/llvm-project/pull/147087

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD alias: Respect explicit deduction guides defined after the first use of the alias template. (PR #125478)

2025-07-08 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

@hokein is there still anything missing to set the feature test macro and mark 
P1814 as done on https://clang.llvm.org/cxx_status.html#cxx26?

https://github.com/llvm/llvm-project/pull/125478
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [debuginfo][coro] Emit debug info labels for coroutine resume points (PR #141937)

2025-07-10 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

I was able to verify that this was indeed the issue by compiling a C++ program 
using `-gmlt`.

Fix is in #148095

https://github.com/llvm/llvm-project/pull/141937
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix FE crash during CGCoroutine GRO Alloca Emission (PR #148962)

2025-07-16 Thread Adrian Vogelsgesang via cfe-commits

vogelsgesang wrote:

> Would like to. Please advise next steps.

efriedma already took care of creating the PR for the backport via the 
`/cherry-pick c36156d` command. It's now up to the original approver 
(@bcardosolopes) to also approve that backport PR. The goal of that second 
review is primarily to judge if this change is carries any risk to destabilize 
the upcoming release. (Usually, I think bug fixes, in particular early during 
the release cycle, carry little risk. That being said, I didn't look at the 
actual code changes here)

https://github.com/llvm/llvm-project/pull/148962
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits