136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//===--- CGCleanup.cpp - Bookkeeping and code emission for cleanups -------===//
236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//
336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//                     The LLVM Compiler Infrastructure
436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//
536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall// This file is distributed under the University of Illinois Open Source
636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall// License. See LICENSE.TXT for details.
736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//
836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//===----------------------------------------------------------------------===//
936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//
1036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall// This file contains code dealing with the IR generation for cleanups
1136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall// and related information.
1236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//
1336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall// A "cleanup" is a piece of code which needs to be executed whenever
1436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall// control transfers out of a particular scope.  This can be
1536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall// conditionalized to occur only on exceptional control flow, only on
1636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall// normal control flow, or both.
1736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//
1836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall//===----------------------------------------------------------------------===//
1936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
2036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall#include "CodeGenFunction.h"
2136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall#include "CGCleanup.h"
2236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
2336f893c1efe367f929d92c8b125f964c22ba189eJohn McCallusing namespace clang;
2436f893c1efe367f929d92c8b125f964c22ba189eJohn McCallusing namespace CodeGen;
2536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
2636f893c1efe367f929d92c8b125f964c22ba189eJohn McCallbool DominatingValue<RValue>::saved_type::needsSaving(RValue rv) {
2736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (rv.isScalar())
2836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return DominatingLLVMValue::needsSaving(rv.getScalarVal());
2936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (rv.isAggregate())
3036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return DominatingLLVMValue::needsSaving(rv.getAggregateAddr());
3136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return true;
3236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
3336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
3436f893c1efe367f929d92c8b125f964c22ba189eJohn McCallDominatingValue<RValue>::saved_type
3536f893c1efe367f929d92c8b125f964c22ba189eJohn McCallDominatingValue<RValue>::saved_type::save(CodeGenFunction &CGF, RValue rv) {
3636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (rv.isScalar()) {
3736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::Value *V = rv.getScalarVal();
3836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
3936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // These automatically dominate and don't need to be saved.
4036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (!DominatingLLVMValue::needsSaving(V))
4136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      return saved_type(V, ScalarLiteral);
4236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
4336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // Everything else needs an alloca.
4436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::Value *addr = CGF.CreateTempAlloca(V->getType(), "saved-rvalue");
4536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    CGF.Builder.CreateStore(V, addr);
4636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return saved_type(addr, ScalarAddress);
4736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
4836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
4936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (rv.isComplex()) {
5036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    CodeGenFunction::ComplexPairTy V = rv.getComplexVal();
512acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *ComplexTy =
527650d95a1a616ea300f37126a8dfc93dc19a662aChris Lattner      llvm::StructType::get(V.first->getType(), V.second->getType(),
5336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                            (void*) 0);
5436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::Value *addr = CGF.CreateTempAlloca(ComplexTy, "saved-complex");
559d232c884ea9872d6555df0fd7359699819bc1f1John McCall    CGF.Builder.CreateStore(V.first, CGF.Builder.CreateStructGEP(addr, 0));
569d232c884ea9872d6555df0fd7359699819bc1f1John McCall    CGF.Builder.CreateStore(V.second, CGF.Builder.CreateStructGEP(addr, 1));
5736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return saved_type(addr, ComplexAddress);
5836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
5936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
6036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(rv.isAggregate());
6136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::Value *V = rv.getAggregateAddr(); // TODO: volatile?
6236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!DominatingLLVMValue::needsSaving(V))
6336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return saved_type(V, AggregateLiteral);
6436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
6536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::Value *addr = CGF.CreateTempAlloca(V->getType(), "saved-rvalue");
6636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  CGF.Builder.CreateStore(V, addr);
6736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return saved_type(addr, AggregateAddress);
6836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
6936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
7036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Given a saved r-value produced by SaveRValue, perform the code
7136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// necessary to restore it to usability at the current insertion
7236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// point.
7336f893c1efe367f929d92c8b125f964c22ba189eJohn McCallRValue DominatingValue<RValue>::saved_type::restore(CodeGenFunction &CGF) {
7436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  switch (K) {
7536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  case ScalarLiteral:
7636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return RValue::get(Value);
7736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  case ScalarAddress:
7836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return RValue::get(CGF.Builder.CreateLoad(Value));
7936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  case AggregateLiteral:
8036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return RValue::getAggregate(Value);
8136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  case AggregateAddress:
8236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return RValue::getAggregate(CGF.Builder.CreateLoad(Value));
839d232c884ea9872d6555df0fd7359699819bc1f1John McCall  case ComplexAddress: {
849d232c884ea9872d6555df0fd7359699819bc1f1John McCall    llvm::Value *real =
859d232c884ea9872d6555df0fd7359699819bc1f1John McCall      CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(Value, 0));
869d232c884ea9872d6555df0fd7359699819bc1f1John McCall    llvm::Value *imag =
879d232c884ea9872d6555df0fd7359699819bc1f1John McCall      CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(Value, 1));
889d232c884ea9872d6555df0fd7359699819bc1f1John McCall    return RValue::getComplex(real, imag);
899d232c884ea9872d6555df0fd7359699819bc1f1John McCall  }
9036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
9136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
9236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm_unreachable("bad saved r-value kind");
9336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
9436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
9536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Push an entry of the given size onto this protected-scope stack.
9636f893c1efe367f929d92c8b125f964c22ba189eJohn McCallchar *EHScopeStack::allocate(size_t Size) {
9736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!StartOfBuffer) {
9836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    unsigned Capacity = 1024;
9936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    while (Capacity < Size) Capacity *= 2;
10036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    StartOfBuffer = new char[Capacity];
10136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    StartOfData = EndOfBuffer = StartOfBuffer + Capacity;
10236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  } else if (static_cast<size_t>(StartOfData - StartOfBuffer) < Size) {
10336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    unsigned CurrentCapacity = EndOfBuffer - StartOfBuffer;
10436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    unsigned UsedCapacity = CurrentCapacity - (StartOfData - StartOfBuffer);
10536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
10636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    unsigned NewCapacity = CurrentCapacity;
10736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    do {
10836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      NewCapacity *= 2;
10936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    } while (NewCapacity < UsedCapacity + Size);
11036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
11136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    char *NewStartOfBuffer = new char[NewCapacity];
11236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    char *NewEndOfBuffer = NewStartOfBuffer + NewCapacity;
11336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    char *NewStartOfData = NewEndOfBuffer - UsedCapacity;
11436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    memcpy(NewStartOfData, StartOfData, UsedCapacity);
11536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    delete [] StartOfBuffer;
11636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    StartOfBuffer = NewStartOfBuffer;
11736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    EndOfBuffer = NewEndOfBuffer;
11836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    StartOfData = NewStartOfData;
11936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
12036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
12136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(StartOfBuffer + Size <= StartOfData);
12236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  StartOfData -= Size;
12336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return StartOfData;
12436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
12536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
12636f893c1efe367f929d92c8b125f964c22ba189eJohn McCallEHScopeStack::stable_iterator
127777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallEHScopeStack::getInnermostActiveNormalCleanup() const {
128777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  for (stable_iterator si = getInnermostNormalCleanup(), se = stable_end();
129777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall         si != se; ) {
130777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EHCleanupScope &cleanup = cast<EHCleanupScope>(*find(si));
131777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    if (cleanup.isActive()) return si;
132777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    si = cleanup.getEnclosingNormalCleanup();
133777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
134777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  return stable_end();
135777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall}
136777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
137777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallEHScopeStack::stable_iterator EHScopeStack::getInnermostActiveEHScope() const {
138777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  for (stable_iterator si = getInnermostEHScope(), se = stable_end();
139777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall         si != se; ) {
140777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // Skip over inactive cleanups.
141777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EHCleanupScope *cleanup = dyn_cast<EHCleanupScope>(&*find(si));
142777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    if (cleanup && !cleanup->isActive()) {
143777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      si = cleanup->getEnclosingEHScope();
144777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      continue;
14536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    }
146777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
147777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    // All other scopes are always active.
148777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    return si;
149777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  }
150777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
15136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return stable_end();
15236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
15336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
15436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
15536f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) {
15636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(((Size % sizeof(void*)) == 0) && "cleanup type is misaligned");
15736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  char *Buffer = allocate(EHCleanupScope::getSizeForCleanupSize(Size));
15836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool IsNormalCleanup = Kind & NormalCleanup;
15936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool IsEHCleanup = Kind & EHCleanup;
16036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool IsActive = !(Kind & InactiveCleanup);
16136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHCleanupScope *Scope =
16236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    new (Buffer) EHCleanupScope(IsNormalCleanup,
16336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                IsEHCleanup,
16436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                IsActive,
16536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                Size,
16636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                BranchFixups.size(),
16736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                InnermostNormalCleanup,
168777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall                                InnermostEHScope);
16936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (IsNormalCleanup)
17036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    InnermostNormalCleanup = stable_begin();
17136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (IsEHCleanup)
172777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    InnermostEHScope = stable_begin();
17336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
17436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return Scope->getCleanupBuffer();
17536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
17636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
17736f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid EHScopeStack::popCleanup() {
17836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(!empty() && "popping exception stack when not empty");
17936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
18036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(isa<EHCleanupScope>(*begin()));
18136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHCleanupScope &Cleanup = cast<EHCleanupScope>(*begin());
18236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  InnermostNormalCleanup = Cleanup.getEnclosingNormalCleanup();
183777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  InnermostEHScope = Cleanup.getEnclosingEHScope();
18436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  StartOfData += Cleanup.getAllocatedSize();
18536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
18636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Destroy the cleanup.
18736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  Cleanup.~EHCleanupScope();
18836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
18936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Check whether we can shrink the branch-fixups stack.
19036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!BranchFixups.empty()) {
19136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // If we no longer have any normal cleanups, all the fixups are
19236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // complete.
19336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (!hasNormalCleanups())
19436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      BranchFixups.clear();
19536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
19636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // Otherwise we can still trim out unnecessary nulls.
19736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    else
19836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      popNullFixups();
19936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
20036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
20136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
202777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallEHFilterScope *EHScopeStack::pushFilter(unsigned numFilters) {
203777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  assert(getInnermostEHScope() == stable_end());
204777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  char *buffer = allocate(EHFilterScope::getSizeForNumFilters(numFilters));
205777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHFilterScope *filter = new (buffer) EHFilterScope(numFilters);
206777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  InnermostEHScope = stable_begin();
207777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  return filter;
20836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
20936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
21036f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid EHScopeStack::popFilter() {
21136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(!empty() && "popping exception stack when not empty");
21236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
213777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHFilterScope &filter = cast<EHFilterScope>(*begin());
214777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  StartOfData += EHFilterScope::getSizeForNumFilters(filter.getNumFilters());
21536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
216777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  InnermostEHScope = filter.getEnclosingEHScope();
21736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
21836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
219777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallEHCatchScope *EHScopeStack::pushCatch(unsigned numHandlers) {
220777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  char *buffer = allocate(EHCatchScope::getSizeForNumHandlers(numHandlers));
221777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHCatchScope *scope =
222777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    new (buffer) EHCatchScope(numHandlers, InnermostEHScope);
223777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  InnermostEHScope = stable_begin();
224777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  return scope;
22536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
22636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
22736f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid EHScopeStack::pushTerminate() {
22836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  char *Buffer = allocate(EHTerminateScope::getSize());
229777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  new (Buffer) EHTerminateScope(InnermostEHScope);
230777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  InnermostEHScope = stable_begin();
23136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
23236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
23336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Remove any 'null' fixups on the stack.  However, we can't pop more
23436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// fixups than the fixup depth on the innermost normal cleanup, or
23536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// else fixups that we try to add to that cleanup will end up in the
23636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// wrong place.  We *could* try to shrink fixup depths, but that's
23736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// actually a lot of work for little benefit.
23836f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid EHScopeStack::popNullFixups() {
23936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // We expect this to only be called when there's still an innermost
24036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // normal cleanup;  otherwise there really shouldn't be any fixups.
24136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(hasNormalCleanups());
24236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
24336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHScopeStack::iterator it = find(InnermostNormalCleanup);
24436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  unsigned MinSize = cast<EHCleanupScope>(*it).getFixupDepth();
24536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(BranchFixups.size() >= MinSize && "fixup stack out of order");
24636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
24736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  while (BranchFixups.size() > MinSize &&
24836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall         BranchFixups.back().Destination == 0)
24936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    BranchFixups.pop_back();
25036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
25136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
25236f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid CodeGenFunction::initFullExprCleanup() {
25336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Create a variable to decide whether the cleanup needs to be run.
25436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::AllocaInst *active
25536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    = CreateTempAlloca(Builder.getInt1Ty(), "cleanup.cond");
25636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
25736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Initialize it to false at a site that's guaranteed to be run
25836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // before each evaluation.
2596f103ba42cb69d50005a977c5ea583984ab63fc4John McCall  setBeforeOutermostConditional(Builder.getFalse(), active);
26036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
26136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Initialize it to true at the current location.
26236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  Builder.CreateStore(Builder.getTrue(), active);
26336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
26436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Set that as the active flag in the cleanup.
26536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHCleanupScope &cleanup = cast<EHCleanupScope>(*EHStack.begin());
26636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(cleanup.getActiveFlag() == 0 && "cleanup already has active flag?");
26736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  cleanup.setActiveFlag(active);
26836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
26936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (cleanup.isNormalCleanup()) cleanup.setTestFlagInNormalCleanup();
27036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (cleanup.isEHCleanup()) cleanup.setTestFlagInEHCleanup();
27136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
27236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
273c4a1a8450a3613ef256a71b9d8305b41f79eef50John McCallvoid EHScopeStack::Cleanup::anchor() {}
27436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
27536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// All the branch fixups on the EH stack have propagated out past the
27636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// outermost normal cleanup; resolve them all by adding cases to the
27736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// given switch instruction.
27836f893c1efe367f929d92c8b125f964c22ba189eJohn McCallstatic void ResolveAllBranchFixups(CodeGenFunction &CGF,
27936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                   llvm::SwitchInst *Switch,
28036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                   llvm::BasicBlock *CleanupEntry) {
28136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::SmallPtrSet<llvm::BasicBlock*, 4> CasesAdded;
28236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
28336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  for (unsigned I = 0, E = CGF.EHStack.getNumBranchFixups(); I != E; ++I) {
28436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // Skip this fixup if its destination isn't set.
28536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    BranchFixup &Fixup = CGF.EHStack.getBranchFixup(I);
28636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (Fixup.Destination == 0) continue;
28736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
28836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // If there isn't an OptimisticBranchBlock, then InitialBranch is
28936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // still pointing directly to its destination; forward it to the
29036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // appropriate cleanup entry.  This is required in the specific
29136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // case of
29236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    //   { std::string s; goto lbl; }
29336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    //   lbl:
29436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // i.e. where there's an unresolved fixup inside a single cleanup
29536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // entry which we're currently popping.
29636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (Fixup.OptimisticBranchBlock == 0) {
29736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      new llvm::StoreInst(CGF.Builder.getInt32(Fixup.DestinationIndex),
29836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                          CGF.getNormalCleanupDestSlot(),
29936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                          Fixup.InitialBranch);
30036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      Fixup.InitialBranch->setSuccessor(0, CleanupEntry);
30136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    }
30236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
30336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // Don't add this case to the switch statement twice.
30436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (!CasesAdded.insert(Fixup.Destination)) continue;
30536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
30636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Switch->addCase(CGF.Builder.getInt32(Fixup.DestinationIndex),
30736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                    Fixup.Destination);
30836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
30936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
31036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  CGF.EHStack.clearFixups();
31136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
31236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
31336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Transitions the terminator of the given exit-block of a cleanup to
31436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// be a cleanup switch.
31536f893c1efe367f929d92c8b125f964c22ba189eJohn McCallstatic llvm::SwitchInst *TransitionToCleanupSwitch(CodeGenFunction &CGF,
31636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                                   llvm::BasicBlock *Block) {
31736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If it's a branch, turn it into a switch whose default
31836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // destination is its original target.
31936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::TerminatorInst *Term = Block->getTerminator();
32036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(Term && "can't transition block without terminator");
32136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
32236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Term)) {
32336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    assert(Br->isUnconditional());
32436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::LoadInst *Load =
32536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      new llvm::LoadInst(CGF.getNormalCleanupDestSlot(), "cleanup.dest", Term);
32636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::SwitchInst *Switch =
32736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      llvm::SwitchInst::Create(Load, Br->getSuccessor(0), 4, Block);
32836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Br->eraseFromParent();
32936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return Switch;
33036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  } else {
33136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return cast<llvm::SwitchInst>(Term);
33236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
33336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
33436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
33536f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid CodeGenFunction::ResolveBranchFixups(llvm::BasicBlock *Block) {
33636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(Block && "resolving a null target block");
33736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!EHStack.getNumBranchFixups()) return;
33836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
33936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(EHStack.hasNormalCleanups() &&
34036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall         "branch fixups exist with no normal cleanups on stack");
34136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
34236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::SmallPtrSet<llvm::BasicBlock*, 4> ModifiedOptimisticBlocks;
34336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool ResolvedAny = false;
34436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
34536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  for (unsigned I = 0, E = EHStack.getNumBranchFixups(); I != E; ++I) {
34636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // Skip this fixup if its destination doesn't match.
34736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    BranchFixup &Fixup = EHStack.getBranchFixup(I);
34836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (Fixup.Destination != Block) continue;
34936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
35036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Fixup.Destination = 0;
35136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    ResolvedAny = true;
35236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
35336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // If it doesn't have an optimistic branch block, LatestBranch is
35436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // already pointing to the right place.
35536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::BasicBlock *BranchBB = Fixup.OptimisticBranchBlock;
35636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (!BranchBB)
35736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      continue;
35836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
35936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // Don't process the same optimistic branch block twice.
36036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (!ModifiedOptimisticBlocks.insert(BranchBB))
36136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      continue;
36236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
36336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::SwitchInst *Switch = TransitionToCleanupSwitch(*this, BranchBB);
36436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
36536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // Add a case to the switch.
36636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Switch->addCase(Builder.getInt32(Fixup.DestinationIndex), Block);
36736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
36836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
36936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (ResolvedAny)
37036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    EHStack.popNullFixups();
37136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
37236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
37336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Pops cleanup blocks until the given savepoint is reached.
37436f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old) {
37536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(Old.isValid());
37636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
37736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  while (EHStack.stable_begin() != Old) {
37836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin());
37936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
38036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // As long as Old strictly encloses the scope's enclosing normal
38136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // cleanup, we're going to emit another normal cleanup which
38236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // fallthrough can propagate through.
38336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    bool FallThroughIsBranchThrough =
38436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      Old.strictlyEncloses(Scope.getEnclosingNormalCleanup());
38536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
38636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    PopCleanupBlock(FallThroughIsBranchThrough);
38736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
38836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
38936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
39036f893c1efe367f929d92c8b125f964c22ba189eJohn McCallstatic llvm::BasicBlock *CreateNormalEntry(CodeGenFunction &CGF,
39136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                           EHCleanupScope &Scope) {
39236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(Scope.isNormalCleanup());
39336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::BasicBlock *Entry = Scope.getNormalBlock();
39436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!Entry) {
39536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Entry = CGF.createBasicBlock("cleanup");
39636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Scope.setNormalBlock(Entry);
39736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
39836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return Entry;
39936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
40036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
40136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Attempts to reduce a cleanup's entry block to a fallthrough.  This
40236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// is basically llvm::MergeBlockIntoPredecessor, except
40336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// simplified/optimized for the tighter constraints on cleanup blocks.
40436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall///
40536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Returns the new block, whatever it is.
40636f893c1efe367f929d92c8b125f964c22ba189eJohn McCallstatic llvm::BasicBlock *SimplifyCleanupEntry(CodeGenFunction &CGF,
40736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                              llvm::BasicBlock *Entry) {
40836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::BasicBlock *Pred = Entry->getSinglePredecessor();
40936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!Pred) return Entry;
41036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
41136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Pred->getTerminator());
41236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!Br || Br->isConditional()) return Entry;
41336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(Br->getSuccessor(0) == Entry);
41436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
41536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If we were previously inserting at the end of the cleanup entry
41636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // block, we'll need to continue inserting at the end of the
41736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // predecessor.
41836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool WasInsertBlock = CGF.Builder.GetInsertBlock() == Entry;
41936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(!WasInsertBlock || CGF.Builder.GetInsertPoint() == Entry->end());
42036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
42136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Kill the branch.
42236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  Br->eraseFromParent();
42336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
42436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Replace all uses of the entry with the predecessor, in case there
42536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // are phis in the cleanup.
42636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  Entry->replaceAllUsesWith(Pred);
42736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
428d36d036c819f7925b933974fa18eacc95d46049aJay Foad  // Merge the blocks.
429d36d036c819f7925b933974fa18eacc95d46049aJay Foad  Pred->getInstList().splice(Pred->end(), Entry->getInstList());
430d36d036c819f7925b933974fa18eacc95d46049aJay Foad
43136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Kill the entry block.
43236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  Entry->eraseFromParent();
43336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
43436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (WasInsertBlock)
43536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    CGF.Builder.SetInsertPoint(Pred);
43636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
43736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return Pred;
43836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
43936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
44036f893c1efe367f929d92c8b125f964c22ba189eJohn McCallstatic void EmitCleanup(CodeGenFunction &CGF,
44136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                        EHScopeStack::Cleanup *Fn,
442ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall                        EHScopeStack::Cleanup::Flags flags,
44336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                        llvm::Value *ActiveFlag) {
44436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // EH cleanups always occur within a terminate scope.
445ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall  if (flags.isForEHCleanup()) CGF.EHStack.pushTerminate();
44636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
44736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If there's an active flag, load it and skip the cleanup if it's
44836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // false.
44936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::BasicBlock *ContBB = 0;
45036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (ActiveFlag) {
45136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    ContBB = CGF.createBasicBlock("cleanup.done");
45236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::BasicBlock *CleanupBB = CGF.createBasicBlock("cleanup.action");
45336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::Value *IsActive
45436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      = CGF.Builder.CreateLoad(ActiveFlag, "cleanup.is_active");
45536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    CGF.Builder.CreateCondBr(IsActive, CleanupBB, ContBB);
45636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    CGF.EmitBlock(CleanupBB);
45736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
45836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
45936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Ask the cleanup to emit itself.
460ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall  Fn->Emit(CGF, flags);
46136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(CGF.HaveInsertPoint() && "cleanup ended with no insertion point?");
46236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
46336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Emit the continuation block if there was an active flag.
46436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (ActiveFlag)
46536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    CGF.EmitBlock(ContBB);
46636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
46736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Leave the terminate scope.
468ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall  if (flags.isForEHCleanup()) CGF.EHStack.popTerminate();
46936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
47036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
47136f893c1efe367f929d92c8b125f964c22ba189eJohn McCallstatic void ForwardPrebranchedFallthrough(llvm::BasicBlock *Exit,
47236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                          llvm::BasicBlock *From,
47336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                          llvm::BasicBlock *To) {
47436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Exit is the exit block of a cleanup, so it always terminates in
47536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // an unconditional branch or a switch.
47636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::TerminatorInst *Term = Exit->getTerminator();
47736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
47836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Term)) {
47936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    assert(Br->isUnconditional() && Br->getSuccessor(0) == From);
48036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Br->setSuccessor(0, To);
48136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  } else {
48236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    llvm::SwitchInst *Switch = cast<llvm::SwitchInst>(Term);
48336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    for (unsigned I = 0, E = Switch->getNumSuccessors(); I != E; ++I)
48436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      if (Switch->getSuccessor(I) == From)
48536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        Switch->setSuccessor(I, To);
48636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
48736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
48836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
48982cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall/// We don't need a normal entry block for the given cleanup.
49082cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall/// Optimistic fixup branches can cause these blocks to come into
49182cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall/// existence anyway;  if so, destroy it.
49282cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall///
49382cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall/// The validity of this transformation is very much specific to the
49482cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall/// exact ways in which we form branches to cleanup entries.
49582cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCallstatic void destroyOptimisticNormalEntry(CodeGenFunction &CGF,
49682cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall                                         EHCleanupScope &scope) {
49782cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall  llvm::BasicBlock *entry = scope.getNormalBlock();
49882cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall  if (!entry) return;
49982cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall
50082cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall  // Replace all the uses with unreachable.
50182cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall  llvm::BasicBlock *unreachableBB = CGF.getUnreachableBlock();
50282cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall  for (llvm::BasicBlock::use_iterator
50382cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall         i = entry->use_begin(), e = entry->use_end(); i != e; ) {
50482cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall    llvm::Use &use = i.getUse();
50582cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall    ++i;
50682cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall
50782cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall    use.set(unreachableBB);
50882cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall
50982cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall    // The only uses should be fixup switches.
51082cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall    llvm::SwitchInst *si = cast<llvm::SwitchInst>(use.getUser());
511ab14ae2ab16088b6a7f69eac6e152c3e9f9ea01bStepan Dyatkovskiy    if (si->getNumCases() == 1 && si->getDefaultDest() == unreachableBB) {
51282cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      // Replace the switch with a branch.
5137c02cfeb0861278c09ba05d1b92bd2a996bbe2e0Stepan Dyatkovskiy      llvm::BranchInst::Create(si->case_begin().getCaseSuccessor(), si);
51482cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall
51582cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      // The switch operand is a load from the cleanup-dest alloca.
51682cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      llvm::LoadInst *condition = cast<llvm::LoadInst>(si->getCondition());
51782cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall
51882cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      // Destroy the switch.
51982cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      si->eraseFromParent();
52082cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall
52182cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      // Destroy the load.
52282cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      assert(condition->getOperand(0) == CGF.NormalCleanupDest);
52382cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      assert(condition->use_empty());
52482cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      condition->eraseFromParent();
52582cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall    }
52682cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall  }
52782cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall
52882cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall  assert(entry->use_empty());
52982cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall  delete entry;
53082cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall}
53182cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall
53236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Pops a cleanup block.  If the block includes a normal cleanup, the
53336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// current insertion point is threaded through the cleanup, as are
53436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// any branch fixups on the cleanup.
53536f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
53636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(!EHStack.empty() && "cleanup stack is empty!");
53736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(isa<EHCleanupScope>(*EHStack.begin()) && "top not a cleanup!");
53836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin());
53936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups());
54036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
54136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Remember activation information.
54236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool IsActive = Scope.isActive();
54336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::Value *NormalActiveFlag =
54436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Scope.shouldTestFlagInNormalCleanup() ? Scope.getActiveFlag() : 0;
54536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::Value *EHActiveFlag =
54636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Scope.shouldTestFlagInEHCleanup() ? Scope.getActiveFlag() : 0;
54736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
54836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Check whether we need an EH cleanup.  This is only true if we've
54936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // generated a lazy EH cleanup block.
550777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  llvm::BasicBlock *EHEntry = Scope.getCachedEHDispatchBlock();
551777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  assert(Scope.hasEHBranches() == (EHEntry != 0));
552777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  bool RequiresEHCleanup = (EHEntry != 0);
553777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHScopeStack::stable_iterator EHParent = Scope.getEnclosingEHScope();
55436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
55536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Check the three conditions which might require a normal cleanup:
55636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
55736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // - whether there are branch fix-ups through this cleanup
55836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  unsigned FixupDepth = Scope.getFixupDepth();
55936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool HasFixups = EHStack.getNumBranchFixups() != FixupDepth;
56036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
56136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // - whether there are branch-throughs or branch-afters
56236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool HasExistingBranches = Scope.hasBranches();
56336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
56436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // - whether there's a fallthrough
56536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
56636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool HasFallthrough = (FallthroughSource != 0 && IsActive);
56736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
56836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Branch-through fall-throughs leave the insertion point set to the
56936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // end of the last cleanup, which points to the current scope.  The
57036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // rest of IR gen doesn't need to worry about this; it only happens
57136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // during the execution of PopCleanupBlocks().
57236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool HasPrebranchedFallthrough =
57336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    (FallthroughSource && FallthroughSource->getTerminator());
57436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
57536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If this is a normal cleanup, then having a prebranched
57636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // fallthrough implies that the fallthrough source unconditionally
57736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // jumps here.
57836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(!Scope.isNormalCleanup() || !HasPrebranchedFallthrough ||
57936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall         (Scope.getNormalBlock() &&
58036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          FallthroughSource->getTerminator()->getSuccessor(0)
58136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall            == Scope.getNormalBlock()));
58236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
58336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  bool RequiresNormalCleanup = false;
58436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (Scope.isNormalCleanup() &&
58536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      (HasFixups || HasExistingBranches || HasFallthrough)) {
58636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    RequiresNormalCleanup = true;
58736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
58836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
589f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall  // If we have a prebranched fallthrough into an inactive normal
590f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall  // cleanup, rewrite it so that it leads to the appropriate place.
591f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall  if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) {
592f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    llvm::BasicBlock *prebranchDest;
593f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall
594f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    // If the prebranch is semantically branching through the next
595f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    // cleanup, just forward it to the next block, leaving the
596f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    // insertion point in the prebranched block.
59736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (FallthroughIsBranchThrough) {
598f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall      EHScope &enclosing = *EHStack.find(Scope.getEnclosingNormalCleanup());
599f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall      prebranchDest = CreateNormalEntry(*this, cast<EHCleanupScope>(enclosing));
60036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
601f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    // Otherwise, we need to make a new block.  If the normal cleanup
602f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    // isn't being used at all, we could actually reuse the normal
603f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    // entry block, but this is simpler, and it avoids conflicts with
604f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    // dead optimistic fixup branches.
60536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    } else {
606f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall      prebranchDest = createBasicBlock("forwarded-prebranch");
607f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall      EmitBlock(prebranchDest);
60836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    }
609f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall
610f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    llvm::BasicBlock *normalEntry = Scope.getNormalBlock();
611f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    assert(normalEntry && !normalEntry->use_empty());
612f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall
613f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall    ForwardPrebranchedFallthrough(FallthroughSource,
614f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall                                  normalEntry, prebranchDest);
61536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
61636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
61736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If we don't need the cleanup at all, we're done.
61836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!RequiresNormalCleanup && !RequiresEHCleanup) {
61982cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall    destroyOptimisticNormalEntry(*this, Scope);
62036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    EHStack.popCleanup(); // safe because there are no fixups
62136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    assert(EHStack.getNumBranchFixups() == 0 ||
62236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall           EHStack.hasNormalCleanups());
62336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return;
62436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
62536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
62636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Copy the cleanup emission data out.  Note that SmallVector
62736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // guarantees maximal alignment for its buffer regardless of its
62836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // type parameter.
6295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<char, 8*sizeof(void*)> CleanupBuffer;
63036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  CleanupBuffer.reserve(Scope.getCleanupSize());
63136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  memcpy(CleanupBuffer.data(),
63236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall         Scope.getCleanupBuffer(), Scope.getCleanupSize());
63336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  CleanupBuffer.set_size(Scope.getCleanupSize());
63436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHScopeStack::Cleanup *Fn =
63536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    reinterpret_cast<EHScopeStack::Cleanup*>(CleanupBuffer.data());
63636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
637777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  EHScopeStack::Cleanup::Flags cleanupFlags;
638777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (Scope.isNormalCleanup())
639777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    cleanupFlags.setIsNormalCleanupKind();
640777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (Scope.isEHCleanup())
641777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    cleanupFlags.setIsEHCleanupKind();
64236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
64336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!RequiresNormalCleanup) {
64482cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall    destroyOptimisticNormalEntry(*this, Scope);
64536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    EHStack.popCleanup();
64636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  } else {
64736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // If we have a fallthrough and no other need for the cleanup,
64836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // emit it directly.
64936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (HasFallthrough && !HasPrebranchedFallthrough &&
65036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        !HasFixups && !HasExistingBranches) {
65136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
65282cd2e5c15aa909ec9613c4228ab69e07f1c6f7aJohn McCall      destroyOptimisticNormalEntry(*this, Scope);
65336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      EHStack.popCleanup();
65436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
655ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall      EmitCleanup(*this, Fn, cleanupFlags, NormalActiveFlag);
65636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
65736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // Otherwise, the best approach is to thread everything through
65836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // the cleanup block and then try to clean up after ourselves.
65936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    } else {
66036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Force the entry block to exist.
66136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      llvm::BasicBlock *NormalEntry = CreateNormalEntry(*this, Scope);
66236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
66336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // I.  Set up the fallthrough edge in.
66436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
665e7d002041dc60521f237b4219fd4167d1fe67aa7John McCall      CGBuilderTy::InsertPoint savedInactiveFallthroughIP;
666f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall
66736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // If there's a fallthrough, we need to store the cleanup
66836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // destination index.  For fall-throughs this is always zero.
66936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      if (HasFallthrough) {
67036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        if (!HasPrebranchedFallthrough)
67136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          Builder.CreateStore(Builder.getInt32(0), getNormalCleanupDestSlot());
67236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
673f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall      // Otherwise, save and clear the IP if we don't have fallthrough
674f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall      // because the cleanup is inactive.
67536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      } else if (FallthroughSource) {
67636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        assert(!IsActive && "source without fallthrough for active cleanup");
677f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall        savedInactiveFallthroughIP = Builder.saveAndClearIP();
67836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      }
67936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
68036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // II.  Emit the entry block.  This implicitly branches to it if
68136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // we have fallthrough.  All the fixups and existing branches
68236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // should already be branched to it.
68336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      EmitBlock(NormalEntry);
68436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
68536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // III.  Figure out where we're going and build the cleanup
68636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // epilogue.
68736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
68836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      bool HasEnclosingCleanups =
68936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        (Scope.getEnclosingNormalCleanup() != EHStack.stable_end());
69036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
69136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Compute the branch-through dest if we need it:
69236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      //   - if there are branch-throughs threaded through the scope
69336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      //   - if fall-through is a branch-through
69436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      //   - if there are fixups that will be optimistically forwarded
69536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      //     to the enclosing cleanup
69636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      llvm::BasicBlock *BranchThroughDest = 0;
69736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      if (Scope.hasBranchThroughs() ||
69836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          (FallthroughSource && FallthroughIsBranchThrough) ||
69936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          (HasFixups && HasEnclosingCleanups)) {
70036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        assert(HasEnclosingCleanups);
70136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        EHScope &S = *EHStack.find(Scope.getEnclosingNormalCleanup());
70236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        BranchThroughDest = CreateNormalEntry(*this, cast<EHCleanupScope>(S));
70336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      }
70436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
70536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      llvm::BasicBlock *FallthroughDest = 0;
7065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      SmallVector<llvm::Instruction*, 2> InstsToAppend;
70736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
70836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // If there's exactly one branch-after and no other threads,
70936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // we can route it without a switch.
71036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      if (!Scope.hasBranchThroughs() && !HasFixups && !HasFallthrough &&
71136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          Scope.getNumBranchAfters() == 1) {
71236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        assert(!BranchThroughDest || !IsActive);
71336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
71436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        // TODO: clean up the possibly dead stores to the cleanup dest slot.
71536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0);
71636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        InstsToAppend.push_back(llvm::BranchInst::Create(BranchAfter));
71736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
71836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Build a switch-out if we need it:
71936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      //   - if there are branch-afters threaded through the scope
72036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      //   - if fall-through is a branch-after
72136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      //   - if there are fixups that have nowhere left to go and
72236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      //     so must be immediately resolved
72336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      } else if (Scope.getNumBranchAfters() ||
72436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                 (HasFallthrough && !FallthroughIsBranchThrough) ||
72536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                 (HasFixups && !HasEnclosingCleanups)) {
72636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
72736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        llvm::BasicBlock *Default =
72836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          (BranchThroughDest ? BranchThroughDest : getUnreachableBlock());
72936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
73036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        // TODO: base this on the number of branch-afters and fixups
73136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        const unsigned SwitchCapacity = 10;
73236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
73336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        llvm::LoadInst *Load =
73436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          new llvm::LoadInst(getNormalCleanupDestSlot(), "cleanup.dest");
73536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        llvm::SwitchInst *Switch =
73636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          llvm::SwitchInst::Create(Load, Default, SwitchCapacity);
73736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
73836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        InstsToAppend.push_back(Load);
73936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        InstsToAppend.push_back(Switch);
74036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
74136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        // Branch-after fallthrough.
74236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        if (FallthroughSource && !FallthroughIsBranchThrough) {
74336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          FallthroughDest = createBasicBlock("cleanup.cont");
74436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          if (HasFallthrough)
74536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall            Switch->addCase(Builder.getInt32(0), FallthroughDest);
74636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        }
74736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
74836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        for (unsigned I = 0, E = Scope.getNumBranchAfters(); I != E; ++I) {
74936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          Switch->addCase(Scope.getBranchAfterIndex(I),
75036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                          Scope.getBranchAfterBlock(I));
75136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        }
75236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
75336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        // If there aren't any enclosing cleanups, we can resolve all
75436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        // the fixups now.
75536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        if (HasFixups && !HasEnclosingCleanups)
75636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          ResolveAllBranchFixups(*this, Switch, NormalEntry);
75736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      } else {
75836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        // We should always have a branch-through destination in this case.
75936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        assert(BranchThroughDest);
76036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        InstsToAppend.push_back(llvm::BranchInst::Create(BranchThroughDest));
76136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      }
76236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
76336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // IV.  Pop the cleanup and emit it.
76436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      EHStack.popCleanup();
76536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      assert(EHStack.hasNormalCleanups() == HasEnclosingCleanups);
76636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
767ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall      EmitCleanup(*this, Fn, cleanupFlags, NormalActiveFlag);
76836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
76936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Append the prepared cleanup prologue from above.
77036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      llvm::BasicBlock *NormalExit = Builder.GetInsertBlock();
77136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      for (unsigned I = 0, E = InstsToAppend.size(); I != E; ++I)
77236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        NormalExit->getInstList().push_back(InstsToAppend[I]);
77336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
77436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Optimistically hope that any fixups will continue falling through.
77536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();
77636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall           I < E; ++I) {
777d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall        BranchFixup &Fixup = EHStack.getBranchFixup(I);
77836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        if (!Fixup.Destination) continue;
77936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        if (!Fixup.OptimisticBranchBlock) {
78036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          new llvm::StoreInst(Builder.getInt32(Fixup.DestinationIndex),
78136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                              getNormalCleanupDestSlot(),
78236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                              Fixup.InitialBranch);
78336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall          Fixup.InitialBranch->setSuccessor(0, NormalEntry);
78436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        }
78536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        Fixup.OptimisticBranchBlock = NormalExit;
78636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      }
78736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
78836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // V.  Set up the fallthrough edge out.
78936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
790f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall      // Case 1: a fallthrough source exists but doesn't branch to the
791f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall      // cleanup because the cleanup is inactive.
79236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      if (!HasFallthrough && FallthroughSource) {
793f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall        // Prebranched fallthrough was forwarded earlier.
794f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall        // Non-prebranched fallthrough doesn't need to be forwarded.
795f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall        // Either way, all we need to do is restore the IP we cleared before.
79636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        assert(!IsActive);
797f66a3ea8595d44843f43b8c4b0825b1f8ceeda78John McCall        Builder.restoreIP(savedInactiveFallthroughIP);
79836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
79936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Case 2: a fallthrough source exists and should branch to the
80036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // cleanup, but we're not supposed to branch through to the next
80136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // cleanup.
80236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      } else if (HasFallthrough && FallthroughDest) {
80336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        assert(!FallthroughIsBranchThrough);
80436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        EmitBlock(FallthroughDest);
80536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
80636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Case 3: a fallthrough source exists and should branch to the
80736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // cleanup and then through to the next.
80836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      } else if (HasFallthrough) {
80936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        // Everything is already set up for this.
81036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
81136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Case 4: no fallthrough source exists.
81236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      } else {
81336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        Builder.ClearInsertionPoint();
81436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      }
81536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
81636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // VI.  Assorted cleaning.
81736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
81836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Check whether we can merge NormalEntry into a single predecessor.
81936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // This might invalidate (non-IR) pointers to NormalEntry.
82036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      llvm::BasicBlock *NewNormalEntry =
82136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        SimplifyCleanupEntry(*this, NormalEntry);
82236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
82336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // If it did invalidate those pointers, and NormalEntry was the same
82436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // as NormalExit, go back and patch up the fixups.
82536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      if (NewNormalEntry != NormalEntry && NormalEntry == NormalExit)
82636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();
82736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall               I < E; ++I)
828d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall          EHStack.getBranchFixup(I).OptimisticBranchBlock = NewNormalEntry;
82936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    }
83036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
83136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
83236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(EHStack.hasNormalCleanups() || EHStack.getNumBranchFixups() == 0);
83336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
83436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Emit the EH cleanup if required.
83536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (RequiresEHCleanup) {
83636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
83736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
83836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    EmitBlock(EHEntry);
839ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall
840ea66f9f9e17d619d617885e26adc1530cec7c0fdEli Friedman    // We only actually emit the cleanup code if the cleanup is either
841ea66f9f9e17d619d617885e26adc1530cec7c0fdEli Friedman    // active or was used before it was deactivated.
842ea66f9f9e17d619d617885e26adc1530cec7c0fdEli Friedman    if (EHActiveFlag || IsActive) {
843ea66f9f9e17d619d617885e26adc1530cec7c0fdEli Friedman      cleanupFlags.setIsForEHCleanup();
844ea66f9f9e17d619d617885e26adc1530cec7c0fdEli Friedman      EmitCleanup(*this, Fn, cleanupFlags, EHActiveFlag);
845ea66f9f9e17d619d617885e26adc1530cec7c0fdEli Friedman    }
84636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
847777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    Builder.CreateBr(getEHDispatchBlock(EHParent));
84836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
84936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Builder.restoreIP(SavedIP);
85036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
85136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    SimplifyCleanupEntry(*this, EHEntry);
85236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
85336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
85436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
855b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner/// isObviouslyBranchWithoutCleanups - Return true if a branch to the
856b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner/// specified destination obviously has no cleanups to run.  'false' is always
857b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner/// a conservatively correct answer for this method.
858b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattnerbool CodeGenFunction::isObviouslyBranchWithoutCleanups(JumpDest Dest) const {
859b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner  assert(Dest.getScopeDepth().encloses(EHStack.stable_begin())
860b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner         && "stale jump destination");
861b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner
862b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner  // Calculate the innermost active normal cleanup.
863b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner  EHScopeStack::stable_iterator TopCleanup =
864b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner    EHStack.getInnermostActiveNormalCleanup();
865b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner
866b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner  // If we're not in an active normal cleanup scope, or if the
867b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner  // destination scope is within the innermost active normal cleanup
868b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner  // scope, we don't need to worry about fixups.
869b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner  if (TopCleanup == EHStack.stable_end() ||
870b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner      TopCleanup.encloses(Dest.getScopeDepth())) // works for invalid
871b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner    return true;
872b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner
873b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner  // Otherwise, we might need some cleanups.
874b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner  return false;
875b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner}
876b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner
877b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner
87836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Terminate the current block by emitting a branch which might leave
87936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// the current cleanup-protected scope.  The target scope may not yet
88036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// be known, in which case this will require a fixup.
88136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall///
88236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// As a side-effect, this method clears the insertion point.
88336f893c1efe367f929d92c8b125f964c22ba189eJohn McCallvoid CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) {
88427f8d703e65095ca9c8c5d08a5a835b5510a730dJohn McCall  assert(Dest.getScopeDepth().encloses(EHStack.stable_begin())
88536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall         && "stale jump destination");
88636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
88736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!HaveInsertPoint())
88836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return;
88936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
89036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Create the branch.
89136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());
89236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
89336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Calculate the innermost active normal cleanup.
89436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHScopeStack::stable_iterator
89536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    TopCleanup = EHStack.getInnermostActiveNormalCleanup();
89636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
89736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If we're not in an active normal cleanup scope, or if the
89836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // destination scope is within the innermost active normal cleanup
89936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // scope, we don't need to worry about fixups.
90036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (TopCleanup == EHStack.stable_end() ||
90136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      TopCleanup.encloses(Dest.getScopeDepth())) { // works for invalid
90236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Builder.ClearInsertionPoint();
90336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return;
90436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
90536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
90636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If we can't resolve the destination cleanup scope, just add this
90736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // to the current cleanup scope as a branch fixup.
90836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!Dest.getScopeDepth().isValid()) {
90936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    BranchFixup &Fixup = EHStack.addBranchFixup();
91036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Fixup.Destination = Dest.getBlock();
91136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Fixup.DestinationIndex = Dest.getDestIndex();
91236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Fixup.InitialBranch = BI;
91336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Fixup.OptimisticBranchBlock = 0;
91436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
91536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Builder.ClearInsertionPoint();
91636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return;
91736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
91836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
91936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Otherwise, thread through all the normal cleanups in scope.
92036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
92136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Store the index at the start.
92236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  llvm::ConstantInt *Index = Builder.getInt32(Dest.getDestIndex());
92336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  new llvm::StoreInst(Index, getNormalCleanupDestSlot(), BI);
92436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
92536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Adjust BI to point to the first cleanup block.
92636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  {
92736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    EHCleanupScope &Scope =
92836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      cast<EHCleanupScope>(*EHStack.find(TopCleanup));
92936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    BI->setSuccessor(0, CreateNormalEntry(*this, Scope));
93036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
93136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
93236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Add this destination to all the scopes involved.
93336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHScopeStack::stable_iterator I = TopCleanup;
93436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHScopeStack::stable_iterator E = Dest.getScopeDepth();
93536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (E.strictlyEncloses(I)) {
93636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    while (true) {
93736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(I));
93836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      assert(Scope.isNormalCleanup());
93936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      I = Scope.getEnclosingNormalCleanup();
94036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
94136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // If this is the last cleanup we're propagating through, tell it
94236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // that there's a resolved jump moving through it.
94336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      if (!E.strictlyEncloses(I)) {
94436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        Scope.addBranchAfter(Index, Dest.getBlock());
94536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        break;
94636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      }
94736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
94836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // Otherwise, tell the scope that there's a jump propoagating
94936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // through it.  If this isn't new information, all the rest of
95036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      // the work has been done before.
95136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      if (!Scope.addBranchThrough(Dest.getBlock()))
95236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall        break;
95336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    }
95436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
95536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
95636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  Builder.ClearInsertionPoint();
95736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
95836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
95936f893c1efe367f929d92c8b125f964c22ba189eJohn McCallstatic bool IsUsedAsNormalCleanup(EHScopeStack &EHStack,
96036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                  EHScopeStack::stable_iterator C) {
96136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If we needed a normal block for any reason, that counts.
96236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (cast<EHCleanupScope>(*EHStack.find(C)).getNormalBlock())
96336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return true;
96436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
96536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Check whether any enclosed cleanups were needed.
96636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  for (EHScopeStack::stable_iterator
96736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall         I = EHStack.getInnermostNormalCleanup();
96836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall         I != C; ) {
96936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    assert(C.strictlyEncloses(I));
97036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    EHCleanupScope &S = cast<EHCleanupScope>(*EHStack.find(I));
97136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    if (S.getNormalBlock()) return true;
97236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    I = S.getEnclosingNormalCleanup();
97336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
97436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
97536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return false;
97636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
97736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
97836f893c1efe367f929d92c8b125f964c22ba189eJohn McCallstatic bool IsUsedAsEHCleanup(EHScopeStack &EHStack,
979777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall                              EHScopeStack::stable_iterator cleanup) {
98036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If we needed an EH block for any reason, that counts.
981777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall  if (EHStack.find(cleanup)->hasEHBranches())
98236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return true;
98336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
98436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Check whether any enclosed cleanups were needed.
98536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  for (EHScopeStack::stable_iterator
986777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall         i = EHStack.getInnermostEHScope(); i != cleanup; ) {
987777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    assert(cleanup.strictlyEncloses(i));
988777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
989777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    EHScope &scope = *EHStack.find(i);
990777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    if (scope.hasEHBranches())
991777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall      return true;
992777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall
993777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall    i = scope.getEnclosingEHScope();
99436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
99536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
99636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return false;
99736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
99836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
99936f893c1efe367f929d92c8b125f964c22ba189eJohn McCallenum ForActivation_t {
100036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  ForActivation,
100136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  ForDeactivation
100236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall};
100336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
100436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// The given cleanup block is changing activation state.  Configure a
100536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// cleanup variable if necessary.
100636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall///
100736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// It would be good if we had some way of determining if there were
100836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// extra uses *after* the change-over point.
100936f893c1efe367f929d92c8b125f964c22ba189eJohn McCallstatic void SetupCleanupBlockActivation(CodeGenFunction &CGF,
101036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall                                        EHScopeStack::stable_iterator C,
10116f103ba42cb69d50005a977c5ea583984ab63fc4John McCall                                        ForActivation_t kind,
10126f103ba42cb69d50005a977c5ea583984ab63fc4John McCall                                        llvm::Instruction *dominatingIP) {
101336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHCleanupScope &Scope = cast<EHCleanupScope>(*CGF.EHStack.find(C));
101436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
1015b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall  // We always need the flag if we're activating the cleanup in a
1016b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall  // conditional context, because we have to assume that the current
1017b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall  // location doesn't necessarily dominate the cleanup's code.
1018b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall  bool isActivatedInConditional =
10196f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    (kind == ForActivation && CGF.isInConditionalBranch());
1020b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall
1021b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall  bool needFlag = false;
102236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
102336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Calculate whether the cleanup was used:
102436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
102536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  //   - as a normal cleanup
1026b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall  if (Scope.isNormalCleanup() &&
1027b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall      (isActivatedInConditional || IsUsedAsNormalCleanup(CGF.EHStack, C))) {
102836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Scope.setTestFlagInNormalCleanup();
1029b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall    needFlag = true;
103036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
103136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
103236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  //  - as an EH cleanup
1033b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall  if (Scope.isEHCleanup() &&
1034b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall      (isActivatedInConditional || IsUsedAsEHCleanup(CGF.EHStack, C))) {
103536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Scope.setTestFlagInEHCleanup();
1036b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall    needFlag = true;
103736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
103836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
103936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If it hasn't yet been used as either, we're done.
1040b99785bdd1cc9ce1ba4f94eeb871faba1a22e95fJohn McCall  if (!needFlag) return;
104136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
10426f103ba42cb69d50005a977c5ea583984ab63fc4John McCall  llvm::AllocaInst *var = Scope.getActiveFlag();
10436f103ba42cb69d50005a977c5ea583984ab63fc4John McCall  if (!var) {
10446f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    var = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "cleanup.isactive");
10456f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    Scope.setActiveFlag(var);
10466f103ba42cb69d50005a977c5ea583984ab63fc4John McCall
10476f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    assert(dominatingIP && "no existing variable and no dominating IP!");
104836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
104936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // Initialize to true or false depending on whether it was
105036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // active up to this point.
10516f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    llvm::Value *value = CGF.Builder.getInt1(kind == ForDeactivation);
10526f103ba42cb69d50005a977c5ea583984ab63fc4John McCall
10536f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    // If we're in a conditional block, ignore the dominating IP and
10546f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    // use the outermost conditional branch.
10556f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    if (CGF.isInConditionalBranch()) {
10566f103ba42cb69d50005a977c5ea583984ab63fc4John McCall      CGF.setBeforeOutermostConditional(value, var);
10576f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    } else {
10586f103ba42cb69d50005a977c5ea583984ab63fc4John McCall      new llvm::StoreInst(value, var, dominatingIP);
10596f103ba42cb69d50005a977c5ea583984ab63fc4John McCall    }
106036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
106136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
10626f103ba42cb69d50005a977c5ea583984ab63fc4John McCall  CGF.Builder.CreateStore(CGF.Builder.getInt1(kind == ForActivation), var);
106336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
106436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
106536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Activate a cleanup that was created in an inactivated state.
10666f103ba42cb69d50005a977c5ea583984ab63fc4John McCallvoid CodeGenFunction::ActivateCleanupBlock(EHScopeStack::stable_iterator C,
10676f103ba42cb69d50005a977c5ea583984ab63fc4John McCall                                           llvm::Instruction *dominatingIP) {
106836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(C != EHStack.stable_end() && "activating bottom of stack?");
106936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C));
107036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(!Scope.isActive() && "double activation");
107136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
10726f103ba42cb69d50005a977c5ea583984ab63fc4John McCall  SetupCleanupBlockActivation(*this, C, ForActivation, dominatingIP);
107336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
107436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  Scope.setActive(true);
107536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
107636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
107736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall/// Deactive a cleanup that was created in an active state.
10786f103ba42cb69d50005a977c5ea583984ab63fc4John McCallvoid CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C,
10796f103ba42cb69d50005a977c5ea583984ab63fc4John McCall                                             llvm::Instruction *dominatingIP) {
108036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(C != EHStack.stable_end() && "deactivating bottom of stack?");
108136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C));
108236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  assert(Scope.isActive() && "double deactivation");
108336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
108436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // If it's the top of the stack, just pop it.
108536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (C == EHStack.stable_begin()) {
108636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // If it's a normal cleanup, we need to pretend that the
108736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    // fallthrough is unreachable.
108836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
108936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    PopCleanupBlock();
109036f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    Builder.restoreIP(SavedIP);
109136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    return;
109236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  }
109336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
109436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  // Otherwise, follow the general case.
10956f103ba42cb69d50005a977c5ea583984ab63fc4John McCall  SetupCleanupBlockActivation(*this, C, ForDeactivation, dominatingIP);
109636f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
109736f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  Scope.setActive(false);
109836f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
109936f893c1efe367f929d92c8b125f964c22ba189eJohn McCall
110036f893c1efe367f929d92c8b125f964c22ba189eJohn McCallllvm::Value *CodeGenFunction::getNormalCleanupDestSlot() {
110136f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  if (!NormalCleanupDest)
110236f893c1efe367f929d92c8b125f964c22ba189eJohn McCall    NormalCleanupDest =
110336f893c1efe367f929d92c8b125f964c22ba189eJohn McCall      CreateTempAlloca(Builder.getInt32Ty(), "cleanup.dest.slot");
110436f893c1efe367f929d92c8b125f964c22ba189eJohn McCall  return NormalCleanupDest;
110536f893c1efe367f929d92c8b125f964c22ba189eJohn McCall}
110686811609d9353e3aed198045d56e790eb3b6118cPeter Collingbourne
110786811609d9353e3aed198045d56e790eb3b6118cPeter Collingbourne/// Emits all the code to cause the given temporary to be cleaned up.
110886811609d9353e3aed198045d56e790eb3b6118cPeter Collingbournevoid CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
110986811609d9353e3aed198045d56e790eb3b6118cPeter Collingbourne                                       QualType TempType,
111086811609d9353e3aed198045d56e790eb3b6118cPeter Collingbourne                                       llvm::Value *Ptr) {
1111516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne  pushDestroy(NormalAndEHCleanup, Ptr, TempType, destroyCXXObject,
111286811609d9353e3aed198045d56e790eb3b6118cPeter Collingbourne              /*useEHCleanup*/ true);
111386811609d9353e3aed198045d56e790eb3b6118cPeter Collingbourne}
1114