[cfe-commits] r150644 - in /cfe/trunk: lib/CodeGen/CGCall.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGenObjC/arc-no-arc-exceptions.m

Dan Gohman gohman at apple.com
Wed Feb 15 16:57:37 PST 2012


Author: djg
Date: Wed Feb 15 18:57:37 2012
New Revision: 150644

URL: http://llvm.org/viewvc/llvm-project?rev=150644&view=rev
Log:
Teach clang to add metadata tags to calls and invokes in ObjC with
-fno-objc-arc-exceptions. This will allow the optimizer to perform
optimizations which are only safe under that flag.

This is a part of rdar://10803830.

Added:
    cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m
Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=150644&r1=150643&r2=150644&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Feb 15 18:57:37 2012
@@ -1593,6 +1593,16 @@
   args.add(EmitAnyExprToTemp(E), type);
 }
 
+// In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
+// optimizer it can aggressively ignore unwind edges.
+void
+CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
+  if (CGM.getCodeGenOpts().OptimizationLevel != 0 &&
+      !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
+    Inst->setMetadata("clang.arc.no_objc_arc_exceptions",
+                      CGM.getNoObjCARCExceptionsMetadata());
+}
+
 /// Emits a call or invoke instruction to the given function, depending
 /// on the current state of the EH stack.
 llvm::CallSite
@@ -1600,14 +1610,22 @@
                                   ArrayRef<llvm::Value *> Args,
                                   const Twine &Name) {
   llvm::BasicBlock *InvokeDest = getInvokeDest();
+
+  llvm::Instruction *Inst;
   if (!InvokeDest)
-    return Builder.CreateCall(Callee, Args, Name);
+    Inst = Builder.CreateCall(Callee, Args, Name);
+  else {
+    llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont");
+    Inst = Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, Name);
+    EmitBlock(ContBB);
+  }
+
+  // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
+  // optimizer it can aggressively ignore unwind edges.
+  if (CGM.getLangOptions().ObjCAutoRefCount)
+    AddObjCARCExceptionMetadata(Inst);
 
-  llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont");
-  llvm::InvokeInst *Invoke = Builder.CreateInvoke(Callee, ContBB, InvokeDest,
-                                                  Args, Name);
-  EmitBlock(ContBB);
-  return Invoke;
+  return Inst;
 }
 
 llvm::CallSite
@@ -1916,6 +1934,11 @@
   CS.setAttributes(Attrs);
   CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
 
+  // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
+  // optimizer it can aggressively ignore unwind edges.
+  if (CGM.getLangOptions().ObjCAutoRefCount)
+    AddObjCARCExceptionMetadata(CS.getInstruction());
+
   // If the call doesn't return, finish the basic block and clear the
   // insertion point; this allows the rest of IRgen to discard
   // unreachable code.

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=150644&r1=150643&r2=150644&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Feb 15 18:57:37 2012
@@ -2566,6 +2566,8 @@
   CodeGenModule::ByrefHelpers *
   buildByrefHelpers(llvm::StructType &byrefType,
                     const AutoVarEmission &emission);
+
+  void AddObjCARCExceptionMetadata(llvm::Instruction *Inst);
 };
 
 /// Helper class with most of the code for saving a value for a

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=150644&r1=150643&r2=150644&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Feb 15 18:57:37 2012
@@ -69,7 +69,8 @@
     Types(C, M, TD, getTargetCodeGenInfo().getABIInfo(), ABI, CGO),
     TBAA(0),
     VTables(*this), ObjCRuntime(0), OpenCLRuntime(0), CUDARuntime(0),
-    DebugInfo(0), ARCData(0), RRData(0), CFConstantStringClassRef(0),
+    DebugInfo(0), ARCData(0), NoObjCARCExceptionsMetadata(0),
+    RRData(0), CFConstantStringClassRef(0),
     ConstantStringClassRef(0), NSConstantStringType(0),
     VMContext(M.getContext()),
     NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=150644&r1=150643&r2=150644&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Feb 15 18:57:37 2012
@@ -233,6 +233,7 @@
   CGCUDARuntime* CUDARuntime;
   CGDebugInfo* DebugInfo;
   ARCEntrypoints *ARCData;
+  llvm::MDNode *NoObjCARCExceptionsMetadata;
   RREntrypoints *RRData;
 
   // WeakRefReferences - A set of references that have only been seen via
@@ -421,6 +422,14 @@
 
   CGDebugInfo *getModuleDebugInfo() { return DebugInfo; }
 
+  llvm::MDNode *getNoObjCARCExceptionsMetadata() {
+    if (!NoObjCARCExceptionsMetadata)
+      NoObjCARCExceptionsMetadata =
+        llvm::MDNode::get(getLLVMContext(),
+                          SmallVector<llvm::Value*,1>());
+    return NoObjCARCExceptionsMetadata;
+  }
+
   ASTContext &getContext() const { return Context; }
   const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
   const LangOptions &getLangOptions() const { return Features; }

Added: cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m?rev=150644&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m (added)
+++ cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m Wed Feb 15 18:57:37 2012
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -O0 -disable-llvm-optzns -o - %s | FileCheck -check-prefix=NO-METADATA %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fblocks -fexceptions -fobjc-exceptions -O2 -disable-llvm-optzns -o - %s -fobjc-arc-exceptions | FileCheck -check-prefix=NO-METADATA %s
+
+// The front-end should emit clang.arc.no_objc_arc_exceptions in -fobjc-arc-exceptions
+// mode when optimization is enabled, and not otherwise.
+
+void thrower(void);
+void not(void) __attribute__((nothrow));
+
+// CHECK: define void @test0(
+// CHECK: call void @thrower(), !clang.arc.no_objc_arc_exceptions !0
+// CHECK: call void @not() nounwind, !clang.arc.no_objc_arc_exceptions !0
+// NO-METADATA: define void @test0(
+// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
+// NO-METADATA: }
+void test0(void) {
+  thrower();
+  not();
+}
+
+// CHECK: define void @test1(
+// CHECK: call void @thrower(), !clang.arc.no_objc_arc_exceptions !0
+// CHECK: call void @not() nounwind, !clang.arc.no_objc_arc_exceptions !0
+// NO-METADATA: define void @test1(
+// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
+// NO-METADATA: }
+void test1(id x) {
+  id y = x;
+  thrower();
+  not();
+}
+
+void NSLog(id, ...);
+
+// CHECK: define void @test2(
+// CHECK: invoke void (i8*, ...)* @NSLog(i8* bitcast (%struct.NSConstantString* @_unnamed_cfstring_ to i8*), i32* %x2)
+// CHECK:   to label %invoke.cont unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
+// NO-METADATA: define void @test2(
+// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
+// NO-METADATA: }
+void test2(void) {
+    @autoreleasepool {
+        __attribute__((__blocks__(byref))) int x;
+        NSLog(@"Address of x outside of block: %p", &x);
+    }
+}
+
+// CHECK: define void @test3(
+// CHECK: invoke void %9(i8* %7)
+// CHECK:   to label %invoke.cont unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
+// NO-METADATA: define void @test3(
+// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
+// NO-METADATA: }
+void test3(void) {
+    @autoreleasepool {
+        __attribute__((__blocks__(byref))) int x;
+        ^{
+            NSLog(@"Address of x in non-assigned block: %p", &x);
+        }();
+    }
+}
+
+// CHECK: define void @test4(
+// CHECK: invoke void %13(i8* %11)
+// CHECK:   to label %invoke.cont unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
+// NO-METADATA: define void @test4(
+// NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions
+// NO-METADATA: }
+void test4(void) {
+    @autoreleasepool {
+        __attribute__((__blocks__(byref))) int x;
+        void (^b)(void) = ^{
+            NSLog(@"Address of x in assigned block: %p", &x);
+        };
+        b();
+    }
+}





More information about the cfe-commits mailing list