diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-17 07:31:37 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-17 07:31:37 +0000 |
commit | abb943284cabd9131586c2758a4f02baba668ace (patch) | |
tree | 42efe3c363a750781cc565152093a39f80b99b1f /lib/CodeGen/CGDeclCXX.cpp | |
parent | 1e009d594325390eda1e3c89e4930b30d8b828dc (diff) |
The clang half of r150794: after the construction of a global or static const
variable ends, if the variable has a trivial destructor and no mutable
subobjects then emit an llvm.invariant.start call for it. globalopt knows to
make the variable const when evaluating this.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150798 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGDeclCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGDeclCXX.cpp | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 189760821b..75bb7dedd9 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -101,6 +101,19 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, CGF.EmitCXXGlobalDtorRegistration(function, argument); } +/// Emit code to cause the variable at the given address to be considered as +/// constant from this point onwards. +static void EmitDeclInvariant(CodeGenFunction &CGF, llvm::Constant *Addr) { + // Grab the llvm.invariant.start intrinsic. + llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start; + llvm::Constant *InvariantStart = CGF.CGM.getIntrinsic(InvStartID); + + // Emit a call, with size -1 signifying the whole object. + llvm::Value *Args[2] = { llvm::ConstantInt::getSigned(CGF.Int64Ty, -1), + llvm::ConstantExpr::getBitCast(Addr, CGF.Int8PtrTy)}; + CGF.Builder.CreateCall(InvariantStart, Args); +} + void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit) { @@ -111,7 +124,10 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, if (!T->isReferenceType()) { if (PerformInit) EmitDeclInit(*this, D, DeclPtr); - EmitDeclDestroy(*this, D, DeclPtr); + if (CGM.isTypeConstant(D.getType(), true)) + EmitDeclInvariant(*this, DeclPtr); + else + EmitDeclDestroy(*this, D, DeclPtr); return; } |