aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-04-21 10:05:39 +0000
committerJohn McCall <rjmccall@apple.com>2010-04-21 10:05:39 +0000
commit3d3ec1c099ec8bfac3aa1fb0126fe515b7c7fa05 (patch)
treefc71638619df042442fe2a23c68c4264a007481c
parentd8383d45e41ba2316610e5d638d2872e37b67cfb (diff)
Miscellaneous codegen cleanups. Mostly, don't create new basic blocks
just to save the current insertion state! This change significantly simplifies the IR CFG in exceptions code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101996 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGBlocks.h3
-rw-r--r--lib/CodeGen/CGException.cpp65
-rw-r--r--lib/CodeGen/CGExpr.cpp24
-rw-r--r--lib/CodeGen/CodeGenFunction.h18
4 files changed, 66 insertions, 44 deletions
diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h
index efee0e36b8..5646d0036e 100644
--- a/lib/CodeGen/CGBlocks.h
+++ b/lib/CodeGen/CGBlocks.h
@@ -38,6 +38,7 @@ namespace llvm {
class GlobalValue;
class TargetData;
class FunctionType;
+ class PointerType;
class Value;
class LLVMContext;
}
@@ -127,7 +128,7 @@ protected:
llvm::LLVMContext &VMContext;
public:
- const llvm::Type *PtrToInt8Ty;
+ const llvm::PointerType *PtrToInt8Ty;
struct HelperInfo {
int index;
int flag;
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 1e1506683d..04c76dfe9a 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -270,7 +270,7 @@ void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
// Now allocate the exception object.
const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
- uint64_t TypeSize = getContext().getTypeSize(ThrowType) / 8;
+ uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this);
llvm::Value *ExceptionPtr =
@@ -649,38 +649,46 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S,
}
CodeGenFunction::EHCleanupBlock::~EHCleanupBlock() {
- llvm::BasicBlock *Cont1 = CGF.createBasicBlock("cont");
- CGF.EmitBranch(Cont1);
CGF.setInvokeDest(PreviousInvokeDest);
+ llvm::BasicBlock *EndOfCleanup = CGF.Builder.GetInsertBlock();
- CGF.EmitBlock(CleanupHandler);
-
+ // Jump to the beginning of the cleanup.
+ CGF.Builder.SetInsertPoint(CleanupHandler, CleanupHandler->begin());
+
+ // The libstdc++ personality function.
+ // TODO: generalize to work with other libraries.
llvm::Constant *Personality =
CGF.CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
(CGF.VMContext),
true),
"__gxx_personality_v0");
Personality = llvm::ConstantExpr::getBitCast(Personality, CGF.PtrToInt8Ty);
+
+ // %exception = call i8* @llvm.eh.exception()
+ // Magic intrinsic which tells gives us a handle to the caught
+ // exception.
llvm::Value *llvm_eh_exception =
CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
- llvm::Value *llvm_eh_selector =
- CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
-
llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
- const llvm::IntegerType *Int8Ty;
- const llvm::PointerType *PtrToInt8Ty;
- Int8Ty = llvm::Type::getInt8Ty(CGF.VMContext);
- // C string type. Used in lots of places.
- PtrToInt8Ty = llvm::PointerType::getUnqual(Int8Ty);
- llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty);
+
+ llvm::Constant *Null = llvm::ConstantPointerNull::get(CGF.PtrToInt8Ty);
+
+ // %ignored = call i32 @llvm.eh.selector(i8* %exception,
+ // i8* @__gxx_personality_v0,
+ // i8* null)
+ // Magic intrinsic which tells LLVM that this invoke landing pad is
+ // just a cleanup block.
llvm::Value *Args[] = { Exc, Personality, Null };
+ llvm::Value *llvm_eh_selector =
+ CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector);
CGF.Builder.CreateCall(llvm_eh_selector, &Args[0], llvm::array_endof(Args));
- CGF.EmitBlock(CleanupEntryBB);
-
- CGF.EmitBlock(Cont1);
+ // And then we fall through into the code that the user put there.
+ // Jump back to the end of the cleanup.
+ CGF.Builder.SetInsertPoint(EndOfCleanup);
+ // Rethrow the exception.
if (CGF.getInvokeDest()) {
llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
CGF.Builder.CreateInvoke(getUnwindResumeOrRethrowFn(CGF), Cont,
@@ -688,10 +696,11 @@ CodeGenFunction::EHCleanupBlock::~EHCleanupBlock() {
CGF.EmitBlock(Cont);
} else
CGF.Builder.CreateCall(getUnwindResumeOrRethrowFn(CGF), Exc);
-
CGF.Builder.CreateUnreachable();
- CGF.EmitBlock(Cont);
+ // Resume inserting where we started, but put the new cleanup
+ // handler in place.
+ CGF.Builder.SetInsertPoint(PreviousInsertionBlock);
if (CGF.Exceptions)
CGF.setInvokeDest(CleanupHandler);
}
@@ -700,12 +709,11 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
if (TerminateHandler)
return TerminateHandler;
- llvm::BasicBlock *Cont = 0;
-
- if (HaveInsertPoint()) {
- Cont = createBasicBlock("cont");
- EmitBranch(Cont);
- }
+ // We don't want to change anything at the current location, so
+ // save it aside and clear the insert point.
+ llvm::BasicBlock *SavedInsertBlock = Builder.GetInsertBlock();
+ llvm::BasicBlock::iterator SavedInsertPoint = Builder.GetInsertPoint();
+ Builder.ClearInsertionPoint();
llvm::Constant *Personality =
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty
@@ -735,11 +743,8 @@ llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
TerminateCall->setDoesNotThrow();
Builder.CreateUnreachable();
- // Clear the insertion point to indicate we are in unreachable code.
- Builder.ClearInsertionPoint();
-
- if (Cont)
- EmitBlock(Cont);
+ // Restore the saved insertion state.
+ Builder.SetInsertPoint(SavedInsertBlock, SavedInsertPoint);
return TerminateHandler;
}
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 7809972630..28ef30ee41 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -111,6 +111,23 @@ RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E,
IsInitializer);
}
+/// EmitAnyExprToMem - Evaluate an expression into a given memory
+/// location.
+void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
+ llvm::Value *Location,
+ bool IsLocationVolatile,
+ bool IsInit) {
+ if (E->getType()->isComplexType())
+ EmitComplexExprIntoAddr(E, Location, IsLocationVolatile);
+ else if (hasAggregateLLVMType(E->getType()))
+ EmitAggExpr(E, Location, IsLocationVolatile, /*Ignore*/ false, IsInit);
+ else {
+ RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false));
+ LValue LV = LValue::MakeAddr(Location, MakeQualifiers(E->getType()));
+ EmitStoreThroughLValue(RV, LV, E->getType());
+ }
+}
+
RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
bool IsInitializer) {
bool ShouldDestroyTemporaries = false;
@@ -1561,12 +1578,7 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E){
const Expr* InitExpr = E->getInitializer();
LValue Result = LValue::MakeAddr(DeclPtr, MakeQualifiers(E->getType()));
- if (E->getType()->isComplexType())
- EmitComplexExprIntoAddr(InitExpr, DeclPtr, false);
- else if (hasAggregateLLVMType(E->getType()))
- EmitAnyExpr(InitExpr, DeclPtr, false);
- else
- EmitStoreThroughLValue(EmitAnyExpr(InitExpr), Result, E->getType());
+ EmitAnyExprToMem(InitExpr, DeclPtr, /*Volatile*/ false);
return Result;
}
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index c43e0006e6..7072301b4b 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -148,19 +148,17 @@ public:
/// block.
class EHCleanupBlock {
CodeGenFunction& CGF;
- llvm::BasicBlock *Cont;
+ llvm::BasicBlock *PreviousInsertionBlock;
llvm::BasicBlock *CleanupHandler;
- llvm::BasicBlock *CleanupEntryBB;
llvm::BasicBlock *PreviousInvokeDest;
public:
EHCleanupBlock(CodeGenFunction &cgf)
- : CGF(cgf), Cont(CGF.createBasicBlock("cont")),
- CleanupHandler(CGF.createBasicBlock("ehcleanup")),
- CleanupEntryBB(CGF.createBasicBlock("ehcleanup.rest")),
+ : CGF(cgf),
+ PreviousInsertionBlock(CGF.Builder.GetInsertBlock()),
+ CleanupHandler(CGF.createBasicBlock("ehcleanup", CGF.CurFn)),
PreviousInvokeDest(CGF.getInvokeDest()) {
- CGF.EmitBranch(Cont);
llvm::BasicBlock *TerminateHandler = CGF.getTerminateHandler();
- CGF.Builder.SetInsertPoint(CleanupEntryBB);
+ CGF.Builder.SetInsertPoint(CleanupHandler);
CGF.setInvokeDest(TerminateHandler);
}
~EHCleanupBlock();
@@ -706,6 +704,12 @@ public:
RValue EmitAnyExprToTemp(const Expr *E, bool IsAggLocVolatile = false,
bool IsInitializer = false);
+ /// EmitsAnyExprToMem - Emits the code necessary to evaluate an
+ /// arbitrary expression into the given memory location.
+ void EmitAnyExprToMem(const Expr *E, llvm::Value *Location,
+ bool IsLocationVolatile = false,
+ bool IsInitializer = false);
+
/// EmitAggregateCopy - Emit an aggrate copy.
///
/// \param isVolatile - True iff either the source or the destination is