diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-10 13:44:06 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-10 13:44:06 +0000 |
commit | 7ab83427af0f77b59941ceba41d509d7d097b065 (patch) | |
tree | cc41c05b1db454e3d802f34df75e636ee922ad87 /lib/CodeGen/CodeGenPrepare.cpp | |
parent | d288ef4c1788d3a951a7558c68312c2d320612b1 (diff) |
Diffstat (limited to 'lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenPrepare.cpp | 294 |
1 files changed, 159 insertions, 135 deletions
diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp index 568b278dd47c..c2037cb7f1ae 100644 --- a/lib/CodeGen/CodeGenPrepare.cpp +++ b/lib/CodeGen/CodeGenPrepare.cpp @@ -13,8 +13,6 @@ // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallSet.h" @@ -31,6 +29,7 @@ #include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -236,12 +235,12 @@ class TypePromotionTransaction; void eliminateMostlyEmptyBlock(BasicBlock *BB); bool isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB, bool isPreheader); - bool optimizeBlock(BasicBlock &BB, bool& ModifiedDT); - bool optimizeInst(Instruction *I, bool& ModifiedDT); + bool optimizeBlock(BasicBlock &BB, bool &ModifiedDT); + bool optimizeInst(Instruction *I, bool &ModifiedDT); bool optimizeMemoryInst(Instruction *I, Value *Addr, Type *AccessTy, unsigned AS); bool optimizeInlineAsmInst(CallInst *CS); - bool optimizeCallInst(CallInst *CI, bool& ModifiedDT); + bool optimizeCallInst(CallInst *CI, bool &ModifiedDT); bool optimizeExt(Instruction *&I); bool optimizeExtUses(Instruction *I); bool optimizeLoadExt(LoadInst *I); @@ -1662,25 +1661,29 @@ class MemCmpExpansion { BasicBlock *EndBlock; PHINode *PhiRes; bool IsUsedForZeroCmp; + const DataLayout &DL; + int calculateNumBlocks(unsigned Size); void createLoadCmpBlocks(); void createResultBlock(); void setupResultBlockPHINodes(); void setupEndBlockPHINodes(); - void emitLoadCompareBlock(unsigned Index, int LoadSize, int GEPIndex, - bool IsLittleEndian); + void emitLoadCompareBlock(unsigned Index, int LoadSize, int GEPIndex); + Value *getCompareLoadPairs(unsigned Index, unsigned Size, + unsigned &NumBytesProcessed, IRBuilder<> &Builder); void emitLoadCompareBlockMultipleLoads(unsigned Index, unsigned Size, unsigned &NumBytesProcessed); void emitLoadCompareByteBlock(unsigned Index, int GEPIndex); - void emitMemCmpResultBlock(bool IsLittleEndian); - Value *getMemCmpExpansionZeroCase(unsigned Size, bool IsLittleEndian); + void emitMemCmpResultBlock(); + Value *getMemCmpExpansionZeroCase(unsigned Size); + Value *getMemCmpEqZeroOneBlock(unsigned Size); unsigned getLoadSize(unsigned Size); unsigned getNumLoads(unsigned Size); public: - MemCmpExpansion(CallInst *CI, unsigned MaxLoadSize, - unsigned NumLoadsPerBlock); - Value *getMemCmpExpansion(bool IsLittleEndian); + MemCmpExpansion(CallInst *CI, uint64_t Size, unsigned MaxLoadSize, + unsigned NumLoadsPerBlock, const DataLayout &DL); + Value *getMemCmpExpansion(uint64_t Size); }; MemCmpExpansion::ResultBlock::ResultBlock() @@ -1694,39 +1697,41 @@ MemCmpExpansion::ResultBlock::ResultBlock() // return from. // 3. ResultBlock, block to branch to for early exit when a // LoadCmpBlock finds a difference. -MemCmpExpansion::MemCmpExpansion(CallInst *CI, unsigned MaxLoadSize, - unsigned NumLoadsPerBlock) - : CI(CI), MaxLoadSize(MaxLoadSize), NumLoadsPerBlock(NumLoadsPerBlock) { - - IRBuilder<> Builder(CI->getContext()); - - BasicBlock *StartBlock = CI->getParent(); - EndBlock = StartBlock->splitBasicBlock(CI, "endblock"); - setupEndBlockPHINodes(); +MemCmpExpansion::MemCmpExpansion(CallInst *CI, uint64_t Size, + unsigned MaxLoadSize, unsigned LoadsPerBlock, + const DataLayout &TheDataLayout) + : CI(CI), MaxLoadSize(MaxLoadSize), NumLoadsPerBlock(LoadsPerBlock), + DL(TheDataLayout) { + + // A memcmp with zero-comparison with only one block of load and compare does + // not need to set up any extra blocks. This case could be handled in the DAG, + // but since we have all of the machinery to flexibly expand any memcpy here, + // we choose to handle this case too to avoid fragmented lowering. IsUsedForZeroCmp = isOnlyUsedInZeroEqualityComparison(CI); - - ConstantInt *SizeCast = dyn_cast<ConstantInt>(CI->getArgOperand(2)); - uint64_t Size = SizeCast->getZExtValue(); - - // Calculate how many load compare blocks are required for an expansion of - // given Size. NumBlocks = calculateNumBlocks(Size); - createResultBlock(); + if (!IsUsedForZeroCmp || NumBlocks != 1) { + BasicBlock *StartBlock = CI->getParent(); + EndBlock = StartBlock->splitBasicBlock(CI, "endblock"); + setupEndBlockPHINodes(); + createResultBlock(); - // If return value of memcmp is not used in a zero equality, we need to - // calculate which source was larger. The calculation requires the - // two loaded source values of each load compare block. - // These will be saved in the phi nodes created by setupResultBlockPHINodes. - if (!IsUsedForZeroCmp) - setupResultBlockPHINodes(); + // If return value of memcmp is not used in a zero equality, we need to + // calculate which source was larger. The calculation requires the + // two loaded source values of each load compare block. + // These will be saved in the phi nodes created by setupResultBlockPHINodes. + if (!IsUsedForZeroCmp) + setupResultBlockPHINodes(); - // Create the number of required load compare basic blocks. - createLoadCmpBlocks(); + // Create the number of required load compare basic blocks. + createLoadCmpBlocks(); - // Update the terminator added by splitBasicBlock to branch to the first - // LoadCmpBlock. + // Update the terminator added by splitBasicBlock to branch to the first + // LoadCmpBlock. + StartBlock->getTerminator()->setSuccessor(0, LoadCmpBlocks[0]); + } + + IRBuilder<> Builder(CI->getContext()); Builder.SetCurrentDebugLocation(CI->getDebugLoc()); - StartBlock->getTerminator()->setSuccessor(0, LoadCmpBlocks[0]); } void MemCmpExpansion::createLoadCmpBlocks() { @@ -1743,7 +1748,7 @@ void MemCmpExpansion::createResultBlock() { } // This function creates the IR instructions for loading and comparing 1 byte. -// It loads 1 byte from each source of the memcmp paramters with the given +// It loads 1 byte from each source of the memcmp parameters with the given // GEPIndex. It then subtracts the two loaded values and adds this result to the // final phi node for selecting the memcmp result. void MemCmpExpansion::emitLoadCompareByteBlock(unsigned Index, int GEPIndex) { @@ -1754,13 +1759,13 @@ void MemCmpExpansion::emitLoadCompareByteBlock(unsigned Index, int GEPIndex) { Builder.SetInsertPoint(LoadCmpBlocks[Index]); Type *LoadSizeType = Type::getInt8Ty(CI->getContext()); - // Cast source to LoadSizeType* + // Cast source to LoadSizeType*. if (Source1->getType() != LoadSizeType) Source1 = Builder.CreateBitCast(Source1, LoadSizeType->getPointerTo()); if (Source2->getType() != LoadSizeType) Source2 = Builder.CreateBitCast(Source2, LoadSizeType->getPointerTo()); - // Get the base address using the GEPIndex + // Get the base address using the GEPIndex. if (GEPIndex != 0) { Source1 = Builder.CreateGEP(LoadSizeType, Source1, ConstantInt::get(LoadSizeType, GEPIndex)); @@ -1778,16 +1783,15 @@ void MemCmpExpansion::emitLoadCompareByteBlock(unsigned Index, int GEPIndex) { PhiRes->addIncoming(Diff, LoadCmpBlocks[Index]); if (Index < (LoadCmpBlocks.size() - 1)) { - // Early exit branch if difference found to EndBlock, otherwise continue to - // next LoadCmpBlock - + // Early exit branch if difference found to EndBlock. Otherwise, continue to + // next LoadCmpBlock, Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_NE, Diff, ConstantInt::get(Diff->getType(), 0)); BranchInst *CmpBr = BranchInst::Create(EndBlock, LoadCmpBlocks[Index + 1], Cmp); Builder.Insert(CmpBr); } else { - // The last block has an unconditional branch to EndBlock + // The last block has an unconditional branch to EndBlock. BranchInst *CmpBr = BranchInst::Create(EndBlock); Builder.Insert(CmpBr); } @@ -1801,11 +1805,12 @@ unsigned MemCmpExpansion::getLoadSize(unsigned Size) { return MinAlign(PowerOf2Floor(Size), MaxLoadSize); } -void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( - unsigned Index, unsigned Size, unsigned &NumBytesProcessed) { - - IRBuilder<> Builder(CI->getContext()); - +/// Generate an equality comparison for one or more pairs of loaded values. +/// This is used in the case where the memcmp() call is compared equal or not +/// equal to zero. +Value *MemCmpExpansion::getCompareLoadPairs(unsigned Index, unsigned Size, + unsigned &NumBytesProcessed, + IRBuilder<> &Builder) { std::vector<Value *> XorList, OrList; Value *Diff; @@ -1813,8 +1818,13 @@ void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( unsigned NumLoadsRemaining = getNumLoads(RemainingBytes); unsigned NumLoads = std::min(NumLoadsRemaining, NumLoadsPerBlock); - Builder.SetInsertPoint(LoadCmpBlocks[Index]); + // For a single-block expansion, start inserting before the memcmp call. + if (LoadCmpBlocks.empty()) + Builder.SetInsertPoint(CI); + else + Builder.SetInsertPoint(LoadCmpBlocks[Index]); + Value *Cmp = nullptr; for (unsigned i = 0; i < NumLoads; ++i) { unsigned LoadSize = getLoadSize(RemainingBytes); unsigned GEPIndex = NumBytesProcessed / LoadSize; @@ -1827,13 +1837,13 @@ void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( Value *Source1 = CI->getArgOperand(0); Value *Source2 = CI->getArgOperand(1); - // Cast source to LoadSizeType* + // Cast source to LoadSizeType*. if (Source1->getType() != LoadSizeType) Source1 = Builder.CreateBitCast(Source1, LoadSizeType->getPointerTo()); if (Source2->getType() != LoadSizeType) Source2 = Builder.CreateBitCast(Source2, LoadSizeType->getPointerTo()); - // Get the base address using the GEPIndex + // Get the base address using the GEPIndex. if (GEPIndex != 0) { Source1 = Builder.CreateGEP(LoadSizeType, Source1, ConstantInt::get(LoadSizeType, GEPIndex)); @@ -1841,16 +1851,23 @@ void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( ConstantInt::get(LoadSizeType, GEPIndex)); } - // Load LoadSizeType from the base address + // Load LoadSizeType from the base address. Value *LoadSrc1 = Builder.CreateLoad(LoadSizeType, Source1); Value *LoadSrc2 = Builder.CreateLoad(LoadSizeType, Source2); - if (LoadSizeType != MaxLoadType) { - LoadSrc1 = Builder.CreateZExtOrTrunc(LoadSrc1, MaxLoadType); - LoadSrc2 = Builder.CreateZExtOrTrunc(LoadSrc2, MaxLoadType); + if (NumLoads != 1) { + if (LoadSizeType != MaxLoadType) { + LoadSrc1 = Builder.CreateZExtOrTrunc(LoadSrc1, MaxLoadType); + LoadSrc2 = Builder.CreateZExtOrTrunc(LoadSrc2, MaxLoadType); + } + // If we have multiple loads per block, we need to generate a composite + // comparison using xor+or. + Diff = Builder.CreateXor(LoadSrc1, LoadSrc2); + Diff = Builder.CreateZExtOrTrunc(Diff, MaxLoadType); + XorList.push_back(Diff); + } else { + // If there's only one load per block, we just compare the loaded values. + Cmp = Builder.CreateICmpNE(LoadSrc1, LoadSrc2); } - Diff = Builder.CreateXor(LoadSrc1, LoadSrc2); - Diff = Builder.CreateZExtOrTrunc(Diff, MaxLoadType); - XorList.push_back(Diff); } auto pairWiseOr = [&](std::vector<Value *> &InList) -> std::vector<Value *> { @@ -1864,27 +1881,36 @@ void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( return OutList; }; - // Pair wise OR the XOR results - OrList = pairWiseOr(XorList); + if (!Cmp) { + // Pairwise OR the XOR results. + OrList = pairWiseOr(XorList); - // Pair wise OR the OR results until one result left - while (OrList.size() != 1) { - OrList = pairWiseOr(OrList); + // Pairwise OR the OR results until one result left. + while (OrList.size() != 1) { + OrList = pairWiseOr(OrList); + } + Cmp = Builder.CreateICmpNE(OrList[0], ConstantInt::get(Diff->getType(), 0)); } - Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_NE, OrList[0], - ConstantInt::get(Diff->getType(), 0)); + return Cmp; +} + +void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( + unsigned Index, unsigned Size, unsigned &NumBytesProcessed) { + IRBuilder<> Builder(CI->getContext()); + Value *Cmp = getCompareLoadPairs(Index, Size, NumBytesProcessed, Builder); + BasicBlock *NextBB = (Index == (LoadCmpBlocks.size() - 1)) ? EndBlock : LoadCmpBlocks[Index + 1]; - // Early exit branch if difference found to ResultBlock, otherwise continue to - // next LoadCmpBlock or EndBlock. + // Early exit branch if difference found to ResultBlock. Otherwise, + // continue to next LoadCmpBlock or EndBlock. BranchInst *CmpBr = BranchInst::Create(ResBlock.BB, NextBB, Cmp); Builder.Insert(CmpBr); // Add a phi edge for the last LoadCmpBlock to Endblock with a value of 0 // since early exit to ResultBlock was not taken (no difference was found in - // any of the bytes) + // any of the bytes). if (Index == LoadCmpBlocks.size() - 1) { Value *Zero = ConstantInt::get(Type::getInt32Ty(CI->getContext()), 0); PhiRes->addIncoming(Zero, LoadCmpBlocks[Index]); @@ -1901,7 +1927,7 @@ void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( // a special case through emitLoadCompareByteBlock. The special handling can // simply subtract the loaded values and add it to the result phi node. void MemCmpExpansion::emitLoadCompareBlock(unsigned Index, int LoadSize, - int GEPIndex, bool IsLittleEndian) { + int GEPIndex) { if (LoadSize == 1) { MemCmpExpansion::emitLoadCompareByteBlock(Index, GEPIndex); return; @@ -1916,13 +1942,13 @@ void MemCmpExpansion::emitLoadCompareBlock(unsigned Index, int LoadSize, Value *Source2 = CI->getArgOperand(1); Builder.SetInsertPoint(LoadCmpBlocks[Index]); - // Cast source to LoadSizeType* + // Cast source to LoadSizeType*. if (Source1->getType() != LoadSizeType) Source1 = Builder.CreateBitCast(Source1, LoadSizeType->getPointerTo()); if (Source2->getType() != LoadSizeType) Source2 = Builder.CreateBitCast(Source2, LoadSizeType->getPointerTo()); - // Get the base address using the GEPIndex + // Get the base address using the GEPIndex. if (GEPIndex != 0) { Source1 = Builder.CreateGEP(LoadSizeType, Source1, ConstantInt::get(LoadSizeType, GEPIndex)); @@ -1930,11 +1956,11 @@ void MemCmpExpansion::emitLoadCompareBlock(unsigned Index, int LoadSize, ConstantInt::get(LoadSizeType, GEPIndex)); } - // Load LoadSizeType from the base address + // Load LoadSizeType from the base address. Value *LoadSrc1 = Builder.CreateLoad(LoadSizeType, Source1); Value *LoadSrc2 = Builder.CreateLoad(LoadSizeType, Source2); - if (IsLittleEndian) { + if (DL.isLittleEndian()) { Function *F = LoadCmpBlocks[Index]->getParent(); Function *Bswap = Intrinsic::getDeclaration(F->getParent(), @@ -1962,14 +1988,14 @@ void MemCmpExpansion::emitLoadCompareBlock(unsigned Index, int LoadSize, BasicBlock *NextBB = (Index == (LoadCmpBlocks.size() - 1)) ? EndBlock : LoadCmpBlocks[Index + 1]; - // Early exit branch if difference found to ResultBlock, otherwise continue to - // next LoadCmpBlock or EndBlock. + // Early exit branch if difference found to ResultBlock. Otherwise, continue + // to next LoadCmpBlock or EndBlock. BranchInst *CmpBr = BranchInst::Create(ResBlock.BB, NextBB, Cmp); Builder.Insert(CmpBr); // Add a phi edge for the last LoadCmpBlock to Endblock with a value of 0 // since early exit to ResultBlock was not taken (no difference was found in - // any of the bytes) + // any of the bytes). if (Index == LoadCmpBlocks.size() - 1) { Value *Zero = ConstantInt::get(Type::getInt32Ty(CI->getContext()), 0); PhiRes->addIncoming(Zero, LoadCmpBlocks[Index]); @@ -1979,7 +2005,7 @@ void MemCmpExpansion::emitLoadCompareBlock(unsigned Index, int LoadSize, // This function populates the ResultBlock with a sequence to calculate the // memcmp result. It compares the two loaded source values and returns -1 if // src1 < src2 and 1 if src1 > src2. -void MemCmpExpansion::emitMemCmpResultBlock(bool IsLittleEndian) { +void MemCmpExpansion::emitMemCmpResultBlock() { IRBuilder<> Builder(CI->getContext()); // Special case: if memcmp result is used in a zero equality, result does not @@ -2010,17 +2036,17 @@ void MemCmpExpansion::emitMemCmpResultBlock(bool IsLittleEndian) { int MemCmpExpansion::calculateNumBlocks(unsigned Size) { int NumBlocks = 0; - bool haveOneByteLoad = false; + bool HaveOneByteLoad = false; unsigned RemainingSize = Size; unsigned LoadSize = MaxLoadSize; while (RemainingSize) { if (LoadSize == 1) - haveOneByteLoad = true; + HaveOneByteLoad = true; NumBlocks += RemainingSize / LoadSize; RemainingSize = RemainingSize % LoadSize; LoadSize = LoadSize / 2; } - NumBlocksNonOneByte = haveOneByteLoad ? (NumBlocks - 1) : NumBlocks; + NumBlocksNonOneByte = HaveOneByteLoad ? (NumBlocks - 1) : NumBlocks; if (IsUsedForZeroCmp) NumBlocks = NumBlocks / NumLoadsPerBlock + @@ -2046,63 +2072,66 @@ void MemCmpExpansion::setupEndBlockPHINodes() { PhiRes = Builder.CreatePHI(Type::getInt32Ty(CI->getContext()), 2, "phi.res"); } -Value *MemCmpExpansion::getMemCmpExpansionZeroCase(unsigned Size, - bool IsLittleEndian) { +Value *MemCmpExpansion::getMemCmpExpansionZeroCase(unsigned Size) { unsigned NumBytesProcessed = 0; - // This loop populates each of the LoadCmpBlocks with IR sequence to handle - // multiple loads per block - for (unsigned i = 0; i < NumBlocks; ++i) { + // This loop populates each of the LoadCmpBlocks with the IR sequence to + // handle multiple loads per block. + for (unsigned i = 0; i < NumBlocks; ++i) emitLoadCompareBlockMultipleLoads(i, Size, NumBytesProcessed); - } - emitMemCmpResultBlock(IsLittleEndian); + emitMemCmpResultBlock(); return PhiRes; } +/// A memcmp expansion that compares equality with 0 and only has one block of +/// load and compare can bypass the compare, branch, and phi IR that is required +/// in the general case. +Value *MemCmpExpansion::getMemCmpEqZeroOneBlock(unsigned Size) { + unsigned NumBytesProcessed = 0; + IRBuilder<> Builder(CI->getContext()); + Value *Cmp = getCompareLoadPairs(0, Size, NumBytesProcessed, Builder); + return Builder.CreateZExt(Cmp, Type::getInt32Ty(CI->getContext())); +} + // This function expands the memcmp call into an inline expansion and returns // the memcmp result. -Value *MemCmpExpansion::getMemCmpExpansion(bool IsLittleEndian) { - - ConstantInt *SizeCast = dyn_cast<ConstantInt>(CI->getArgOperand(2)); - uint64_t Size = SizeCast->getZExtValue(); +Value *MemCmpExpansion::getMemCmpExpansion(uint64_t Size) { + if (IsUsedForZeroCmp) + return NumBlocks == 1 ? getMemCmpEqZeroOneBlock(Size) : + getMemCmpExpansionZeroCase(Size); + // This loop calls emitLoadCompareBlock for comparing Size bytes of the two + // memcmp sources. It starts with loading using the maximum load size set by + // the target. It processes any remaining bytes using a load size which is the + // next smallest power of 2. int LoadSize = MaxLoadSize; int NumBytesToBeProcessed = Size; - - if (IsUsedForZeroCmp) { - return getMemCmpExpansionZeroCase(Size, IsLittleEndian); - } - unsigned Index = 0; - // This loop calls emitLoadCompareBlock for comparing SizeVal bytes of the two - // memcmp source. It starts with loading using the maximum load size set by - // the target. It processes any remaining bytes using a load size which is the - // next smallest power of 2. while (NumBytesToBeProcessed) { - // Calculate how many blocks we can create with the current load size + // Calculate how many blocks we can create with the current load size. int NumBlocks = NumBytesToBeProcessed / LoadSize; int GEPIndex = (Size - NumBytesToBeProcessed) / LoadSize; NumBytesToBeProcessed = NumBytesToBeProcessed % LoadSize; // For each NumBlocks, populate the instruction sequence for loading and - // comparing LoadSize bytes + // comparing LoadSize bytes. while (NumBlocks--) { - emitLoadCompareBlock(Index, LoadSize, GEPIndex, IsLittleEndian); + emitLoadCompareBlock(Index, LoadSize, GEPIndex); Index++; GEPIndex++; } - // Get the next LoadSize to use + // Get the next LoadSize to use. LoadSize = LoadSize / 2; } - emitMemCmpResultBlock(IsLittleEndian); + emitMemCmpResultBlock(); return PhiRes; } // This function checks to see if an expansion of memcmp can be generated. // It checks for constant compare size that is less than the max inline size. // If an expansion cannot occur, returns false to leave as a library call. -// Otherwise, the library call is replaced wtih new IR instruction sequence. +// Otherwise, the library call is replaced with a new IR instruction sequence. /// We want to transform: /// %call = call signext i32 @memcmp(i8* %0, i8* %1, i64 15) /// To: @@ -2177,27 +2206,25 @@ static bool expandMemCmp(CallInst *CI, const TargetTransformInfo *TTI, NumMemCmpCalls++; IRBuilder<> Builder(CI->getContext()); - // TTI call to check if target would like to expand memcmp and get the - // MaxLoadSize + // TTI call to check if target would like to expand memcmp. Also, get the + // MaxLoadSize. unsigned MaxLoadSize; if (!TTI->expandMemCmp(CI, MaxLoadSize)) return false; - // Early exit from expansion if -Oz - if (CI->getParent()->getParent()->optForMinSize()) { + // Early exit from expansion if -Oz. + if (CI->getFunction()->optForMinSize()) return false; - } - // Early exit from expansion if size is not a constant + // Early exit from expansion if size is not a constant. ConstantInt *SizeCast = dyn_cast<ConstantInt>(CI->getArgOperand(2)); if (!SizeCast) { NumMemCmpNotConstant++; return false; } - // Early exit from expansion if size greater than max bytes to load + // Early exit from expansion if size greater than max bytes to load. uint64_t SizeVal = SizeCast->getZExtValue(); - unsigned NumLoads = 0; unsigned RemainingSize = SizeVal; unsigned LoadSize = MaxLoadSize; @@ -2207,29 +2234,28 @@ static bool expandMemCmp(CallInst *CI, const TargetTransformInfo *TTI, LoadSize = LoadSize / 2; } - if (NumLoads > - TLI->getMaxExpandSizeMemcmp(CI->getParent()->getParent()->optForSize())) { + if (NumLoads > TLI->getMaxExpandSizeMemcmp(CI->getFunction()->optForSize())) { NumMemCmpGreaterThanMax++; return false; } NumMemCmpInlined++; - // MemCmpHelper object, creates and sets up basic blocks required for - // expanding memcmp with size SizeVal + // MemCmpHelper object creates and sets up basic blocks required for + // expanding memcmp with size SizeVal. unsigned NumLoadsPerBlock = MemCmpNumLoadsPerBlock; - MemCmpExpansion MemCmpHelper(CI, MaxLoadSize, NumLoadsPerBlock); + MemCmpExpansion MemCmpHelper(CI, SizeVal, MaxLoadSize, NumLoadsPerBlock, *DL); - Value *Res = MemCmpHelper.getMemCmpExpansion(DL->isLittleEndian()); + Value *Res = MemCmpHelper.getMemCmpExpansion(SizeVal); - // Replace call with result of expansion and erarse call. + // Replace call with result of expansion and erase call. CI->replaceAllUsesWith(Res); CI->eraseFromParent(); return true; } -bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool& ModifiedDT) { +bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) { BasicBlock *BB = CI->getParent(); // Lower inline assembly if we can. @@ -2382,12 +2408,10 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool& ModifiedDT) { } LibFunc Func; - if (TLInfo->getLibFunc(*CI->getCalledFunction(), Func) && - Func == LibFunc_memcmp) { - if (expandMemCmp(CI, TTI, TLI, DL)) { - ModifiedDT = true; - return true; - } + if (TLInfo->getLibFunc(ImmutableCallSite(CI), Func) && + Func == LibFunc_memcmp && expandMemCmp(CI, TTI, TLI, DL)) { + ModifiedDT = true; + return true; } return false; } @@ -3934,7 +3958,7 @@ bool AddressingModeMatcher::matchAddr(Value *Addr, unsigned Depth) { static bool IsOperandAMemoryOperand(CallInst *CI, InlineAsm *IA, Value *OpVal, const TargetLowering &TLI, const TargetRegisterInfo &TRI) { - const Function *F = CI->getParent()->getParent(); + const Function *F = CI->getFunction(); TargetLowering::AsmOperandInfoVector TargetConstraints = TLI.ParseConstraints(F->getParent()->getDataLayout(), &TRI, ImmutableCallSite(CI)); @@ -4531,7 +4555,7 @@ bool CodeGenPrepare::optimizeInlineAsmInst(CallInst *CS) { bool MadeChange = false; const TargetRegisterInfo *TRI = - TM->getSubtargetImpl(*CS->getParent()->getParent())->getRegisterInfo(); + TM->getSubtargetImpl(*CS->getFunction())->getRegisterInfo(); TargetLowering::AsmOperandInfoVector TargetConstraints = TLI->ParseConstraints(*DL, TRI, CS); unsigned ArgNo = 0; @@ -6015,7 +6039,7 @@ static bool splitMergedValStore(StoreInst &SI, const DataLayout &DL, return true; } -bool CodeGenPrepare::optimizeInst(Instruction *I, bool& ModifiedDT) { +bool CodeGenPrepare::optimizeInst(Instruction *I, bool &ModifiedDT) { // Bail out if we inserted the instruction to prevent optimizations from // stepping on each other's toes. if (InsertedInsts.count(I)) @@ -6170,7 +6194,7 @@ static bool makeBitReverse(Instruction &I, const DataLayout &DL, // In this pass we look for GEP and cast instructions that are used // across basic blocks and rewrite them to improve basic-block-at-a-time // selection. -bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, bool& ModifiedDT) { +bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, bool &ModifiedDT) { SunkAddrs.clear(); bool MadeChange = false; |