From 371d5d86bd70756d2066692114fec599c33baf92 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Tue, 18 Sep 2012 17:06:32 +0000 Subject: [PATCH] SROA: Use CRTP for OpSplitter to get rid of virtual dispatch and the virtual-dtor warnings that come with it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164140 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SROA.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index b9318db5e33..1215f417691 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -2466,6 +2466,7 @@ private: bool visitInstruction(Instruction &I) { return false; } /// \brief Generic recursive split emission class. + template class OpSplitter { protected: /// The builder used to form new instructions. @@ -2483,11 +2484,9 @@ private: /// Initialize the splitter with an insertion point, Ptr and start with a /// single zero GEP index. OpSplitter(Instruction *InsertionPoint, Value *Ptr) - : IRB(InsertionPoint), Ptr(Ptr), GEPIndices(1, IRB.getInt32(0)) {} + : IRB(InsertionPoint), GEPIndices(1, IRB.getInt32(0)), Ptr(Ptr) {} public: - virtual void emitFunc(Type *Ty, Value *&Agg, const Twine &Name) = 0; - /// \brief Generic recursive split emission routine. /// /// This method recursively splits an aggregate op (load or store) into @@ -2503,7 +2502,7 @@ private: /// whether this is splitting a load or a store respectively. void emitSplitOps(Type *Ty, Value *&Agg, const Twine &Name) { if (Ty->isSingleValueType()) - return emitFunc(Ty, Agg, Name); + return static_cast(this)->emitFunc(Ty, Agg, Name); if (ArrayType *ATy = dyn_cast(Ty)) { unsigned OldSize = Indices.size(); @@ -2539,13 +2538,13 @@ private: } }; - struct LoadOpSplitter : public OpSplitter { + struct LoadOpSplitter : public OpSplitter { LoadOpSplitter(Instruction *InsertionPoint, Value *Ptr) : OpSplitter(InsertionPoint, Ptr) {} /// Emit a leaf load of a single value. This is called at the leaves of the /// recursive emission to actually load values. - virtual void emitFunc(Type *Ty, Value *&Agg, const Twine &Name) { + void emitFunc(Type *Ty, Value *&Agg, const Twine &Name) { assert(Ty->isSingleValueType()); // Load the single value and insert it using the indices. Value *Load = IRB.CreateLoad(IRB.CreateInBoundsGEP(Ptr, GEPIndices, @@ -2571,13 +2570,13 @@ private: return true; } - struct StoreOpSplitter : public OpSplitter { + struct StoreOpSplitter : public OpSplitter { StoreOpSplitter(Instruction *InsertionPoint, Value *Ptr) : OpSplitter(InsertionPoint, Ptr) {} /// Emit a leaf store of a single value. This is called at the leaves of the /// recursive emission to actually produce stores. - virtual void emitFunc(Type *Ty, Value *&Agg, const Twine &Name) { + void emitFunc(Type *Ty, Value *&Agg, const Twine &Name) { assert(Ty->isSingleValueType()); // Extract the single value and store it using the indices. Value *Store = IRB.CreateStore(