junbuml created this revision.
junbuml added reviewers: hfinkel, mcrosier, reames, ashutosh.nema, majnemer.
junbuml added subscribers: gberry, cfe-commits.

It might be reasonably to avoid inlining CallSites invoked in
exception handling context so that we can reduce code size blow-up in
EH regions as well as indirectly increase inline opportunites for unwinding
functions containing exception handling code.

In this change, the NoInline attribute is added in CallSites
invoked specifically by the throw statement.

http://reviews.llvm.org/D13304

Files:
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGException.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGenCXX/throw-expressions.cpp

Index: test/CodeGenCXX/throw-expressions.cpp
===================================================================
--- test/CodeGenCXX/throw-expressions.cpp
+++ test/CodeGenCXX/throw-expressions.cpp
@@ -112,3 +112,14 @@
   // CHECK: ret i32* @val
   return cond ? val : ((throw "foo"));
 }
+
+// CHECK-LABEL: _Z5test9v
+// CHECK: invoke void @_ZN2EHC1Ev(%class.EH* %0) [[ATTR_NUM:#[0-9]+]]
+// CHECK: attributes [[ATTR_NUM]] = { cold noinline }
+class EH {
+public :
+  EH();
+};
+void test9() {
+  throw EH();
+}
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -283,6 +283,11 @@
   /// finally block or filter expression.
   bool IsOutlinedSEHHelper;
 
+  // True if the current insertion point is in cold regions (e.g., exception
+  // handling regions). As of now, this flag is ture only when handling throw
+  // statement.
+  bool IsColdRegion;
+
   const CodeGen::CGBlockInfo *BlockInfo;
   llvm::Value *BlockPointer;
 
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -44,7 +44,7 @@
       CapturedStmtInfo(nullptr),
       SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false),
       CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false),
-      IsOutlinedSEHHelper(false),
+      IsOutlinedSEHHelper(false), IsColdRegion(false),
       BlockInfo(nullptr), BlockPointer(nullptr),
       LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
       NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
Index: lib/CodeGen/CGException.cpp
===================================================================
--- lib/CodeGen/CGException.cpp
+++ lib/CodeGen/CGException.cpp
@@ -400,6 +400,11 @@
 
 void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,
                                        bool KeepInsertionPoint) {
+  // While handling the throw statement, inform that the insertion point is in
+  // cold regions so that we could perform cold region specific IR generation.
+  // For example, the NoInline attribute could be added in CallSites in throw
+  // statements.
+  IsColdRegion = true;
   if (const Expr *SubExpr = E->getSubExpr()) {
     QualType ThrowType = SubExpr->getType();
     if (ThrowType->isObjCObjectPointerType()) {
@@ -417,6 +422,9 @@
   // to leave ourselves at a valid insertion point.
   if (KeepInsertionPoint)
     EmitBlock(createBasicBlock("throw.cont"));
+
+  IsColdRegion = false;
+  // FIXME: Similarly, we could set IsColdRegion for catch blocks in ExitCXXTryStmt().
 }
 
 void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -3464,6 +3464,27 @@
         Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
                            llvm::Attribute::NoInline);
 
+  // As of now, IsColdRegion is true only while handling throw statements.
+  // It might be reasonable to avoid inlining CallSites invoked in exception
+  // handling context so that we can reduce code size blow-up in EH regions
+  // as well as indirectly increase inline opportunities for unwinding
+  // functions containing exception handling code.
+  if (IsColdRegion) {
+    // FIXME: We add both NoInline and Cold because the inline cold-threshold
+    // is not tuned yet (r200898). As of now, considering that CallSites in
+    // exception handling regions are very cold is not unreasonable even without
+    // profiling, and avoiding inlining in exception handling region may not have
+    // significant impacts on performance unless a program execution logic
+    // really depends on exception handling flows. However, when the inline
+    // cold-threshold is tuned, we may need to remove NoInline here so that we
+    // can allow a trivial constructor to be inlined.
+    Attrs =
+        Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
+                           llvm::Attribute::NoInline);
+    Attrs =
+        Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
+                           llvm::Attribute::Cold);
+  }
   CS.setAttributes(Attrs);
   CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to