From 2360b7ad99eedecaae512373e7be49c2143550cf Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Thu, 18 Oct 2012 09:56:08 +0000 Subject: [PATCH] Refactor insert and extract of sub-integers into static helpers that operate purely on values. Sink the alloca loading and storing logic into the rewrite routines that are specific to alloca-integer-rewrite driving. This is just a refactoring here, but the subsequent step will be to reuse the insertion and extraction logic when rewriting integer loads and stores that have been split and decomposed into narrower loads and stores. No functionality changed other than different names for instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166176 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SROA.cpp | 152 ++++++++++++++++++--------------- 1 file changed, 84 insertions(+), 68 deletions(-) diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index 929f1b5c07a..377a6250de9 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -2208,6 +2208,48 @@ static bool isIntegerWideningViable(const DataLayout &TD, return WholeAllocaOp; } +static Value *extractInteger(const DataLayout &DL, IRBuilder<> &IRB, Value *V, + IntegerType *Ty, uint64_t Offset, + const Twine &Name) { + IntegerType *IntTy = cast(V->getType()); + assert(DL.getTypeStoreSize(Ty) + Offset <= DL.getTypeStoreSize(IntTy) && + "Element extends past full value"); + uint64_t ShAmt = 8*Offset; + if (DL.isBigEndian()) + ShAmt = 8*(DL.getTypeStoreSize(IntTy) - DL.getTypeStoreSize(Ty) - Offset); + if (ShAmt) + V = IRB.CreateLShr(V, ShAmt, Name + ".shift"); + assert(Ty->getBitWidth() <= IntTy->getBitWidth() && + "Cannot extract to a larger integer!"); + if (Ty != IntTy) + V = IRB.CreateTrunc(V, Ty, Name + ".trunc"); + return V; +} + +static Value *insertInteger(const DataLayout &DL, IRBuilder<> &IRB, Value *Old, + Value *V, uint64_t Offset, const Twine &Name) { + IntegerType *IntTy = cast(Old->getType()); + IntegerType *Ty = cast(V->getType()); + assert(Ty->getBitWidth() <= IntTy->getBitWidth() && + "Cannot insert a larger integer!"); + if (Ty != IntTy) + V = IRB.CreateZExt(V, IntTy, Name + ".ext"); + assert(DL.getTypeStoreSize(Ty) + Offset <= DL.getTypeStoreSize(IntTy) && + "Element store outside of alloca store"); + uint64_t ShAmt = 8*Offset; + if (DL.isBigEndian()) + ShAmt = 8*(DL.getTypeStoreSize(IntTy) - DL.getTypeStoreSize(Ty) - Offset); + if (ShAmt) + V = IRB.CreateShl(V, ShAmt, Name + ".shift"); + + if (ShAmt || Ty->getBitWidth() < IntTy->getBitWidth()) { + APInt Mask = ~Ty->getMask().zext(IntTy->getBitWidth()).shl(ShAmt); + Old = IRB.CreateAnd(Old, Mask, Name + ".mask"); + V = IRB.CreateOr(Old, V, Name + ".insert"); + } + return V; +} + namespace { /// \brief Visitor to rewrite instructions using a partition of an alloca to /// use a new alloca. @@ -2368,60 +2410,6 @@ private: return IRB.getInt32(Index); } - Value *extractInteger(IRBuilder<> &IRB, IntegerType *TargetTy, - uint64_t Offset) { - assert(IntTy && "We cannot extract an integer from the alloca"); - Value *V = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), - getName(".load")); - V = convertValue(TD, IRB, V, IntTy); - assert(Offset >= NewAllocaBeginOffset && "Out of bounds offset"); - uint64_t RelOffset = Offset - NewAllocaBeginOffset; - assert(TD.getTypeStoreSize(TargetTy) + RelOffset <= - TD.getTypeStoreSize(IntTy) && - "Element load outside of alloca store"); - uint64_t ShAmt = 8*RelOffset; - if (TD.isBigEndian()) - ShAmt = 8*(TD.getTypeStoreSize(IntTy) - - TD.getTypeStoreSize(TargetTy) - RelOffset); - if (ShAmt) - V = IRB.CreateLShr(V, ShAmt, getName(".shift")); - assert(TargetTy->getBitWidth() <= IntTy->getBitWidth() && - "Cannot extract to a larger integer!"); - if (TargetTy != IntTy) - V = IRB.CreateTrunc(V, TargetTy, getName(".trunc")); - return V; - } - - StoreInst *insertInteger(IRBuilder<> &IRB, Value *V, uint64_t Offset) { - IntegerType *Ty = cast(V->getType()); - assert(Ty->getBitWidth() <= IntTy->getBitWidth() && - "Cannot insert a larger integer!"); - if (Ty != IntTy) - V = IRB.CreateZExt(V, IntTy, getName(".ext")); - assert(Offset >= NewAllocaBeginOffset && "Out of bounds offset"); - uint64_t RelOffset = Offset - NewAllocaBeginOffset; - assert(TD.getTypeStoreSize(Ty) + RelOffset <= - TD.getTypeStoreSize(IntTy) && - "Element store outside of alloca store"); - uint64_t ShAmt = 8*RelOffset; - if (TD.isBigEndian()) - ShAmt = 8*(TD.getTypeStoreSize(IntTy) - TD.getTypeStoreSize(Ty) - - RelOffset); - if (ShAmt) - V = IRB.CreateShl(V, ShAmt, getName(".shift")); - - if (ShAmt || Ty->getBitWidth() < IntTy->getBitWidth()) { - APInt Mask = ~Ty->getMask().zext(IntTy->getBitWidth()).shl(ShAmt); - Value *Old = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), - getName(".oldload")); - Old = convertValue(TD, IRB, Old, IntTy); - Old = IRB.CreateAnd(Old, Mask, getName(".mask")); - V = IRB.CreateOr(Old, V, getName(".insert")); - } - V = convertValue(TD, IRB, V, NewAllocaTy); - return IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment()); - } - void deleteIfTriviallyDead(Value *V) { Instruction *I = cast(V); if (isInstructionTriviallyDead(I)) @@ -2449,12 +2437,18 @@ private: } bool rewriteIntegerLoad(IRBuilder<> &IRB, LoadInst &LI) { + assert(IntTy && "We cannot insert an integer to the alloca"); assert(!LI.isVolatile()); - Value *Result = extractInteger(IRB, cast(LI.getType()), - BeginOffset); - LI.replaceAllUsesWith(Result); + Value *V = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), + getName(".load")); + V = convertValue(TD, IRB, V, IntTy); + assert(BeginOffset >= NewAllocaBeginOffset && "Out of bounds offset"); + uint64_t Offset = BeginOffset - NewAllocaBeginOffset; + V = extractInteger(TD, IRB, V, cast(LI.getType()), Offset, + getName(".extract")); + LI.replaceAllUsesWith(V); Pass.DeadInsts.push_back(&LI); - DEBUG(dbgs() << " to: " << *Result << "\n"); + DEBUG(dbgs() << " to: " << *V << "\n"); return true; } @@ -2516,8 +2510,20 @@ private: } bool rewriteIntegerStore(IRBuilder<> &IRB, StoreInst &SI) { + assert(IntTy && "We cannot extract an integer from the alloca"); assert(!SI.isVolatile()); - StoreInst *Store = insertInteger(IRB, SI.getValueOperand(), BeginOffset); + Value *V = SI.getValueOperand(); + if (TD.getTypeSizeInBits(V->getType()) != IntTy->getBitWidth()) { + Value *Old = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), + getName(".oldload")); + Old = convertValue(TD, IRB, Old, IntTy); + assert(BeginOffset >= NewAllocaBeginOffset && "Out of bounds offset"); + uint64_t Offset = BeginOffset - NewAllocaBeginOffset; + V = insertInteger(TD, IRB, Old, SI.getValueOperand(), Offset, + getName(".insert")); + } + V = convertValue(TD, IRB, V, NewAllocaTy); + StoreInst *Store = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment()); Pass.DeadInsts.push_back(&SI); (void)Store; DEBUG(dbgs() << " to: " << *Store << "\n"); @@ -2649,10 +2655,12 @@ private: if (IntTy && (BeginOffset > NewAllocaBeginOffset || EndOffset < NewAllocaEndOffset)) { assert(!II.isVolatile()); - StoreInst *Store = insertInteger(IRB, V, BeginOffset); - (void)Store; - DEBUG(dbgs() << " to: " << *Store << "\n"); - return true; + Value *Old = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), + getName(".oldload")); + Old = convertValue(TD, IRB, Old, IntTy); + assert(BeginOffset >= NewAllocaBeginOffset && "Out of bounds offset"); + uint64_t Offset = BeginOffset - NewAllocaBeginOffset; + V = insertInteger(TD, IRB, Old, V, Offset, getName(".insert")); } if (V->getType() != AllocaTy) @@ -2808,17 +2816,25 @@ private: getIndex(IRB, BeginOffset), getName(".copyextract")); } else if (IntTy && !IsWholeAlloca && !IsDest) { - Src = extractInteger(IRB, SubIntTy, BeginOffset); + Src = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), + getName(".load")); + Src = convertValue(TD, IRB, Src, IntTy); + assert(BeginOffset >= NewAllocaBeginOffset && "Out of bounds offset"); + uint64_t Offset = BeginOffset - NewAllocaBeginOffset; + Src = extractInteger(TD, IRB, Src, SubIntTy, Offset, getName(".extract")); } else { Src = IRB.CreateAlignedLoad(SrcPtr, Align, II.isVolatile(), getName(".copyload")); } if (IntTy && !IsWholeAlloca && IsDest) { - StoreInst *Store = insertInteger(IRB, Src, BeginOffset); - (void)Store; - DEBUG(dbgs() << " to: " << *Store << "\n"); - return true; + Value *Old = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), + getName(".oldload")); + Old = convertValue(TD, IRB, Old, IntTy); + assert(BeginOffset >= NewAllocaBeginOffset && "Out of bounds offset"); + uint64_t Offset = BeginOffset - NewAllocaBeginOffset; + Src = insertInteger(TD, IRB, Old, Src, Offset, getName(".insert")); + Src = convertValue(TD, IRB, Src, NewAllocaTy); } if (IsVectorElement && IsDest) {