ahatanak updated this revision to Diff 84434.
ahatanak added a comment.

Remove lifetime markers completely for variables that are declared after a 
label was seen in a compound statement

I tested this patch building llvm's test-suite and SPEC benchmarks with -Os. 
Surprisingly (maybe not so surprising), none of the 3000+ object files changed, 
so I think removing the markers should be fine at least for now.


https://reviews.llvm.org/D27680

Files:
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  test/CodeGen/lifetime2.c

Index: test/CodeGen/lifetime2.c
===================================================================
--- test/CodeGen/lifetime2.c
+++ test/CodeGen/lifetime2.c
@@ -1,7 +1,7 @@
-// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefixes=CHECK,O2
-// RUN: %clang -S -emit-llvm -o - -O2 -Xclang -disable-lifetime-markers %s \
+// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s -check-prefixes=CHECK,O2
+// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-lifetime-markers %s \
 // RUN:       | FileCheck %s -check-prefixes=CHECK,O0
-// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
+// RUN: %clang_cc1 -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
 
 extern int bar(char *A, int n);
 
@@ -25,13 +25,11 @@
   char x;
 l1:
   bar(&x, 1);
-  // O2: @llvm.lifetime.start(i64 5
-  // O2: @llvm.lifetime.end(i64 5
   char y[5];
   bar(y, 5);
   goto l1;
   // Infinite loop
-  // O2-NOT: @llvm.lifetime.end(i64 1
+  // O2-NOT: @llvm.lifetime.end(
 }
 
 // CHECK-LABEL: @goto_bypass
@@ -91,3 +89,24 @@
 L:
   bar(&x, 1);
 }
+
+// O2-LABEL: define i32 @jump_backward_over_declaration(
+// O2-NOT: call void @llvm.lifetime.{{.*}}(i64 4,
+
+extern void foo2(int p);
+
+int jump_backward_over_declaration(int a) {
+  int *p = 0;
+label1:
+  if (p) {
+    foo2(*p);
+    return 0;
+  }
+
+  int i = 999;
+  if (a != 2) {
+    p = &i;
+    goto label1;
+  }
+  return -1;
+}
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -212,6 +212,33 @@
   /// value. This is invalid iff the function has no return value.
   Address ReturnValue;
 
+  /// This is used to keep track of whether a label was seen in compound
+  /// statements.
+  llvm::SmallVector<bool, 4> LabelSeenStack;
+
+  /// RAII class to push and pop LabelSeenStack.
+  class LabelSeenRAII {
+    CodeGenFunction &CGF;
+  public:
+    LabelSeenRAII(CodeGenFunction &CGF) : CGF(CGF) {
+      CGF.LabelSeenStack.push_back(false);
+    }
+
+    ~LabelSeenRAII() {
+      bool LabelSeen = CGF.LabelSeenStack.pop_back_val();
+      if (!CGF.LabelSeenStack.empty())
+        CGF.LabelSeenStack.back() |= LabelSeen;
+    }
+  };
+
+  void setLabelSeen() {
+    LabelSeenStack.back() = true;
+  }
+
+  bool labelSeen() const {
+    return LabelSeenStack.back();
+  }
+
   /// AllocaInsertPoint - This is an instruction in the entry block before which
   /// we prefer to insert allocas.
   llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp
+++ lib/CodeGen/CGStmt.cpp
@@ -375,6 +375,7 @@
 CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S,
                                               bool GetLast,
                                               AggValueSlot AggSlot) {
+  LabelSeenRAII LabelSeen(*this);
 
   for (CompoundStmt::const_body_iterator I = S.body_begin(),
        E = S.body_end()-GetLast; I != E; ++I)
@@ -550,6 +551,7 @@
 
 
 void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
+  setLabelSeen();
   EmitLabel(S.getDecl());
   EmitStmt(S.getSubStmt());
 }
Index: lib/CodeGen/CGDecl.cpp
===================================================================
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -1026,7 +1026,11 @@
         // regions which need more efforts to handle them correctly. PR28267
         // This is rare case, but it's better just omit intrinsics than have
         // them incorrectly placed.
-        if (!Bypasses.IsBypassed(&D)) {
+        //
+        // Skip emitting lifetime intrinsics when a label was seen in the
+        // current compound statement and we are compiling for C.
+        if (!Bypasses.IsBypassed(&D) &&
+            !(!getLangOpts().CPlusPlus && labelSeen())) {
           uint64_t size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
           emission.SizeForLifetimeMarkers =
               EmitLifetimeStart(size, address.getPointer());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to