diff options
Diffstat (limited to 'llvm/lib/Analysis')
| -rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 122 | 
1 files changed, 27 insertions, 95 deletions
| diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index e25eb290a66..914561f0f3f 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -231,13 +231,6 @@ static bool isNonVolatileLoad(const Instruction *I) {    return false;  } -static bool isNonVolatileStore(const Instruction *I) { -  if (const auto *SI = dyn_cast<StoreInst>(I)) -    return !SI->isVolatile(); - -  return false; -} -  static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,                                     const Function &F, BlockFrequencyInfo *BFI,                                     ProfileSummaryInfo *PSI, DominatorTree &DT, @@ -252,7 +245,7 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,    // Map from callee ValueId to profile count. Used to accumulate profile    // counts for all static calls to a given callee.    MapVector<ValueInfo, CalleeInfo> CallGraphEdges; -  SetVector<ValueInfo> RefEdges, LoadRefEdges, StoreRefEdges; +  SetVector<ValueInfo> RefEdges;    SetVector<GlobalValue::GUID> TypeTests;    SetVector<FunctionSummary::VFuncId> TypeTestAssumeVCalls,        TypeCheckedLoadVCalls; @@ -265,7 +258,6 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,    // list.    findRefEdges(Index, &F, RefEdges, Visited);    std::vector<const Instruction *> NonVolatileLoads; -  std::vector<const Instruction *> NonVolatileStores;    bool HasInlineAsmMaybeReferencingInternal = false;    for (const BasicBlock &BB : F) @@ -273,34 +265,12 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,        if (isa<DbgInfoIntrinsic>(I))          continue;        ++NumInsts; -      // Regular LTO module doesn't participate in ThinLTO import, -      // so no reference from it can be read/writeonly, since this -      // would require importing variable as local copy -      if (IsThinLTO) { -        if (isNonVolatileLoad(&I)) { -          // Postpone processing of non-volatile load instructions -          // See comments below -          Visited.insert(&I); -          NonVolatileLoads.push_back(&I); -          continue; -        } else if (isNonVolatileStore(&I)) { -          Visited.insert(&I); -          NonVolatileStores.push_back(&I); -          // All references from second operand of store (destination address) -          // can be considered write-only if they're not referenced by any -          // non-store instruction. References from first operand of store -          // (stored value) can't be treated either as read- or as write-only -          // so we add them to RefEdges as we do with all other instructions -          // except non-volatile load. -          Value *Stored = I.getOperand(0); -          if (auto *GV = dyn_cast<GlobalValue>(Stored)) -            // findRefEdges will try to examine GV operands, so instead -            // of calling it we should add GV to RefEdges directly. -            RefEdges.insert(Index.getOrInsertValueInfo(GV)); -          else if (auto *U = dyn_cast<User>(Stored)) -            findRefEdges(Index, U, RefEdges, Visited); -          continue; -        } +      if (isNonVolatileLoad(&I)) { +        // Postpone processing of non-volatile load instructions +        // See comments below +        Visited.insert(&I); +        NonVolatileLoads.push_back(&I); +        continue;        }        findRefEdges(Index, &I, RefEdges, Visited);        auto CS = ImmutableCallSite(&I); @@ -391,61 +361,24 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,        }      } -  std::vector<ValueInfo> Refs; -  if (IsThinLTO) { -    auto AddRefEdges = [&](const std::vector<const Instruction *> &Instrs, -                           SetVector<ValueInfo> &Edges, -                           SmallPtrSet<const User *, 8> &Cache) { -      for (const auto *I : Instrs) { -        Cache.erase(I); -        findRefEdges(Index, I, Edges, Cache); -      } -    }; - -    // By now we processed all instructions in a function, except -    // non-volatile loads and non-volatile value stores. Let's find -    // ref edges for both of instruction sets -    AddRefEdges(NonVolatileLoads, LoadRefEdges, Visited); -    // We can add some values to the Visited set when processing load -    // instructions which are also used by stores in NonVolatileStores. -    // For example this can happen if we have following code: -    // -    // store %Derived* @foo, %Derived** bitcast (%Base** @bar to %Derived**) -    // %42 = load %Derived*, %Derived** bitcast (%Base** @bar to %Derived**) -    // -    // After processing loads we'll add bitcast to the Visited set, and if -    // we use the same set while processing stores, we'll never see store -    // to @bar and @bar will be mistakenly treated as readonly. -    SmallPtrSet<const llvm::User *, 8> StoreCache; -    AddRefEdges(NonVolatileStores, StoreRefEdges, StoreCache); - -    // If both load and store instruction reference the same variable -    // we won't be able to optimize it. Add all such reference edges -    // to RefEdges set. -    for (auto &VI : StoreRefEdges) -      if (LoadRefEdges.remove(VI)) -        RefEdges.insert(VI); - -    unsigned RefCnt = RefEdges.size(); -    // All new reference edges inserted in two loops below are either -    // read or write only. They will be grouped in the end of RefEdges -    // vector, so we can use a single integer value to identify them. -    for (auto &VI : LoadRefEdges) -      RefEdges.insert(VI); - -    unsigned FirstWORef = RefEdges.size(); -    for (auto &VI : StoreRefEdges) -      RefEdges.insert(VI); - -    Refs = RefEdges.takeVector(); -    for (; RefCnt < FirstWORef; ++RefCnt) +  // By now we processed all instructions in a function, except +  // non-volatile loads. All new refs we add in a loop below +  // are obviously constant. All constant refs are grouped in the +  // end of RefEdges vector, so we can use a single integer value +  // to identify them. +  unsigned RefCnt = RefEdges.size(); +  for (const Instruction *I : NonVolatileLoads) { +    Visited.erase(I); +    findRefEdges(Index, I, RefEdges, Visited); +  } +  std::vector<ValueInfo> Refs = RefEdges.takeVector(); +  // Regular LTO module doesn't participate in ThinLTO import, +  // so no reference from it can be readonly, since this would +  // require importing variable as local copy +  if (IsThinLTO) +    for (; RefCnt < Refs.size(); ++RefCnt)        Refs[RefCnt].setReadOnly(); -    for (; RefCnt < Refs.size(); ++RefCnt) -      Refs[RefCnt].setWriteOnly(); -  } else { -    Refs = RefEdges.takeVector(); -  }    // Explicit add hot edges to enforce importing for designated GUIDs for    // sample PGO, to enable the same inlines as the profiled optimized binary.    for (auto &I : F.getImportGUIDs()) @@ -593,11 +526,10 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,      }    } -  // Don't mark variables we won't be able to internalize as read/write-only. -  bool CanBeInternalized = +  // Don't mark variables we won't be able to internalize as read-only. +  GlobalVarSummary::GVarFlags VarFlags(        !V.hasComdat() && !V.hasAppendingLinkage() && !V.isInterposable() && -      !V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass(); -  GlobalVarSummary::GVarFlags VarFlags(CanBeInternalized, CanBeInternalized); +      !V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass());    auto GVarSummary = llvm::make_unique<GlobalVarSummary>(Flags, VarFlags,                                                           RefEdges.takeVector());    if (NonRenamableLocal) @@ -715,7 +647,7 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(            } else {              std::unique_ptr<GlobalVarSummary> Summary =                  llvm::make_unique<GlobalVarSummary>( -                    GVFlags, GlobalVarSummary::GVarFlags(false, false), +                    GVFlags, GlobalVarSummary::GVarFlags(),                      ArrayRef<ValueInfo>{});              Index.addGlobalValueSummary(*GV, std::move(Summary));            } | 

