[PATCH] D25258: [coroutines] Create allocation and deallocation sub-statements.

2016-10-20 Thread Gor Nishanov via cfe-commits
GorNishanov abandoned this revision.
GorNishanov added a comment.

I'll simplify and split it into super tiny microscopic patches to have a better 
chance of being reviewed.


https://reviews.llvm.org/D25258



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


[PATCH] D25258: [coroutines] Create allocation and deallocation sub-statements.

2016-10-17 Thread Gor Nishanov via cfe-commits
GorNishanov added a comment.

friendly ping


https://reviews.llvm.org/D25258



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


[PATCH] D25258: [coroutines] Create allocation and deallocation sub-statements.

2016-10-17 Thread Gor Nishanov via cfe-commits
GorNishanov added a comment.

friendly ping


https://reviews.llvm.org/D25258



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


[PATCH] D25258: [coroutines] Create allocation and deallocation sub-statements.

2016-10-06 Thread Gor Nishanov via cfe-commits
GorNishanov updated this revision to Diff 73835.
GorNishanov added a comment.

Addressed review comments. Anything else, @rsmith?

1. compute default new align and pass it to coro.id
2. fix typo in comment


https://reviews.llvm.org/D25258

Files:
  include/clang/AST/StmtCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/CGCoroutine.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Sema/SemaCoroutine.cpp
  test/CodeGenCoroutines/coro-alloc.cpp
  test/SemaCXX/coroutines.cpp

Index: test/SemaCXX/coroutines.cpp
===
--- test/SemaCXX/coroutines.cpp
+++ test/SemaCXX/coroutines.cpp
@@ -143,13 +143,12 @@
 }
 
 void only_coreturn() {
-  co_return; // expected-warning {{'co_return' used in a function that uses neither 'co_await' nor 'co_yield'}}
+  co_return; // OK
 }
 
 void mixed_coreturn(bool b) {
   if (b)
-// expected-warning@+1 {{'co_return' used in a function that uses neither}}
-co_return; // expected-note {{use of 'co_return'}}
+co_return; // expected-note {{use of 'co_return' here}}
   else
 return; // expected-error {{not allowed in coroutine}}
 }
Index: test/CodeGenCoroutines/coro-alloc.cpp
===
--- /dev/null
+++ test/CodeGenCoroutines/coro-alloc.cpp
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s
+
+namespace std {
+namespace experimental {
+template 
+struct coroutine_traits; // expected-note {{declared here}}
+}
+}
+
+struct suspend_always {
+  bool await_ready() { return false; }
+  void await_suspend() {}
+  void await_resume() {}
+};
+
+struct global_new_delete_tag {};
+
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void get_return_object() {}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+  };
+};
+
+// CHECK-LABEL: f0( 
+extern "C" void f0(global_new_delete_tag) {
+  // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
+  // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
+  // CHECK: call i8* @_Znwm(i64 %[[SIZE]])
+
+  // CHECK: coro.destroy.label:
+  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
+  // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
+  // CHECK: call void @_ZdlPv(i8* %[[MEM]])
+  co_return;
+}
+
+struct promise_new_tag {};
+
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void *operator new(unsigned long);
+void get_return_object() {}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+  };
+};
+
+// CHECK-LABEL: f1( 
+extern "C" void f1(promise_new_tag ) {
+  // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
+  // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
+  // CHECK: call i8* @_ZNSt12experimental16coroutine_traitsIJv15promise_new_tagEE12promise_typenwEm(i64 %[[SIZE]])
+
+  // CHECK: coro.destroy.label:
+  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
+  // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
+  // CHECK: call void @_ZdlPv(i8* %[[MEM]])
+  co_return;
+}
+
+struct promise_delete_tag {};
+
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void operator delete(void*);
+void get_return_object() {}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+  };
+};
+
+// CHECK-LABEL: f2( 
+extern "C" void f2(promise_delete_tag) {
+  // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
+  // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
+  // CHECK: call i8* @_Znwm(i64 %[[SIZE]])
+
+  // CHECK: coro.destroy.label:
+  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
+  // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
+  // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJv18promise_delete_tagEE12promise_typedlEPv(i8* %[[MEM]])
+  co_return;
+}
+
+struct promise_sized_delete_tag {};
+
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void operator delete(void*, unsigned long);
+void get_return_object() {}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+  };
+};
+
+// CHECK-LABEL: f3( 
+extern "C" void f3(promise_sized_delete_tag) {
+  // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
+  // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
+  // CHECK: call i8* @_Znwm(i64 %[[SIZE]])
+
+  // CHECK: coro.destroy.label:
+  // CHECK: %[[FRAME:.+]] = call i8* 

[PATCH] D25258: [coroutines] Create allocation and deallocation sub-statements.

2016-10-04 Thread Gor Nishanov via cfe-commits
GorNishanov added inline comments.


> majnemer wrote in CGCoroutine.cpp:68-69
> I think that's just `CGM.getContext().getTargetInfo().getSuitableAlign() / 
> CGM.getContext().getTargetInfo().getCharWidth()`

Yay! One less FIXME.

I think I will make it to match __STDCPP_DEFAULT_NEW_ALIGNMENT__:

  Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__",
  Twine(TI.getNewAlign() / TI.getCharWidth()) +
  TI.getTypeConstantSuffix(TI.getSizeType()));

> SemaCoroutine.cpp:570
> +
> +  // Build allocation function and deallocation expressions.
> +  Expr *Allocation = nullptr;

Remove 'function' from the comment to read:

  // Build allocation and deallocation expressions.

https://reviews.llvm.org/D25258



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


[PATCH] D25258: [coroutines] Create allocation and deallocation sub-statements.

2016-10-04 Thread David Majnemer via cfe-commits
majnemer added inline comments.


> CGCoroutine.cpp:68-69
> +void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt ) {
> +  auto *NullPtr = llvm::ConstantPointerNull::get(Builder.getInt8PtrTy());
> +  // FIXME: Instead of 0, pass an equivalent of alignas(maxalign_t).
> +  auto *CoroId =

I think that's just `CGM.getContext().getTargetInfo().getSuitableAlign() / 
CGM.getContext().getTargetInfo().getCharWidth()`

https://reviews.llvm.org/D25258



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


[PATCH] D25258: [coroutines] Create allocation and deallocation sub-statements.

2016-10-04 Thread Gor Nishanov via cfe-commits
GorNishanov created this revision.
GorNishanov added reviewers: rsmith, EricWF.
GorNishanov added a subscriber: cfe-commits.
Herald added a subscriber: mehdi_amini.

1. Sema: Add allocation / deallocation substatements.
2. Sema: Add labels to final-suspend and deallocation substatements.
3. Sema: Allow co_return in a coroutine all by itself
4. CG: Emit allocation and deallocation + test


https://reviews.llvm.org/D25258

Files:
  include/clang/AST/StmtCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/CGCoroutine.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Sema/SemaCoroutine.cpp
  test/CodeGenCoroutines/coro-alloc.cpp
  test/SemaCXX/coroutines.cpp

Index: test/SemaCXX/coroutines.cpp
===
--- test/SemaCXX/coroutines.cpp
+++ test/SemaCXX/coroutines.cpp
@@ -143,13 +143,12 @@
 }
 
 void only_coreturn() {
-  co_return; // expected-warning {{'co_return' used in a function that uses neither 'co_await' nor 'co_yield'}}
+  co_return; // OK
 }
 
 void mixed_coreturn(bool b) {
   if (b)
-// expected-warning@+1 {{'co_return' used in a function that uses neither}}
-co_return; // expected-note {{use of 'co_return'}}
+co_return; // expected-note {{use of 'co_return' here}}
   else
 return; // expected-error {{not allowed in coroutine}}
 }
Index: test/CodeGenCoroutines/coro-alloc.cpp
===
--- /dev/null
+++ test/CodeGenCoroutines/coro-alloc.cpp
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s
+
+namespace std {
+namespace experimental {
+template 
+struct coroutine_traits; // expected-note {{declared here}}
+}
+}
+
+struct suspend_always {
+  bool await_ready() { return false; }
+  void await_suspend() {}
+  void await_resume() {}
+};
+
+struct global_new_delete_tag {};
+
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void get_return_object() {}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+  };
+};
+
+// CHECK-LABEL: f0( 
+extern "C" void f0(global_new_delete_tag) {
+  // CHECK: %[[ID:.+]] = call token @llvm.coro.id(
+  // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
+  // CHECK: call i8* @_Znwm(i64 %[[SIZE]])
+
+  // CHECK: coro.destroy.label:
+  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
+  // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
+  // CHECK: call void @_ZdlPv(i8* %[[MEM]])
+  co_return;
+}
+
+struct promise_new_tag {};
+
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void *operator new(unsigned long);
+void get_return_object() {}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+  };
+};
+
+// CHECK-LABEL: f1( 
+extern "C" void f1(promise_new_tag ) {
+  // CHECK: %[[ID:.+]] = call token @llvm.coro.id(
+  // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
+  // CHECK: call i8* @_ZNSt12experimental16coroutine_traitsIJv15promise_new_tagEE12promise_typenwEm(i64 %[[SIZE]])
+
+  // CHECK: coro.destroy.label:
+  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
+  // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
+  // CHECK: call void @_ZdlPv(i8* %[[MEM]])
+  co_return;
+}
+
+struct promise_delete_tag {};
+
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void operator delete(void*);
+void get_return_object() {}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+  };
+};
+
+// CHECK-LABEL: f2( 
+extern "C" void f2(promise_delete_tag) {
+  // CHECK: %[[ID:.+]] = call token @llvm.coro.id(
+  // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
+  // CHECK: call i8* @_Znwm(i64 %[[SIZE]])
+
+  // CHECK: coro.destroy.label:
+  // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame()
+  // CHECK: %[[MEM:.+]] = call i8* @llvm.coro.free(token %[[ID]], i8* %[[FRAME]])
+  // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJv18promise_delete_tagEE12promise_typedlEPv(i8* %[[MEM]])
+  co_return;
+}
+
+struct promise_sized_delete_tag {};
+
+template<>
+struct std::experimental::coroutine_traits {
+  struct promise_type {
+void operator delete(void*, unsigned long);
+void get_return_object() {}
+suspend_always initial_suspend() { return {}; }
+suspend_always final_suspend() { return {}; }
+void return_void() {}
+  };
+};
+
+// CHECK-LABEL: f3( 
+extern "C" void f3(promise_sized_delete_tag) {
+  // CHECK: %[[ID:.+]] = call token @llvm.coro.id(
+  // CHECK: