Switch the main possibly-conditional temporary cleanup over to being lazy.

llvm-svn: 108995
This commit is contained in:
John McCall 2010-07-21 06:44:28 +00:00
parent 8680f87d99
commit fb442ae7b9
1 changed files with 36 additions and 32 deletions

View File

@ -15,34 +15,43 @@
using namespace clang;
using namespace CodeGen;
static void EmitTemporaryCleanup(CodeGenFunction &CGF,
const CXXTemporary *Temporary,
llvm::Value *Addr,
llvm::Value *CondPtr) {
llvm::BasicBlock *CondEnd = 0;
namespace {
struct DestroyTemporary : EHScopeStack::LazyCleanup {
const CXXTemporary *Temporary;
llvm::Value *Addr;
llvm::Value *CondPtr;
DestroyTemporary(const CXXTemporary *Temporary, llvm::Value *Addr,
llvm::Value *CondPtr)
: Temporary(Temporary), Addr(Addr), CondPtr(CondPtr) {}
void Emit(CodeGenFunction &CGF, bool IsForEH) {
llvm::BasicBlock *CondEnd = 0;
// If this is a conditional temporary, we need to check the condition
// boolean and only call the destructor if it's true.
if (CondPtr) {
llvm::BasicBlock *CondBlock = CGF.createBasicBlock("temp.cond-dtor.call");
CondEnd = CGF.createBasicBlock("temp.cond-dtor.cont");
// If this is a conditional temporary, we need to check the condition
// boolean and only call the destructor if it's true.
if (CondPtr) {
llvm::BasicBlock *CondBlock =
CGF.createBasicBlock("temp.cond-dtor.call");
CondEnd = CGF.createBasicBlock("temp.cond-dtor.cont");
llvm::Value *Cond = CGF.Builder.CreateLoad(CondPtr);
CGF.Builder.CreateCondBr(Cond, CondBlock, CondEnd);
CGF.EmitBlock(CondBlock);
}
llvm::Value *Cond = CGF.Builder.CreateLoad(CondPtr);
CGF.Builder.CreateCondBr(Cond, CondBlock, CondEnd);
CGF.EmitBlock(CondBlock);
}
CGF.EmitCXXDestructorCall(Temporary->getDestructor(),
Dtor_Complete, /*ForVirtualBase=*/false,
Addr);
CGF.EmitCXXDestructorCall(Temporary->getDestructor(),
Dtor_Complete, /*ForVirtualBase=*/false,
Addr);
if (CondPtr) {
// Reset the condition to false.
CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(CGF.getLLVMContext()),
CondPtr);
CGF.EmitBlock(CondEnd);
}
}
if (CondPtr) {
// Reset the condition to false.
CGF.Builder.CreateStore(CGF.Builder.getFalse(), CondPtr);
CGF.EmitBlock(CondEnd);
}
}
};
}
/// Emits all the code to cause the given temporary to be cleaned up.
void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
@ -59,16 +68,11 @@ void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
InitTempAlloca(CondPtr, llvm::ConstantInt::getFalse(VMContext));
// Now set it to true.
Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext), CondPtr);
Builder.CreateStore(Builder.getTrue(), CondPtr);
}
CleanupBlock Cleanup(*this, NormalCleanup);
EmitTemporaryCleanup(*this, Temporary, Ptr, CondPtr);
if (Exceptions) {
Cleanup.beginEHCleanup();
EmitTemporaryCleanup(*this, Temporary, Ptr, CondPtr);
}
EHStack.pushLazyCleanup<DestroyTemporary>(NormalAndEHCleanup,
Temporary, Ptr, CondPtr);
}
RValue