[PATCH] D24695: [CodeGen] Move shouldEmitLifetimeMarkers into more convenient place

2016-10-25 Thread Vitaly Buka via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL285158: [CodeGen] Move shouldEmitLifetimeMarkers into more 
convenient place (authored by vitalybuka).

Changed prior to commit:
  https://reviews.llvm.org/D24695?vs=72908=75827#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D24695

Files:
  cfe/trunk/lib/CodeGen/CGDecl.cpp
  cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
  cfe/trunk/lib/CodeGen/CodeGenFunction.h

Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h
===
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h
@@ -1186,6 +1186,9 @@
   llvm::BasicBlock *TerminateHandler;
   llvm::BasicBlock *TrapBB;
 
+  /// True if we need emit the life-time markers.
+  const bool ShouldEmitLifetimeMarkers;
+
   /// Add a kernel metadata node to the named metadata node 'opencl.kernels'.
   /// In the kernel metadata node, reference the kernel function and metadata 
   /// nodes for its optional attribute qualifiers (OpenCL 1.1 6.7.2):
Index: cfe/trunk/lib/CodeGen/CGDecl.cpp
===
--- cfe/trunk/lib/CodeGen/CGDecl.cpp
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp
@@ -885,29 +885,12 @@
   EmitAutoVarCleanups(emission);
 }
 
-/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
-/// markers.
-static bool shouldEmitLifetimeMarkers(const CodeGenOptions ,
-  const LangOptions ) {
-  // Asan uses markers for use-after-scope checks.
-  if (CGOpts.SanitizeAddressUseAfterScope)
-return true;
-
-  // Disable lifetime markers in msan builds.
-  // FIXME: Remove this when msan works with lifetime markers.
-  if (LangOpts.Sanitize.has(SanitizerKind::Memory))
-return false;
-
-  // For now, only in optimized builds.
-  return CGOpts.OptimizationLevel != 0;
-}
-
 /// Emit a lifetime.begin marker if some criteria are satisfied.
 /// \return a pointer to the temporary size Value if a marker was emitted, null
 /// otherwise
 llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
 llvm::Value *Addr) {
-  if (!shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), getLangOpts()))
+  if (!ShouldEmitLifetimeMarkers)
 return nullptr;
 
   llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
Index: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
===
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
@@ -38,29 +38,46 @@
 using namespace clang;
 using namespace CodeGen;
 
+/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
+/// markers.
+static bool shouldEmitLifetimeMarkers(const CodeGenOptions ,
+  const LangOptions ) {
+  // Asan uses markers for use-after-scope checks.
+  if (CGOpts.SanitizeAddressUseAfterScope)
+return true;
+
+  // Disable lifetime markers in msan builds.
+  // FIXME: Remove this when msan works with lifetime markers.
+  if (LangOpts.Sanitize.has(SanitizerKind::Memory))
+return false;
+
+  // For now, only in optimized builds.
+  return CGOpts.OptimizationLevel != 0;
+}
+
 CodeGenFunction::CodeGenFunction(CodeGenModule , bool suppressNewContext)
 : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
   Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
   CGBuilderInserterTy(this)),
   CurFn(nullptr), ReturnValue(Address::invalid()),
-  CapturedStmtInfo(nullptr),
-  SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false),
-  CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false),
-  IsOutlinedSEHHelper(false),
-  BlockInfo(nullptr), BlockPointer(nullptr),
-  LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
-  NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
-  ExceptionSlot(nullptr), EHSelectorSlot(nullptr),
-  DebugInfo(CGM.getModuleDebugInfo()),
+  CapturedStmtInfo(nullptr), SanOpts(CGM.getLangOpts().Sanitize),
+  IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false),
+  SawAsmBlock(false), IsOutlinedSEHHelper(false), BlockInfo(nullptr),
+  BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
+  NormalCleanupDest(nullptr), NextCleanupDestIndex(1),
+  FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
+  EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()),
   DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
   PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr),
   CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0),
   NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr),
   CXXABIThisValue(nullptr), CXXThisValue(nullptr),
   CXXStructorImplicitParamDecl(nullptr),

Re: [PATCH] D24695: [CodeGen] Move shouldEmitLifetimeMarkers into more convenient place

2016-09-28 Thread Vitaly Buka via cfe-commits
vitalybuka updated this revision to Diff 72908.
vitalybuka added a comment.

rebase


https://reviews.llvm.org/D24695

Files:
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h

Index: lib/CodeGen/CodeGenFunction.h
===
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -1175,6 +1175,9 @@
   llvm::BasicBlock *TerminateHandler;
   llvm::BasicBlock *TrapBB;
 
+  /// True if we need emit the life-time markers.
+  const bool ShouldEmitLifetimeMarkers;
+
   /// Add a kernel metadata node to the named metadata node 'opencl.kernels'.
   /// In the kernel metadata node, reference the kernel function and metadata 
   /// nodes for its optional attribute qualifiers (OpenCL 1.1 6.7.2):
Index: lib/CodeGen/CodeGenFunction.cpp
===
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -38,29 +38,46 @@
 using namespace clang;
 using namespace CodeGen;
 
+/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
+/// markers.
+static bool shouldEmitLifetimeMarkers(const CodeGenOptions ,
+  const LangOptions ) {
+  // Asan uses markers for use-after-scope checks.
+  if (CGOpts.SanitizeAddressUseAfterScope)
+return true;
+
+  // Disable lifetime markers in msan builds.
+  // FIXME: Remove this when msan works with lifetime markers.
+  if (LangOpts.Sanitize.has(SanitizerKind::Memory))
+return false;
+
+  // For now, only in optimized builds.
+  return CGOpts.OptimizationLevel != 0;
+}
+
 CodeGenFunction::CodeGenFunction(CodeGenModule , bool suppressNewContext)
 : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
   Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
   CGBuilderInserterTy(this)),
   CurFn(nullptr), ReturnValue(Address::invalid()),
-  CapturedStmtInfo(nullptr),
-  SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false),
-  CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false),
-  IsOutlinedSEHHelper(false),
-  BlockInfo(nullptr), BlockPointer(nullptr),
-  LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
-  NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
-  ExceptionSlot(nullptr), EHSelectorSlot(nullptr),
-  DebugInfo(CGM.getModuleDebugInfo()),
+  CapturedStmtInfo(nullptr), SanOpts(CGM.getLangOpts().Sanitize),
+  IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false),
+  SawAsmBlock(false), IsOutlinedSEHHelper(false), BlockInfo(nullptr),
+  BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
+  NormalCleanupDest(nullptr), NextCleanupDestIndex(1),
+  FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
+  EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()),
   DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
   PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr),
   CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0),
   NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr),
   CXXABIThisValue(nullptr), CXXThisValue(nullptr),
   CXXStructorImplicitParamDecl(nullptr),
   CXXStructorImplicitParamValue(nullptr), OutermostConditional(nullptr),
   CurLexicalScope(nullptr), TerminateLandingPad(nullptr),
-  TerminateHandler(nullptr), TrapBB(nullptr) {
+  TerminateHandler(nullptr), TrapBB(nullptr),
+  ShouldEmitLifetimeMarkers(
+  shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) {
   if (!suppressNewContext)
 CGM.getCXXABI().getMangleContext().startNewFunction();
 
Index: lib/CodeGen/CGDecl.cpp
===
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -916,29 +916,12 @@
   EmitAutoVarCleanups(emission);
 }
 
-/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
-/// markers.
-static bool shouldEmitLifetimeMarkers(const CodeGenOptions ,
-  const LangOptions ) {
-  // Asan uses markers for use-after-scope checks.
-  if (CGOpts.SanitizeAddressUseAfterScope)
-return true;
-
-  // Disable lifetime markers in msan builds.
-  // FIXME: Remove this when msan works with lifetime markers.
-  if (LangOpts.Sanitize.has(SanitizerKind::Memory))
-return false;
-
-  // For now, only in optimized builds.
-  return CGOpts.OptimizationLevel != 0;
-}
-
 /// Emit a lifetime.begin marker if some criteria are satisfied.
 /// \return a pointer to the temporary size Value if a marker was emitted, null
 /// otherwise
 llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
 llvm::Value *Addr) {
-  if (!shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), getLangOpts()))
+  

Re: [PATCH] D24695: [CodeGen] Move shouldEmitLifetimeMarkers into more convenient place

2016-09-28 Thread Vitaly Buka via cfe-commits
vitalybuka updated this revision to Diff 72907.
vitalybuka added a comment.
Herald added subscribers: mgorny, beanz.

rebase


https://reviews.llvm.org/D24695

Files:
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CMakeLists.txt
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/VarBypassDetector.cpp
  lib/CodeGen/VarBypassDetector.h
  test/CodeGen/lifetime2.c

Index: test/CodeGen/lifetime2.c
===
--- test/CodeGen/lifetime2.c
+++ test/CodeGen/lifetime2.c
@@ -1,8 +1,9 @@
-// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefix=O2
-// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix=O0
+// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefixes=CHECK,O2
+// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
 
 extern int bar(char *A, int n);
 
+// CHECK-LABEL: @foo
 // O0-NOT: @llvm.lifetime.start
 int foo (int n) {
   if (n) {
@@ -15,3 +16,66 @@
 return bar(A, 2);
   }
 }
+
+// CHECK-LABEL: @no_goto_bypass
+void no_goto_bypass() {
+  // O2: @llvm.lifetime.start(i64 1
+  char x;
+l1:
+  bar(, 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
+}
+
+// CHECK-LABEL: @goto_bypass
+void goto_bypass() {
+  {
+// O2-NOT: @llvm.lifetime.start(i64 1
+// O2-NOT: @llvm.lifetime.end(i64 1
+char x;
+  l1:
+bar(, 1);
+  }
+  goto l1;
+}
+
+// CHECK-LABEL: @no_switch_bypass
+void no_switch_bypass(int n) {
+  switch (n) {
+  case 1: {
+// O2: @llvm.lifetime.start(i64 1
+// O2: @llvm.lifetime.end(i64 1
+char x;
+bar(, 1);
+break;
+  }
+  case 2:
+n = n;
+// O2: @llvm.lifetime.start(i64 5
+// O2: @llvm.lifetime.end(i64 5
+char y[5];
+bar(y, 5);
+break;
+  }
+}
+
+// CHECK-LABEL: @switch_bypass
+void switch_bypass(int n) {
+  switch (n) {
+  case 1:
+n = n;
+// O2-NOT: @llvm.lifetime.start(i64 1
+// O2-NOT: @llvm.lifetime.end(i64 1
+char x;
+bar(, 1);
+break;
+  case 2:
+bar(, 1);
+break;
+  }
+}
Index: lib/CodeGen/VarBypassDetector.h
===
--- /dev/null
+++ lib/CodeGen/VarBypassDetector.h
@@ -0,0 +1,67 @@
+//===--- VarBypassDetector.cpp - Bypass jumps detector *- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This file contains VarBypassDetector class, which is used to detect
+// local variable declarations which can be bypassed by jumps.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H
+#define LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class Decl;
+class Stmt;
+class VarDecl;
+
+namespace CodeGen {
+
+/// VarBypassDetector - This class detects jumps which bypass local variables
+/// declaration:
+///goto L;
+///int a;
+///  L:
+/// This is simplified version of JumpScopeChecker. Primary differences:
+///  * Detects only jumps into the scope local variables.
+///  * Does not detect jumps out of the scope of local variables.
+///  * Not limited to variables with initializers, JumpScopeChecker is limited.
+///  * FIXME: Does not support indirect jumps.
+class VarBypassDetector {
+  // Scope information. Contains a parent scope and related variable
+  // declaration.
+  llvm::SmallVector, 48> Scopes;
+  // Lookup map to file scope for jumps and its destinations.
+  llvm::DenseMap LabelAndGotoScopes;
+  // Set of variables which were bypassed by some jump.
+  llvm::DenseSet Bypasses;
+
+public:
+  void Init(const Stmt *Body);
+
+  /// IsBypassed - Returns true if the variable declaration was by bypassed by
+  /// any goto or switch statement.
+  bool IsBypassed(const VarDecl *D) const {
+return Bypasses.find(D) != Bypasses.end();
+  }
+
+private:
+  void BuildScopeInformation(const Decl *D, unsigned );
+  void BuildScopeInformation(const Stmt *S, unsigned );
+  void Detect();
+  void Detect(const Stmt *FromStmt, const Stmt *ToStmt);
+};
+}
+}
+
+#endif
Index: lib/CodeGen/VarBypassDetector.cpp
===
--- /dev/null
+++ lib/CodeGen/VarBypassDetector.cpp
@@ -0,0 +1,154 @@
+//===--- VarBypassDetector.h - Bypass jumps detector --*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//

Re: [PATCH] D24695: [CodeGen] Move shouldEmitLifetimeMarkers into more convenient place

2016-09-19 Thread Vitaly Buka via cfe-commits
vitalybuka updated this revision to Diff 71860.
vitalybuka added a comment.

Fixed accidentally changed test


https://reviews.llvm.org/D24695

Files:
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenFunction.h

Index: lib/CodeGen/CodeGenFunction.h
===
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -1175,6 +1175,9 @@
   llvm::BasicBlock *TerminateHandler;
   llvm::BasicBlock *TrapBB;
 
+  /// True if we need emit the life-time markers.
+  const bool ShouldEmitLifetimeMarkers;
+
   /// Add a kernel metadata node to the named metadata node 'opencl.kernels'.
   /// In the kernel metadata node, reference the kernel function and metadata 
   /// nodes for its optional attribute qualifiers (OpenCL 1.1 6.7.2):
Index: lib/CodeGen/CodeGenFunction.cpp
===
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -37,29 +37,46 @@
 using namespace clang;
 using namespace CodeGen;
 
+/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
+/// markers.
+static bool shouldEmitLifetimeMarkers(const CodeGenOptions ,
+  const LangOptions ) {
+  // Asan uses markers for use-after-scope checks.
+  if (CGOpts.SanitizeAddressUseAfterScope)
+return true;
+
+  // Disable lifetime markers in msan builds.
+  // FIXME: Remove this when msan works with lifetime markers.
+  if (LangOpts.Sanitize.has(SanitizerKind::Memory))
+return false;
+
+  // For now, only in optimized builds.
+  return CGOpts.OptimizationLevel != 0;
+}
+
 CodeGenFunction::CodeGenFunction(CodeGenModule , bool suppressNewContext)
 : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
   Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
   CGBuilderInserterTy(this)),
   CurFn(nullptr), ReturnValue(Address::invalid()),
-  CapturedStmtInfo(nullptr),
-  SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false),
-  CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false),
-  IsOutlinedSEHHelper(false),
-  BlockInfo(nullptr), BlockPointer(nullptr),
-  LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
-  NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
-  ExceptionSlot(nullptr), EHSelectorSlot(nullptr),
-  DebugInfo(CGM.getModuleDebugInfo()),
+  CapturedStmtInfo(nullptr), SanOpts(CGM.getLangOpts().Sanitize),
+  IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false),
+  SawAsmBlock(false), IsOutlinedSEHHelper(false), BlockInfo(nullptr),
+  BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
+  NormalCleanupDest(nullptr), NextCleanupDestIndex(1),
+  FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
+  EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()),
   DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
   PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr),
   CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0),
   NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr),
   CXXABIThisValue(nullptr), CXXThisValue(nullptr),
   CXXStructorImplicitParamDecl(nullptr),
   CXXStructorImplicitParamValue(nullptr), OutermostConditional(nullptr),
   CurLexicalScope(nullptr), TerminateLandingPad(nullptr),
-  TerminateHandler(nullptr), TrapBB(nullptr) {
+  TerminateHandler(nullptr), TrapBB(nullptr),
+  ShouldEmitLifetimeMarkers(
+  shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) {
   if (!suppressNewContext)
 CGM.getCXXABI().getMangleContext().startNewFunction();
 
Index: lib/CodeGen/CGDecl.cpp
===
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -916,29 +916,12 @@
   EmitAutoVarCleanups(emission);
 }
 
-/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
-/// markers.
-static bool shouldEmitLifetimeMarkers(const CodeGenOptions ,
-  const LangOptions ) {
-  // Asan uses markers for use-after-scope checks.
-  if (CGOpts.SanitizeAddressUseAfterScope)
-return true;
-
-  // Disable lifetime markers in msan builds.
-  // FIXME: Remove this when msan works with lifetime markers.
-  if (LangOpts.Sanitize.has(SanitizerKind::Memory))
-return false;
-
-  // For now, only in optimized builds.
-  return CGOpts.OptimizationLevel != 0;
-}
-
 /// Emit a lifetime.begin marker if some criteria are satisfied.
 /// \return a pointer to the temporary size Value if a marker was emitted, null
 /// otherwise
 llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
 llvm::Value *Addr) {
-  if 

Re: [PATCH] D24695: [CodeGen] Move shouldEmitLifetimeMarkers into more convenient place

2016-09-19 Thread Vitaly Buka via cfe-commits
vitalybuka updated this revision to Diff 71856.
vitalybuka added a comment.

Removed unrelated test


https://reviews.llvm.org/D24695

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

Index: test/CodeGen/lifetime2.c
===
--- test/CodeGen/lifetime2.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefix=O2
-// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix=O0
-
-extern int bar(char *A, int n);
-
-// O0-NOT: @llvm.lifetime.start
-int foo (int n) {
-  if (n) {
-// O2: @llvm.lifetime.start
-char A[100];
-return bar(A, 1);
-  } else {
-// O2: @llvm.lifetime.start
-char A[100];
-return bar(A, 2);
-  }
-}
Index: lib/CodeGen/CodeGenFunction.h
===
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -1175,6 +1175,9 @@
   llvm::BasicBlock *TerminateHandler;
   llvm::BasicBlock *TrapBB;
 
+  /// True if we need emit the life-time markers.
+  const bool ShouldEmitLifetimeMarkers;
+
   /// Add a kernel metadata node to the named metadata node 'opencl.kernels'.
   /// In the kernel metadata node, reference the kernel function and metadata 
   /// nodes for its optional attribute qualifiers (OpenCL 1.1 6.7.2):
Index: lib/CodeGen/CodeGenFunction.cpp
===
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -37,29 +37,46 @@
 using namespace clang;
 using namespace CodeGen;
 
+/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
+/// markers.
+static bool shouldEmitLifetimeMarkers(const CodeGenOptions ,
+  const LangOptions ) {
+  // Asan uses markers for use-after-scope checks.
+  if (CGOpts.SanitizeAddressUseAfterScope)
+return true;
+
+  // Disable lifetime markers in msan builds.
+  // FIXME: Remove this when msan works with lifetime markers.
+  if (LangOpts.Sanitize.has(SanitizerKind::Memory))
+return false;
+
+  // For now, only in optimized builds.
+  return CGOpts.OptimizationLevel != 0;
+}
+
 CodeGenFunction::CodeGenFunction(CodeGenModule , bool suppressNewContext)
 : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
   Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
   CGBuilderInserterTy(this)),
   CurFn(nullptr), ReturnValue(Address::invalid()),
-  CapturedStmtInfo(nullptr),
-  SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false),
-  CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false),
-  IsOutlinedSEHHelper(false),
-  BlockInfo(nullptr), BlockPointer(nullptr),
-  LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
-  NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
-  ExceptionSlot(nullptr), EHSelectorSlot(nullptr),
-  DebugInfo(CGM.getModuleDebugInfo()),
+  CapturedStmtInfo(nullptr), SanOpts(CGM.getLangOpts().Sanitize),
+  IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false),
+  SawAsmBlock(false), IsOutlinedSEHHelper(false), BlockInfo(nullptr),
+  BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
+  NormalCleanupDest(nullptr), NextCleanupDestIndex(1),
+  FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
+  EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()),
   DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
   PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr),
   CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0),
   NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr),
   CXXABIThisValue(nullptr), CXXThisValue(nullptr),
   CXXStructorImplicitParamDecl(nullptr),
   CXXStructorImplicitParamValue(nullptr), OutermostConditional(nullptr),
   CurLexicalScope(nullptr), TerminateLandingPad(nullptr),
-  TerminateHandler(nullptr), TrapBB(nullptr) {
+  TerminateHandler(nullptr), TrapBB(nullptr),
+  ShouldEmitLifetimeMarkers(
+  shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) {
   if (!suppressNewContext)
 CGM.getCXXABI().getMangleContext().startNewFunction();
 
Index: lib/CodeGen/CGDecl.cpp
===
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -916,29 +916,12 @@
   EmitAutoVarCleanups(emission);
 }
 
-/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
-/// markers.
-static bool shouldEmitLifetimeMarkers(const CodeGenOptions ,
-  const LangOptions ) {
-  // Asan uses markers for use-after-scope checks.
-  if (CGOpts.SanitizeAddressUseAfterScope)
-return true;
-
-  // Disable lifetime markers 

[PATCH] D24695: [CodeGen] Move shouldEmitLifetimeMarkers into more convenient place

2016-09-16 Thread Vitaly Buka via cfe-commits
vitalybuka created this revision.
vitalybuka added a reviewer: eugenis.
vitalybuka added a subscriber: cfe-commits.

D24693 will need access to it from other places

https://reviews.llvm.org/D24695

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

Index: test/CodeGen/lifetime2.c
===
--- test/CodeGen/lifetime2.c
+++ test/CodeGen/lifetime2.c
@@ -1,8 +1,9 @@
-// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefix=O2
-// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix=O0
+// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefixes=CHECK,O2
+// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
 
 extern int bar(char *A, int n);
 
+// CHECK-LABEL: @foo
 // O0-NOT: @llvm.lifetime.start
 int foo (int n) {
   if (n) {
@@ -15,3 +16,66 @@
 return bar(A, 2);
   }
 }
+
+// CHECK-LABEL: @no_goto_bypass
+void no_goto_bypass() {
+  // O2: @llvm.lifetime.start(i64 1
+  char x;
+l1:
+  bar(, 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
+}
+
+// CHECK-LABEL: @goto_bypass
+void goto_bypass() {
+  {
+// O2-NOT: @llvm.lifetime.start(i64 1
+// O2-NOT: @llvm.lifetime.end(i64 1
+char x;
+  l1:
+bar(, 1);
+  }
+  goto l1;
+}
+
+// CHECK-LABEL: @no_switch_bypass
+void no_switch_bypass(int n) {
+  switch (n) {
+  case 1: {
+// O2: @llvm.lifetime.start(i64 1
+// O2: @llvm.lifetime.end(i64 1
+char x;
+bar(, 1);
+break;
+  }
+  case 2:
+n = n;
+// O2: @llvm.lifetime.start(i64 5
+// O2: @llvm.lifetime.end(i64 5
+char y[5];
+bar(y, 5);
+break;
+  }
+}
+
+// CHECK-LABEL: @switch_bypass
+void switch_bypass(int n) {
+  switch (n) {
+  case 1:
+n = n;
+// O2-NOT: @llvm.lifetime.start(i64 1
+// O2-NOT: @llvm.lifetime.end(i64 1
+char x;
+bar(, 1);
+break;
+  case 2:
+bar(, 1);
+break;
+  }
+}
Index: lib/CodeGen/CodeGenFunction.h
===
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -1175,6 +1175,9 @@
   llvm::BasicBlock *TerminateHandler;
   llvm::BasicBlock *TrapBB;
 
+  /// True if we need emit the life-time markers.
+  const bool ShouldEmitLifetimeMarkers;
+
   /// Add a kernel metadata node to the named metadata node 'opencl.kernels'.
   /// In the kernel metadata node, reference the kernel function and metadata 
   /// nodes for its optional attribute qualifiers (OpenCL 1.1 6.7.2):
Index: lib/CodeGen/CodeGenFunction.cpp
===
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -37,29 +37,46 @@
 using namespace clang;
 using namespace CodeGen;
 
+/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
+/// markers.
+static bool shouldEmitLifetimeMarkers(const CodeGenOptions ,
+  const LangOptions ) {
+  // Asan uses markers for use-after-scope checks.
+  if (CGOpts.SanitizeAddressUseAfterScope)
+return true;
+
+  // Disable lifetime markers in msan builds.
+  // FIXME: Remove this when msan works with lifetime markers.
+  if (LangOpts.Sanitize.has(SanitizerKind::Memory))
+return false;
+
+  // For now, only in optimized builds.
+  return CGOpts.OptimizationLevel != 0;
+}
+
 CodeGenFunction::CodeGenFunction(CodeGenModule , bool suppressNewContext)
 : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
   Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
   CGBuilderInserterTy(this)),
   CurFn(nullptr), ReturnValue(Address::invalid()),
-  CapturedStmtInfo(nullptr),
-  SanOpts(CGM.getLangOpts().Sanitize), IsSanitizerScope(false),
-  CurFuncIsThunk(false), AutoreleaseResult(false), SawAsmBlock(false),
-  IsOutlinedSEHHelper(false),
-  BlockInfo(nullptr), BlockPointer(nullptr),
-  LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
-  NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
-  ExceptionSlot(nullptr), EHSelectorSlot(nullptr),
-  DebugInfo(CGM.getModuleDebugInfo()),
+  CapturedStmtInfo(nullptr), SanOpts(CGM.getLangOpts().Sanitize),
+  IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false),
+  SawAsmBlock(false), IsOutlinedSEHHelper(false), BlockInfo(nullptr),
+  BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
+  NormalCleanupDest(nullptr), NextCleanupDestIndex(1),
+  FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
+  EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()),
   DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
   PGO(cgm),