jmciver created this revision. jmciver added reviewers: nikic, efriedma, fhahn. Herald added subscribers: kmitropoulou, ormris, ChuanqiXu, StephenFan, wenlei, steven_wu, hiraditya. Herald added a project: All. jmciver published this revision for review. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
This commit is in support of future uninitialized memory handling and adds alloca instruction support to getInitialValueOfAllocation. This unifies initial memory state querying (both stack and heap) to a single utility function. Several optimizations are refactored to take advantage of alloca support in getInitialValueOfAllocation, see below list. A majority of the optimizations are effected by the migration of PromoteMemToReg to use getInitialValueOfAllocation, which requires TLI for allocation function data, but is not used in support of alloca instructions. - PromoteMemToReg - Mem2Reg - IPO - CoroSplit - Coroutines (clang) - GVN - NewGVN - Statepoint Coroutines have a clang based optimization call to PromoteMemToReg from FinishFunction, which requires a TLI object outside of the optimization pass framework. Generation of the TLI is added at the module level to prevent generation of multiple TLI objects for each coroutine function contained within. Furthermore generation of the TLI object is lazy. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D155773 Files: clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h llvm/include/llvm/Analysis/MemoryBuiltins.h llvm/include/llvm/Transforms/Scalar/SROA.h llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h llvm/lib/Analysis/MemoryBuiltins.cpp llvm/lib/Transforms/Coroutines/CoroFrame.cpp llvm/lib/Transforms/Coroutines/CoroInternal.h llvm/lib/Transforms/Coroutines/CoroSplit.cpp llvm/lib/Transforms/IPO/ArgumentPromotion.cpp llvm/lib/Transforms/Scalar/GVN.cpp llvm/lib/Transforms/Scalar/NewGVN.cpp llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp llvm/lib/Transforms/Scalar/SROA.cpp llvm/lib/Transforms/Utils/Mem2Reg.cpp llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp llvm/test/Other/new-pm-defaults.ll llvm/test/Other/new-pm-thinlto-postlink-defaults.ll llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll llvm/test/Other/new-pm-thinlto-prelink-defaults.ll llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll
Index: llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll +++ llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll @@ -39,8 +39,8 @@ ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis -; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: SampleProfileLoaderPass ; CHECK-O-NEXT: Running analysis: ProfileSummaryAnalysis Index: llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll +++ llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll @@ -40,8 +40,8 @@ ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis -; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: OpenMPOptPass ; CHECK-O-NEXT: Running pass: IPSCCPPass Index: llvm/test/Other/new-pm-thinlto-prelink-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-prelink-defaults.ll +++ llvm/test/Other/new-pm-thinlto-prelink-defaults.ll @@ -52,8 +52,8 @@ ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis -; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: OpenMPOptPass ; CHECK-O-NEXT: Running pass: IPSCCPPass Index: llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll +++ llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll @@ -38,8 +38,8 @@ ; CHECK-O-NEXT: Running pass: GlobalOptPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: PromotePass -; CHECK-O-NEXT: Running pass: InstCombinePass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: InstCombinePass ; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O-NEXT: Running analysis: BasicAA ; CHECK-O-NEXT: Running analysis: ScopedNoAliasAA Index: llvm/test/Other/new-pm-thinlto-postlink-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-postlink-defaults.ll +++ llvm/test/Other/new-pm-thinlto-postlink-defaults.ll @@ -53,8 +53,8 @@ ; CHECK-O-NEXT: Running pass: GlobalOptPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: PromotePass -; CHECK-O-NEXT: Running pass: InstCombinePass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: InstCombinePass ; CHECK-O-NEXT: Running analysis: AAManager ; CHECK-O-NEXT: Running analysis: BasicAA ; CHECK-O-NEXT: Running analysis: ScopedNoAliasAA Index: llvm/test/Other/new-pm-defaults.ll =================================================================== --- llvm/test/Other/new-pm-defaults.ll +++ llvm/test/Other/new-pm-defaults.ll @@ -103,8 +103,8 @@ ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis -; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: OpenMPOptPass ; CHECK-EP-PIPELINE-EARLY-SIMPLIFICATION-NEXT: Running pass: NoOpModulePass Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp =================================================================== --- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -24,6 +24,7 @@ #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/IteratedDominanceFrontier.h" +#include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" @@ -304,6 +305,7 @@ DominatorTree &DT; DIBuilder DIB; + const TargetLibraryInfo *TLI; /// A cache of @llvm.assume intrinsics used by SimplifyInstruction. AssumptionCache *AC; @@ -349,11 +351,12 @@ public: PromoteMem2Reg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT, - AssumptionCache *AC) + const TargetLibraryInfo *TLI, AssumptionCache *AC) : Allocas(Allocas.begin(), Allocas.end()), DT(DT), DIB(*DT.getRoot()->getParent()->getParent(), /*AllowUnresolved*/ false), - AC(AC), SQ(DT.getRoot()->getParent()->getParent()->getDataLayout(), - nullptr, &DT, AC) {} + TLI(TLI), AC(AC), + SQ(DT.getRoot()->getParent()->getParent()->getDataLayout(), nullptr, + &DT, AC) {} void run(); @@ -563,7 +566,8 @@ /// } static bool promoteSingleBlockAlloca( AllocaInst *AI, const AllocaInfo &Info, LargeBlockInfo &LBI, - const DataLayout &DL, DominatorTree &DT, AssumptionCache *AC, + const DataLayout &DL, DominatorTree &DT, const TargetLibraryInfo *TLI, + AssumptionCache *AC, SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete) { // The trickiest case to handle is when we have large blocks. Because of this, // this code is optimized assuming that large blocks happen. This does not @@ -600,7 +604,7 @@ if (I == StoresByIndex.begin()) { if (StoresByIndex.empty()) // If there are no stores, the load takes the undef value. - ReplVal = UndefValue::get(LI->getType()); + ReplVal = getInitialValueOfAllocation(AI, TLI, LI->getType()); else // There is no store before this load, bail out (load may be affected // by the following stores - see main comment). @@ -700,7 +704,7 @@ // If the alloca is only read and written in one basic block, just perform a // linear sweep over the block to eliminate it. if (Info.OnlyUsedInOneBlock && - promoteSingleBlockAlloca(AI, Info, LBI, SQ.DL, DT, AC, + promoteSingleBlockAlloca(AI, Info, LBI, SQ.DL, DT, TLI, AC, &DbgAssignsToDelete)) { // The alloca has been processed, move on. RemoveFromAllocasList(AllocaNum); @@ -1127,10 +1131,10 @@ } void llvm::PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT, - AssumptionCache *AC) { + const TargetLibraryInfo *TLI, AssumptionCache *AC) { // If there is nothing to do, bail out... if (Allocas.empty()) return; - PromoteMem2Reg(Allocas, DT, AC).run(); + PromoteMem2Reg(Allocas, DT, TLI, AC).run(); } Index: llvm/lib/Transforms/Utils/Mem2Reg.cpp =================================================================== --- llvm/lib/Transforms/Utils/Mem2Reg.cpp +++ llvm/lib/Transforms/Utils/Mem2Reg.cpp @@ -14,6 +14,7 @@ #include "llvm/Transforms/Utils/Mem2Reg.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" @@ -33,6 +34,7 @@ STATISTIC(NumPromoted, "Number of alloca's promoted"); static bool promoteMemoryToRegister(Function &F, DominatorTree &DT, + TargetLibraryInfo &TLI, AssumptionCache &AC) { std::vector<AllocaInst *> Allocas; BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function @@ -51,7 +53,7 @@ if (Allocas.empty()) break; - PromoteMemToReg(Allocas, DT, &AC); + PromoteMemToReg(Allocas, DT, &TLI, &AC); NumPromoted += Allocas.size(); Changed = true; } @@ -60,8 +62,9 @@ PreservedAnalyses PromotePass::run(Function &F, FunctionAnalysisManager &AM) { auto &DT = AM.getResult<DominatorTreeAnalysis>(F); + auto &TLI = AM.getResult<TargetLibraryAnalysis>(F); auto &AC = AM.getResult<AssumptionAnalysis>(F); - if (!promoteMemoryToRegister(F, DT, AC)) + if (!promoteMemoryToRegister(F, DT, TLI, AC)) return PreservedAnalyses::all(); PreservedAnalyses PA; @@ -90,9 +93,11 @@ return false; DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree(); + TargetLibraryInfo &TLI = + getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); AssumptionCache &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); - return promoteMemoryToRegister(F, DT, AC); + return promoteMemoryToRegister(F, DT, TLI, AC); } void getAnalysisUsage(AnalysisUsage &AU) const override { Index: llvm/lib/Transforms/Scalar/SROA.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SROA.cpp +++ llvm/lib/Transforms/Scalar/SROA.cpp @@ -42,6 +42,7 @@ #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/PtrUseVisitor.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" @@ -5066,7 +5067,7 @@ LLVM_DEBUG(dbgs() << "Not promoting allocas with mem2reg!\n"); } else { LLVM_DEBUG(dbgs() << "Promoting allocas with mem2reg...\n"); - PromoteMemToReg(PromotableAllocas, DTU->getDomTree(), AC); + PromoteMemToReg(PromotableAllocas, DTU->getDomTree(), TLI, AC); } PromotableAllocas.clear(); @@ -5074,10 +5075,12 @@ } PreservedAnalyses SROAPass::runImpl(Function &F, DomTreeUpdater &RunDTU, + TargetLibraryInfo &RunTLI, AssumptionCache &RunAC) { LLVM_DEBUG(dbgs() << "SROA function: " << F.getName() << "\n"); C = &F.getContext(); DTU = &RunDTU; + TLI = &RunTLI; AC = &RunAC; const DataLayout &DL = F.getParent()->getDataLayout(); @@ -5145,15 +5148,17 @@ } PreservedAnalyses SROAPass::runImpl(Function &F, DominatorTree &RunDT, + TargetLibraryInfo &RunTLI, AssumptionCache &RunAC) { DomTreeUpdater DTU(RunDT, DomTreeUpdater::UpdateStrategy::Lazy); - return runImpl(F, DTU, RunAC); + return runImpl(F, DTU, RunTLI, RunAC); } PreservedAnalyses SROAPass::run(Function &F, FunctionAnalysisManager &AM) { DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F); + TargetLibraryInfo &TLI = AM.getResult<TargetLibraryAnalysis>(F); AssumptionCache &AC = AM.getResult<AssumptionAnalysis>(F); - return runImpl(F, DT, AC); + return runImpl(F, DT, TLI, AC); } void SROAPass::printPipeline( @@ -5188,6 +5193,7 @@ auto PA = Impl.runImpl( F, getAnalysis<DominatorTreeWrapperPass>().getDomTree(), + getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F), getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F)); return !PA.areAllPreserved(); } Index: llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp =================================================================== --- llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1980,7 +1980,8 @@ /// Do all the relocation update via allocas and mem2reg static void relocationViaAlloca( Function &F, DominatorTree &DT, ArrayRef<Value *> Live, - ArrayRef<PartiallyConstructedSafepointRecord> Records) { + ArrayRef<PartiallyConstructedSafepointRecord> Records, + const TargetLibraryInfo &TLI) { #ifndef NDEBUG // record initial number of (static) allocas; we'll check we have the same // number when we get done. @@ -2165,7 +2166,7 @@ (void) NumRematerializedValues; if (!PromotableAllocas.empty()) { // Apply mem2reg to promote alloca to SSA - PromoteMemToReg(PromotableAllocas, DT); + PromoteMemToReg(PromotableAllocas, DT, &TLI); } #ifndef NDEBUG @@ -2618,6 +2619,7 @@ static bool insertParsePoints(Function &F, DominatorTree &DT, TargetTransformInfo &TTI, + const TargetLibraryInfo &TLI, SmallVectorImpl<CallBase *> &ToUpdate, DefiningValueMapTy &DVCache, IsKnownBaseMapTy &KnownBases) { @@ -2840,7 +2842,7 @@ "must be a gc pointer type"); #endif - relocationViaAlloca(F, DT, Live, Records); + relocationViaAlloca(F, DT, Live, Records, TLI); return !Records.empty(); } @@ -3146,7 +3148,7 @@ if (!ParsePointNeeded.empty()) MadeChange |= - insertParsePoints(F, DT, TTI, ParsePointNeeded, DVCache, KnownBases); + insertParsePoints(F, DT, TTI, TLI, ParsePointNeeded, DVCache, KnownBases); return MadeChange; } Index: llvm/lib/Transforms/Scalar/NewGVN.cpp =================================================================== --- llvm/lib/Transforms/Scalar/NewGVN.cpp +++ llvm/lib/Transforms/Scalar/NewGVN.cpp @@ -1489,21 +1489,18 @@ if (LoadPtr != lookupOperandLeader(DepInst) && !AA->isMustAlias(LoadPtr, DepInst)) return nullptr; - // If this load really doesn't depend on anything, then we must be loading an - // undef value. This can happen when loading for a fresh allocation with no - // intervening stores, for example. Note that this is only true in the case - // that the result of the allocation is pointer equal to the load ptr. - if (isa<AllocaInst>(DepInst)) { - return createConstantExpression(UndefValue::get(LoadType)); - } // If this load occurs either right after a lifetime begin, // then the loaded value is undefined. - else if (auto *II = dyn_cast<IntrinsicInst>(DepInst)) { + if (auto *II = dyn_cast<IntrinsicInst>(DepInst)) { if (II->getIntrinsicID() == Intrinsic::lifetime_start) return createConstantExpression(UndefValue::get(LoadType)); - } else if (auto *InitVal = - getInitialValueOfAllocation(DepInst, TLI, LoadType)) - return createConstantExpression(InitVal); + } + // If this load really doesn't depend on anything, then we must be loading an + // undef value. This can happen when loading for a fresh allocation with no + // intervening stores, for example. Note that this is only true in the case + // that the result of the allocation is pointer equal to the load ptr. + else if (auto *InitVal = getInitialValueOfAllocation(DepInst, TLI, LoadType)) + return createConstantExpression(InitVal); return nullptr; } Index: llvm/lib/Transforms/Scalar/GVN.cpp =================================================================== --- llvm/lib/Transforms/Scalar/GVN.cpp +++ llvm/lib/Transforms/Scalar/GVN.cpp @@ -1240,11 +1240,12 @@ } assert(DepInfo.isDef() && "follows from above"); - // Loading the alloca -> undef. // Loading immediately after lifetime begin -> undef. - if (isa<AllocaInst>(DepInst) || isLifetimeStart(DepInst)) + if (isLifetimeStart(DepInst)) return AvailableValue::get(UndefValue::get(Load->getType())); + // In addition to allocator function calls this includes loading the alloca -> + // undef. if (Constant *InitVal = getInitialValueOfAllocation(DepInst, TLI, Load->getType())) return AvailableValue::get(InitVal); Index: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -391,8 +391,9 @@ // Our earlier checks have ensured that PromoteMemToReg() will // succeed. auto &DT = FAM.getResult<DominatorTreeAnalysis>(*NF); + auto <I = FAM.getResult<TargetLibraryAnalysis>(*NF); auto &AC = FAM.getResult<AssumptionAnalysis>(*NF); - PromoteMemToReg(Allocas, DT, &AC); + PromoteMemToReg(Allocas, DT, <I, &AC); } return NF; Index: llvm/lib/Transforms/Coroutines/CoroSplit.cpp =================================================================== --- llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -32,6 +32,7 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/LazyCallGraph.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/Argument.h" @@ -1950,7 +1951,8 @@ static coro::Shape splitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones, - TargetTransformInfo &TTI, bool OptimizeFrame, + TargetTransformInfo &TTI, TargetLibraryInfo &TLI, + bool OptimizeFrame, std::function<bool(Instruction &)> MaterializableCallback) { PrettyStackTraceFunction prettyStackTrace(F); @@ -1963,7 +1965,7 @@ return Shape; simplifySuspendPoints(Shape); - buildCoroutineFrame(F, Shape, MaterializableCallback); + buildCoroutineFrame(F, Shape, TLI, MaterializableCallback); replaceFrameSizeAndAlignment(Shape); // If there are no suspend points, no split required, just remove @@ -2155,7 +2157,8 @@ auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F); const coro::Shape Shape = splitCoroutine(F, Clones, FAM.getResult<TargetIRAnalysis>(F), - OptimizeFrame, MaterializableCallback); + FAM.getResult<TargetLibraryAnalysis>(F), OptimizeFrame, + MaterializableCallback); updateCallGraphAfterCoroutineSplit(*N, Shape, Clones, C, CG, AM, UR, FAM); ORE.emit([&]() { Index: llvm/lib/Transforms/Coroutines/CoroInternal.h =================================================================== --- llvm/lib/Transforms/Coroutines/CoroInternal.h +++ llvm/lib/Transforms/Coroutines/CoroInternal.h @@ -17,6 +17,7 @@ namespace llvm { class CallGraph; +class TargetLibraryInfo; namespace coro { @@ -265,7 +266,7 @@ bool defaultMaterializable(Instruction &V); void buildCoroutineFrame( - Function &F, Shape &Shape, + Function &F, Shape &Shape, const TargetLibraryInfo &TLI, const std::function<bool(Instruction &)> &MaterializableCallback); CallInst *createMustTailCall(DebugLoc Loc, Function *MustTailCallFn, ArrayRef<Value *> Arguments, IRBuilder<> &); Index: llvm/lib/Transforms/Coroutines/CoroFrame.cpp =================================================================== --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Analysis/PtrUseVisitor.h" #include "llvm/Analysis/StackLifetime.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/CFG.h" #include "llvm/IR/DIBuilder.h" @@ -2633,8 +2634,9 @@ /// Eliminate all problematic uses of swifterror arguments and allocas /// from the function. We'll fix them up later when splitting the function. -static void eliminateSwiftError(Function &F, coro::Shape &Shape) { - SmallVector<AllocaInst*, 4> AllocasToPromote; +static void eliminateSwiftError(Function &F, coro::Shape &Shape, + const TargetLibraryInfo &TLI) { + SmallVector<AllocaInst *, 4> AllocasToPromote; // Look for a swifterror argument. for (auto &Arg : F.args()) { @@ -2660,7 +2662,7 @@ // promote them en masse. if (!AllocasToPromote.empty()) { DominatorTree DT(F); - PromoteMemToReg(AllocasToPromote, DT); + PromoteMemToReg(AllocasToPromote, DT, &TLI); } } @@ -2988,11 +2990,11 @@ } void coro::buildCoroutineFrame( - Function &F, Shape &Shape, + Function &F, Shape &Shape, const TargetLibraryInfo &TLI, const std::function<bool(Instruction &)> &MaterializableCallback) { // Don't eliminate swifterror in async functions that won't be split. if (Shape.ABI != coro::ABI::Async || !Shape.CoroSuspends.empty()) - eliminateSwiftError(F, Shape); + eliminateSwiftError(F, Shape, TLI); if (Shape.ABI == coro::ABI::Switch && Shape.SwitchLowering.PromiseAlloca) { Index: llvm/lib/Analysis/MemoryBuiltins.cpp =================================================================== --- llvm/lib/Analysis/MemoryBuiltins.cpp +++ llvm/lib/Analysis/MemoryBuiltins.cpp @@ -436,6 +436,9 @@ Constant *llvm::getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty) { + if (isa<AllocaInst>(V)) + return UndefValue::get(Ty); + auto *Alloc = dyn_cast<CallBase>(V); if (!Alloc) return nullptr; Index: llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h =================================================================== --- llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h +++ llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h @@ -19,6 +19,7 @@ template <typename T> class ArrayRef; class AllocaInst; class DominatorTree; +class TargetLibraryInfo; class AssumptionCache; /// Return true if this alloca is legal for promotion. @@ -37,6 +38,7 @@ /// the same function. /// void PromoteMemToReg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT, + const TargetLibraryInfo *TLI, AssumptionCache *AC = nullptr); } // End llvm namespace Index: llvm/include/llvm/Transforms/Scalar/SROA.h =================================================================== --- llvm/include/llvm/Transforms/Scalar/SROA.h +++ llvm/include/llvm/Transforms/Scalar/SROA.h @@ -36,6 +36,7 @@ class LLVMContext; class PHINode; class SelectInst; +class TargetLibraryInfo; class Use; /// A private "module" namespace for types and utilities used by SROA. These @@ -96,6 +97,7 @@ class SROAPass : public PassInfoMixin<SROAPass> { LLVMContext *C = nullptr; DomTreeUpdater *DTU = nullptr; + TargetLibraryInfo *TLI = nullptr; AssumptionCache *AC = nullptr; const bool PreserveCFG; @@ -173,9 +175,9 @@ /// Helper used by both the public run method and by the legacy pass. PreservedAnalyses runImpl(Function &F, DomTreeUpdater &RunDTU, - AssumptionCache &RunAC); + TargetLibraryInfo &RunTLI, AssumptionCache &RunAC); PreservedAnalyses runImpl(Function &F, DominatorTree &RunDT, - AssumptionCache &RunAC); + TargetLibraryInfo &RunTLI, AssumptionCache &RunAC); bool presplitLoadsAndStores(AllocaInst &AI, sroa::AllocaSlices &AS); AllocaInst *rewritePartition(AllocaInst &AI, sroa::AllocaSlices &AS, Index: llvm/include/llvm/Analysis/MemoryBuiltins.h =================================================================== --- llvm/include/llvm/Analysis/MemoryBuiltins.h +++ llvm/include/llvm/Analysis/MemoryBuiltins.h @@ -119,8 +119,8 @@ }); /// If this is a call to an allocation function that initializes memory to a -/// fixed value, return said value in the requested type. Otherwise, return -/// nullptr. +/// fixed value, return said value in the requested type. If this is a call to +/// alloca instruction the returned value is undef. Otherwise, return nullptr. Constant *getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty); Index: clang/lib/CodeGen/CodeGenModule.h =================================================================== --- clang/lib/CodeGen/CodeGenModule.h +++ clang/lib/CodeGen/CodeGenModule.h @@ -33,6 +33,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Module.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Transforms/Utils/SanitizerStats.h" @@ -595,6 +596,10 @@ std::pair<std::unique_ptr<CodeGenFunction>, const TopLevelStmtDecl *> GlobalTopLevelStmtBlockInFlight; + // Used to generate TargetLibraryInfo objects for functions contained within + // this module. + std::optional<llvm::TargetLibraryInfoImpl> TLIImpl; + public: CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, const HeaderSearchOptions &headersearchopts, @@ -1550,6 +1555,9 @@ /// because we'll lose all important information after each repl. void moveLazyEmissionStates(CodeGenModule *NewBuilder); + /// Provide lazily-generated TLI object. + llvm::TargetLibraryInfo getTargetLibraryInfo(llvm::Function &F); + private: llvm::Constant *GetOrCreateLLVMFunction( StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable, Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -7485,3 +7485,9 @@ NewBuilder->ABI->MangleCtx = std::move(ABI->MangleCtx); } + +llvm::TargetLibraryInfo CodeGenModule::getTargetLibraryInfo(llvm::Function &F) { + if (!TLIImpl) + TLIImpl = llvm::TargetLibraryInfoImpl(getTriple()); + return llvm::TargetLibraryInfo(*TLIImpl, &F); +} Index: clang/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenFunction.cpp +++ clang/lib/CodeGen/CodeGenFunction.cpp @@ -35,6 +35,7 @@ #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" @@ -474,8 +475,9 @@ // difficult. if (NormalCleanupDest.isValid() && isCoroutine()) { llvm::DominatorTree DT(*CurFn); + auto TLI = CGM.getTargetLibraryInfo(*CurFn); llvm::PromoteMemToReg( - cast<llvm::AllocaInst>(NormalCleanupDest.getPointer()), DT); + cast<llvm::AllocaInst>(NormalCleanupDest.getPointer()), DT, &TLI); NormalCleanupDest = Address::invalid(); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits