aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGBlocks.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-06-05 23:26:36 +0000
committerMike Stump <mrs@apple.com>2009-06-05 23:26:36 +0000
commit3899a7fb9c7eeed19cc38d082921dd8b3d0d6624 (patch)
tree313b1abd855d32f5112253cb029a60e5846d9d85 /lib/CodeGen/CGBlocks.cpp
parent547d495a7d11d67639c68774a7011dfa8c36e347 (diff)
As an optimization, we maintain a cache of generated
___Block_byref_id_object_dispose and ___Block_byref_id_object_copy functions so that we can simply reuse instead of creating a new one. Additionally, add an assert to ensure no one yet tries to align a __block variable beyond the alignment of a pointer as the codegen is incomplete. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72974 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r--lib/CodeGen/CGBlocks.cpp39
1 files changed, 35 insertions, 4 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index ead689cc01..d5f803ba98 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -724,6 +724,8 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,
const CGFunctionInfo &FI =
CGM.getTypes().getFunctionInfo(R, Args);
+ // FIXME: We'd like to put these into a mergable by content, with
+ // internal linkage.
std::string Name = std::string("__copy_helper_block_");
CodeGenTypes &Types = CGM.getTypes();
const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
@@ -803,6 +805,8 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose,
const CGFunctionInfo &FI =
CGM.getTypes().getFunctionInfo(R, Args);
+ // FIXME: We'd like to put these into a mergable by content, with
+ // internal linkage.
std::string Name = std::string("__destroy_helper_block_");
CodeGenTypes &Types = CGM.getTypes();
const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
@@ -889,6 +893,8 @@ GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) {
CodeGenTypes &Types = CGM.getTypes();
const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
+ // FIXME: We'd like to put these into a mergable by content, with
+ // internal linkage.
llvm::Function *Fn =
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
Name,
@@ -950,6 +956,8 @@ BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T,
CodeGenTypes &Types = CGM.getTypes();
const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
+ // FIXME: We'd like to put these into a mergable by content, with
+ // internal linkage.
llvm::Function *Fn =
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
Name,
@@ -980,13 +988,36 @@ BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T,
}
llvm::Constant *BlockFunction::BuildbyrefCopyHelper(const llvm::Type *T,
- int flag) {
- return CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(T, flag);
+ int flag, unsigned Align) {
+ // All alignments below that of pointer alignment collpase down to just
+ // pointer alignment, as we always have at least that much alignment to begin
+ // with.
+ Align /= unsigned(CGF.Target.getPointerAlign(0)/8);
+ // As an optimization, we only generate a single function of each kind we
+ // might need. We need a different one for each alignment and for each
+ // setting of flags. We mix Align and flag to get the kind.
+ uint64_t kind = (uint64_t)Align*BLOCK_BYREF_CURRENT_MAX + flag;
+ llvm::Constant *& Entry = CGM.AssignCache[kind];
+ if (Entry)
+ return Entry;
+ return Entry=CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction(T, flag);
}
llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(const llvm::Type *T,
- int flag) {
- return CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(T, flag);
+ int flag,
+ unsigned Align) {
+ // All alignments below that of pointer alignment collpase down to just
+ // pointer alignment, as we always have at least that much alignment to begin
+ // with.
+ Align /= unsigned(CGF.Target.getPointerAlign(0)/8);
+ // As an optimization, we only generate a single function of each kind we
+ // might need. We need a different one for each alignment and for each
+ // setting of flags. We mix Align and flag to get the kind.
+ uint64_t kind = (uint64_t)Align*BLOCK_BYREF_CURRENT_MAX + flag;
+ llvm::Constant *& Entry = CGM.DestroyCache[kind];
+ if (Entry)
+ return Entry;
+ return Entry=CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction(T, flag);
}
llvm::Value *BlockFunction::getBlockObjectDispose() {