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 &LTI = FAM.getResult<TargetLibraryAnalysis>(*NF);
     auto &AC = FAM.getResult<AssumptionAnalysis>(*NF);
-    PromoteMemToReg(Allocas, DT, &AC);
+    PromoteMemToReg(Allocas, DT, &LTI, &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

Reply via email to