r177819 - Make clang to mark static stack allocations with lifetime markers to enable a more aggressive stack coloring.

Nadav Rotem nrotem at apple.com
Wed Mar 27 15:40:17 PDT 2013


Hi Eric, 

Yes, Adrian is helping me with this.  He identified the problem and we'll address this soon. 

Thanks,
Nadav

On 03/27/13, Eric Christopher  <echristo at gmail.com> wrote:
> Nadav,
> 
> These tests are still failing and I haven't heard from you. Have you made any progress here?
> 
> 
> -eric
> 
> 
> 
> 
> On Mon, Mar 25, 2013 at 11:34 AM, Eric Christopher <echristo at gmail.com> wrote:
> 
> > 
> > Nadav,
> > 
> > Looks like the debug info bot is still broken. Can you take a look and see what you ended up changing? For the record the particular tests are these:
> > 
> > 
> > 
> > gdb.cp/cp-blocks-linetables.exp: Fifth next gdb.cp/cp-blocks-linetables.exp: Sixth next
> > 
> > 
> > Thanks!
> > 
> > 
> > -eric
> > 
> > 
> > 
> > 
> > 
> > On Sat, Mar 23, 2013 at 2:20 PM, David Blaikie <dblaikie at gmail.com> wrote:
> > 
> > > 
> > > 
> > > This commit may've regressed debug info:
> > > 
> > > http://lab.llvm.org:8011/builders/clang-x86_64-darwin10-gdb/builds/1578
> > > 
> > > 
> > > 
> > > On Fri, Mar 22, 2013 at 11:43 PM, Nadav Rotem <nrotem at apple.com> wrote:
> > > 
> > > > Author: nadav
> > > 
> > > > Date: Sat Mar 23 01:43:35 2013
> > > 
> > > > New Revision: 177819
> > > 
> > > >
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project?rev=177819&view=rev
> > > 
> > > > Log:
> > > 
> > > > Make clang to mark static stack allocations with lifetime markers to enable a more aggressive stack coloring.
> > > 
> > > > Patch by John McCall with help by Shuxin Yang.
> > > 
> > > > rdar://13115369
> > > 
> > > >
> > > 
> > > >
> > > 
> > > > Added:
> > > 
> > > >     cfe/trunk/test/CodeGen/lifetime2.c
> > > 
> > > > Modified:
> > > 
> > > >     cfe/trunk/lib/CodeGen/CGDecl.cpp
> > > 
> > > >     cfe/trunk/lib/CodeGen/CGStmt.cpp
> > > 
> > > >     cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> > > 
> > > >     cfe/trunk/lib/CodeGen/CodeGenFunction.h
> > > 
> > > >     cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> > > 
> > > >     cfe/trunk/lib/CodeGen/CodeGenModule.h
> > > 
> > > >     cfe/trunk/test/CodeGenObjC/arc-blocks.m
> > > 
> > > >     cfe/trunk/test/CodeGenObjC/arc.m
> > > 
> > > >
> > > 
> > > > Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=177819&r1=177818&r2=177819&view=diff
> > > 
> > > 
> > > 
> > > > ==============================================================================
> > > 
> > > > --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
> > > 
> > > > +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Sat Mar 23 01:43:35 2013
> > > 
> > > > @@ -452,6 +452,22 @@ namespace {
> > > 
> > > >        CGF.EmitCall(FnInfo, CleanupFn, ReturnValueSlot(), Args);
> > > 
> > > >      }
> > > 
> > > >    };
> > > 
> > > > +
> > > 
> > > > +  /// A cleanup to call @llvm.lifetime.end.
> > > 
> > > > +  class CallLifetimeEnd : public EHScopeStack::Cleanup {
> > > 
> > > > +    llvm::Value *Addr;
> > > 
> > > > +    llvm::Value *Size;
> > > 
> > > > +  public:
> > > 
> > > > +    CallLifetimeEnd(llvm::Value *addr, llvm::Value *size)
> > > 
> > > > +      : Addr(addr), Size(size) {}
> > > 
> > > > +
> > > 
> > > > +    void Emit(CodeGenFunction &CGF, Flags flags) {
> > > 
> > > > +      llvm::Value *castAddr = CGF.Builder.CreateBitCast(Addr, CGF.Int8PtrTy);
> > > 
> > > > +      CGF.Builder.CreateCall2(CGF.CGM.getLLVMLifetimeEndFn(),
> > > 
> > > > +                              Size, castAddr)
> > > 
> > > > +        ->setDoesNotThrow();
> > > 
> > > > +    }
> > > 
> > > > +  };
> > > 
> > > >  }
> > > 
> > > >
> > > 
> > > >  /// EmitAutoVarWithLifetime - Does the setup required for an automatic
> > > 
> > > > @@ -756,7 +772,6 @@ static bool shouldUseMemSetPlusStoresToI
> > > 
> > > >    // If a global is all zeros, always use a memset.
> > > 
> > > >    if (isa<llvm::ConstantAggregateZero>(Init)) return true;
> > > 
> > > >
> > > 
> > > > -
> > > 
> > > >    // If a non-zero global is <= 32 bytes, always use a memcpy.  If it is large,
> > > 
> > > >    // do it if it will require 6 or fewer scalar stores.
> > > 
> > > >    // TODO: Should budget depends on the size?  Avoiding a large global warrants
> > > 
> > > > @@ -768,6 +783,20 @@ static bool shouldUseMemSetPlusStoresToI
> > > 
> > > >           canEmitInitWithFewStoresAfterMemset(Init, StoreBudget);
> > > 
> > > >  }
> > > 
> > > >
> > > 
> > > > +/// Should we use the LLVM lifetime intrinsics for the given local variable?
> > > 
> > > > +static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D,
> > > 
> > > > +                                     unsigned Size) {
> > > 
> > > > +  // For now, only in optimized builds.
> > > 
> > > > +  if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0)
> > > 
> > > > +    return false;
> > > 
> > > > +
> > > 
> > > > +  // Limit the size of marked objects to 32 bytes. We don't want to increase
> > > 
> > > > +  // compile time by marking tiny objects.
> > > 
> > > > +  unsigned SizeThreshold = 32;
> > > 
> > > > +
> > > 
> > > > +  return Size > SizeThreshold;
> > > 
> > > > +}
> > > 
> > > > +
> > > 
> > > >
> > > 
> > > >  /// EmitAutoVarDecl - Emit code and set up an entry in LocalDeclMap for a
> > > 
> > > >  /// variable declaration with auto, register, or no storage class specifier.
> > > 
> > > > @@ -870,6 +899,20 @@ CodeGenFunction::EmitAutoVarAlloca(const
> > > 
> > > >                getContext().toCharUnitsFromBits(Target.getPointerAlign(0)));
> > > 
> > > >          Alloc->setAlignment(allocaAlignment.getQuantity());
> > > 
> > > >          DeclPtr = Alloc;
> > > 
> > > > +
> > > 
> > > > +        // Emit a lifetime intrinsic if meaningful.  There's no point
> > > 
> > > > +        // in doing this if we don't have a valid insertion point (?).
> > > 
> > > > +        uint64_t size = CGM.getDataLayout().getTypeAllocSize(LTy);
> > > 
> > > > +        if (HaveInsertPoint() && shouldUseLifetimeMarkers(*this, D, size)) {
> > > 
> > > > +          llvm::Value *sizeV = llvm::ConstantInt::get(Int64Ty, size);
> > > 
> > > > +
> > > 
> > > > +          emission.SizeForLifetimeMarkers = sizeV;
> > > 
> > > > +          llvm::Value *castAddr = Builder.CreateBitCast(Alloc, Int8PtrTy);
> > > 
> > > > +          Builder.CreateCall2(CGM.getLLVMLifetimeStartFn(), sizeV, castAddr)
> > > 
> > > > +            ->setDoesNotThrow();
> > > 
> > > > +        } else {
> > > 
> > > > +          assert(!emission.useLifetimeMarkers());
> > > 
> > > > +        }
> > > 
> > > >        }
> > > 
> > > >      } else {
> > > 
> > > >        // Targets that don't support recursion emit locals as globals.
> > > 
> > > > @@ -1215,6 +1258,14 @@ void CodeGenFunction::EmitAutoVarCleanup
> > > 
> > > >
> > > 
> > > >    const VarDecl &D = *emission.Variable;
> > > 
> > > >
> > > 
> > > > +  // Make sure we call @llvm.lifetime.end.  This needs to happen
> > > 
> > > > +  // *last*, so the cleanup needs to be pushed *first*.
> > > 
> > > > +  if (emission.useLifetimeMarkers()) {
> > > 
> > > > +    EHStack.pushCleanup<CallLifetimeEnd>(NormalCleanup,
> > > 
> > > > +                                         emission.getAllocatedAddress(),
> > > 
> > > > +                                         emission.getSizeForLifetimeMarkers());
> > > 
> > > > +  }
> > > 
> > > > +
> > > 
> > > >    // Check the type for a cleanup.
> > > 
> > > >    if (QualType::DestructionKind dtorKind = D.getType().isDestructedType())
> > > 
> > > >      emitAutoVarTypeCleanup(emission, dtorKind);
> > > 
> > > > @@ -1485,6 +1536,22 @@ void CodeGenFunction::pushRegularPartial
> > > 
> > > >                                                    elementType, destroyer);
> > > 
> > > >  }
> > > 
> > > >
> > > 
> > > > +/// Lazily declare the @llvm.lifetime.start intrinsic.
> > > 
> > > > +llvm::Constant *CodeGenModule::getLLVMLifetimeStartFn() {
> > > 
> > > > +  if (LifetimeStartFn) return LifetimeStartFn;
> > > 
> > > > +  LifetimeStartFn = llvm::Intrinsic::getDeclaration(&getModule(),
> > > 
> > > > +                                            llvm::Intrinsic::lifetime_start);
> > > 
> > > > +  return LifetimeStartFn;
> > > 
> > > > +}
> > > 
> > > > +
> > > 
> > > > +/// Lazily declare the @llvm.lifetime.end intrinsic.
> > > 
> > > > +llvm::Constant *CodeGenModule::getLLVMLifetimeEndFn() {
> > > 
> > > > +  if (LifetimeEndFn) return LifetimeEndFn;
> > > 
> > > > +  LifetimeEndFn = llvm::Intrinsic::getDeclaration(&getModule(),
> > > 
> > > > +                                              llvm::Intrinsic::lifetime_end);
> > > 
> > > > +  return LifetimeEndFn;
> > > 
> > > > +}
> > > 
> > > > +
> > > 
> > > >  namespace {
> > > 
> > > >    /// A cleanup to perform a release of an object at the end of a
> > > 
> > > >    /// function.  This is used to balance out the incoming +1 of a
> > > 
> > > >
> > > 
> > > > Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=177819&r1=177818&r2=177819&view=diff
> > > 
> > > 
> > > 
> > > > ==============================================================================
> > > 
> > > > --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
> > > 
> > > > +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Sat Mar 23 01:43:35 2013
> > > 
> > > > @@ -319,6 +319,12 @@ CodeGenFunction::getJumpDestForLabel(con
> > > 
> > > >  }
> > > 
> > > >
> > > 
> > > >  void CodeGenFunction::EmitLabel(const LabelDecl *D) {
> > > 
> > > > +  // Add this label to the current lexical scope if we're within any
> > > 
> > > > +  // normal cleanups.  Jumps "in" to this label --- when permitted by
> > > 
> > > > +  // the language --- may need to be routed around such cleanups.
> > > 
> > > > +  if (EHStack.hasNormalCleanups() && CurLexicalScope)
> > > 
> > > > +    CurLexicalScope->addLabel(D);
> > > 
> > > > +
> > > 
> > > >    JumpDest &Dest = LabelMap[D];
> > > 
> > > >
> > > 
> > > >    // If we didn't need a forward reference to this label, just go
> > > 
> > > > @@ -330,16 +336,36 @@ void CodeGenFunction::EmitLabel(const La
> > > 
> > > >    // it from the branch-fixups list.
> > > 
> > > >    } else {
> > > 
> > > >      assert(!Dest.getScopeDepth().isValid() && "already emitted label!");
> > > 
> > > > -    Dest = JumpDest(Dest.getBlock(),
> > > 
> > > > -                    EHStack.stable_begin(),
> > > 
> > > > -                    Dest.getDestIndex());
> > > 
> > > > -
> > > 
> > > > +    Dest.setScopeDepth(EHStack.stable_begin());
> > > 
> > > >      ResolveBranchFixups(Dest.getBlock());
> > > 
> > > >    }
> > > 
> > > >
> > > 
> > > >    EmitBlock(Dest.getBlock());
> > > 
> > > >  }
> > > 
> > > >
> > > 
> > > > +/// Change the cleanup scope of the labels in this lexical scope to
> > > 
> > > > +/// match the scope of the enclosing context.
> > > 
> > > > +void CodeGenFunction::LexicalScope::rescopeLabels() {
> > > 
> > > > +  assert(!Labels.empty());
> > > 
> > > > +  EHScopeStack::stable_iterator innermostScope
> > > 
> > > > +    = CGF.EHStack.getInnermostNormalCleanup();
> > > 
> > > > +
> > > 
> > > > +  // Change the scope depth of all the labels.
> > > 
> > > > +  for (SmallVectorImpl<const LabelDecl*>::const_iterator
> > > 
> > > > +         i = Labels.begin(), e = Labels.end(); i != e; ++i) {
> > > 
> > > > +    assert(CGF.LabelMap.count(*i));
> > > 
> > > > +    JumpDest &dest = CGF.LabelMap.find(*i)->second;
> > > 
> > > > +    assert(dest.getScopeDepth().isValid());
> > > 
> > > > +    assert(innermostScope.encloses(dest.getScopeDepth()));
> > > 
> > > > +    dest.setScopeDepth(innermostScope);
> > > 
> > > > +  }
> > > 
> > > > +
> > > 
> > > > +  // Reparent the labels if the new scope also has cleanups.
> > > 
> > > > +  if (innermostScope != EHScopeStack::stable_end() && ParentScope) {
> > > 
> > > > +    ParentScope->Labels.append(Labels.begin(), Labels.end());
> > > 
> > > > +  }
> > > 
> > > > +}
> > > 
> > > > +
> > > 
> > > >
> > > 
> > > >  void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
> > > 
> > > >    EmitLabel(S.getDecl());
> > > 
> > > >
> > > 
> > > > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=177819&r1=177818&r2=177819&view=diff
> > > 
> > > 
> > > 
> > > > ==============================================================================
> > > 
> > > > --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
> > > 
> > > > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Sat Mar 23 01:43:35 2013
> > > 
> > > > @@ -45,7 +45,7 @@ CodeGenFunction::CodeGenFunction(CodeGen
> > > 
> > > >      IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0),
> > > 
> > > >      CXXABIThisDecl(0), CXXABIThisValue(0), CXXThisValue(0),
> > > 
> > > >      CXXStructorImplicitParamDecl(0), CXXStructorImplicitParamValue(0),
> > > 
> > > > -    OutermostConditional(0), TerminateLandingPad(0),
> > > 
> > > > +    OutermostConditional(0), CurLexicalScope(0), TerminateLandingPad(0),
> > > 
> > > >      TerminateHandler(0), TrapBB(0) {
> > > 
> > > >    if (!suppressNewContext)
> > > 
> > > >      CGM.getCXXABI().getMangleContext().startNewFunction();
> > > 
> > > >
> > > 
> > > > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=177819&r1=177818&r2=177819&view=diff
> > > 
> > > 
> > > 
> > > > ==============================================================================
> > > 
> > > > --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> > > 
> > > > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sat Mar 23 01:43:35 2013
> > > 
> > > > @@ -562,6 +562,11 @@ public:
> > > 
> > > >      EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; }
> > > 
> > > >      unsigned getDestIndex() const { return Index; }
> > > 
> > > >
> > > 
> > > > +    // This should be used cautiously.
> > > 
> > > > +    void setScopeDepth(EHScopeStack::stable_iterator depth) {
> > > 
> > > > +      ScopeDepth = depth;
> > > 
> > > > +    }
> > > 
> > > > +
> > > 
> > > >    private:
> > > 
> > > >      llvm::BasicBlock *Block;
> > > 
> > > >      EHScopeStack::stable_iterator ScopeDepth;
> > > 
> > > > @@ -853,6 +858,8 @@ public:
> > > 
> > > >
> > > 
> > > >    class LexicalScope: protected RunCleanupsScope {
> > > 
> > > >      SourceRange Range;
> > > 
> > > > +    SmallVector<const LabelDecl*, 4> Labels;
> > > 
> > > > +    LexicalScope *ParentScope;
> > > 
> > > >
> > > 
> > > >      LexicalScope(const LexicalScope &) LLVM_DELETED_FUNCTION;
> > > 
> > > >      void operator=(const LexicalScope &) LLVM_DELETED_FUNCTION;
> > > 
> > > > @@ -860,15 +867,23 @@ public:
> > > 
> > > >    public:
> > > 
> > > >      /// \brief Enter a new cleanup scope.
> > > 
> > > >      explicit LexicalScope(CodeGenFunction &CGF, SourceRange Range)
> > > 
> > > > -      : RunCleanupsScope(CGF), Range(Range) {
> > > 
> > > > +      : RunCleanupsScope(CGF), Range(Range), ParentScope(CGF.CurLexicalScope) {
> > > 
> > > > +      CGF.CurLexicalScope = this;
> > > 
> > > >        if (CGDebugInfo *DI = CGF.getDebugInfo())
> > > 
> > > >          DI->EmitLexicalBlockStart(CGF.Builder, Range.getBegin());
> > > 
> > > >      }
> > > 
> > > >
> > > 
> > > > +    void addLabel(const LabelDecl *label) {
> > > 
> > > > +      assert(PerformCleanup && "adding label to dead scope?");
> > > 
> > > > +      Labels.push_back(label);
> > > 
> > > > +    }
> > > 
> > > > +
> > > 
> > > >      /// \brief Exit this cleanup scope, emitting any accumulated
> > > 
> > > >      /// cleanups.
> > > 
> > > >      ~LexicalScope() {
> > > 
> > > > -      if (PerformCleanup) endLexicalScope();
> > > 
> > > > +      // If we should perform a cleanup, force them now.  Note that
> > > 
> > > > +      // this ends the cleanup scope before rescoping any labels.
> > > 
> > > > +      if (PerformCleanup) ForceCleanup();
> > > 
> > > >      }
> > > 
> > > >
> > > 
> > > >      /// \brief Force the emission of cleanups now, instead of waiting
> > > 
> > > > @@ -880,9 +895,14 @@ public:
> > > 
> > > >
> > > 
> > > >    private:
> > > 
> > > >      void endLexicalScope() {
> > > 
> > > > +      CGF.CurLexicalScope = ParentScope;
> > > 
> > > >        if (CGDebugInfo *DI = CGF.getDebugInfo())
> > > 
> > > >          DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd());
> > > 
> > > > +      if (!Labels.empty())
> > > 
> > > > +        rescopeLabels();
> > > 
> > > >      }
> > > 
> > > > +
> > > 
> > > > +    void rescopeLabels();
> > > 
> > > >    };
> > > 
> > > >
> > > 
> > > >
> > > 
> > > > @@ -1205,6 +1225,8 @@ private:
> > > 
> > > >    /// temporary should be destroyed conditionally.
> > > 
> > > >    ConditionalEvaluation *OutermostConditional;
> > > 
> > > >
> > > 
> > > > +  /// The current lexical scope.
> > > 
> > > > +  LexicalScope *CurLexicalScope;
> > > 
> > > >
> > > 
> > > >    /// ByrefValueInfoMap - For each __block variable, contains a pair of the LLVM
> > > 
> > > >    /// type as well as the field number that contains the actual data.
> > > 
> > > > @@ -2001,18 +2023,34 @@ public:
> > > 
> > > >      /// initializer.
> > > 
> > > >      bool IsConstantAggregate;
> > > 
> > > >
> > > 
> > > > +    /// Non-null if we should use lifetime annotations.
> > > 
> > > > +    llvm::Value *SizeForLifetimeMarkers;
> > > 
> > > > +
> > > 
> > > >      struct Invalid {};
> > > 
> > > >      AutoVarEmission(Invalid) : Variable(0) {}
> > > 
> > > >
> > > 
> > > >      AutoVarEmission(const VarDecl &variable)
> > > 
> > > >        : Variable(&variable), Address(0), NRVOFlag(0),
> > > 
> > > > -        IsByRef(false), IsConstantAggregate(false) {}
> > > 
> > > > +        IsByRef(false), IsConstantAggregate(false),
> > > 
> > > > +        SizeForLifetimeMarkers(0) {}
> > > 
> > > >
> > > 
> > > >      bool wasEmittedAsGlobal() const { return Address == 0; }
> > > 
> > > >
> > > 
> > > >    public:
> > > 
> > > >      static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); }
> > > 
> > > >
> > > 
> > > > +    bool useLifetimeMarkers() const { return SizeForLifetimeMarkers != 0; }
> > > 
> > > > +    llvm::Value *getSizeForLifetimeMarkers() const {
> > > 
> > > > +      assert(useLifetimeMarkers());
> > > 
> > > > +      return SizeForLifetimeMarkers;
> > > 
> > > > +    }
> > > 
> > > > +
> > > 
> > > > +    /// Returns the raw, allocated address, which is not necessarily
> > > 
> > > > +    /// the address of the object itself.
> > > 
> > > > +    llvm::Value *getAllocatedAddress() const {
> > > 
> > > > +      return Address;
> > > 
> > > > +    }
> > > 
> > > > +
> > > 
> > > >      /// Returns the address of the object within this declaration.
> > > 
> > > >      /// Note that this does not chase the forwarding pointer for
> > > 
> > > >      /// __block decls.
> > > 
> > > >
> > > 
> > > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=177819&r1=177818&r2=177819&view=diff
> > > 
> > > 
> > > 
> > > > ==============================================================================
> > > 
> > > > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> > > 
> > > > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sat Mar 23 01:43:35 2013
> > > 
> > > > @@ -86,6 +86,7 @@ CodeGenModule::CodeGenModule(ASTContext
> > > 
> > > >      NSConcreteGlobalBlock(0), NSConcreteStackBlock(0),
> > > 
> > > >      BlockObjectAssign(0), BlockObjectDispose(0),
> > > 
> > > >      BlockDescriptorType(0), GenericBlockLiteralType(0),
> > > 
> > > > +    LifetimeStartFn(0), LifetimeEndFn(0),
> > > 
> > > >      SanitizerBlacklist(CGO.SanitizerBlacklistFile),
> > > 
> > > >      SanOpts(SanitizerBlacklist.isIn(M) ?
> > > 
> > > >              SanitizerOptions::Disabled : LangOpts.Sanitize) {
> > > 
> > > >
> > > 
> > > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=177819&r1=177818&r2=177819&view=diff
> > > 
> > > 
> > > 
> > > > ==============================================================================
> > > 
> > > > --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
> > > 
> > > > +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Sat Mar 23 01:43:35 2013
> > > 
> > > > @@ -381,6 +381,12 @@ class CodeGenModule : public CodeGenType
> > > 
> > > >      int GlobalUniqueCount;
> > > 
> > > >    } Block;
> > > 
> > > >
> > > 
> > > > +  /// void @llvm.lifetime.start(i64 %size, i8* nocapture <ptr>)
> > > 
> > > > +  llvm::Constant *LifetimeStartFn;
> > > 
> > > > +
> > > 
> > > > +  /// void @llvm.lifetime.end(i64 %size, i8* nocapture <ptr>)
> > > 
> > > > +  llvm::Constant *LifetimeEndFn;
> > > 
> > > > +
> > > 
> > > >    GlobalDecl initializedGlobalDecl;
> > > 
> > > >
> > > 
> > > >    llvm::BlackList SanitizerBlacklist;
> > > 
> > > > @@ -757,6 +763,9 @@ public:
> > > 
> > > >
> > > 
> > > >    ///@}
> > > 
> > > >
> > > 
> > > > +  llvm::Constant *getLLVMLifetimeStartFn();
> > > 
> > > > +  llvm::Constant *getLLVMLifetimeEndFn();
> > > 
> > > > +
> > > 
> > > >    // UpdateCompleteType - Make sure that this type is translated.
> > > 
> > > >    void UpdateCompletedType(const TagDecl *TD);
> > > 
> > > >
> > > 
> > > >
> > > 
> > > > Added: cfe/trunk/test/CodeGen/lifetime2.c
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/lifetime2.c?rev=177819&view=auto
> > > 
> > > 
> > > 
> > > > ==============================================================================
> > > 
> > > > --- cfe/trunk/test/CodeGen/lifetime2.c (added)
> > > 
> > > > +++ cfe/trunk/test/CodeGen/lifetime2.c Sat Mar 23 01:43:35 2013
> > > 
> > > > @@ -0,0 +1,17 @@
> > > 
> > > > +// 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);
> > > 
> > > > +  }
> > > 
> > > > +}
> > > 
> > > >
> > > 
> > > > Modified: cfe/trunk/test/CodeGenObjC/arc-blocks.m
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-blocks.m?rev=177819&r1=177818&r2=177819&view=diff
> > > 
> > > 
> > > 
> > > > ==============================================================================
> > > 
> > > > --- cfe/trunk/test/CodeGenObjC/arc-blocks.m (original)
> > > 
> > > > +++ cfe/trunk/test/CodeGenObjC/arc-blocks.m Sat Mar 23 01:43:35 2013
> > > 
> > > > @@ -128,7 +128,7 @@ void test4(void) {
> > > 
> > > >    // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
> > > 
> > > >    // CHECK-NEXT: [[T0:%.*]] = load i8** [[SLOT]]
> > > 
> > > >    // CHECK-NEXT: call void @objc_release(i8* [[T0]])
> > > 
> > > > -  // CHECK-NEXT: ret void
> > > 
> > > > +  // CHECK: ret void
> > > 
> > > >
> > > 
> > > >    // CHECK:    define internal void @__Block_byref_object_copy_
> > > 
> > > >    // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
> > > 
> > > > @@ -207,7 +207,7 @@ void test6(void) {
> > > 
> > > >    // CHECK:      [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*
> > > 
> > > >    // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)
> > > 
> > > >    // CHECK-NEXT: call void @objc_destroyWeak(i8** [[SLOT]])
> > > 
> > > > -  // CHECK-NEXT: ret void
> > > 
> > > > +  // CHECK: ret void
> > > 
> > > >
> > > 
> > > >    // CHECK:    define internal void @__Block_byref_object_copy_
> > > 
> > > >    // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BYREF_T]]* {{%.*}}, i32 0, i32 6
> > > 
> > > > @@ -256,14 +256,14 @@ void test7(void) {
> > > 
> > > >    // CHECK:      call void @test7_helper(
> > > 
> > > >    // CHECK-NEXT: call void @objc_destroyWeak(i8** {{%.*}})
> > > 
> > > >    // CHECK-NEXT: call void @objc_destroyWeak(i8** [[VAR]])
> > > 
> > > > -  // CHECK-NEXT: ret void
> > > 
> > > > +  // CHECK: ret void
> > > 
> > > >
> > > 
> > > >    // CHECK:    define internal void @__test7_block_invoke
> > > 
> > > >    // CHECK:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* {{%.*}}, i32 0, i32 5
> > > 
> > > >    // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_loadWeakRetained(i8** [[SLOT]])
> > > 
> > > >    // CHECK-NEXT: call void @test7_consume(i8* [[T0]])
> > > 
> > > >    // CHECK-NEXT: call void @objc_release(i8* [[T0]])
> > > 
> > > > -  // CHECK-NEXT: ret void
> > > 
> > > > +  // CHECK: ret void
> > > 
> > > >
> > > 
> > > >    // CHECK:    define internal void @__copy_helper_block_
> > > 
> > > >    // CHECK:      getelementptr
> > > 
> > > > @@ -296,7 +296,7 @@ void test7(void) {
> > > 
> > > >  // CHECK-NEXT: [[T1:%.*]] = load [[TEST8]]** [[D0]]
> > > 
> > > >  // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST8]]* [[T1]] to i8*
> > > 
> > > >  // CHECK-NEXT: call void @objc_release(i8* [[T2]])
> > > 
> > > > -// CHECK-NEXT: ret void
> > > 
> > > > +// CHECK: ret void
> > > 
> > > >
> > > 
> > > >    extern void test8_helper(void (^)(void));
> > > 
> > > >    test8_helper(^{ (void) self; });
> > > 
> > > > @@ -354,7 +354,7 @@ void test10a(void) {
> > > 
> > > >    // CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]]
> > > 
> > > >    // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
> > > 
> > > >    // CHECK-NEXT: call void @objc_release(i8* [[T2]])
> > > 
> > > > -  // CHECK-NEXT: ret void
> > > 
> > > > +  // CHECK: ret void
> > > 
> > > >  }
> > > 
> > > >
> > > 
> > > >  // <rdar://problem/10402698>: do this copy and dispose with
> > > 
> > > > @@ -374,7 +374,7 @@ void test10a(void) {
> > > 
> > > >  // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainBlock(i8* [[T1]])
> > > 
> > > >  // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to void ()*
> > > 
> > > >  // CHECK-NEXT: store void ()* [[T3]], void ()** [[D2]], align 8
> > > 
> > > > -// CHECK-NEXT: ret void
> > > 
> > > > +// CHECK: ret void
> > > 
> > > >
> > > 
> > > >  // CHECK: define internal void @__Block_byref_object_dispose
> > > 
> > > >  // CHECK:      [[T0:%.*]] = load i8** {{%.*}}
> > > 
> > > > @@ -418,7 +418,7 @@ void test10b(void) {
> > > 
> > > >    // CHECK-NEXT: [[T1:%.*]] = load void ()** [[SLOT]]
> > > 
> > > >    // CHECK-NEXT: [[T2:%.*]] = bitcast void ()* [[T1]] to i8*
> > > 
> > > >    // CHECK-NEXT: call void @objc_release(i8* [[T2]])
> > > 
> > > > -  // CHECK-NEXT: ret void
> > > 
> > > > +  // CHECK: ret void
> > > 
> > > >  }
> > > 
> > > >
> > > 
> > > >  // rdar://problem/10088932
> > > 
> > > > @@ -438,7 +438,7 @@ void test11a(void) {
> > > 
> > > >    // CHECK-NEXT: call void @test11_helper(i8* [[T4]])
> > > 
> > > >    // CHECK-NEXT: [[T5:%.*]] = bitcast void ()* [[T3]] to i8*
> > > 
> > > >    // CHECK-NEXT: call void @objc_release(i8* [[T5]])
> > > 
> > > > -  // CHECK-NEXT: ret void
> > > 
> > > > +  // CHECK: ret void
> > > 
> > > >  }
> > > 
> > > >  void test11b(void) {
> > > 
> > > >    int x;
> > > 
> > > > @@ -456,7 +456,7 @@ void test11b(void) {
> > > 
> > > >    // CHECK-NEXT: store i8* [[T4]], i8** [[B]], align 8
> > > 
> > > >    // CHECK-NEXT: [[T5:%.*]] = load i8** [[B]]
> > > 
> > > >    // CHECK-NEXT: call void @objc_release(i8* [[T5]])
> > > 
> > > > -  // CHECK-NEXT: ret void
> > > 
> > > > +  // CHECK: ret void
> > > 
> > > >  }
> > > 
> > > >
> > > 
> > > >  // rdar://problem/9979150
> > > 
> > > >
> > > 
> > > > Modified: cfe/trunk/test/CodeGenObjC/arc.m
> > > 
> > > > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc.m?rev=177819&r1=177818&r2=177819&view=diff
> > > 
> > > 
> > > 
> > > > ==============================================================================
> > > 
> > > > --- cfe/trunk/test/CodeGenObjC/arc.m (original)
> > > 
> > > > +++ cfe/trunk/test/CodeGenObjC/arc.m Sat Mar 23 01:43:35 2013
> > > 
> > > > @@ -353,7 +353,7 @@ void test12(void) {
> > > 
> > > >    // CHECK-NEXT: [[T4:%.*]] = load i8** [[Y]]
> > > 
> > > >    // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]], !clang.imprecise_release
> > > 
> > > >    // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]])
> > > 
> > > > -  // CHECK-NEXT: ret void
> > > 
> > > > +  // CHECK: ret void
> > > 
> > > >  }
> > > 
> > > >
> > > 
> > > >  // Indirect consuming calls.
> > > 
> > > > @@ -460,8 +460,9 @@ void test13(void) {
> > > 
> > > >  void test19() {
> > > 
> > > >    // CHECK: define void @test19()
> > > 
> > > >    // CHECK:      [[X:%.*]] = alloca [5 x i8*], align 16
> > > 
> > > > +  // CHECK: call void @llvm.lifetime.start
> > > 
> > > >    // CHECK-NEXT: [[T0:%.*]] = bitcast [5 x i8*]* [[X]] to i8*
> > > 
> > > > -  // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 40, i32 16, i1 false)
> > > 
> > > > +  // CHECK: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 40, i32 16, i1 false)
> > > 
> > > >    id x[5];
> > > 
> > > >
> > > 
> > > >    extern id test19_helper(void);
> > > 
> > > >
> > > 
> > > >
> > > 
> > > > _______________________________________________
> > > 
> > > > cfe-commits mailing list
> > > 
> > > > cfe-commits at cs.uiuc.edu
> > > 
> > > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> > > 
> > > _______________________________________________
> > > 
> > > cfe-commits mailing list
> > > 
> > > cfe-commits at cs.uiuc.edu
> > > 
> > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> > > 
> > > 
> > > 
> > > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> 
> 
> 
> 
> 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130327/4aa10447/attachment.html>


More information about the cfe-commits mailing list