After much contemplation, I've decided that we probably shouldn't "unique"
__block object copy/dispose helpers for C++ objects with those for
different variables with completely different semantics simply because
they happen to both be no more aligned than a pointer.
Found by inspection.
Also, internalize most of the helper generation logic within CGBlocks.cpp,
and refactor it to fit my peculiar aesthetic sense.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128618 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index aa6a053..0f86257 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -247,9 +247,6 @@
int GlobalUniqueCount;
} Block;
- llvm::DenseMap<uint64_t, llvm::Constant *> AssignCache;
- llvm::DenseMap<uint64_t, llvm::Constant *> DestroyCache;
-
/// @}
public:
CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts,
@@ -385,14 +382,35 @@
CastExpr::path_const_iterator PathBegin,
CastExpr::path_const_iterator PathEnd);
- llvm::Constant *BuildbyrefCopyHelper(const llvm::Type *T,
- BlockFieldFlags flags,
- unsigned Align,
- const VarDecl *variable);
- llvm::Constant *BuildbyrefDestroyHelper(const llvm::Type *T,
- BlockFieldFlags flags,
- unsigned Align,
- const VarDecl *variable);
+ /// A pair of helper functions for a __block variable.
+ class ByrefHelpers : public llvm::FoldingSetNode {
+ public:
+ llvm::Constant *CopyHelper;
+ llvm::Constant *DisposeHelper;
+
+ /// The alignment of the field. This is important because
+ /// different offsets to the field within the byref struct need to
+ /// have different helper functions.
+ CharUnits Alignment;
+
+ ByrefHelpers(CharUnits alignment) : Alignment(alignment) {}
+ virtual ~ByrefHelpers();
+
+ void Profile(llvm::FoldingSetNodeID &id) const {
+ id.AddInteger(Alignment.getQuantity());
+ profileImpl(id);
+ }
+ virtual void profileImpl(llvm::FoldingSetNodeID &id) const = 0;
+
+ virtual bool needsCopy() const { return true; }
+ virtual void emitCopy(CodeGenFunction &CGF,
+ llvm::Value *dest, llvm::Value *src) = 0;
+
+ virtual bool needsDispose() const { return true; }
+ virtual void emitDispose(CodeGenFunction &CGF, llvm::Value *field) = 0;
+ };
+
+ llvm::FoldingSet<ByrefHelpers> ByrefHelpersCache;
/// getUniqueBlockCount - Fetches the global unique block count.
int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; }