aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/ItaniumCXXABI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/ItaniumCXXABI.cpp')
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp94
1 files changed, 35 insertions, 59 deletions
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index ce16c86b8d..6fcf83d5ac 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -123,7 +123,7 @@ public:
llvm::Value *&AllocPtr, CharUnits &CookieSize);
void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
- llvm::Constant *addr, bool PerformInit);
+ llvm::GlobalVariable *DeclPtr, bool PerformInit);
};
class ARMCXXABI : public ItaniumCXXABI {
@@ -1051,7 +1051,7 @@ static llvm::Constant *getGuardAbortFn(CodeGenModule &CGM,
namespace {
struct CallGuardAbort : EHScopeStack::Cleanup {
llvm::GlobalVariable *Guard;
- CallGuardAbort(llvm::GlobalVariable *guard) : Guard(guard) {}
+ CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
void Emit(CodeGenFunction &CGF, Flags flags) {
CGF.Builder.CreateCall(getGuardAbortFn(CGF.CGM, Guard->getType()), Guard)
@@ -1064,7 +1064,7 @@ namespace {
/// just special-case it at particular places.
void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
- llvm::Constant *varAddr,
+ llvm::GlobalVariable *GV,
bool PerformInit) {
CGBuilderTy &Builder = CGF.Builder;
@@ -1073,60 +1073,35 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
bool threadsafe =
(getContext().getLangOpts().ThreadsafeStatics && D.isLocalVarDecl());
- llvm::IntegerType *guardTy;
-
- // Find the underlying global variable for linkage purposes.
- // This may not have the right type for actual evaluation purposes.
- llvm::GlobalVariable *var =
- cast<llvm::GlobalVariable>(varAddr->stripPointerCasts());
+ llvm::IntegerType *GuardTy;
// If we have a global variable with internal linkage and thread-safe statics
// are disabled, we can just let the guard variable be of type i8.
- bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
+ bool useInt8GuardVariable = !threadsafe && GV->hasInternalLinkage();
if (useInt8GuardVariable) {
- guardTy = CGF.Int8Ty;
+ GuardTy = CGF.Int8Ty;
} else {
// Guard variables are 64 bits in the generic ABI and 32 bits on ARM.
- guardTy = (IsARM ? CGF.Int32Ty : CGF.Int64Ty);
+ GuardTy = (IsARM ? CGF.Int32Ty : CGF.Int64Ty);
}
- llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
+ llvm::PointerType *GuardPtrTy = GuardTy->getPointerTo();
// Create the guard variable.
- SmallString<256> guardName;
- {
- llvm::raw_svector_ostream out(guardName);
- getMangleContext().mangleItaniumGuardVariable(&D, out);
- out.flush();
- }
+ SmallString<256> GuardVName;
+ llvm::raw_svector_ostream Out(GuardVName);
+ getMangleContext().mangleItaniumGuardVariable(&D, Out);
+ Out.flush();
+
+ // Just absorb linkage and visibility from the variable.
+ llvm::GlobalVariable *GuardVariable =
+ new llvm::GlobalVariable(CGM.getModule(), GuardTy,
+ false, GV->getLinkage(),
+ llvm::ConstantInt::get(GuardTy, 0),
+ GuardVName.str());
+ GuardVariable->setVisibility(GV->getVisibility());
- // There are strange possibilities here involving the
- // double-emission of constructors and destructors.
- llvm::GlobalVariable *guard = 0;
- if (llvm::GlobalValue *existingGuard
- = CGM.getModule().getNamedValue(guardName.str())) {
- if (isa<llvm::GlobalVariable>(existingGuard) &&
- existingGuard->getType() == guardPtrTy) {
- guard = cast<llvm::GlobalVariable>(existingGuard); // okay
- } else {
- CGM.Error(D.getLocation(), "problem emitting static variable '"
- + guardName.str() +
- "': already present as different kind of symbol");
-
- // Fall through and implicitly give it a uniqued name.
- }
- }
-
- if (!guard) {
- // Just absorb linkage and visibility from the variable.
- guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,
- false, var->getLinkage(),
- llvm::ConstantInt::get(guardTy, 0),
- guardName.str());
- guard->setVisibility(var->getVisibility());
- }
-
// Test whether the variable has completed initialization.
- llvm::Value *isInitialized;
+ llvm::Value *IsInitialized;
// ARM C++ ABI 3.2.3.1:
// To support the potential use of initialization guard variables
@@ -1140,9 +1115,9 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
// ...
// }
if (IsARM && !useInt8GuardVariable) {
- llvm::Value *V = Builder.CreateLoad(guard);
+ llvm::Value *V = Builder.CreateLoad(GuardVariable);
V = Builder.CreateAnd(V, Builder.getInt32(1));
- isInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
+ IsInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
// Itanium C++ ABI 3.3.2:
// The following is pseudo-code showing how these functions can be used:
@@ -1160,9 +1135,10 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
// }
} else {
// Load the first byte of the guard variable.
- llvm::LoadInst *load =
- Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy));
- load->setAlignment(1);
+ llvm::Type *PtrTy = Builder.getInt8PtrTy();
+ llvm::LoadInst *LI =
+ Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy));
+ LI->setAlignment(1);
// Itanium ABI:
// An implementation supporting thread-safety on multiprocessor
@@ -1171,16 +1147,16 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
//
// In LLVM, we do this by marking the load Acquire.
if (threadsafe)
- load->setAtomic(llvm::Acquire);
+ LI->setAtomic(llvm::Acquire);
- isInitialized = Builder.CreateIsNull(load, "guard.uninitialized");
+ IsInitialized = Builder.CreateIsNull(LI, "guard.uninitialized");
}
llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
// Check if the first byte of the guard variable is zero.
- Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
+ Builder.CreateCondBr(IsInitialized, InitCheckBlock, EndBlock);
CGF.EmitBlock(InitCheckBlock);
@@ -1188,7 +1164,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
if (threadsafe) {
// Call __cxa_guard_acquire.
llvm::Value *V
- = Builder.CreateCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
+ = Builder.CreateCall(getGuardAcquireFn(CGM, GuardPtrTy), GuardVariable);
llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
@@ -1196,22 +1172,22 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
InitBlock, EndBlock);
// Call __cxa_guard_abort along the exceptional edge.
- CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard);
+ CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable);
CGF.EmitBlock(InitBlock);
}
// Emit the initializer and add a global destructor if appropriate.
- CGF.EmitCXXGlobalVarDeclInit(D, varAddr, PerformInit);
+ CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
if (threadsafe) {
// Pop the guard-abort cleanup if we pushed one.
CGF.PopCleanupBlock();
// Call __cxa_guard_release. This cannot throw.
- Builder.CreateCall(getGuardReleaseFn(CGM, guardPtrTy), guard);
+ Builder.CreateCall(getGuardReleaseFn(CGM, GuardPtrTy), GuardVariable);
} else {
- Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard);
+ Builder.CreateStore(llvm::ConstantInt::get(GuardTy, 1), GuardVariable);
}
CGF.EmitBlock(EndBlock);