[PATCH] D47988: [CodeGen] Emit MSVC funclet IR for Obj-C exceptions

2018-06-22 Thread Shoaib Meenai via Phabricator via cfe-commits
smeenai added inline comments.



Comment at: lib/CodeGen/CGCXXABI.h:248
+llvm_unreachable("Only needed for the Microsoft ABI");
+  }
 

rjmccall wrote:
> Should you just generalize the existing method to only take a VarDecl* so it 
> can be used for either kind of catch?
The Itanium version of emitBeginCatch actually uses the statement for location 
info (it calls `getLocStart` on it). I suppose I could generalize the existing 
method to take both a VarDecl* and a SourceLocation though.


Repository:
  rC Clang

https://reviews.llvm.org/D47988



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


[PATCH] D47988: [CodeGen] Emit MSVC funclet IR for Obj-C exceptions

2018-06-18 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

In https://reviews.llvm.org/D47988#1135929, @rnk wrote:

> In https://reviews.llvm.org/D47988#1135533, @rjmccall wrote:
>
> > In general, it's unfortunate that this has to leave so many 
> > C++-runtime-specific tendrils in the ObjC code.  Unlike the EH type patch, 
> > though, I'm not sure I can see a great alternative here, especially because 
> > of the semantic restrictions required by outlining.
>
>
> It's technically possible to lift those restrictions by returning an i32 from 
> the outlined function and switching on it. Right? The question is, is it 
> worth it? The catch funclet would effectively store the i32 to the stack 
> frame, then "catchret" via the runtime, and then we'd switch out to the jump 
> target.


I don't think it's important.  Uses of control flow out of `@finally` are rare, 
and we could probably forbid it entirely without significant loss.


Repository:
  rC Clang

https://reviews.llvm.org/D47988



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


[PATCH] D47988: [CodeGen] Emit MSVC funclet IR for Obj-C exceptions

2018-06-18 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

In https://reviews.llvm.org/D47988#1135533, @rjmccall wrote:

> In general, it's unfortunate that this has to leave so many 
> C++-runtime-specific tendrils in the ObjC code.  Unlike the EH type patch, 
> though, I'm not sure I can see a great alternative here, especially because 
> of the semantic restrictions required by outlining.


It's technically possible to lift those restrictions by returning an i32 from 
the outlined function and switching on it. Right? The question is, is it worth 
it? The catch funclet would effectively store the i32 to the stack frame, then 
"catchret" via the runtime, and then we'd switch out to the jump target.


Repository:
  rC Clang

https://reviews.llvm.org/D47988



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


[PATCH] D47988: [CodeGen] Emit MSVC funclet IR for Obj-C exceptions

2018-06-18 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

In general, it's unfortunate that this has to leave so many 
C++-runtime-specific tendrils in the ObjC code.  Unlike the EH type patch, 
though, I'm not sure I can see a great alternative here, especially because of 
the semantic restrictions required by outlining.




Comment at: lib/CodeGen/CGCXXABI.h:248
+llvm_unreachable("Only needed for the Microsoft ABI");
+  }
 

Should you just generalize the existing method to only take a VarDecl* so it 
can be used for either kind of catch?


Repository:
  rC Clang

https://reviews.llvm.org/D47988



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


[PATCH] D47988: [CodeGen] Emit MSVC funclet IR for Obj-C exceptions

2018-06-18 Thread Shoaib Meenai via Phabricator via cfe-commits
smeenai added a comment.

Ping.


Repository:
  rC Clang

https://reviews.llvm.org/D47988



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


[PATCH] D47988: [CodeGen] Emit MSVC funclet IR for Obj-C exceptions

2018-06-12 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

In https://reviews.llvm.org/D47988#1127432, @smeenai wrote:

> Any idea why we would see inlining in one case and not the other? i686 vs. 
> x86-64 doesn't make any difference, and neither does -Os vs. -O1 vs. -O2.


My theory is that the inliner is attempting to avoid inlining on cold codepaths 
that are post-dominated by unreachable. When you put an outer try around it, 
the function may continue by unwinding, so the inline cost analysis gives 
different results. Of course, that's all just a wild guess.


Repository:
  rC Clang

https://reviews.llvm.org/D47988



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


[PATCH] D47988: [CodeGen] Emit MSVC funclet IR for Obj-C exceptions

2018-06-09 Thread Shoaib Meenai via Phabricator via cfe-commits
smeenai added a comment.

@rnk remember how I was asking you about inlining into catchpads on IRC a few 
days back? It was in relation to this change.

If I have a file `finally1.m`:

  void f(void);
  void g() {
@try {
  f();
} @finally {
  f();
}
  }

and compile it with:

  clang -cc1 -triple i686-windows-msvc -fobjc-runtime=ios-6.0 -fexceptions 
-fobjc-exceptions -Os -emit-llvm -o - finally1.m

the @finally calls out to the captured statement instead of inlining it:

  finally.catchall: ; preds = %catch.dispatch
%1 = catchpad within %0 [i8* null, i32 64, i8* null]
call fastcc void @__captured_stmt() [ "funclet"(token %1) ]
call void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #3 [ 
"funclet"(token %1) ]
unreachable

If I add an outer try-catch scope, as in `finally2.m`:

  void f(void);
  void g() {
@try {
  @try {
f();
  } @finally {
f();
  }
} @catch (...) {
}
  }

and run the same compilation command:

  clang -cc1 -triple i686-windows-msvc -fobjc-runtime=ios-6.0 -fexceptions 
-fobjc-exceptions -Os -emit-llvm -o - finally2.m

the @finally inlines the captured statement:

  finally.catchall: ; preds = %catch.dispatch
%2 = catchpad within %0 [i8* null, i32 64, i8* null]
invoke void @f() #2 [ "funclet"(token %2) ]
to label %invoke.cont1 unwind label %catch.dispatch4
  
  invoke.cont1: ; preds = %finally.catchall
invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #3 [ 
"funclet"(token %2) ]
to label %unreachable unwind label %catch.dispatch4

Any idea why we would see inlining in one case and not the other? i686 vs. 
x86-64 doesn't make any difference, and neither does -Os vs. -O1 vs. -O2.


Repository:
  rC Clang

https://reviews.llvm.org/D47988



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


[PATCH] D47988: [CodeGen] Emit MSVC funclet IR for Obj-C exceptions

2018-06-09 Thread Shoaib Meenai via Phabricator via cfe-commits
smeenai created this revision.
smeenai added reviewers: DHowett-MSFT, compnerd, majnemer, rjmccall, rnk.

We're implementing funclet-compatible code generation for Obj-C
exceptions when using the MSVC ABI. The idea is that the Obj-C runtime
will wrap Obj-C exceptions inside C++ exceptions, which allows for
interoperability with C++ exceptions (for Obj-C++) and zero-cost
exceptions. This is the approach taken by e.g. WinObjC, and I believe it
to be the best approach for Obj-C exceptions in the MSVC ABI.

This change implements emitting the actual funclet-compatible IR. The
generic exceptions codegen already takes care of emitting the proper
catch dispatch structures, but we need to ensure proper handling of
catch parameters and scoping (emitting the catchret). Finally blocks are
handled quite differently from Itanium; they're expected to be outlined
by the frontend, which limits some control flow possibilities but also
greatly simplifies their codegen. See r334251 for further discussion of
why frontend outlining is used.

Worked on with Saleem Abdulrasool .


Repository:
  rC Clang

https://reviews.llvm.org/D47988

Files:
  lib/CodeGen/CGCXXABI.h
  lib/CodeGen/CGException.cpp
  lib/CodeGen/CGObjCGNU.cpp
  lib/CodeGen/CGObjCMac.cpp
  lib/CodeGen/CGObjCRuntime.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGenObjC/catch-lexical-block.m
  test/CodeGenObjC/exceptions-msvc.m

Index: test/CodeGenObjC/exceptions-msvc.m
===
--- test/CodeGenObjC/exceptions-msvc.m
+++ test/CodeGenObjC/exceptions-msvc.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple i686--windows-msvc -fobjc-runtime=ios-6.0 -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X86 %s
-// RUN: %clang_cc1 -triple i686--windows-msvc -fobjc-runtime=ios-6.0 -fobjc-arc -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X86 %s
-// RUN: %clang_cc1 -triple x86_64--windows-msvc -fobjc-runtime=ios-6.0 -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X64 %s
-// RUN: %clang_cc1 -triple x86_64--windows-msvc -fobjc-runtime=ios-6.0 -fobjc-arc -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X64 %s
+// RUN: %clang_cc1 -triple i686--windows-msvc -fobjc-runtime=ios-6.0 -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X86 --enable-var-scope %s
+// RUN: %clang_cc1 -triple i686--windows-msvc -fobjc-runtime=ios-6.0 -fobjc-arc -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X86,ARC --enable-var-scope %s
+// RUN: %clang_cc1 -triple x86_64--windows-msvc -fobjc-runtime=ios-6.0 -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X64 --enable-var-scope %s
+// RUN: %clang_cc1 -triple x86_64--windows-msvc -fobjc-runtime=ios-6.0 -fobjc-arc -fdeclspec -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK,X64,ARC --enable-var-scope %s
 
 #if __has_feature(objc_arc)
 #define WEAK __weak
@@ -67,8 +67,9 @@
 @protocol P;
 
 void f(void);
+void __declspec(nothrow) g(void);
 
-void g() {
+void generate_ehtypes() {
   @try {
 f();
   } @catch (I *) {
@@ -79,3 +80,393 @@
   } @catch (id) {
   }
 }
+
+void basic_try_catch_1() {
+  @try {
+f();
+  } @catch (...) {
+g();
+  }
+}
+
+// CHECK-LABEL: define {{.*}}void @basic_try_catch_1(){{.*}} {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:invoke void @f()
+// CHECK-NEXT:to label %[[INVOKECONT:[^ ]+]] unwind label %[[DISPATCH:[^ ]+]]
+// CHECK:   [[DISPATCH]]:
+// CHECK-NEXT:%[[CATCHSWITCH:[^ ]+]] = catchswitch within none [label %[[CATCH:[^ ]+]]] unwind to caller
+// CHECK:   [[INVOKECONT]]:
+// CHECK-NEXT:br label %[[EHCONT:[^ ]+]]
+// CHECK:   [[EHCONT]]:
+// CHECK-NEXT:ret void
+// CHECK:   [[CATCH]]:
+// CHECK-NEXT:%[[CATCHPAD:[^ ]+]] = catchpad within %[[CATCHSWITCH]] [i8* null, i32 64, i8* null]
+// CHECK-NEXT:call void @g(){{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT:catchret from %[[CATCHPAD]] to label %[[CATCHRETDEST:[^ ]+]]
+// CHECK:   [[CATCHRETDEST]]:
+// CHECK-NEXT:br label %[[EHCONT]]
+// CHECK-NEXT:  }
+
+void basic_try_catch_2() {
+  @try {
+f();
+  } @catch (id) {
+g();
+  }
+}
+
+// CHECK-LABEL: define {{.*}}void @basic_try_catch_2(){{.*}} {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:invoke void @f()
+// CHECK-NEXT:to label %[[INVOKECONT:[^ ]+]] unwind label %[[DISPATCH:[^ ]+]]
+// CHECK:   [[DISPATCH]]:
+// CHECK-NEXT:%[[CATCHSWITCH:[^ ]+]] = catchswitch within none [label %[[CATCH:[^ ]+]]] unwind to caller
+// CHECK:   [[INVOKECONT]]:
+// CHECK-NEXT:br label %[[EHCONT:[^ ]+]]
+// CHECK:   [[EHCONT]]:
+// CHECK-NEXT:ret void
+// CHECK: