brintos

brintos / llvm-project-archived public Read only

0
0
Text · 153.4 KiB · 3b59ebb Raw
4170 lines · cpp
1//===- Attributor.cpp - Module-wide attribute deduction -------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements an interprocedural pass that deduces and/or propagates10// attributes. This is done in an abstract interpretation style fixpoint11// iteration. See the Attributor.h file comment and the class descriptions in12// that file for more information.13//14//===----------------------------------------------------------------------===//15 16#include "llvm/Transforms/IPO/Attributor.h"17 18#include "llvm/ADT/ArrayRef.h"19#include "llvm/ADT/PointerIntPair.h"20#include "llvm/ADT/STLExtras.h"21#include "llvm/ADT/SmallPtrSet.h"22#include "llvm/ADT/Statistic.h"23#include "llvm/Analysis/AliasAnalysis.h"24#include "llvm/Analysis/CallGraph.h"25#include "llvm/Analysis/InlineCost.h"26#include "llvm/Analysis/MemoryBuiltins.h"27#include "llvm/Analysis/MustExecute.h"28#include "llvm/IR/AttributeMask.h"29#include "llvm/IR/Attributes.h"30#include "llvm/IR/Constant.h"31#include "llvm/IR/ConstantFold.h"32#include "llvm/IR/Constants.h"33#include "llvm/IR/DataLayout.h"34#include "llvm/IR/GlobalValue.h"35#include "llvm/IR/GlobalVariable.h"36#include "llvm/IR/Instruction.h"37#include "llvm/IR/Instructions.h"38#include "llvm/IR/IntrinsicInst.h"39#include "llvm/IR/LLVMContext.h"40#include "llvm/IR/ValueHandle.h"41#include "llvm/Support/Casting.h"42#include "llvm/Support/CommandLine.h"43#include "llvm/Support/Debug.h"44#include "llvm/Support/DebugCounter.h"45#include "llvm/Support/FileSystem.h"46#include "llvm/Support/GraphWriter.h"47#include "llvm/Support/ModRef.h"48#include "llvm/Support/raw_ostream.h"49#include "llvm/Transforms/Utils/BasicBlockUtils.h"50#include "llvm/Transforms/Utils/Cloning.h"51#include "llvm/Transforms/Utils/Local.h"52#include <cstdint>53#include <memory>54 55#ifdef EXPENSIVE_CHECKS56#include "llvm/IR/Verifier.h"57#endif58 59#include <cassert>60#include <optional>61#include <string>62 63using namespace llvm;64 65#define DEBUG_TYPE "attributor"66#define VERBOSE_DEBUG_TYPE DEBUG_TYPE "-verbose"67 68DEBUG_COUNTER(ManifestDBGCounter, "attributor-manifest",69              "Determine what attributes are manifested in the IR");70 71STATISTIC(NumFnDeleted, "Number of function deleted");72STATISTIC(NumFnWithExactDefinition,73          "Number of functions with exact definitions");74STATISTIC(NumFnWithoutExactDefinition,75          "Number of functions without exact definitions");76STATISTIC(NumFnShallowWrappersCreated, "Number of shallow wrappers created");77STATISTIC(NumAttributesTimedOut,78          "Number of abstract attributes timed out before fixpoint");79STATISTIC(NumAttributesValidFixpoint,80          "Number of abstract attributes in a valid fixpoint state");81STATISTIC(NumAttributesManifested,82          "Number of abstract attributes manifested in IR");83 84// TODO: Determine a good default value.85//86// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads87// (when run with the first 5 abstract attributes). The results also indicate88// that we never reach 32 iterations but always find a fixpoint sooner.89//90// This will become more evolved once we perform two interleaved fixpoint91// iterations: bottom-up and top-down.92static cl::opt<unsigned>93    SetFixpointIterations("attributor-max-iterations", cl::Hidden,94                          cl::desc("Maximal number of fixpoint iterations."),95                          cl::init(32));96 97static cl::opt<unsigned>98    MaxSpecializationPerCB("attributor-max-specializations-per-call-base",99                           cl::Hidden,100                           cl::desc("Maximal number of callees specialized for "101                                    "a call base"),102                           cl::init(UINT32_MAX));103 104static cl::opt<unsigned, true> MaxInitializationChainLengthX(105    "attributor-max-initialization-chain-length", cl::Hidden,106    cl::desc(107        "Maximal number of chained initializations (to avoid stack overflows)"),108    cl::location(MaxInitializationChainLength), cl::init(1024));109unsigned llvm::MaxInitializationChainLength;110 111static cl::opt<bool> AnnotateDeclarationCallSites(112    "attributor-annotate-decl-cs", cl::Hidden,113    cl::desc("Annotate call sites of function declarations."), cl::init(false));114 115static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",116                                       cl::init(true), cl::Hidden);117 118static cl::opt<bool>119    AllowShallowWrappers("attributor-allow-shallow-wrappers", cl::Hidden,120                         cl::desc("Allow the Attributor to create shallow "121                                  "wrappers for non-exact definitions."),122                         cl::init(false));123 124static cl::opt<bool>125    AllowDeepWrapper("attributor-allow-deep-wrappers", cl::Hidden,126                     cl::desc("Allow the Attributor to use IP information "127                              "derived from non-exact functions via cloning"),128                     cl::init(false));129 130// These options can only used for debug builds.131#ifndef NDEBUG132static cl::list<std::string>133    SeedAllowList("attributor-seed-allow-list", cl::Hidden,134                  cl::desc("Comma separated list of attribute names that are "135                           "allowed to be seeded."),136                  cl::CommaSeparated);137 138static cl::list<std::string> FunctionSeedAllowList(139    "attributor-function-seed-allow-list", cl::Hidden,140    cl::desc("Comma separated list of function names that are "141             "allowed to be seeded."),142    cl::CommaSeparated);143#endif144 145static cl::opt<bool>146    DumpDepGraph("attributor-dump-dep-graph", cl::Hidden,147                 cl::desc("Dump the dependency graph to dot files."),148                 cl::init(false));149 150static cl::opt<std::string> DepGraphDotFileNamePrefix(151    "attributor-depgraph-dot-filename-prefix", cl::Hidden,152    cl::desc("The prefix used for the CallGraph dot file names."));153 154static cl::opt<bool> ViewDepGraph("attributor-view-dep-graph", cl::Hidden,155                                  cl::desc("View the dependency graph."),156                                  cl::init(false));157 158static cl::opt<bool> PrintDependencies("attributor-print-dep", cl::Hidden,159                                       cl::desc("Print attribute dependencies"),160                                       cl::init(false));161 162static cl::opt<bool> EnableCallSiteSpecific(163    "attributor-enable-call-site-specific-deduction", cl::Hidden,164    cl::desc("Allow the Attributor to do call site specific analysis"),165    cl::init(false));166 167static cl::opt<bool>168    PrintCallGraph("attributor-print-call-graph", cl::Hidden,169                   cl::desc("Print Attributor's internal call graph"),170                   cl::init(false));171 172static cl::opt<bool> SimplifyAllLoads("attributor-simplify-all-loads",173                                      cl::Hidden,174                                      cl::desc("Try to simplify all loads."),175                                      cl::init(true));176 177static cl::opt<bool> CloseWorldAssumption(178    "attributor-assume-closed-world", cl::Hidden,179    cl::desc("Should a closed world be assumed, or not. Default if not set."));180 181/// Logic operators for the change status enum class.182///183///{184ChangeStatus llvm::operator|(ChangeStatus L, ChangeStatus R) {185  return L == ChangeStatus::CHANGED ? L : R;186}187ChangeStatus &llvm::operator|=(ChangeStatus &L, ChangeStatus R) {188  L = L | R;189  return L;190}191ChangeStatus llvm::operator&(ChangeStatus L, ChangeStatus R) {192  return L == ChangeStatus::UNCHANGED ? L : R;193}194ChangeStatus &llvm::operator&=(ChangeStatus &L, ChangeStatus R) {195  L = L & R;196  return L;197}198///}199 200bool AA::isGPU(const Module &M) {201  Triple T(M.getTargetTriple());202  return T.isGPU();203}204 205bool AA::isNoSyncInst(Attributor &A, const Instruction &I,206                      const AbstractAttribute &QueryingAA) {207  // We are looking for volatile instructions or non-relaxed atomics.208  if (const auto *CB = dyn_cast<CallBase>(&I)) {209    if (CB->hasFnAttr(Attribute::NoSync))210      return true;211 212    // Non-convergent and readnone imply nosync.213    if (!CB->isConvergent() && !CB->mayReadOrWriteMemory())214      return true;215 216    if (AANoSync::isNoSyncIntrinsic(&I))217      return true;218 219    bool IsKnownNoSync;220    return AA::hasAssumedIRAttr<Attribute::NoSync>(221        A, &QueryingAA, IRPosition::callsite_function(*CB),222        DepClassTy::OPTIONAL, IsKnownNoSync);223  }224 225  if (!I.mayReadOrWriteMemory())226    return true;227 228  return !I.isVolatile() && !AANoSync::isNonRelaxedAtomic(&I);229}230 231bool AA::isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA,232                             const Value &V, bool ForAnalysisOnly) {233  // TODO: See the AAInstanceInfo class comment.234  if (!ForAnalysisOnly)235    return false;236  auto *InstanceInfoAA = A.getAAFor<AAInstanceInfo>(237      QueryingAA, IRPosition::value(V), DepClassTy::OPTIONAL);238  return InstanceInfoAA && InstanceInfoAA->isAssumedUniqueForAnalysis();239}240 241Constant *242AA::getInitialValueForObj(Attributor &A, const AbstractAttribute &QueryingAA,243                          Value &Obj, Type &Ty, const TargetLibraryInfo *TLI,244                          const DataLayout &DL, AA::RangeTy *RangePtr) {245  if (Constant *Init = getInitialValueOfAllocation(&Obj, TLI, &Ty))246    return Init;247  auto *GV = dyn_cast<GlobalVariable>(&Obj);248  if (!GV)249    return nullptr;250 251  bool UsedAssumedInformation = false;252  Constant *Initializer = nullptr;253  if (A.hasGlobalVariableSimplificationCallback(*GV)) {254    auto AssumedGV = A.getAssumedInitializerFromCallBack(255        *GV, &QueryingAA, UsedAssumedInformation);256    Initializer = *AssumedGV;257    if (!Initializer)258      return nullptr;259  } else {260    if (!GV->hasLocalLinkage()) {261      // Externally visible global that's either non-constant,262      // or a constant with an uncertain initializer.263      if (!GV->hasDefinitiveInitializer() || !GV->isConstant())264        return nullptr;265    }266 267    // Globals with local linkage are always initialized.268    assert(!GV->hasLocalLinkage() || GV->hasInitializer());269 270    if (!Initializer)271      Initializer = GV->getInitializer();272  }273 274  if (RangePtr && !RangePtr->offsetOrSizeAreUnknown()) {275    int64_t StorageSize = DL.getTypeStoreSize(&Ty);276    if (StorageSize != RangePtr->Size)277      return nullptr;278    APInt Offset = APInt(64, RangePtr->Offset);279    return ConstantFoldLoadFromConst(Initializer, &Ty, Offset, DL);280  }281 282  return ConstantFoldLoadFromUniformValue(Initializer, &Ty, DL);283}284 285bool AA::isValidInScope(const Value &V, const Function *Scope) {286  if (isa<Constant>(V))287    return true;288  if (auto *I = dyn_cast<Instruction>(&V))289    return I->getFunction() == Scope;290  if (auto *A = dyn_cast<Argument>(&V))291    return A->getParent() == Scope;292  return false;293}294 295bool AA::isValidAtPosition(const AA::ValueAndContext &VAC,296                           InformationCache &InfoCache) {297  if (isa<Constant>(VAC.getValue()) || VAC.getValue() == VAC.getCtxI())298    return true;299  const Function *Scope = nullptr;300  const Instruction *CtxI = VAC.getCtxI();301  if (CtxI)302    Scope = CtxI->getFunction();303  if (auto *A = dyn_cast<Argument>(VAC.getValue()))304    return A->getParent() == Scope;305  if (auto *I = dyn_cast<Instruction>(VAC.getValue())) {306    if (I->getFunction() == Scope) {307      if (const DominatorTree *DT =308              InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(309                  *Scope))310        return DT->dominates(I, CtxI);311      // Local dominance check mostly for the old PM passes.312      if (CtxI && I->getParent() == CtxI->getParent())313        return llvm::any_of(314            make_range(I->getIterator(), I->getParent()->end()),315            [&](const Instruction &AfterI) { return &AfterI == CtxI; });316    }317  }318  return false;319}320 321Value *AA::getWithType(Value &V, Type &Ty) {322  if (V.getType() == &Ty)323    return &V;324  if (isa<PoisonValue>(V))325    return PoisonValue::get(&Ty);326  if (isa<UndefValue>(V))327    return UndefValue::get(&Ty);328  if (auto *C = dyn_cast<Constant>(&V)) {329    if (C->isNullValue() && !Ty.isPtrOrPtrVectorTy())330      return Constant::getNullValue(&Ty);331    if (C->getType()->isPointerTy() && Ty.isPointerTy())332      return ConstantExpr::getPointerCast(C, &Ty);333    if (C->getType()->getPrimitiveSizeInBits() >= Ty.getPrimitiveSizeInBits()) {334      if (C->getType()->isIntegerTy() && Ty.isIntegerTy())335        return ConstantExpr::getTrunc(C, &Ty, /* OnlyIfReduced */ true);336      if (C->getType()->isFloatingPointTy() && Ty.isFloatingPointTy())337        return ConstantFoldCastInstruction(Instruction::FPTrunc, C, &Ty);338    }339  }340  return nullptr;341}342 343std::optional<Value *>344AA::combineOptionalValuesInAAValueLatice(const std::optional<Value *> &A,345                                         const std::optional<Value *> &B,346                                         Type *Ty) {347  if (A == B)348    return A;349  if (!B)350    return A;351  if (*B == nullptr)352    return nullptr;353  if (!A)354    return Ty ? getWithType(**B, *Ty) : nullptr;355  if (*A == nullptr)356    return nullptr;357  if (!Ty)358    Ty = (*A)->getType();359  if (isa_and_nonnull<UndefValue>(*A))360    return getWithType(**B, *Ty);361  if (isa<UndefValue>(*B))362    return A;363  if (*A && *B && *A == getWithType(**B, *Ty))364    return A;365  return nullptr;366}367 368template <bool IsLoad, typename Ty>369static bool getPotentialCopiesOfMemoryValue(370    Attributor &A, Ty &I, SmallSetVector<Value *, 4> &PotentialCopies,371    SmallSetVector<Instruction *, 4> *PotentialValueOrigins,372    const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,373    bool OnlyExact) {374  LLVM_DEBUG(dbgs() << "Trying to determine the potential copies of " << I375                    << " (only exact: " << OnlyExact << ")\n";);376 377  Value &Ptr = *I.getPointerOperand();378  // Containers to remember the pointer infos and new copies while we are not379  // sure that we can find all of them. If we abort we want to avoid spurious380  // dependences and potential copies in the provided container.381  SmallVector<const AAPointerInfo *> PIs;382  SmallSetVector<Value *, 8> NewCopies;383  SmallSetVector<Instruction *, 8> NewCopyOrigins;384 385  const auto *TLI =386      A.getInfoCache().getTargetLibraryInfoForFunction(*I.getFunction());387 388  auto Pred = [&](Value &Obj) {389    LLVM_DEBUG(dbgs() << "Visit underlying object " << Obj << "\n");390    if (isa<UndefValue>(&Obj))391      return true;392    if (isa<ConstantPointerNull>(&Obj)) {393      // A null pointer access can be undefined but any offset from null may394      // be OK. We do not try to optimize the latter.395      if (!NullPointerIsDefined(I.getFunction(),396                                Ptr.getType()->getPointerAddressSpace()) &&397          A.getAssumedSimplified(Ptr, QueryingAA, UsedAssumedInformation,398                                 AA::Interprocedural) == &Obj)399        return true;400      LLVM_DEBUG(401          dbgs() << "Underlying object is a valid nullptr, giving up.\n";);402      return false;403    }404    // TODO: Use assumed noalias return.405    if (!isa<AllocaInst>(&Obj) && !isa<GlobalVariable>(&Obj) &&406        !(IsLoad ? isAllocationFn(&Obj, TLI) : isNoAliasCall(&Obj))) {407      LLVM_DEBUG(dbgs() << "Underlying object is not supported yet: " << Obj408                        << "\n";);409      return false;410    }411    if (auto *GV = dyn_cast<GlobalVariable>(&Obj))412      if (!GV->hasLocalLinkage() &&413          !(GV->isConstant() && GV->hasInitializer())) {414        LLVM_DEBUG(dbgs() << "Underlying object is global with external "415                             "linkage, not supported yet: "416                          << Obj << "\n";);417        return false;418      }419 420    bool NullOnly = true;421    bool NullRequired = false;422    auto CheckForNullOnlyAndUndef = [&](std::optional<Value *> V,423                                        bool IsExact) {424      if (!V || *V == nullptr)425        NullOnly = false;426      else if (isa<UndefValue>(*V))427        /* No op */;428      else if (isa<Constant>(*V) && cast<Constant>(*V)->isNullValue())429        NullRequired = !IsExact;430      else431        NullOnly = false;432    };433 434    auto AdjustWrittenValueType = [&](const AAPointerInfo::Access &Acc,435                                      Value &V) {436      Value *AdjV = AA::getWithType(V, *I.getType());437      if (!AdjV) {438        LLVM_DEBUG(dbgs() << "Underlying object written but stored value "439                             "cannot be converted to read type: "440                          << *Acc.getRemoteInst() << " : " << *I.getType()441                          << "\n";);442      }443      return AdjV;444    };445 446    auto SkipCB = [&](const AAPointerInfo::Access &Acc) {447      if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))448        return true;449      if (IsLoad) {450        if (Acc.isWrittenValueYetUndetermined())451          return true;452        if (PotentialValueOrigins && !isa<AssumeInst>(Acc.getRemoteInst()))453          return false;454        if (!Acc.isWrittenValueUnknown())455          if (Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue()))456            if (NewCopies.count(V)) {457              NewCopyOrigins.insert(Acc.getRemoteInst());458              return true;459            }460        if (auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst()))461          if (Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand()))462            if (NewCopies.count(V)) {463              NewCopyOrigins.insert(Acc.getRemoteInst());464              return true;465            }466      }467      return false;468    };469 470    auto CheckAccess = [&](const AAPointerInfo::Access &Acc, bool IsExact) {471      if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))472        return true;473      if (IsLoad && Acc.isWrittenValueYetUndetermined())474        return true;475      CheckForNullOnlyAndUndef(Acc.getContent(), IsExact);476      if (OnlyExact && !IsExact && !NullOnly &&477          !isa_and_nonnull<UndefValue>(Acc.getWrittenValue())) {478        LLVM_DEBUG(dbgs() << "Non exact access " << *Acc.getRemoteInst()479                          << ", abort!\n");480        return false;481      }482      if (NullRequired && !NullOnly) {483        LLVM_DEBUG(dbgs() << "Required all `null` accesses due to non exact "484                             "one, however found non-null one: "485                          << *Acc.getRemoteInst() << ", abort!\n");486        return false;487      }488      if (IsLoad) {489        assert(isa<LoadInst>(I) && "Expected load or store instruction only!");490        if (!Acc.isWrittenValueUnknown()) {491          Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue());492          if (!V)493            return false;494          NewCopies.insert(V);495          if (PotentialValueOrigins)496            NewCopyOrigins.insert(Acc.getRemoteInst());497          return true;498        }499        auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst());500        if (!SI) {501          LLVM_DEBUG(dbgs() << "Underlying object written through a non-store "502                               "instruction not supported yet: "503                            << *Acc.getRemoteInst() << "\n";);504          return false;505        }506        Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand());507        if (!V)508          return false;509        NewCopies.insert(V);510        if (PotentialValueOrigins)511          NewCopyOrigins.insert(SI);512      } else {513        assert(isa<StoreInst>(I) && "Expected load or store instruction only!");514        auto *LI = dyn_cast<LoadInst>(Acc.getRemoteInst());515        if (!LI && OnlyExact) {516          LLVM_DEBUG(dbgs() << "Underlying object read through a non-load "517                               "instruction not supported yet: "518                            << *Acc.getRemoteInst() << "\n";);519          return false;520        }521        NewCopies.insert(Acc.getRemoteInst());522      }523      return true;524    };525 526    // If the value has been written to we don't need the initial value of the527    // object.528    bool HasBeenWrittenTo = false;529 530    AA::RangeTy Range;531    auto *PI = A.getAAFor<AAPointerInfo>(QueryingAA, IRPosition::value(Obj),532                                         DepClassTy::NONE);533    if (!PI || !PI->forallInterferingAccesses(534                   A, QueryingAA, I,535                   /* FindInterferingWrites */ IsLoad,536                   /* FindInterferingReads */ !IsLoad, CheckAccess,537                   HasBeenWrittenTo, Range, SkipCB)) {538      LLVM_DEBUG(539          dbgs()540          << "Failed to verify all interfering accesses for underlying object: "541          << Obj << "\n");542      return false;543    }544 545    if (IsLoad && !HasBeenWrittenTo && !Range.isUnassigned()) {546      const DataLayout &DL = A.getDataLayout();547      Value *InitialValue = AA::getInitialValueForObj(548          A, QueryingAA, Obj, *I.getType(), TLI, DL, &Range);549      if (!InitialValue) {550        LLVM_DEBUG(dbgs() << "Could not determine required initial value of "551                             "underlying object, abort!\n");552        return false;553      }554      CheckForNullOnlyAndUndef(InitialValue, /* IsExact */ true);555      if (NullRequired && !NullOnly) {556        LLVM_DEBUG(dbgs() << "Non exact access but initial value that is not "557                             "null or undef, abort!\n");558        return false;559      }560 561      NewCopies.insert(InitialValue);562      if (PotentialValueOrigins)563        NewCopyOrigins.insert(nullptr);564    }565 566    PIs.push_back(PI);567 568    return true;569  };570 571  const auto *AAUO = A.getAAFor<AAUnderlyingObjects>(572      QueryingAA, IRPosition::value(Ptr), DepClassTy::OPTIONAL);573  if (!AAUO || !AAUO->forallUnderlyingObjects(Pred)) {574    LLVM_DEBUG(575        dbgs() << "Underlying objects stored into could not be determined\n";);576    return false;577  }578 579  // Only if we were successful collection all potential copies we record580  // dependences (on non-fix AAPointerInfo AAs). We also only then modify the581  // given PotentialCopies container.582  for (const auto *PI : PIs) {583    if (!PI->getState().isAtFixpoint())584      UsedAssumedInformation = true;585    A.recordDependence(*PI, QueryingAA, DepClassTy::OPTIONAL);586  }587  PotentialCopies.insert_range(NewCopies);588  if (PotentialValueOrigins)589    PotentialValueOrigins->insert_range(NewCopyOrigins);590 591  return true;592}593 594bool AA::getPotentiallyLoadedValues(595    Attributor &A, LoadInst &LI, SmallSetVector<Value *, 4> &PotentialValues,596    SmallSetVector<Instruction *, 4> &PotentialValueOrigins,597    const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,598    bool OnlyExact) {599  return getPotentialCopiesOfMemoryValue</* IsLoad */ true>(600      A, LI, PotentialValues, &PotentialValueOrigins, QueryingAA,601      UsedAssumedInformation, OnlyExact);602}603 604bool AA::getPotentialCopiesOfStoredValue(605    Attributor &A, StoreInst &SI, SmallSetVector<Value *, 4> &PotentialCopies,606    const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,607    bool OnlyExact) {608  return getPotentialCopiesOfMemoryValue</* IsLoad */ false>(609      A, SI, PotentialCopies, nullptr, QueryingAA, UsedAssumedInformation,610      OnlyExact);611}612 613static bool isAssumedReadOnlyOrReadNone(Attributor &A, const IRPosition &IRP,614                                        const AbstractAttribute &QueryingAA,615                                        bool RequireReadNone, bool &IsKnown) {616  if (RequireReadNone) {617    if (AA::hasAssumedIRAttr<Attribute::ReadNone>(618            A, &QueryingAA, IRP, DepClassTy::OPTIONAL, IsKnown,619            /* IgnoreSubsumingPositions */ true))620      return true;621  } else if (AA::hasAssumedIRAttr<Attribute::ReadOnly>(622                 A, &QueryingAA, IRP, DepClassTy::OPTIONAL, IsKnown,623                 /* IgnoreSubsumingPositions */ true))624    return true;625 626  IRPosition::Kind Kind = IRP.getPositionKind();627  if (Kind == IRPosition::IRP_FUNCTION || Kind == IRPosition::IRP_CALL_SITE) {628    const auto *MemLocAA =629        A.getAAFor<AAMemoryLocation>(QueryingAA, IRP, DepClassTy::NONE);630    if (MemLocAA && MemLocAA->isAssumedReadNone()) {631      IsKnown = MemLocAA->isKnownReadNone();632      if (!IsKnown)633        A.recordDependence(*MemLocAA, QueryingAA, DepClassTy::OPTIONAL);634      return true;635    }636  }637 638  const auto *MemBehaviorAA =639      A.getAAFor<AAMemoryBehavior>(QueryingAA, IRP, DepClassTy::NONE);640  if (MemBehaviorAA &&641      (MemBehaviorAA->isAssumedReadNone() ||642       (!RequireReadNone && MemBehaviorAA->isAssumedReadOnly()))) {643    IsKnown = RequireReadNone ? MemBehaviorAA->isKnownReadNone()644                              : MemBehaviorAA->isKnownReadOnly();645    if (!IsKnown)646      A.recordDependence(*MemBehaviorAA, QueryingAA, DepClassTy::OPTIONAL);647    return true;648  }649 650  return false;651}652 653bool AA::isAssumedReadOnly(Attributor &A, const IRPosition &IRP,654                           const AbstractAttribute &QueryingAA, bool &IsKnown) {655  return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,656                                     /* RequireReadNone */ false, IsKnown);657}658bool AA::isAssumedReadNone(Attributor &A, const IRPosition &IRP,659                           const AbstractAttribute &QueryingAA, bool &IsKnown) {660  return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,661                                     /* RequireReadNone */ true, IsKnown);662}663 664static bool665isPotentiallyReachable(Attributor &A, const Instruction &FromI,666                       const Instruction *ToI, const Function &ToFn,667                       const AbstractAttribute &QueryingAA,668                       const AA::InstExclusionSetTy *ExclusionSet,669                       std::function<bool(const Function &F)> GoBackwardsCB) {670  DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, {671    dbgs() << "[AA] isPotentiallyReachable @" << ToFn.getName() << " from "672           << FromI << " [GBCB: " << bool(GoBackwardsCB) << "][#ExS: "673           << (ExclusionSet ? std::to_string(ExclusionSet->size()) : "none")674           << "]\n";675    if (ExclusionSet)676      for (auto *ES : *ExclusionSet)677        dbgs() << *ES << "\n";678  });679 680  // We know kernels (generally) cannot be called from within the module. Thus,681  // for reachability we would need to step back from a kernel which would allow682  // us to reach anything anyway. Even if a kernel is invoked from another683  // kernel, values like allocas and shared memory are not accessible. We684  // implicitly check for this situation to avoid costly lookups.685  if (GoBackwardsCB && &ToFn != FromI.getFunction() &&686      !GoBackwardsCB(*FromI.getFunction()) && A.getInfoCache().isKernel(ToFn) &&687      A.getInfoCache().isKernel(*FromI.getFunction())) {688    LLVM_DEBUG(dbgs() << "[AA] assume kernel cannot be reached from within the "689                         "module; success\n";);690    return false;691  }692 693  // If we can go arbitrarily backwards we will eventually reach an entry point694  // that can reach ToI. Only if a set of blocks through which we cannot go is695  // provided, or once we track internal functions not accessible from the696  // outside, it makes sense to perform backwards analysis in the absence of a697  // GoBackwardsCB.698  if (!GoBackwardsCB && !ExclusionSet) {699    LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI700                      << " is not checked backwards and does not have an "701                         "exclusion set, abort\n");702    return true;703  }704 705  SmallPtrSet<const Instruction *, 8> Visited;706  SmallVector<const Instruction *> Worklist;707  Worklist.push_back(&FromI);708 709  while (!Worklist.empty()) {710    const Instruction *CurFromI = Worklist.pop_back_val();711    if (!Visited.insert(CurFromI).second)712      continue;713 714    const Function *FromFn = CurFromI->getFunction();715    if (FromFn == &ToFn) {716      if (!ToI)717        return true;718      LLVM_DEBUG(dbgs() << "[AA] check " << *ToI << " from " << *CurFromI719                        << " intraprocedurally\n");720      const auto *ReachabilityAA = A.getAAFor<AAIntraFnReachability>(721          QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);722      bool Result = !ReachabilityAA || ReachabilityAA->isAssumedReachable(723                                           A, *CurFromI, *ToI, ExclusionSet);724      LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " "725                        << (Result ? "can potentially " : "cannot ") << "reach "726                        << *ToI << " [Intra]\n");727      if (Result)728        return true;729    }730 731    bool Result = true;732    if (!ToFn.isDeclaration() && ToI) {733      const auto *ToReachabilityAA = A.getAAFor<AAIntraFnReachability>(734          QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);735      const Instruction &EntryI = ToFn.getEntryBlock().front();736      Result = !ToReachabilityAA || ToReachabilityAA->isAssumedReachable(737                                        A, EntryI, *ToI, ExclusionSet);738      LLVM_DEBUG(dbgs() << "[AA] Entry " << EntryI << " of @" << ToFn.getName()739                        << " " << (Result ? "can potentially " : "cannot ")740                        << "reach @" << *ToI << " [ToFn]\n");741    }742 743    if (Result) {744      // The entry of the ToFn can reach the instruction ToI. If the current745      // instruction is already known to reach the ToFn.746      const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(747          QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);748      Result = !FnReachabilityAA || FnReachabilityAA->instructionCanReach(749                                        A, *CurFromI, ToFn, ExclusionSet);750      LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " in @" << FromFn->getName()751                        << " " << (Result ? "can potentially " : "cannot ")752                        << "reach @" << ToFn.getName() << " [FromFn]\n");753      if (Result)754        return true;755    }756 757    // TODO: Check assumed nounwind.758    const auto *ReachabilityAA = A.getAAFor<AAIntraFnReachability>(759        QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);760    auto ReturnInstCB = [&](Instruction &Ret) {761      bool Result = !ReachabilityAA || ReachabilityAA->isAssumedReachable(762                                           A, *CurFromI, Ret, ExclusionSet);763      LLVM_DEBUG(dbgs() << "[AA][Ret] " << *CurFromI << " "764                        << (Result ? "can potentially " : "cannot ") << "reach "765                        << Ret << " [Intra]\n");766      return !Result;767    };768 769    // Check if we can reach returns.770    bool UsedAssumedInformation = false;771    if (A.checkForAllInstructions(ReturnInstCB, FromFn, &QueryingAA,772                                  {Instruction::Ret}, UsedAssumedInformation)) {773      LLVM_DEBUG(dbgs() << "[AA] No return is reachable, done\n");774      continue;775    }776 777    if (!GoBackwardsCB) {778      LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI779                        << " is not checked backwards, abort\n");780      return true;781    }782 783    // If we do not go backwards from the FromFn we are done here and so far we784    // could not find a way to reach ToFn/ToI.785    if (!GoBackwardsCB(*FromFn))786      continue;787 788    LLVM_DEBUG(dbgs() << "Stepping backwards to the call sites of @"789                      << FromFn->getName() << "\n");790 791    auto CheckCallSite = [&](AbstractCallSite ACS) {792      CallBase *CB = ACS.getInstruction();793      if (!CB)794        return false;795 796      if (isa<InvokeInst>(CB))797        return false;798 799      Instruction *Inst = CB->getNextNode();800      Worklist.push_back(Inst);801      return true;802    };803 804    Result = !A.checkForAllCallSites(CheckCallSite, *FromFn,805                                     /* RequireAllCallSites */ true,806                                     &QueryingAA, UsedAssumedInformation);807    if (Result) {808      LLVM_DEBUG(dbgs() << "[AA] stepping back to call sites from " << *CurFromI809                        << " in @" << FromFn->getName()810                        << " failed, give up\n");811      return true;812    }813 814    LLVM_DEBUG(dbgs() << "[AA] stepped back to call sites from " << *CurFromI815                      << " in @" << FromFn->getName()816                      << " worklist size is: " << Worklist.size() << "\n");817  }818  return false;819}820 821bool AA::isPotentiallyReachable(822    Attributor &A, const Instruction &FromI, const Instruction &ToI,823    const AbstractAttribute &QueryingAA,824    const AA::InstExclusionSetTy *ExclusionSet,825    std::function<bool(const Function &F)> GoBackwardsCB) {826  const Function *ToFn = ToI.getFunction();827  return ::isPotentiallyReachable(A, FromI, &ToI, *ToFn, QueryingAA,828                                  ExclusionSet, GoBackwardsCB);829}830 831bool AA::isPotentiallyReachable(832    Attributor &A, const Instruction &FromI, const Function &ToFn,833    const AbstractAttribute &QueryingAA,834    const AA::InstExclusionSetTy *ExclusionSet,835    std::function<bool(const Function &F)> GoBackwardsCB) {836  return ::isPotentiallyReachable(A, FromI, /* ToI */ nullptr, ToFn, QueryingAA,837                                  ExclusionSet, GoBackwardsCB);838}839 840bool AA::isAssumedThreadLocalObject(Attributor &A, Value &Obj,841                                    const AbstractAttribute &QueryingAA) {842  if (isa<UndefValue>(Obj))843    return true;844  if (isa<AllocaInst>(Obj)) {845    InformationCache &InfoCache = A.getInfoCache();846    if (!InfoCache.stackIsAccessibleByOtherThreads()) {847      LLVM_DEBUG(848          dbgs() << "[AA] Object '" << Obj849                 << "' is thread local; stack objects are thread local.\n");850      return true;851    }852    bool IsKnownNoCapture;853    bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(854        A, &QueryingAA, IRPosition::value(Obj), DepClassTy::OPTIONAL,855        IsKnownNoCapture);856    LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj << "' is "857                      << (IsAssumedNoCapture ? "" : "not") << " thread local; "858                      << (IsAssumedNoCapture ? "non-" : "")859                      << "captured stack object.\n");860    return IsAssumedNoCapture;861  }862  if (auto *GV = dyn_cast<GlobalVariable>(&Obj)) {863    if (GV->isConstant()) {864      LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj865                        << "' is thread local; constant global\n");866      return true;867    }868    if (GV->isThreadLocal()) {869      LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj870                        << "' is thread local; thread local global\n");871      return true;872    }873  }874 875  if (A.getInfoCache().targetIsGPU()) {876    if (Obj.getType()->getPointerAddressSpace() ==877        (int)AA::GPUAddressSpace::Local) {878      LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj879                        << "' is thread local; GPU local memory\n");880      return true;881    }882    if (Obj.getType()->getPointerAddressSpace() ==883        (int)AA::GPUAddressSpace::Constant) {884      LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj885                        << "' is thread local; GPU constant memory\n");886      return true;887    }888  }889 890  LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj << "' is not thread local\n");891  return false;892}893 894bool AA::isPotentiallyAffectedByBarrier(Attributor &A, const Instruction &I,895                                        const AbstractAttribute &QueryingAA) {896  if (!I.mayHaveSideEffects() && !I.mayReadFromMemory())897    return false;898 899  SmallSetVector<const Value *, 8> Ptrs;900 901  auto AddLocationPtr = [&](std::optional<MemoryLocation> Loc) {902    if (!Loc || !Loc->Ptr) {903      LLVM_DEBUG(904          dbgs() << "[AA] Access to unknown location; -> requires barriers\n");905      return false;906    }907    Ptrs.insert(Loc->Ptr);908    return true;909  };910 911  if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&I)) {912    if (!AddLocationPtr(MemoryLocation::getForDest(MI)))913      return true;914    if (const MemTransferInst *MTI = dyn_cast<MemTransferInst>(&I))915      if (!AddLocationPtr(MemoryLocation::getForSource(MTI)))916        return true;917  } else if (!AddLocationPtr(MemoryLocation::getOrNone(&I)))918    return true;919 920  return isPotentiallyAffectedByBarrier(A, Ptrs.getArrayRef(), QueryingAA, &I);921}922 923bool AA::isPotentiallyAffectedByBarrier(Attributor &A,924                                        ArrayRef<const Value *> Ptrs,925                                        const AbstractAttribute &QueryingAA,926                                        const Instruction *CtxI) {927  for (const Value *Ptr : Ptrs) {928    if (!Ptr) {929      LLVM_DEBUG(dbgs() << "[AA] nullptr; -> requires barriers\n");930      return true;931    }932 933    auto Pred = [&](Value &Obj) {934      if (AA::isAssumedThreadLocalObject(A, Obj, QueryingAA))935        return true;936      LLVM_DEBUG(dbgs() << "[AA] Access to '" << Obj << "' via '" << *Ptr937                        << "'; -> requires barrier\n");938      return false;939    };940 941    const auto *UnderlyingObjsAA = A.getAAFor<AAUnderlyingObjects>(942        QueryingAA, IRPosition::value(*Ptr), DepClassTy::OPTIONAL);943    if (!UnderlyingObjsAA || !UnderlyingObjsAA->forallUnderlyingObjects(Pred))944      return true;945  }946  return false;947}948 949/// Return true if \p New is equal or worse than \p Old.950static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {951  if (!Old.isIntAttribute())952    return true;953 954  return Old.getValueAsInt() >= New.getValueAsInt();955}956 957/// Return true if the information provided by \p Attr was added to the958/// attribute set \p AttrSet. This is only the case if it was not already959/// present in \p AttrSet.960static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,961                             AttributeSet AttrSet, bool ForceReplace,962                             AttrBuilder &AB) {963 964  if (Attr.isEnumAttribute()) {965    Attribute::AttrKind Kind = Attr.getKindAsEnum();966    if (AttrSet.hasAttribute(Kind))967      return false;968    AB.addAttribute(Kind);969    return true;970  }971  if (Attr.isStringAttribute()) {972    StringRef Kind = Attr.getKindAsString();973    if (AttrSet.hasAttribute(Kind)) {974      if (!ForceReplace)975        return false;976    }977    AB.addAttribute(Kind, Attr.getValueAsString());978    return true;979  }980  if (Attr.isIntAttribute()) {981    Attribute::AttrKind Kind = Attr.getKindAsEnum();982    if (!ForceReplace && Kind == Attribute::Memory) {983      MemoryEffects ME = Attr.getMemoryEffects() & AttrSet.getMemoryEffects();984      if (ME == AttrSet.getMemoryEffects())985        return false;986      AB.addMemoryAttr(ME);987      return true;988    }989    if (AttrSet.hasAttribute(Kind)) {990      if (!ForceReplace && isEqualOrWorse(Attr, AttrSet.getAttribute(Kind)))991        return false;992    }993    AB.addAttribute(Attr);994    return true;995  }996  if (Attr.isConstantRangeAttribute()) {997    Attribute::AttrKind Kind = Attr.getKindAsEnum();998    if (!ForceReplace && AttrSet.hasAttribute(Kind))999      return false;1000    AB.addAttribute(Attr);1001    return true;1002  }1003 1004  llvm_unreachable("Expected enum or string attribute!");1005}1006 1007Argument *IRPosition::getAssociatedArgument() const {1008  if (getPositionKind() == IRP_ARGUMENT)1009    return cast<Argument>(&getAnchorValue());1010 1011  // Not an Argument and no argument number means this is not a call site1012  // argument, thus we cannot find a callback argument to return.1013  int ArgNo = getCallSiteArgNo();1014  if (ArgNo < 0)1015    return nullptr;1016 1017  // Use abstract call sites to make the connection between the call site1018  // values and the ones in callbacks. If a callback was found that makes use1019  // of the underlying call site operand, we want the corresponding callback1020  // callee argument and not the direct callee argument.1021  std::optional<Argument *> CBCandidateArg;1022  SmallVector<const Use *, 4> CallbackUses;1023  const auto &CB = cast<CallBase>(getAnchorValue());1024  AbstractCallSite::getCallbackUses(CB, CallbackUses);1025  for (const Use *U : CallbackUses) {1026    AbstractCallSite ACS(U);1027    assert(ACS && ACS.isCallbackCall());1028    if (!ACS.getCalledFunction())1029      continue;1030 1031    for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {1032 1033      // Test if the underlying call site operand is argument number u of the1034      // callback callee.1035      if (ACS.getCallArgOperandNo(u) != ArgNo)1036        continue;1037 1038      assert(ACS.getCalledFunction()->arg_size() > u &&1039             "ACS mapped into var-args arguments!");1040      if (CBCandidateArg) {1041        CBCandidateArg = nullptr;1042        break;1043      }1044      CBCandidateArg = ACS.getCalledFunction()->getArg(u);1045    }1046  }1047 1048  // If we found a unique callback candidate argument, return it.1049  if (CBCandidateArg && *CBCandidateArg)1050    return *CBCandidateArg;1051 1052  // If no callbacks were found, or none used the underlying call site operand1053  // exclusively, use the direct callee argument if available.1054  auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());1055  if (Callee && Callee->arg_size() > unsigned(ArgNo))1056    return Callee->getArg(ArgNo);1057 1058  return nullptr;1059}1060 1061ChangeStatus AbstractAttribute::update(Attributor &A) {1062  ChangeStatus HasChanged = ChangeStatus::UNCHANGED;1063  if (getState().isAtFixpoint())1064    return HasChanged;1065 1066  LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");1067 1068  HasChanged = updateImpl(A);1069 1070  LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this1071                    << "\n");1072 1073  return HasChanged;1074}1075 1076Attributor::Attributor(SetVector<Function *> &Functions,1077                       InformationCache &InfoCache,1078                       AttributorConfig Configuration)1079    : Allocator(InfoCache.Allocator), Functions(Functions),1080      InfoCache(InfoCache), Configuration(Configuration) {1081  if (!isClosedWorldModule())1082    return;1083  for (Function *Fn : Functions)1084    if (Fn->hasAddressTaken(/*PutOffender=*/nullptr,1085                            /*IgnoreCallbackUses=*/false,1086                            /*IgnoreAssumeLikeCalls=*/true,1087                            /*IgnoreLLVMUsed=*/true,1088                            /*IgnoreARCAttachedCall=*/false,1089                            /*IgnoreCastedDirectCall=*/true))1090      InfoCache.IndirectlyCallableFunctions.push_back(Fn);1091}1092 1093bool Attributor::getAttrsFromAssumes(const IRPosition &IRP,1094                                     Attribute::AttrKind AK,1095                                     SmallVectorImpl<Attribute> &Attrs) {1096  assert(IRP.getPositionKind() != IRPosition::IRP_INVALID &&1097         "Did expect a valid position!");1098  MustBeExecutedContextExplorer *Explorer =1099      getInfoCache().getMustBeExecutedContextExplorer();1100  if (!Explorer)1101    return false;1102 1103  Value &AssociatedValue = IRP.getAssociatedValue();1104 1105  const Assume2KnowledgeMap &A2K =1106      getInfoCache().getKnowledgeMap().lookup({&AssociatedValue, AK});1107 1108  // Check if we found any potential assume use, if not we don't need to create1109  // explorer iterators.1110  if (A2K.empty())1111    return false;1112 1113  LLVMContext &Ctx = AssociatedValue.getContext();1114  unsigned AttrsSize = Attrs.size();1115  auto EIt = Explorer->begin(IRP.getCtxI()),1116       EEnd = Explorer->end(IRP.getCtxI());1117  for (const auto &It : A2K)1118    if (Explorer->findInContextOf(It.first, EIt, EEnd))1119      Attrs.push_back(Attribute::get(Ctx, AK, It.second.Max));1120  return AttrsSize != Attrs.size();1121}1122 1123template <typename DescTy>1124ChangeStatus1125Attributor::updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,1126                          function_ref<bool(const DescTy &, AttributeSet,1127                                            AttributeMask &, AttrBuilder &)>1128                              CB) {1129  if (AttrDescs.empty())1130    return ChangeStatus::UNCHANGED;1131  switch (IRP.getPositionKind()) {1132  case IRPosition::IRP_FLOAT:1133  case IRPosition::IRP_INVALID:1134    return ChangeStatus::UNCHANGED;1135  default:1136    break;1137  };1138 1139  AttributeList AL;1140  Value *AttrListAnchor = IRP.getAttrListAnchor();1141  auto It = AttrsMap.find(AttrListAnchor);1142  if (It == AttrsMap.end())1143    AL = IRP.getAttrList();1144  else1145    AL = It->getSecond();1146 1147  LLVMContext &Ctx = IRP.getAnchorValue().getContext();1148  auto AttrIdx = IRP.getAttrIdx();1149  AttributeSet AS = AL.getAttributes(AttrIdx);1150  AttributeMask AM;1151  AttrBuilder AB(Ctx);1152 1153  ChangeStatus HasChanged = ChangeStatus::UNCHANGED;1154  for (const DescTy &AttrDesc : AttrDescs)1155    if (CB(AttrDesc, AS, AM, AB))1156      HasChanged = ChangeStatus::CHANGED;1157 1158  if (HasChanged == ChangeStatus::UNCHANGED)1159    return ChangeStatus::UNCHANGED;1160 1161  AL = AL.removeAttributesAtIndex(Ctx, AttrIdx, AM);1162  AL = AL.addAttributesAtIndex(Ctx, AttrIdx, AB);1163  AttrsMap[AttrListAnchor] = AL;1164  return ChangeStatus::CHANGED;1165}1166 1167bool Attributor::hasAttr(const IRPosition &IRP,1168                         ArrayRef<Attribute::AttrKind> AttrKinds,1169                         bool IgnoreSubsumingPositions,1170                         Attribute::AttrKind ImpliedAttributeKind) {1171  bool Implied = false;1172  bool HasAttr = false;1173  auto HasAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,1174                       AttributeMask &, AttrBuilder &) {1175    if (AttrSet.hasAttribute(Kind)) {1176      Implied |= Kind != ImpliedAttributeKind;1177      HasAttr = true;1178    }1179    return false;1180  };1181  for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {1182    updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, HasAttrCB);1183    if (HasAttr)1184      break;1185    // The first position returned by the SubsumingPositionIterator is1186    // always the position itself. If we ignore subsuming positions we1187    // are done after the first iteration.1188    if (IgnoreSubsumingPositions)1189      break;1190    Implied = true;1191  }1192  if (!HasAttr) {1193    Implied = true;1194    SmallVector<Attribute> Attrs;1195    for (Attribute::AttrKind AK : AttrKinds)1196      if (getAttrsFromAssumes(IRP, AK, Attrs)) {1197        HasAttr = true;1198        break;1199      }1200  }1201 1202  // Check if we should manifest the implied attribute kind at the IRP.1203  if (ImpliedAttributeKind != Attribute::None && HasAttr && Implied)1204    manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),1205                                       ImpliedAttributeKind)});1206  return HasAttr;1207}1208 1209void Attributor::getAttrs(const IRPosition &IRP,1210                          ArrayRef<Attribute::AttrKind> AttrKinds,1211                          SmallVectorImpl<Attribute> &Attrs,1212                          bool IgnoreSubsumingPositions) {1213  auto CollectAttrCB = [&](const Attribute::AttrKind &Kind,1214                           AttributeSet AttrSet, AttributeMask &,1215                           AttrBuilder &) {1216    if (AttrSet.hasAttribute(Kind))1217      Attrs.push_back(AttrSet.getAttribute(Kind));1218    return false;1219  };1220  for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {1221    updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, CollectAttrCB);1222    // The first position returned by the SubsumingPositionIterator is1223    // always the position itself. If we ignore subsuming positions we1224    // are done after the first iteration.1225    if (IgnoreSubsumingPositions)1226      break;1227  }1228  for (Attribute::AttrKind AK : AttrKinds)1229    getAttrsFromAssumes(IRP, AK, Attrs);1230}1231 1232ChangeStatus Attributor::removeAttrs(const IRPosition &IRP,1233                                     ArrayRef<Attribute::AttrKind> AttrKinds) {1234  auto RemoveAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,1235                          AttributeMask &AM, AttrBuilder &) {1236    if (!AttrSet.hasAttribute(Kind))1237      return false;1238    AM.addAttribute(Kind);1239    return true;1240  };1241  return updateAttrMap<Attribute::AttrKind>(IRP, AttrKinds, RemoveAttrCB);1242}1243 1244ChangeStatus Attributor::removeAttrs(const IRPosition &IRP,1245                                     ArrayRef<StringRef> Attrs) {1246  auto RemoveAttrCB = [&](StringRef Attr, AttributeSet AttrSet,1247                          AttributeMask &AM, AttrBuilder &) -> bool {1248    if (!AttrSet.hasAttribute(Attr))1249      return false;1250    AM.addAttribute(Attr);1251    return true;1252  };1253 1254  return updateAttrMap<StringRef>(IRP, Attrs, RemoveAttrCB);1255}1256 1257ChangeStatus Attributor::manifestAttrs(const IRPosition &IRP,1258                                       ArrayRef<Attribute> Attrs,1259                                       bool ForceReplace) {1260  LLVMContext &Ctx = IRP.getAnchorValue().getContext();1261  auto AddAttrCB = [&](const Attribute &Attr, AttributeSet AttrSet,1262                       AttributeMask &, AttrBuilder &AB) {1263    return addIfNotExistent(Ctx, Attr, AttrSet, ForceReplace, AB);1264  };1265  return updateAttrMap<Attribute>(IRP, Attrs, AddAttrCB);1266}1267 1268const IRPosition IRPosition::EmptyKey(DenseMapInfo<void *>::getEmptyKey());1269const IRPosition1270    IRPosition::TombstoneKey(DenseMapInfo<void *>::getTombstoneKey());1271 1272SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {1273  IRPositions.emplace_back(IRP);1274 1275  // Helper to determine if operand bundles on a call site are benign or1276  // potentially problematic. We handle only llvm.assume for now.1277  auto CanIgnoreOperandBundles = [](const CallBase &CB) {1278    return (isa<IntrinsicInst>(CB) &&1279            cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);1280  };1281 1282  const auto *CB = dyn_cast<CallBase>(&IRP.getAnchorValue());1283  switch (IRP.getPositionKind()) {1284  case IRPosition::IRP_INVALID:1285  case IRPosition::IRP_FLOAT:1286  case IRPosition::IRP_FUNCTION:1287    return;1288  case IRPosition::IRP_ARGUMENT:1289  case IRPosition::IRP_RETURNED:1290    IRPositions.emplace_back(IRPosition::function(*IRP.getAnchorScope()));1291    return;1292  case IRPosition::IRP_CALL_SITE:1293    assert(CB && "Expected call site!");1294    // TODO: We need to look at the operand bundles similar to the redirection1295    //       in CallBase.1296    if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))1297      if (auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand()))1298        IRPositions.emplace_back(IRPosition::function(*Callee));1299    return;1300  case IRPosition::IRP_CALL_SITE_RETURNED:1301    assert(CB && "Expected call site!");1302    // TODO: We need to look at the operand bundles similar to the redirection1303    //       in CallBase.1304    if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {1305      if (auto *Callee =1306              dyn_cast_if_present<Function>(CB->getCalledOperand())) {1307        IRPositions.emplace_back(IRPosition::returned(*Callee));1308        IRPositions.emplace_back(IRPosition::function(*Callee));1309        for (const Argument &Arg : Callee->args())1310          if (Arg.hasReturnedAttr()) {1311            IRPositions.emplace_back(1312                IRPosition::callsite_argument(*CB, Arg.getArgNo()));1313            IRPositions.emplace_back(1314                IRPosition::value(*CB->getArgOperand(Arg.getArgNo())));1315            IRPositions.emplace_back(IRPosition::argument(Arg));1316          }1317      }1318    }1319    IRPositions.emplace_back(IRPosition::callsite_function(*CB));1320    return;1321  case IRPosition::IRP_CALL_SITE_ARGUMENT: {1322    assert(CB && "Expected call site!");1323    // TODO: We need to look at the operand bundles similar to the redirection1324    //       in CallBase.1325    if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {1326      auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());1327      if (Callee) {1328        if (Argument *Arg = IRP.getAssociatedArgument())1329          IRPositions.emplace_back(IRPosition::argument(*Arg));1330        IRPositions.emplace_back(IRPosition::function(*Callee));1331      }1332    }1333    IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));1334    return;1335  }1336  }1337}1338 1339void IRPosition::verify() {1340#ifdef EXPENSIVE_CHECKS1341  switch (getPositionKind()) {1342  case IRP_INVALID:1343    assert((CBContext == nullptr) &&1344           "Invalid position must not have CallBaseContext!");1345    assert(!Enc.getOpaqueValue() &&1346           "Expected a nullptr for an invalid position!");1347    return;1348  case IRP_FLOAT:1349    assert((!isa<Argument>(&getAssociatedValue())) &&1350           "Expected specialized kind for argument values!");1351    return;1352  case IRP_RETURNED:1353    assert(isa<Function>(getAsValuePtr()) &&1354           "Expected function for a 'returned' position!");1355    assert(getAsValuePtr() == &getAssociatedValue() &&1356           "Associated value mismatch!");1357    return;1358  case IRP_CALL_SITE_RETURNED:1359    assert((CBContext == nullptr) &&1360           "'call site returned' position must not have CallBaseContext!");1361    assert((isa<CallBase>(getAsValuePtr())) &&1362           "Expected call base for 'call site returned' position!");1363    assert(getAsValuePtr() == &getAssociatedValue() &&1364           "Associated value mismatch!");1365    return;1366  case IRP_CALL_SITE:1367    assert((CBContext == nullptr) &&1368           "'call site function' position must not have CallBaseContext!");1369    assert((isa<CallBase>(getAsValuePtr())) &&1370           "Expected call base for 'call site function' position!");1371    assert(getAsValuePtr() == &getAssociatedValue() &&1372           "Associated value mismatch!");1373    return;1374  case IRP_FUNCTION:1375    assert(isa<Function>(getAsValuePtr()) &&1376           "Expected function for a 'function' position!");1377    assert(getAsValuePtr() == &getAssociatedValue() &&1378           "Associated value mismatch!");1379    return;1380  case IRP_ARGUMENT:1381    assert(isa<Argument>(getAsValuePtr()) &&1382           "Expected argument for a 'argument' position!");1383    assert(getAsValuePtr() == &getAssociatedValue() &&1384           "Associated value mismatch!");1385    return;1386  case IRP_CALL_SITE_ARGUMENT: {1387    assert((CBContext == nullptr) &&1388           "'call site argument' position must not have CallBaseContext!");1389    Use *U = getAsUsePtr();1390    (void)U; // Silence unused variable warning.1391    assert(U && "Expected use for a 'call site argument' position!");1392    assert(isa<CallBase>(U->getUser()) &&1393           "Expected call base user for a 'call site argument' position!");1394    assert(cast<CallBase>(U->getUser())->isArgOperand(U) &&1395           "Expected call base argument operand for a 'call site argument' "1396           "position");1397    assert(cast<CallBase>(U->getUser())->getArgOperandNo(U) ==1398               unsigned(getCallSiteArgNo()) &&1399           "Argument number mismatch!");1400    assert(U->get() == &getAssociatedValue() && "Associated value mismatch!");1401    return;1402  }1403  }1404#endif1405}1406 1407std::optional<Constant *>1408Attributor::getAssumedConstant(const IRPosition &IRP,1409                               const AbstractAttribute &AA,1410                               bool &UsedAssumedInformation) {1411  // First check all callbacks provided by outside AAs. If any of them returns1412  // a non-null value that is different from the associated value, or1413  // std::nullopt, we assume it's simplified.1414  for (auto &CB : SimplificationCallbacks.lookup(IRP)) {1415    std::optional<Value *> SimplifiedV = CB(IRP, &AA, UsedAssumedInformation);1416    if (!SimplifiedV)1417      return std::nullopt;1418    if (isa_and_nonnull<Constant>(*SimplifiedV))1419      return cast<Constant>(*SimplifiedV);1420    return nullptr;1421  }1422  if (auto *C = dyn_cast<Constant>(&IRP.getAssociatedValue()))1423    return C;1424  SmallVector<AA::ValueAndContext> Values;1425  if (getAssumedSimplifiedValues(IRP, &AA, Values,1426                                 AA::ValueScope::Interprocedural,1427                                 UsedAssumedInformation)) {1428    if (Values.empty())1429      return std::nullopt;1430    if (auto *C = dyn_cast_or_null<Constant>(1431            AAPotentialValues::getSingleValue(*this, AA, IRP, Values)))1432      return C;1433  }1434  return nullptr;1435}1436 1437std::optional<Value *> Attributor::getAssumedSimplified(1438    const IRPosition &IRP, const AbstractAttribute *AA,1439    bool &UsedAssumedInformation, AA::ValueScope S) {1440  // First check all callbacks provided by outside AAs. If any of them returns1441  // a non-null value that is different from the associated value, or1442  // std::nullopt, we assume it's simplified.1443  for (auto &CB : SimplificationCallbacks.lookup(IRP))1444    return CB(IRP, AA, UsedAssumedInformation);1445 1446  SmallVector<AA::ValueAndContext> Values;1447  if (!getAssumedSimplifiedValues(IRP, AA, Values, S, UsedAssumedInformation))1448    return &IRP.getAssociatedValue();1449  if (Values.empty())1450    return std::nullopt;1451  if (AA)1452    if (Value *V = AAPotentialValues::getSingleValue(*this, *AA, IRP, Values))1453      return V;1454  if (IRP.getPositionKind() == IRPosition::IRP_RETURNED ||1455      IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_RETURNED)1456    return nullptr;1457  return &IRP.getAssociatedValue();1458}1459 1460bool Attributor::getAssumedSimplifiedValues(1461    const IRPosition &InitialIRP, const AbstractAttribute *AA,1462    SmallVectorImpl<AA::ValueAndContext> &Values, AA::ValueScope S,1463    bool &UsedAssumedInformation, bool RecurseForSelectAndPHI) {1464  SmallPtrSet<Value *, 8> Seen;1465  SmallVector<IRPosition, 8> Worklist;1466  Worklist.push_back(InitialIRP);1467  while (!Worklist.empty()) {1468    const IRPosition &IRP = Worklist.pop_back_val();1469 1470    // First check all callbacks provided by outside AAs. If any of them returns1471    // a non-null value that is different from the associated value, or1472    // std::nullopt, we assume it's simplified.1473    int NV = Values.size();1474    const auto &SimplificationCBs = SimplificationCallbacks.lookup(IRP);1475    for (const auto &CB : SimplificationCBs) {1476      std::optional<Value *> CBResult = CB(IRP, AA, UsedAssumedInformation);1477      if (!CBResult.has_value())1478        continue;1479      Value *V = *CBResult;1480      if (!V)1481        return false;1482      if ((S & AA::ValueScope::Interprocedural) ||1483          AA::isValidInScope(*V, IRP.getAnchorScope()))1484        Values.push_back(AA::ValueAndContext{*V, nullptr});1485      else1486        return false;1487    }1488    if (SimplificationCBs.empty()) {1489      // If no high-level/outside simplification occurred, use1490      // AAPotentialValues.1491      const auto *PotentialValuesAA =1492          getOrCreateAAFor<AAPotentialValues>(IRP, AA, DepClassTy::OPTIONAL);1493      if (PotentialValuesAA &&1494          PotentialValuesAA->getAssumedSimplifiedValues(*this, Values, S)) {1495        UsedAssumedInformation |= !PotentialValuesAA->isAtFixpoint();1496      } else if (IRP.getPositionKind() != IRPosition::IRP_RETURNED) {1497        Values.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});1498      } else {1499        // TODO: We could visit all returns and add the operands.1500        return false;1501      }1502    }1503 1504    if (!RecurseForSelectAndPHI)1505      break;1506 1507    for (int I = NV, E = Values.size(); I < E; ++I) {1508      Value *V = Values[I].getValue();1509      if (!isa<PHINode>(V) && !isa<SelectInst>(V))1510        continue;1511      if (!Seen.insert(V).second)1512        continue;1513      // Move the last element to this slot.1514      Values[I] = Values[E - 1];1515      // Eliminate the last slot, adjust the indices.1516      Values.pop_back();1517      --E;1518      --I;1519      // Add a new value (select or phi) to the worklist.1520      Worklist.push_back(IRPosition::value(*V));1521    }1522  }1523  return true;1524}1525 1526std::optional<Value *> Attributor::translateArgumentToCallSiteContent(1527    std::optional<Value *> V, CallBase &CB, const AbstractAttribute &AA,1528    bool &UsedAssumedInformation) {1529  if (!V)1530    return V;1531  if (*V == nullptr || isa<Constant>(*V))1532    return V;1533  if (auto *Arg = dyn_cast<Argument>(*V))1534    if (CB.getCalledOperand() == Arg->getParent() &&1535        CB.arg_size() > Arg->getArgNo())1536      if (!Arg->hasPointeeInMemoryValueAttr())1537        return getAssumedSimplified(1538            IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,1539            UsedAssumedInformation, AA::Intraprocedural);1540  return nullptr;1541}1542 1543Attributor::~Attributor() {1544  // The abstract attributes are allocated via the BumpPtrAllocator Allocator,1545  // thus we cannot delete them. We can, and want to, destruct them though.1546  for (auto &It : AAMap) {1547    AbstractAttribute *AA = It.getSecond();1548    AA->~AbstractAttribute();1549  }1550}1551 1552bool Attributor::isAssumedDead(const AbstractAttribute &AA,1553                               const AAIsDead *FnLivenessAA,1554                               bool &UsedAssumedInformation,1555                               bool CheckBBLivenessOnly, DepClassTy DepClass) {1556  if (!Configuration.UseLiveness)1557    return false;1558  const IRPosition &IRP = AA.getIRPosition();1559  if (!Functions.count(IRP.getAnchorScope()))1560    return false;1561  return isAssumedDead(IRP, &AA, FnLivenessAA, UsedAssumedInformation,1562                       CheckBBLivenessOnly, DepClass);1563}1564 1565bool Attributor::isAssumedDead(const Use &U,1566                               const AbstractAttribute *QueryingAA,1567                               const AAIsDead *FnLivenessAA,1568                               bool &UsedAssumedInformation,1569                               bool CheckBBLivenessOnly, DepClassTy DepClass) {1570  if (!Configuration.UseLiveness)1571    return false;1572  Instruction *UserI = dyn_cast<Instruction>(U.getUser());1573  if (!UserI)1574    return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,1575                         UsedAssumedInformation, CheckBBLivenessOnly, DepClass);1576 1577  if (auto *CB = dyn_cast<CallBase>(UserI)) {1578    // For call site argument uses we can check if the argument is1579    // unused/dead.1580    if (CB->isArgOperand(&U)) {1581      const IRPosition &CSArgPos =1582          IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));1583      return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,1584                           UsedAssumedInformation, CheckBBLivenessOnly,1585                           DepClass);1586    }1587  } else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {1588    const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());1589    return isAssumedDead(RetPos, QueryingAA, FnLivenessAA,1590                         UsedAssumedInformation, CheckBBLivenessOnly, DepClass);1591  } else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {1592    BasicBlock *IncomingBB = PHI->getIncomingBlock(U);1593    return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,1594                         UsedAssumedInformation, CheckBBLivenessOnly, DepClass);1595  } else if (StoreInst *SI = dyn_cast<StoreInst>(UserI)) {1596    if (!CheckBBLivenessOnly && SI->getPointerOperand() != U.get()) {1597      const IRPosition IRP = IRPosition::inst(*SI);1598      const AAIsDead *IsDeadAA =1599          getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);1600      if (IsDeadAA && IsDeadAA->isRemovableStore()) {1601        if (QueryingAA)1602          recordDependence(*IsDeadAA, *QueryingAA, DepClass);1603        if (!IsDeadAA->isKnown(AAIsDead::IS_REMOVABLE))1604          UsedAssumedInformation = true;1605        return true;1606      }1607    }1608  }1609 1610  return isAssumedDead(IRPosition::inst(*UserI), QueryingAA, FnLivenessAA,1611                       UsedAssumedInformation, CheckBBLivenessOnly, DepClass);1612}1613 1614bool Attributor::isAssumedDead(const Instruction &I,1615                               const AbstractAttribute *QueryingAA,1616                               const AAIsDead *FnLivenessAA,1617                               bool &UsedAssumedInformation,1618                               bool CheckBBLivenessOnly, DepClassTy DepClass,1619                               bool CheckForDeadStore) {1620  if (!Configuration.UseLiveness)1621    return false;1622  const IRPosition::CallBaseContext *CBCtx =1623      QueryingAA ? QueryingAA->getCallBaseContext() : nullptr;1624 1625  if (ManifestAddedBlocks.contains(I.getParent()))1626    return false;1627 1628  const Function &F = *I.getFunction();1629  if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)1630    FnLivenessAA = getOrCreateAAFor<AAIsDead>(IRPosition::function(F, CBCtx),1631                                              QueryingAA, DepClassTy::NONE);1632 1633  // Don't use recursive reasoning.1634  if (!FnLivenessAA || QueryingAA == FnLivenessAA)1635    return false;1636 1637  // If we have a context instruction and a liveness AA we use it.1638  if (CheckBBLivenessOnly ? FnLivenessAA->isAssumedDead(I.getParent())1639                          : FnLivenessAA->isAssumedDead(&I)) {1640    if (QueryingAA)1641      recordDependence(*FnLivenessAA, *QueryingAA, DepClass);1642    if (!FnLivenessAA->isKnownDead(&I))1643      UsedAssumedInformation = true;1644    return true;1645  }1646 1647  if (CheckBBLivenessOnly)1648    return false;1649 1650  const IRPosition IRP = IRPosition::inst(I, CBCtx);1651  const AAIsDead *IsDeadAA =1652      getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);1653 1654  // Don't use recursive reasoning.1655  if (!IsDeadAA || QueryingAA == IsDeadAA)1656    return false;1657 1658  if (IsDeadAA->isAssumedDead()) {1659    if (QueryingAA)1660      recordDependence(*IsDeadAA, *QueryingAA, DepClass);1661    if (!IsDeadAA->isKnownDead())1662      UsedAssumedInformation = true;1663    return true;1664  }1665 1666  if (CheckForDeadStore && isa<StoreInst>(I) && IsDeadAA->isRemovableStore()) {1667    if (QueryingAA)1668      recordDependence(*IsDeadAA, *QueryingAA, DepClass);1669    if (!IsDeadAA->isKnownDead())1670      UsedAssumedInformation = true;1671    return true;1672  }1673 1674  return false;1675}1676 1677bool Attributor::isAssumedDead(const IRPosition &IRP,1678                               const AbstractAttribute *QueryingAA,1679                               const AAIsDead *FnLivenessAA,1680                               bool &UsedAssumedInformation,1681                               bool CheckBBLivenessOnly, DepClassTy DepClass) {1682  if (!Configuration.UseLiveness)1683    return false;1684  // Don't check liveness for constants, e.g. functions, used as (floating)1685  // values since the context instruction and such is here meaningless.1686  if (IRP.getPositionKind() == IRPosition::IRP_FLOAT &&1687      isa<Constant>(IRP.getAssociatedValue())) {1688    return false;1689  }1690 1691  Instruction *CtxI = IRP.getCtxI();1692  if (CtxI &&1693      isAssumedDead(*CtxI, QueryingAA, FnLivenessAA, UsedAssumedInformation,1694                    /* CheckBBLivenessOnly */ true,1695                    CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))1696    return true;1697 1698  if (CheckBBLivenessOnly)1699    return false;1700 1701  // If we haven't succeeded we query the specific liveness info for the IRP.1702  const AAIsDead *IsDeadAA;1703  if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE)1704    IsDeadAA = getOrCreateAAFor<AAIsDead>(1705        IRPosition::callsite_returned(cast<CallBase>(IRP.getAssociatedValue())),1706        QueryingAA, DepClassTy::NONE);1707  else1708    IsDeadAA = getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);1709 1710  // Don't use recursive reasoning.1711  if (!IsDeadAA || QueryingAA == IsDeadAA)1712    return false;1713 1714  if (IsDeadAA->isAssumedDead()) {1715    if (QueryingAA)1716      recordDependence(*IsDeadAA, *QueryingAA, DepClass);1717    if (!IsDeadAA->isKnownDead())1718      UsedAssumedInformation = true;1719    return true;1720  }1721 1722  return false;1723}1724 1725bool Attributor::isAssumedDead(const BasicBlock &BB,1726                               const AbstractAttribute *QueryingAA,1727                               const AAIsDead *FnLivenessAA,1728                               DepClassTy DepClass) {1729  if (!Configuration.UseLiveness)1730    return false;1731  const Function &F = *BB.getParent();1732  if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)1733    FnLivenessAA = getOrCreateAAFor<AAIsDead>(IRPosition::function(F),1734                                              QueryingAA, DepClassTy::NONE);1735 1736  // Don't use recursive reasoning.1737  if (!FnLivenessAA || QueryingAA == FnLivenessAA)1738    return false;1739 1740  if (FnLivenessAA->isAssumedDead(&BB)) {1741    if (QueryingAA)1742      recordDependence(*FnLivenessAA, *QueryingAA, DepClass);1743    return true;1744  }1745 1746  return false;1747}1748 1749bool Attributor::checkForAllCallees(1750    function_ref<bool(ArrayRef<const Function *>)> Pred,1751    const AbstractAttribute &QueryingAA, const CallBase &CB) {1752  if (const Function *Callee = dyn_cast<Function>(CB.getCalledOperand()))1753    return Pred(Callee);1754 1755  const auto *CallEdgesAA = getAAFor<AACallEdges>(1756      QueryingAA, IRPosition::callsite_function(CB), DepClassTy::OPTIONAL);1757  if (!CallEdgesAA || CallEdgesAA->hasUnknownCallee())1758    return false;1759 1760  const auto &Callees = CallEdgesAA->getOptimisticEdges();1761  return Pred(Callees.getArrayRef());1762}1763 1764bool canMarkAsVisited(const User *Usr) {1765  return isa<PHINode>(Usr) || !isa<Instruction>(Usr);1766}1767 1768bool Attributor::checkForAllUses(1769    function_ref<bool(const Use &, bool &)> Pred,1770    const AbstractAttribute &QueryingAA, const Value &V,1771    bool CheckBBLivenessOnly, DepClassTy LivenessDepClass,1772    bool IgnoreDroppableUses,1773    function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB) {1774 1775  // Check virtual uses first.1776  for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&V))1777    if (!CB(*this, &QueryingAA))1778      return false;1779 1780  if (isa<ConstantData>(V))1781    return false;1782 1783  // Check the trivial case first as it catches void values.1784  if (V.use_empty())1785    return true;1786 1787  const IRPosition &IRP = QueryingAA.getIRPosition();1788  SmallVector<const Use *, 16> Worklist;1789  SmallPtrSet<const Use *, 16> Visited;1790 1791  auto AddUsers = [&](const Value &V, const Use *OldUse) {1792    for (const Use &UU : V.uses()) {1793      if (OldUse && EquivalentUseCB && !EquivalentUseCB(*OldUse, UU)) {1794        LLVM_DEBUG(dbgs() << "[Attributor] Potential copy was "1795                             "rejected by the equivalence call back: "1796                          << *UU << "!\n");1797        return false;1798      }1799 1800      Worklist.push_back(&UU);1801    }1802    return true;1803  };1804 1805  AddUsers(V, /* OldUse */ nullptr);1806 1807  LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()1808                    << " initial uses to check\n");1809 1810  const Function *ScopeFn = IRP.getAnchorScope();1811  const auto *LivenessAA =1812      ScopeFn ? getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),1813                                   DepClassTy::NONE)1814              : nullptr;1815 1816  while (!Worklist.empty()) {1817    const Use *U = Worklist.pop_back_val();1818    if (canMarkAsVisited(U->getUser()) && !Visited.insert(U).second)1819      continue;1820    DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, {1821      if (auto *Fn = dyn_cast<Function>(U->getUser()))1822        dbgs() << "[Attributor] Check use: " << **U << " in " << Fn->getName()1823               << "\n";1824      else1825        dbgs() << "[Attributor] Check use: " << **U << " in " << *U->getUser()1826               << "\n";1827    });1828    bool UsedAssumedInformation = false;1829    if (isAssumedDead(*U, &QueryingAA, LivenessAA, UsedAssumedInformation,1830                      CheckBBLivenessOnly, LivenessDepClass)) {1831      DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,1832                      dbgs() << "[Attributor] Dead use, skip!\n");1833      continue;1834    }1835    if (IgnoreDroppableUses && U->getUser()->isDroppable()) {1836      DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,1837                      dbgs() << "[Attributor] Droppable user, skip!\n");1838      continue;1839    }1840 1841    if (auto *SI = dyn_cast<StoreInst>(U->getUser())) {1842      if (&SI->getOperandUse(0) == U) {1843        if (!Visited.insert(U).second)1844          continue;1845        SmallSetVector<Value *, 4> PotentialCopies;1846        if (AA::getPotentialCopiesOfStoredValue(1847                *this, *SI, PotentialCopies, QueryingAA, UsedAssumedInformation,1848                /* OnlyExact */ true)) {1849          DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,1850                          dbgs()1851                              << "[Attributor] Value is stored, continue with "1852                              << PotentialCopies.size()1853                              << " potential copies instead!\n");1854          for (Value *PotentialCopy : PotentialCopies)1855            if (!AddUsers(*PotentialCopy, U))1856              return false;1857          continue;1858        }1859      }1860    }1861 1862    bool Follow = false;1863    if (!Pred(*U, Follow))1864      return false;1865    if (!Follow)1866      continue;1867 1868    User &Usr = *U->getUser();1869    AddUsers(Usr, /* OldUse */ nullptr);1870  }1871 1872  return true;1873}1874 1875bool Attributor::checkForAllCallSites(function_ref<bool(AbstractCallSite)> Pred,1876                                      const AbstractAttribute &QueryingAA,1877                                      bool RequireAllCallSites,1878                                      bool &UsedAssumedInformation) {1879  // We can try to determine information from1880  // the call sites. However, this is only possible all call sites are known,1881  // hence the function has internal linkage.1882  const IRPosition &IRP = QueryingAA.getIRPosition();1883  const Function *AssociatedFunction = IRP.getAssociatedFunction();1884  if (!AssociatedFunction) {1885    LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP1886                      << "\n");1887    return false;1888  }1889 1890  return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,1891                              &QueryingAA, UsedAssumedInformation);1892}1893 1894bool Attributor::checkForAllCallSites(function_ref<bool(AbstractCallSite)> Pred,1895                                      const Function &Fn,1896                                      bool RequireAllCallSites,1897                                      const AbstractAttribute *QueryingAA,1898                                      bool &UsedAssumedInformation,1899                                      bool CheckPotentiallyDead) {1900  if (RequireAllCallSites && !Fn.hasLocalLinkage()) {1901    LLVM_DEBUG(1902        dbgs()1903        << "[Attributor] Function " << Fn.getName()1904        << " has no internal linkage, hence not all call sites are known\n");1905    return false;1906  }1907  // Check virtual uses first.1908  for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&Fn))1909    if (!CB(*this, QueryingAA))1910      return false;1911 1912  SmallVector<const Use *, 8> Uses(make_pointer_range(Fn.uses()));1913  for (unsigned u = 0; u < Uses.size(); ++u) {1914    const Use &U = *Uses[u];1915    DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, {1916      if (auto *Fn = dyn_cast<Function>(U))1917        dbgs() << "[Attributor] Check use: " << Fn->getName() << " in "1918               << *U.getUser() << "\n";1919      else1920        dbgs() << "[Attributor] Check use: " << *U << " in " << *U.getUser()1921               << "\n";1922    });1923    if (!CheckPotentiallyDead &&1924        isAssumedDead(U, QueryingAA, nullptr, UsedAssumedInformation,1925                      /* CheckBBLivenessOnly */ true)) {1926      DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,1927                      dbgs() << "[Attributor] Dead use, skip!\n");1928      continue;1929    }1930    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {1931      if (CE->isCast() && CE->getType()->isPointerTy()) {1932        DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, {1933          dbgs() << "[Attributor] Use, is constant cast expression, add "1934                 << CE->getNumUses() << " uses of that expression instead!\n";1935        });1936        for (const Use &CEU : CE->uses())1937          Uses.push_back(&CEU);1938        continue;1939      }1940    }1941 1942    AbstractCallSite ACS(&U);1943    if (!ACS) {1944      LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()1945                        << " has non call site use " << *U.get() << " in "1946                        << *U.getUser() << "\n");1947      return false;1948    }1949 1950    const Use *EffectiveUse =1951        ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;1952    if (!ACS.isCallee(EffectiveUse)) {1953      if (!RequireAllCallSites) {1954        LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()1955                          << " is not a call of " << Fn.getName()1956                          << ", skip use\n");1957        continue;1958      }1959      LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()1960                        << " is an invalid use of " << Fn.getName() << "\n");1961      return false;1962    }1963 1964    // Make sure the arguments that can be matched between the call site and the1965    // callee argee on their type. It is unlikely they do not and it doesn't1966    // make sense for all attributes to know/care about this.1967    assert(&Fn == ACS.getCalledFunction() && "Expected known callee");1968    unsigned MinArgsParams =1969        std::min(size_t(ACS.getNumArgOperands()), Fn.arg_size());1970    for (unsigned u = 0; u < MinArgsParams; ++u) {1971      Value *CSArgOp = ACS.getCallArgOperand(u);1972      if (CSArgOp && Fn.getArg(u)->getType() != CSArgOp->getType()) {1973        LLVM_DEBUG(1974            dbgs() << "[Attributor] Call site / callee argument type mismatch ["1975                   << u << "@" << Fn.getName() << ": "1976                   << *Fn.getArg(u)->getType() << " vs. "1977                   << *ACS.getCallArgOperand(u)->getType() << "\n");1978        return false;1979      }1980    }1981 1982    if (Pred(ACS))1983      continue;1984 1985    LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "1986                      << *ACS.getInstruction() << "\n");1987    return false;1988  }1989 1990  return true;1991}1992 1993bool Attributor::shouldPropagateCallBaseContext(const IRPosition &IRP) {1994  // TODO: Maintain a cache of Values that are1995  // on the pathway from a Argument to a Instruction that would effect the1996  // liveness/return state etc.1997  return EnableCallSiteSpecific;1998}1999 2000bool Attributor::checkForAllReturnedValues(function_ref<bool(Value &)> Pred,2001                                           const AbstractAttribute &QueryingAA,2002                                           AA::ValueScope S,2003                                           bool RecurseForSelectAndPHI) {2004 2005  const IRPosition &IRP = QueryingAA.getIRPosition();2006  const Function *AssociatedFunction = IRP.getAssociatedFunction();2007  if (!AssociatedFunction)2008    return false;2009 2010  bool UsedAssumedInformation = false;2011  SmallVector<AA::ValueAndContext> Values;2012  if (!getAssumedSimplifiedValues(2013          IRPosition::returned(*AssociatedFunction), &QueryingAA, Values, S,2014          UsedAssumedInformation, RecurseForSelectAndPHI))2015    return false;2016 2017  return llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {2018    return Pred(*VAC.getValue());2019  });2020}2021 2022static bool checkForAllInstructionsImpl(2023    Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap,2024    function_ref<bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA,2025    const AAIsDead *LivenessAA, ArrayRef<unsigned> Opcodes,2026    bool &UsedAssumedInformation, bool CheckBBLivenessOnly = false,2027    bool CheckPotentiallyDead = false) {2028  for (unsigned Opcode : Opcodes) {2029    // Check if we have instructions with this opcode at all first.2030    auto *Insts = OpcodeInstMap.lookup(Opcode);2031    if (!Insts)2032      continue;2033 2034    for (Instruction *I : *Insts) {2035      // Skip dead instructions.2036      if (A && !CheckPotentiallyDead &&2037          A->isAssumedDead(IRPosition::inst(*I), QueryingAA, LivenessAA,2038                           UsedAssumedInformation, CheckBBLivenessOnly)) {2039        DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,2040                        dbgs() << "[Attributor] Instruction " << *I2041                               << " is potentially dead, skip!\n";);2042        continue;2043      }2044 2045      if (!Pred(*I))2046        return false;2047    }2048  }2049  return true;2050}2051 2052bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,2053                                         const Function *Fn,2054                                         const AbstractAttribute *QueryingAA,2055                                         ArrayRef<unsigned> Opcodes,2056                                         bool &UsedAssumedInformation,2057                                         bool CheckBBLivenessOnly,2058                                         bool CheckPotentiallyDead) {2059  // Since we need to provide instructions we have to have an exact definition.2060  if (!Fn || Fn->isDeclaration())2061    return false;2062 2063  const IRPosition &QueryIRP = IRPosition::function(*Fn);2064  const auto *LivenessAA =2065      CheckPotentiallyDead && QueryingAA2066          ? (getAAFor<AAIsDead>(*QueryingAA, QueryIRP, DepClassTy::NONE))2067          : nullptr;2068 2069  auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);2070  if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, QueryingAA,2071                                   LivenessAA, Opcodes, UsedAssumedInformation,2072                                   CheckBBLivenessOnly, CheckPotentiallyDead))2073    return false;2074 2075  return true;2076}2077 2078bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,2079                                         const AbstractAttribute &QueryingAA,2080                                         ArrayRef<unsigned> Opcodes,2081                                         bool &UsedAssumedInformation,2082                                         bool CheckBBLivenessOnly,2083                                         bool CheckPotentiallyDead) {2084  const IRPosition &IRP = QueryingAA.getIRPosition();2085  const Function *AssociatedFunction = IRP.getAssociatedFunction();2086  return checkForAllInstructions(Pred, AssociatedFunction, &QueryingAA, Opcodes,2087                                 UsedAssumedInformation, CheckBBLivenessOnly,2088                                 CheckPotentiallyDead);2089}2090 2091bool Attributor::checkForAllReadWriteInstructions(2092    function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA,2093    bool &UsedAssumedInformation) {2094  TimeTraceScope TS("checkForAllReadWriteInstructions");2095 2096  const Function *AssociatedFunction =2097      QueryingAA.getIRPosition().getAssociatedFunction();2098  if (!AssociatedFunction)2099    return false;2100 2101  const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);2102  const auto *LivenessAA =2103      getAAFor<AAIsDead>(QueryingAA, QueryIRP, DepClassTy::NONE);2104 2105  for (Instruction *I :2106       InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {2107    // Skip dead instructions.2108    if (isAssumedDead(IRPosition::inst(*I), &QueryingAA, LivenessAA,2109                      UsedAssumedInformation))2110      continue;2111 2112    if (!Pred(*I))2113      return false;2114  }2115 2116  return true;2117}2118 2119void Attributor::runTillFixpoint() {2120  TimeTraceScope TimeScope("Attributor::runTillFixpoint");2121  LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "2122                    << DG.SyntheticRoot.Deps.size()2123                    << " abstract attributes.\n");2124 2125  // Now that all abstract attributes are collected and initialized we start2126  // the abstract analysis.2127 2128  unsigned IterationCounter = 1;2129  unsigned MaxIterations =2130      Configuration.MaxFixpointIterations.value_or(SetFixpointIterations);2131 2132  SmallVector<AbstractAttribute *, 32> ChangedAAs;2133  SetVector<AbstractAttribute *> Worklist, InvalidAAs;2134  Worklist.insert_range(DG.SyntheticRoot);2135 2136  do {2137    // Remember the size to determine new attributes.2138    size_t NumAAs = DG.SyntheticRoot.Deps.size();2139    LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter2140                      << ", Worklist size: " << Worklist.size() << "\n");2141 2142    // For invalid AAs we can fix dependent AAs that have a required dependence,2143    // thereby folding long dependence chains in a single step without the need2144    // to run updates.2145    for (unsigned u = 0; u < InvalidAAs.size(); ++u) {2146      AbstractAttribute *InvalidAA = InvalidAAs[u];2147 2148      // Check the dependences to fast track invalidation.2149      DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,2150                      dbgs() << "[Attributor] InvalidAA: " << *InvalidAA2151                             << " has " << InvalidAA->Deps.size()2152                             << " required & optional dependences\n");2153      for (auto &DepIt : InvalidAA->Deps) {2154        AbstractAttribute *DepAA = cast<AbstractAttribute>(DepIt.getPointer());2155        if (DepIt.getInt() == unsigned(DepClassTy::OPTIONAL)) {2156          DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,2157                          dbgs() << " - recompute: " << *DepAA);2158          Worklist.insert(DepAA);2159          continue;2160        }2161        DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, dbgs()2162                                                << " - invalidate: " << *DepAA);2163        DepAA->getState().indicatePessimisticFixpoint();2164        assert(DepAA->getState().isAtFixpoint() && "Expected fixpoint state!");2165        if (!DepAA->getState().isValidState())2166          InvalidAAs.insert(DepAA);2167        else2168          ChangedAAs.push_back(DepAA);2169      }2170      InvalidAA->Deps.clear();2171    }2172 2173    // Add all abstract attributes that are potentially dependent on one that2174    // changed to the work list.2175    for (AbstractAttribute *ChangedAA : ChangedAAs) {2176      for (auto &DepIt : ChangedAA->Deps)2177        Worklist.insert(cast<AbstractAttribute>(DepIt.getPointer()));2178      ChangedAA->Deps.clear();2179    }2180 2181    LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter2182                      << ", Worklist+Dependent size: " << Worklist.size()2183                      << "\n");2184 2185    // Reset the changed and invalid set.2186    ChangedAAs.clear();2187    InvalidAAs.clear();2188 2189    // Update all abstract attribute in the work list and record the ones that2190    // changed.2191    for (AbstractAttribute *AA : Worklist) {2192      const auto &AAState = AA->getState();2193      if (!AAState.isAtFixpoint())2194        if (updateAA(*AA) == ChangeStatus::CHANGED)2195          ChangedAAs.push_back(AA);2196 2197      // Use the InvalidAAs vector to propagate invalid states fast transitively2198      // without requiring updates.2199      if (!AAState.isValidState())2200        InvalidAAs.insert(AA);2201    }2202 2203    // Add attributes to the changed set if they have been created in the last2204    // iteration.2205    ChangedAAs.append(DG.SyntheticRoot.begin() + NumAAs,2206                      DG.SyntheticRoot.end());2207 2208    // Reset the work list and repopulate with the changed abstract attributes.2209    // Note that dependent ones are added above.2210    Worklist.clear();2211    Worklist.insert_range(ChangedAAs);2212    Worklist.insert_range(QueryAAsAwaitingUpdate);2213    QueryAAsAwaitingUpdate.clear();2214 2215  } while (!Worklist.empty() && (IterationCounter++ < MaxIterations));2216 2217  if (IterationCounter > MaxIterations && !Functions.empty()) {2218    auto Remark = [&](OptimizationRemarkMissed ORM) {2219      return ORM << "Attributor did not reach a fixpoint after "2220                 << ore::NV("Iterations", MaxIterations) << " iterations.";2221    };2222    Function *F = Functions.front();2223    emitRemark<OptimizationRemarkMissed>(F, "FixedPoint", Remark);2224  }2225 2226  LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "2227                    << IterationCounter << "/" << MaxIterations2228                    << " iterations\n");2229 2230  // Reset abstract arguments not settled in a sound fixpoint by now. This2231  // happens when we stopped the fixpoint iteration early. Note that only the2232  // ones marked as "changed" *and* the ones transitively depending on them2233  // need to be reverted to a pessimistic state. Others might not be in a2234  // fixpoint state but we can use the optimistic results for them anyway.2235  SmallPtrSet<AbstractAttribute *, 32> Visited;2236  for (unsigned u = 0; u < ChangedAAs.size(); u++) {2237    AbstractAttribute *ChangedAA = ChangedAAs[u];2238    if (!Visited.insert(ChangedAA).second)2239      continue;2240 2241    AbstractState &State = ChangedAA->getState();2242    if (!State.isAtFixpoint()) {2243      State.indicatePessimisticFixpoint();2244 2245      NumAttributesTimedOut++;2246    }2247 2248    for (auto &DepIt : ChangedAA->Deps)2249      ChangedAAs.push_back(cast<AbstractAttribute>(DepIt.getPointer()));2250    ChangedAA->Deps.clear();2251  }2252 2253  LLVM_DEBUG({2254    if (!Visited.empty())2255      dbgs() << "\n[Attributor] Finalized " << Visited.size()2256             << " abstract attributes.\n";2257  });2258}2259 2260void Attributor::registerForUpdate(AbstractAttribute &AA) {2261  assert(AA.isQueryAA() &&2262         "Non-query AAs should not be required to register for updates!");2263  QueryAAsAwaitingUpdate.insert(&AA);2264}2265 2266ChangeStatus Attributor::manifestAttributes() {2267  TimeTraceScope TimeScope("Attributor::manifestAttributes");2268  size_t NumFinalAAs = DG.SyntheticRoot.Deps.size();2269 2270  unsigned NumManifested = 0;2271  unsigned NumAtFixpoint = 0;2272  ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;2273  for (auto &DepAA : DG.SyntheticRoot.Deps) {2274    AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());2275    AbstractState &State = AA->getState();2276 2277    // If there is not already a fixpoint reached, we can now take the2278    // optimistic state. This is correct because we enforced a pessimistic one2279    // on abstract attributes that were transitively dependent on a changed one2280    // already above.2281    if (!State.isAtFixpoint())2282      State.indicateOptimisticFixpoint();2283 2284    // We must not manifest Attributes that use Callbase info.2285    if (AA->hasCallBaseContext())2286      continue;2287    // If the state is invalid, we do not try to manifest it.2288    if (!State.isValidState())2289      continue;2290 2291    if (AA->getCtxI() && !isRunOn(*AA->getAnchorScope()))2292      continue;2293 2294    // Skip dead code.2295    bool UsedAssumedInformation = false;2296    if (isAssumedDead(*AA, nullptr, UsedAssumedInformation,2297                      /* CheckBBLivenessOnly */ true))2298      continue;2299    // Check if the manifest debug counter that allows skipping manifestation of2300    // AAs2301    if (!DebugCounter::shouldExecute(ManifestDBGCounter))2302      continue;2303    // Manifest the state and record if we changed the IR.2304    ChangeStatus LocalChange = AA->manifest(*this);2305    if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())2306      AA->trackStatistics();2307    LLVM_DEBUG(dbgs() << "[Attributor] Manifest " << LocalChange << " : " << *AA2308                      << "\n");2309 2310    ManifestChange = ManifestChange | LocalChange;2311 2312    NumAtFixpoint++;2313    NumManifested += (LocalChange == ChangeStatus::CHANGED);2314  }2315 2316  (void)NumManifested;2317  (void)NumAtFixpoint;2318  LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested2319                    << " arguments while " << NumAtFixpoint2320                    << " were in a valid fixpoint state\n");2321 2322  NumAttributesManifested += NumManifested;2323  NumAttributesValidFixpoint += NumAtFixpoint;2324 2325  (void)NumFinalAAs;2326  if (NumFinalAAs != DG.SyntheticRoot.Deps.size()) {2327    auto DepIt = DG.SyntheticRoot.Deps.begin();2328    for (unsigned u = 0; u < NumFinalAAs; ++u)2329      ++DepIt;2330    for (unsigned u = NumFinalAAs; u < DG.SyntheticRoot.Deps.size();2331         ++u, ++DepIt) {2332      errs() << "Unexpected abstract attribute: "2333             << cast<AbstractAttribute>(DepIt->getPointer()) << " :: "2334             << cast<AbstractAttribute>(DepIt->getPointer())2335                    ->getIRPosition()2336                    .getAssociatedValue()2337             << "\n";2338    }2339    llvm_unreachable("Expected the final number of abstract attributes to "2340                     "remain unchanged!");2341  }2342 2343  for (auto &It : AttrsMap) {2344    AttributeList &AL = It.getSecond();2345    const IRPosition &IRP =2346        isa<Function>(It.getFirst())2347            ? IRPosition::function(*cast<Function>(It.getFirst()))2348            : IRPosition::callsite_function(*cast<CallBase>(It.getFirst()));2349    IRP.setAttrList(AL);2350  }2351 2352  return ManifestChange;2353}2354 2355void Attributor::identifyDeadInternalFunctions() {2356  // Early exit if we don't intend to delete functions.2357  if (!Configuration.DeleteFns)2358    return;2359 2360  // To avoid triggering an assertion in the lazy call graph we will not delete2361  // any internal library functions. We should modify the assertion though and2362  // allow internals to be deleted.2363  const auto *TLI =2364      isModulePass()2365          ? nullptr2366          : getInfoCache().getTargetLibraryInfoForFunction(*Functions.back());2367  LibFunc LF;2368 2369  // Identify dead internal functions and delete them. This happens outside2370  // the other fixpoint analysis as we might treat potentially dead functions2371  // as live to lower the number of iterations. If they happen to be dead, the2372  // below fixpoint loop will identify and eliminate them.2373 2374  SmallVector<Function *, 8> InternalFns;2375  for (Function *F : Functions)2376    if (F->hasLocalLinkage() && (isModulePass() || !TLI->getLibFunc(*F, LF)))2377      InternalFns.push_back(F);2378 2379  SmallPtrSet<Function *, 8> LiveInternalFns;2380  bool FoundLiveInternal = true;2381  while (FoundLiveInternal) {2382    FoundLiveInternal = false;2383    for (Function *&F : InternalFns) {2384      if (!F)2385        continue;2386 2387      bool UsedAssumedInformation = false;2388      if (checkForAllCallSites(2389              [&](AbstractCallSite ACS) {2390                Function *Callee = ACS.getInstruction()->getFunction();2391                return ToBeDeletedFunctions.count(Callee) ||2392                       (Functions.count(Callee) && Callee->hasLocalLinkage() &&2393                        !LiveInternalFns.count(Callee));2394              },2395              *F, true, nullptr, UsedAssumedInformation)) {2396        continue;2397      }2398 2399      LiveInternalFns.insert(F);2400      F = nullptr;2401      FoundLiveInternal = true;2402    }2403  }2404 2405  for (Function *F : InternalFns)2406    if (F)2407      ToBeDeletedFunctions.insert(F);2408}2409 2410ChangeStatus Attributor::cleanupIR() {2411  TimeTraceScope TimeScope("Attributor::cleanupIR");2412  // Delete stuff at the end to avoid invalid references and a nice order.2413  LLVM_DEBUG(dbgs() << "\n[Attributor] Delete/replace at least "2414                    << ToBeDeletedFunctions.size() << " functions and "2415                    << ToBeDeletedBlocks.size() << " blocks and "2416                    << ToBeDeletedInsts.size() << " instructions and "2417                    << ToBeChangedValues.size() << " values and "2418                    << ToBeChangedUses.size() << " uses. To insert "2419                    << ToBeChangedToUnreachableInsts.size()2420                    << " unreachables.\n"2421                    << "Preserve manifest added " << ManifestAddedBlocks.size()2422                    << " blocks\n");2423 2424  SmallVector<WeakTrackingVH, 32> DeadInsts;2425  SmallVector<Instruction *, 32> TerminatorsToFold;2426 2427  auto ReplaceUse = [&](Use *U, Value *NewV) {2428    Value *OldV = U->get();2429 2430    // If we plan to replace NewV we need to update it at this point.2431    do {2432      const auto &Entry = ToBeChangedValues.lookup(NewV);2433      if (!get<0>(Entry))2434        break;2435      NewV = get<0>(Entry);2436    } while (true);2437 2438    Instruction *I = dyn_cast<Instruction>(U->getUser());2439    assert((!I || isRunOn(*I->getFunction())) &&2440           "Cannot replace an instruction outside the current SCC!");2441 2442    // Do not replace uses in returns if the value is a must-tail call we will2443    // not delete.2444    if (auto *RI = dyn_cast_or_null<ReturnInst>(I)) {2445      if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))2446        if (CI->isMustTailCall() && !ToBeDeletedInsts.count(CI))2447          return;2448      // If we rewrite a return and the new value is not an argument, strip the2449      // `returned` attribute as it is wrong now.2450      if (!isa<Argument>(NewV))2451        for (auto &Arg : RI->getFunction()->args())2452          Arg.removeAttr(Attribute::Returned);2453    }2454 2455    LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()2456                      << " instead of " << *OldV << "\n");2457    U->set(NewV);2458 2459    if (Instruction *I = dyn_cast<Instruction>(OldV)) {2460      CGModifiedFunctions.insert(I->getFunction());2461      if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&2462          isInstructionTriviallyDead(I))2463        DeadInsts.push_back(I);2464    }2465    if (isa<UndefValue>(NewV) && isa<CallBase>(U->getUser())) {2466      auto *CB = cast<CallBase>(U->getUser());2467      if (CB->isArgOperand(U)) {2468        unsigned Idx = CB->getArgOperandNo(U);2469        CB->removeParamAttr(Idx, Attribute::NoUndef);2470        auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());2471        if (Callee && Callee->arg_size() > Idx)2472          Callee->removeParamAttr(Idx, Attribute::NoUndef);2473      }2474    }2475    if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {2476      Instruction *UserI = cast<Instruction>(U->getUser());2477      if (isa<UndefValue>(NewV)) {2478        ToBeChangedToUnreachableInsts.insert(UserI);2479      } else {2480        TerminatorsToFold.push_back(UserI);2481      }2482    }2483  };2484 2485  for (auto &It : ToBeChangedUses) {2486    Use *U = It.first;2487    Value *NewV = It.second;2488    ReplaceUse(U, NewV);2489  }2490 2491  SmallVector<Use *, 4> Uses;2492  for (auto &It : ToBeChangedValues) {2493    Value *OldV = It.first;2494    auto [NewV, Done] = It.second;2495    Uses.clear();2496    for (auto &U : OldV->uses())2497      if (Done || !U.getUser()->isDroppable())2498        Uses.push_back(&U);2499    for (Use *U : Uses) {2500      if (auto *I = dyn_cast<Instruction>(U->getUser()))2501        if (!isRunOn(*I->getFunction()))2502          continue;2503      ReplaceUse(U, NewV);2504    }2505  }2506 2507  for (const auto &V : InvokeWithDeadSuccessor)2508    if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {2509      assert(isRunOn(*II->getFunction()) &&2510             "Cannot replace an invoke outside the current SCC!");2511      bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);2512      bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);2513      bool Invoke2CallAllowed =2514          !AAIsDead::mayCatchAsynchronousExceptions(*II->getFunction());2515      assert((UnwindBBIsDead || NormalBBIsDead) &&2516             "Invoke does not have dead successors!");2517      BasicBlock *BB = II->getParent();2518      BasicBlock *NormalDestBB = II->getNormalDest();2519      if (UnwindBBIsDead) {2520        Instruction *NormalNextIP = &NormalDestBB->front();2521        if (Invoke2CallAllowed) {2522          changeToCall(II);2523          NormalNextIP = BB->getTerminator();2524        }2525        if (NormalBBIsDead)2526          ToBeChangedToUnreachableInsts.insert(NormalNextIP);2527      } else {2528        assert(NormalBBIsDead && "Broken invariant!");2529        if (!NormalDestBB->getUniquePredecessor())2530          NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");2531        ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());2532      }2533    }2534  for (Instruction *I : TerminatorsToFold) {2535    assert(isRunOn(*I->getFunction()) &&2536           "Cannot replace a terminator outside the current SCC!");2537    CGModifiedFunctions.insert(I->getFunction());2538    ConstantFoldTerminator(I->getParent());2539  }2540  for (const auto &V : ToBeChangedToUnreachableInsts)2541    if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {2542      LLVM_DEBUG(dbgs() << "[Attributor] Change to unreachable: " << *I2543                        << "\n");2544      assert(isRunOn(*I->getFunction()) &&2545             "Cannot replace an instruction outside the current SCC!");2546      CGModifiedFunctions.insert(I->getFunction());2547      changeToUnreachable(I);2548    }2549 2550  for (const auto &V : ToBeDeletedInsts) {2551    if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {2552      assert((!isa<CallBase>(I) || isa<IntrinsicInst>(I) ||2553              isRunOn(*I->getFunction())) &&2554             "Cannot delete an instruction outside the current SCC!");2555      I->dropDroppableUses();2556      CGModifiedFunctions.insert(I->getFunction());2557      if (!I->getType()->isVoidTy())2558        I->replaceAllUsesWith(UndefValue::get(I->getType()));2559      if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))2560        DeadInsts.push_back(I);2561      else2562        I->eraseFromParent();2563    }2564  }2565 2566  llvm::erase_if(DeadInsts, [&](WeakTrackingVH I) { return !I; });2567 2568  LLVM_DEBUG({2569    dbgs() << "[Attributor] DeadInsts size: " << DeadInsts.size() << "\n";2570    for (auto &I : DeadInsts)2571      if (I)2572        dbgs() << "  - " << *I << "\n";2573  });2574 2575  RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);2576 2577  if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {2578    SmallVector<BasicBlock *, 8> ToBeDeletedBBs;2579    ToBeDeletedBBs.reserve(NumDeadBlocks);2580    for (BasicBlock *BB : ToBeDeletedBlocks) {2581      assert(isRunOn(*BB->getParent()) &&2582             "Cannot delete a block outside the current SCC!");2583      CGModifiedFunctions.insert(BB->getParent());2584      // Do not delete BBs added during manifests of AAs.2585      if (ManifestAddedBlocks.contains(BB))2586        continue;2587      ToBeDeletedBBs.push_back(BB);2588    }2589    // Actually we do not delete the blocks but squash them into a single2590    // unreachable but untangling branches that jump here is something we need2591    // to do in a more generic way.2592    detachDeadBlocks(ToBeDeletedBBs, nullptr);2593  }2594 2595  identifyDeadInternalFunctions();2596 2597  // Rewrite the functions as requested during manifest.2598  ChangeStatus ManifestChange = rewriteFunctionSignatures(CGModifiedFunctions);2599 2600  for (Function *Fn : CGModifiedFunctions)2601    if (!ToBeDeletedFunctions.count(Fn) && Functions.count(Fn))2602      Configuration.CGUpdater.reanalyzeFunction(*Fn);2603 2604  for (Function *Fn : ToBeDeletedFunctions) {2605    if (!Functions.count(Fn))2606      continue;2607    Configuration.CGUpdater.removeFunction(*Fn);2608  }2609 2610  if (!ToBeChangedUses.empty())2611    ManifestChange = ChangeStatus::CHANGED;2612 2613  if (!ToBeChangedToUnreachableInsts.empty())2614    ManifestChange = ChangeStatus::CHANGED;2615 2616  if (!ToBeDeletedFunctions.empty())2617    ManifestChange = ChangeStatus::CHANGED;2618 2619  if (!ToBeDeletedBlocks.empty())2620    ManifestChange = ChangeStatus::CHANGED;2621 2622  if (!ToBeDeletedInsts.empty())2623    ManifestChange = ChangeStatus::CHANGED;2624 2625  if (!InvokeWithDeadSuccessor.empty())2626    ManifestChange = ChangeStatus::CHANGED;2627 2628  if (!DeadInsts.empty())2629    ManifestChange = ChangeStatus::CHANGED;2630 2631  NumFnDeleted += ToBeDeletedFunctions.size();2632 2633  LLVM_DEBUG(dbgs() << "[Attributor] Deleted " << ToBeDeletedFunctions.size()2634                    << " functions after manifest.\n");2635 2636#ifdef EXPENSIVE_CHECKS2637  for (Function *F : Functions) {2638    if (ToBeDeletedFunctions.count(F))2639      continue;2640    assert(!verifyFunction(*F, &errs()) && "Module verification failed!");2641  }2642#endif2643 2644  return ManifestChange;2645}2646 2647ChangeStatus Attributor::run() {2648  TimeTraceScope TimeScope("Attributor::run");2649  AttributorCallGraph ACallGraph(*this);2650 2651  if (PrintCallGraph)2652    ACallGraph.populateAll();2653 2654  Phase = AttributorPhase::UPDATE;2655  runTillFixpoint();2656 2657  // dump graphs on demand2658  if (DumpDepGraph)2659    DG.dumpGraph();2660 2661  if (ViewDepGraph)2662    DG.viewGraph();2663 2664  if (PrintDependencies)2665    DG.print();2666 2667  Phase = AttributorPhase::MANIFEST;2668  ChangeStatus ManifestChange = manifestAttributes();2669 2670  Phase = AttributorPhase::CLEANUP;2671  ChangeStatus CleanupChange = cleanupIR();2672 2673  if (PrintCallGraph)2674    ACallGraph.print();2675 2676  return ManifestChange | CleanupChange;2677}2678 2679ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {2680  TimeTraceScope TimeScope("updateAA", [&]() {2681    return AA.getName().str() +2682           std::to_string(AA.getIRPosition().getPositionKind());2683  });2684  assert(Phase == AttributorPhase::UPDATE &&2685         "We can update AA only in the update stage!");2686 2687  // Use a new dependence vector for this update.2688  DependenceVector DV;2689  DependenceStack.push_back(&DV);2690 2691  auto &AAState = AA.getState();2692  ChangeStatus CS = ChangeStatus::UNCHANGED;2693  bool UsedAssumedInformation = false;2694  if (!isAssumedDead(AA, nullptr, UsedAssumedInformation,2695                     /* CheckBBLivenessOnly */ true))2696    CS = AA.update(*this);2697 2698  if (!AA.isQueryAA() && DV.empty() && !AA.getState().isAtFixpoint()) {2699    // If the AA did not rely on outside information but changed, we run it2700    // again to see if it found a fixpoint. Most AAs do but we don't require2701    // them to. Hence, it might take the AA multiple iterations to get to a2702    // fixpoint even if it does not rely on outside information, which is fine.2703    ChangeStatus RerunCS = ChangeStatus::UNCHANGED;2704    if (CS == ChangeStatus::CHANGED)2705      RerunCS = AA.update(*this);2706 2707    // If the attribute did not change during the run or rerun, and it still did2708    // not query any non-fix information, the state will not change and we can2709    // indicate that right at this point.2710    if (RerunCS == ChangeStatus::UNCHANGED && !AA.isQueryAA() && DV.empty())2711      AAState.indicateOptimisticFixpoint();2712  }2713 2714  if (!AAState.isAtFixpoint())2715    rememberDependences();2716 2717  // Verify the stack was used properly, that is we pop the dependence vector we2718  // put there earlier.2719  DependenceVector *PoppedDV = DependenceStack.pop_back_val();2720  (void)PoppedDV;2721  assert(PoppedDV == &DV && "Inconsistent usage of the dependence stack!");2722 2723  return CS;2724}2725 2726void Attributor::createShallowWrapper(Function &F) {2727  assert(!F.isDeclaration() && "Cannot create a wrapper around a declaration!");2728 2729  Module &M = *F.getParent();2730  LLVMContext &Ctx = M.getContext();2731  FunctionType *FnTy = F.getFunctionType();2732 2733  Function *Wrapper =2734      Function::Create(FnTy, F.getLinkage(), F.getAddressSpace(), F.getName());2735  F.setName(""); // set the inside function anonymous2736  M.getFunctionList().insert(F.getIterator(), Wrapper);2737 2738  F.setLinkage(GlobalValue::InternalLinkage);2739 2740  F.replaceAllUsesWith(Wrapper);2741  assert(F.use_empty() && "Uses remained after wrapper was created!");2742 2743  // Move the COMDAT section to the wrapper.2744  // TODO: Check if we need to keep it for F as well.2745  Wrapper->setComdat(F.getComdat());2746  F.setComdat(nullptr);2747 2748  // Copy all metadata and attributes but keep them on F as well.2749  SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;2750  F.getAllMetadata(MDs);2751  for (auto MDIt : MDs)2752    Wrapper->addMetadata(MDIt.first, *MDIt.second);2753  Wrapper->setAttributes(F.getAttributes());2754 2755  // Create the call in the wrapper.2756  BasicBlock *EntryBB = BasicBlock::Create(Ctx, "entry", Wrapper);2757 2758  SmallVector<Value *, 8> Args;2759  Argument *FArgIt = F.arg_begin();2760  for (Argument &Arg : Wrapper->args()) {2761    Args.push_back(&Arg);2762    Arg.setName((FArgIt++)->getName());2763  }2764 2765  CallInst *CI = CallInst::Create(&F, Args, "", EntryBB);2766  CI->setTailCall(true);2767  CI->addFnAttr(Attribute::NoInline);2768  ReturnInst::Create(Ctx, CI->getType()->isVoidTy() ? nullptr : CI, EntryBB);2769 2770  NumFnShallowWrappersCreated++;2771}2772 2773bool Attributor::isInternalizable(Function &F) {2774  if (F.isDeclaration() || F.hasLocalLinkage() ||2775      GlobalValue::isInterposableLinkage(F.getLinkage()))2776    return false;2777  return true;2778}2779 2780Function *Attributor::internalizeFunction(Function &F, bool Force) {2781  if (!AllowDeepWrapper && !Force)2782    return nullptr;2783  if (!isInternalizable(F))2784    return nullptr;2785 2786  SmallPtrSet<Function *, 2> FnSet = {&F};2787  DenseMap<Function *, Function *> InternalizedFns;2788  internalizeFunctions(FnSet, InternalizedFns);2789 2790  return InternalizedFns[&F];2791}2792 2793bool Attributor::internalizeFunctions(SmallPtrSetImpl<Function *> &FnSet,2794                                      DenseMap<Function *, Function *> &FnMap) {2795  for (Function *F : FnSet)2796    if (!Attributor::isInternalizable(*F))2797      return false;2798 2799  FnMap.clear();2800  // Generate the internalized version of each function.2801  for (Function *F : FnSet) {2802    Module &M = *F->getParent();2803    FunctionType *FnTy = F->getFunctionType();2804 2805    // Create a copy of the current function2806    Function *Copied =2807        Function::Create(FnTy, F->getLinkage(), F->getAddressSpace(),2808                         F->getName() + ".internalized");2809    ValueToValueMapTy VMap;2810    auto *NewFArgIt = Copied->arg_begin();2811    for (auto &Arg : F->args()) {2812      auto ArgName = Arg.getName();2813      NewFArgIt->setName(ArgName);2814      VMap[&Arg] = &(*NewFArgIt++);2815    }2816    SmallVector<ReturnInst *, 8> Returns;2817 2818    // Copy the body of the original function to the new one2819    CloneFunctionInto(Copied, F, VMap,2820                      CloneFunctionChangeType::LocalChangesOnly, Returns);2821 2822    // Set the linakage and visibility late as CloneFunctionInto has some2823    // implicit requirements.2824    Copied->setVisibility(GlobalValue::DefaultVisibility);2825    Copied->setLinkage(GlobalValue::PrivateLinkage);2826 2827    // Copy metadata2828    SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;2829    F->getAllMetadata(MDs);2830    for (auto MDIt : MDs)2831      if (!Copied->hasMetadata())2832        Copied->addMetadata(MDIt.first, *MDIt.second);2833 2834    M.getFunctionList().insert(F->getIterator(), Copied);2835    Copied->setDSOLocal(true);2836    FnMap[F] = Copied;2837  }2838 2839  // Replace all uses of the old function with the new internalized function2840  // unless the caller is a function that was just internalized.2841  for (Function *F : FnSet) {2842    auto &InternalizedFn = FnMap[F];2843    auto IsNotInternalized = [&](Use &U) -> bool {2844      if (auto *CB = dyn_cast<CallBase>(U.getUser()))2845        return !FnMap.lookup(CB->getCaller());2846      return false;2847    };2848    F->replaceUsesWithIf(InternalizedFn, IsNotInternalized);2849  }2850 2851  return true;2852}2853 2854bool Attributor::isValidFunctionSignatureRewrite(2855    Argument &Arg, ArrayRef<Type *> ReplacementTypes) {2856 2857  if (!Configuration.RewriteSignatures)2858    return false;2859 2860  Function *Fn = Arg.getParent();2861  auto CallSiteCanBeChanged = [Fn](AbstractCallSite ACS) {2862    // Forbid the call site to cast the function return type. If we need to2863    // rewrite these functions we need to re-create a cast for the new call site2864    // (if the old had uses).2865    if (!ACS.getCalledFunction() ||2866        ACS.getInstruction()->getType() !=2867            ACS.getCalledFunction()->getReturnType())2868      return false;2869    if (cast<CallBase>(ACS.getInstruction())->getCalledOperand()->getType() !=2870        Fn->getType())2871      return false;2872    if (ACS.getNumArgOperands() != Fn->arg_size())2873      return false;2874    // Forbid must-tail calls for now.2875    return !ACS.isCallbackCall() && !ACS.getInstruction()->isMustTailCall();2876  };2877 2878  // Avoid var-arg functions for now.2879  if (Fn->isVarArg()) {2880    LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");2881    return false;2882  }2883 2884  // Avoid functions with complicated argument passing semantics.2885  AttributeList FnAttributeList = Fn->getAttributes();2886  if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||2887      FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||2888      FnAttributeList.hasAttrSomewhere(Attribute::InAlloca) ||2889      FnAttributeList.hasAttrSomewhere(Attribute::Preallocated)) {2890    LLVM_DEBUG(2891        dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");2892    return false;2893  }2894 2895  // Avoid callbacks for now.2896  bool UsedAssumedInformation = false;2897  if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,2898                            UsedAssumedInformation,2899                            /* CheckPotentiallyDead */ true)) {2900    LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");2901    return false;2902  }2903 2904  auto InstPred = [](Instruction &I) {2905    if (auto *CI = dyn_cast<CallInst>(&I))2906      return !CI->isMustTailCall();2907    return true;2908  };2909 2910  // Forbid must-tail calls for now.2911  // TODO:2912  auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);2913  if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,2914                                   nullptr, {Instruction::Call},2915                                   UsedAssumedInformation)) {2916    LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");2917    return false;2918  }2919 2920  return true;2921}2922 2923bool Attributor::registerFunctionSignatureRewrite(2924    Argument &Arg, ArrayRef<Type *> ReplacementTypes,2925    ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,2926    ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {2927  LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "2928                    << Arg.getParent()->getName() << " with "2929                    << ReplacementTypes.size() << " replacements\n");2930  assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&2931         "Cannot register an invalid rewrite");2932 2933  Function *Fn = Arg.getParent();2934  SmallVectorImpl<std::unique_ptr<ArgumentReplacementInfo>> &ARIs =2935      ArgumentReplacementMap[Fn];2936  if (ARIs.empty())2937    ARIs.resize(Fn->arg_size());2938 2939  // If we have a replacement already with less than or equal new arguments,2940  // ignore this request.2941  std::unique_ptr<ArgumentReplacementInfo> &ARI = ARIs[Arg.getArgNo()];2942  if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {2943    LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");2944    return false;2945  }2946 2947  // If we have a replacement already but we like the new one better, delete2948  // the old.2949  ARI.reset();2950 2951  LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "2952                    << Arg.getParent()->getName() << " with "2953                    << ReplacementTypes.size() << " replacements\n");2954 2955  // Remember the replacement.2956  ARI.reset(new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,2957                                        std::move(CalleeRepairCB),2958                                        std::move(ACSRepairCB)));2959 2960  return true;2961}2962 2963bool Attributor::shouldSeedAttribute(AbstractAttribute &AA) {2964  bool Result = true;2965#ifndef NDEBUG2966  if (SeedAllowList.size() != 0)2967    Result = llvm::is_contained(SeedAllowList, AA.getName());2968  Function *Fn = AA.getAnchorScope();2969  if (FunctionSeedAllowList.size() != 0 && Fn)2970    Result &= llvm::is_contained(FunctionSeedAllowList, Fn->getName());2971#endif2972  return Result;2973}2974 2975ChangeStatus Attributor::rewriteFunctionSignatures(2976    SmallSetVector<Function *, 8> &ModifiedFns) {2977  ChangeStatus Changed = ChangeStatus::UNCHANGED;2978 2979  for (auto &It : ArgumentReplacementMap) {2980    Function *OldFn = It.getFirst();2981 2982    // Deleted functions do not require rewrites.2983    if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn))2984      continue;2985 2986    const SmallVectorImpl<std::unique_ptr<ArgumentReplacementInfo>> &ARIs =2987        It.getSecond();2988    assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");2989 2990    SmallVector<Type *, 16> NewArgumentTypes;2991    SmallVector<AttributeSet, 16> NewArgumentAttributes;2992 2993    // Collect replacement argument types and copy over existing attributes.2994    AttributeList OldFnAttributeList = OldFn->getAttributes();2995    for (Argument &Arg : OldFn->args()) {2996      if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =2997              ARIs[Arg.getArgNo()]) {2998        NewArgumentTypes.append(ARI->ReplacementTypes.begin(),2999                                ARI->ReplacementTypes.end());3000        NewArgumentAttributes.append(ARI->getNumReplacementArgs(),3001                                     AttributeSet());3002      } else {3003        NewArgumentTypes.push_back(Arg.getType());3004        NewArgumentAttributes.push_back(3005            OldFnAttributeList.getParamAttrs(Arg.getArgNo()));3006      }3007    }3008 3009    uint64_t LargestVectorWidth = 0;3010    for (auto *I : NewArgumentTypes)3011      if (auto *VT = dyn_cast<llvm::VectorType>(I))3012        LargestVectorWidth =3013            std::max(LargestVectorWidth,3014                     VT->getPrimitiveSizeInBits().getKnownMinValue());3015 3016    FunctionType *OldFnTy = OldFn->getFunctionType();3017    Type *RetTy = OldFnTy->getReturnType();3018 3019    // Construct the new function type using the new arguments types.3020    FunctionType *NewFnTy =3021        FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());3022 3023    LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()3024                      << "' from " << *OldFn->getFunctionType() << " to "3025                      << *NewFnTy << "\n");3026 3027    // Create the new function body and insert it into the module.3028    Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),3029                                       OldFn->getAddressSpace(), "");3030    Functions.insert(NewFn);3031    OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);3032    NewFn->takeName(OldFn);3033    NewFn->copyAttributesFrom(OldFn);3034 3035    // Patch the pointer to LLVM function in debug info descriptor.3036    NewFn->setSubprogram(OldFn->getSubprogram());3037    OldFn->setSubprogram(nullptr);3038 3039    // Recompute the parameter attributes list based on the new arguments for3040    // the function.3041    LLVMContext &Ctx = OldFn->getContext();3042    NewFn->setAttributes(AttributeList::get(3043        Ctx, OldFnAttributeList.getFnAttrs(), OldFnAttributeList.getRetAttrs(),3044        NewArgumentAttributes));3045    AttributeFuncs::updateMinLegalVectorWidthAttr(*NewFn, LargestVectorWidth);3046 3047    // Remove argmem from the memory effects if we have no more pointer3048    // arguments, or they are readnone.3049    MemoryEffects ME = NewFn->getMemoryEffects();3050    int ArgNo = -1;3051    if (ME.doesAccessArgPointees() && all_of(NewArgumentTypes, [&](Type *T) {3052          ++ArgNo;3053          return !T->isPtrOrPtrVectorTy() ||3054                 NewFn->hasParamAttribute(ArgNo, Attribute::ReadNone);3055        })) {3056      NewFn->setMemoryEffects(ME - MemoryEffects::argMemOnly());3057    }3058 3059    // Since we have now created the new function, splice the body of the old3060    // function right into the new function, leaving the old rotting hulk of the3061    // function empty.3062    NewFn->splice(NewFn->begin(), OldFn);3063 3064    // Set of all "call-like" instructions that invoke the old function mapped3065    // to their new replacements.3066    SmallVector<std::pair<CallBase *, CallBase *>, 8> CallSitePairs;3067 3068    // Callback to create a new "call-like" instruction for a given one.3069    auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {3070      CallBase *OldCB = cast<CallBase>(ACS.getInstruction());3071      const AttributeList &OldCallAttributeList = OldCB->getAttributes();3072 3073      // Collect the new argument operands for the replacement call site.3074      SmallVector<Value *, 16> NewArgOperands;3075      SmallVector<AttributeSet, 16> NewArgOperandAttributes;3076      for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {3077        unsigned NewFirstArgNum = NewArgOperands.size();3078        (void)NewFirstArgNum; // only used inside assert.3079        if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =3080                ARIs[OldArgNum]) {3081          if (ARI->ACSRepairCB)3082            ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);3083          assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==3084                     NewArgOperands.size() &&3085                 "ACS repair callback did not provide as many operand as new "3086                 "types were registered!");3087          // TODO: Exose the attribute set to the ACS repair callback3088          NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),3089                                         AttributeSet());3090        } else {3091          NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));3092          NewArgOperandAttributes.push_back(3093              OldCallAttributeList.getParamAttrs(OldArgNum));3094        }3095      }3096 3097      assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&3098             "Mismatch # argument operands vs. # argument operand attributes!");3099      assert(NewArgOperands.size() == NewFn->arg_size() &&3100             "Mismatch # argument operands vs. # function arguments!");3101 3102      SmallVector<OperandBundleDef, 4> OperandBundleDefs;3103      OldCB->getOperandBundlesAsDefs(OperandBundleDefs);3104 3105      // Create a new call or invoke instruction to replace the old one.3106      CallBase *NewCB;3107      if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {3108        NewCB = InvokeInst::Create(NewFn, II->getNormalDest(),3109                                   II->getUnwindDest(), NewArgOperands,3110                                   OperandBundleDefs, "", OldCB->getIterator());3111      } else {3112        auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,3113                                       "", OldCB->getIterator());3114        NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());3115        NewCB = NewCI;3116      }3117 3118      // Copy over various properties and the new attributes.3119      NewCB->copyMetadata(*OldCB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});3120      NewCB->setCallingConv(OldCB->getCallingConv());3121      NewCB->takeName(OldCB);3122      NewCB->setAttributes(AttributeList::get(3123          Ctx, OldCallAttributeList.getFnAttrs(),3124          OldCallAttributeList.getRetAttrs(), NewArgOperandAttributes));3125 3126      AttributeFuncs::updateMinLegalVectorWidthAttr(*NewCB->getCaller(),3127                                                    LargestVectorWidth);3128 3129      CallSitePairs.push_back({OldCB, NewCB});3130      return true;3131    };3132 3133    // Use the CallSiteReplacementCreator to create replacement call sites.3134    bool UsedAssumedInformation = false;3135    bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,3136                                        true, nullptr, UsedAssumedInformation,3137                                        /* CheckPotentiallyDead */ true);3138    (void)Success;3139    assert(Success && "Assumed call site replacement to succeed!");3140 3141    // Rewire the arguments.3142    Argument *OldFnArgIt = OldFn->arg_begin();3143    Argument *NewFnArgIt = NewFn->arg_begin();3144    for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();3145         ++OldArgNum, ++OldFnArgIt) {3146      if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =3147              ARIs[OldArgNum]) {3148        if (ARI->CalleeRepairCB)3149          ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);3150        if (ARI->ReplacementTypes.empty())3151          OldFnArgIt->replaceAllUsesWith(3152              PoisonValue::get(OldFnArgIt->getType()));3153        NewFnArgIt += ARI->ReplacementTypes.size();3154      } else {3155        NewFnArgIt->takeName(&*OldFnArgIt);3156        OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);3157        ++NewFnArgIt;3158      }3159    }3160 3161    // Eliminate the instructions *after* we visited all of them.3162    for (auto &CallSitePair : CallSitePairs) {3163      CallBase &OldCB = *CallSitePair.first;3164      CallBase &NewCB = *CallSitePair.second;3165      assert(OldCB.getType() == NewCB.getType() &&3166             "Cannot handle call sites with different types!");3167      ModifiedFns.insert(OldCB.getFunction());3168      OldCB.replaceAllUsesWith(&NewCB);3169      OldCB.eraseFromParent();3170    }3171 3172    // Replace the function in the call graph (if any).3173    Configuration.CGUpdater.replaceFunctionWith(*OldFn, *NewFn);3174 3175    // If the old function was modified and needed to be reanalyzed, the new one3176    // does now.3177    if (ModifiedFns.remove(OldFn))3178      ModifiedFns.insert(NewFn);3179 3180    Changed = ChangeStatus::CHANGED;3181  }3182 3183  return Changed;3184}3185 3186void InformationCache::initializeInformationCache(const Function &CF,3187                                                  FunctionInfo &FI) {3188  // As we do not modify the function here we can remove the const3189  // withouth breaking implicit assumptions. At the end of the day, we could3190  // initialize the cache eagerly which would look the same to the users.3191  Function &F = const_cast<Function &>(CF);3192 3193  FI.IsKernel = F.hasFnAttribute("kernel");3194 3195  // Walk all instructions to find interesting instructions that might be3196  // queried by abstract attributes during their initialization or update.3197  // This has to happen before we create attributes.3198 3199  DenseMap<const Value *, std::optional<short>> AssumeUsesMap;3200 3201  // Add \p V to the assume uses map which track the number of uses outside of3202  // "visited" assumes. If no outside uses are left the value is added to the3203  // assume only use vector.3204  auto AddToAssumeUsesMap = [&](const Value &V) -> void {3205    SmallVector<const Instruction *> Worklist;3206    if (auto *I = dyn_cast<Instruction>(&V))3207      Worklist.push_back(I);3208    while (!Worklist.empty()) {3209      const Instruction *I = Worklist.pop_back_val();3210      std::optional<short> &NumUses = AssumeUsesMap[I];3211      if (!NumUses)3212        NumUses = I->getNumUses();3213      NumUses = *NumUses - /* this assume */ 1;3214      if (*NumUses != 0)3215        continue;3216      AssumeOnlyValues.insert(I);3217      for (const Value *Op : I->operands())3218        if (auto *OpI = dyn_cast<Instruction>(Op))3219          Worklist.push_back(OpI);3220    }3221  };3222 3223  for (Instruction &I : instructions(&F)) {3224    bool IsInterestingOpcode = false;3225 3226    // To allow easy access to all instructions in a function with a given3227    // opcode we store them in the InfoCache. As not all opcodes are interesting3228    // to concrete attributes we only cache the ones that are as identified in3229    // the following switch.3230    // Note: There are no concrete attributes now so this is initially empty.3231    switch (I.getOpcode()) {3232    default:3233      assert(!isa<CallBase>(&I) &&3234             "New call base instruction type needs to be known in the "3235             "Attributor.");3236      break;3237    case Instruction::Call:3238      // Calls are interesting on their own, additionally:3239      // For `llvm.assume` calls we also fill the KnowledgeMap as we find them.3240      // For `must-tail` calls we remember the caller and callee.3241      if (auto *Assume = dyn_cast<AssumeInst>(&I)) {3242        AssumeOnlyValues.insert(Assume);3243        fillMapFromAssume(*Assume, KnowledgeMap);3244        AddToAssumeUsesMap(*Assume->getArgOperand(0));3245      } else if (cast<CallInst>(I).isMustTailCall()) {3246        FI.ContainsMustTailCall = true;3247        if (auto *Callee = dyn_cast_if_present<Function>(3248                cast<CallInst>(I).getCalledOperand()))3249          getFunctionInfo(*Callee).CalledViaMustTail = true;3250      }3251      [[fallthrough]];3252    case Instruction::CallBr:3253    case Instruction::Invoke:3254    case Instruction::CleanupRet:3255    case Instruction::CatchSwitch:3256    case Instruction::AtomicRMW:3257    case Instruction::AtomicCmpXchg:3258    case Instruction::Br:3259    case Instruction::Resume:3260    case Instruction::Ret:3261    case Instruction::Load:3262      // The alignment of a pointer is interesting for loads.3263    case Instruction::Store:3264      // The alignment of a pointer is interesting for stores.3265    case Instruction::Alloca:3266    case Instruction::AddrSpaceCast:3267      IsInterestingOpcode = true;3268    }3269    if (IsInterestingOpcode) {3270      auto *&Insts = FI.OpcodeInstMap[I.getOpcode()];3271      if (!Insts)3272        Insts = new (Allocator) InstructionVectorTy();3273      Insts->push_back(&I);3274    }3275    if (I.mayReadOrWriteMemory())3276      FI.RWInsts.push_back(&I);3277  }3278 3279  if (F.hasFnAttribute(Attribute::AlwaysInline) &&3280      isInlineViable(F).isSuccess())3281    InlineableFunctions.insert(&F);3282}3283 3284InformationCache::FunctionInfo::~FunctionInfo() {3285  // The instruction vectors are allocated using a BumpPtrAllocator, we need to3286  // manually destroy them.3287  for (auto &It : OpcodeInstMap)3288    It.getSecond()->~InstructionVectorTy();3289}3290 3291ArrayRef<Function *>3292InformationCache::getIndirectlyCallableFunctions(Attributor &A) const {3293  assert(A.isClosedWorldModule() && "Cannot see all indirect callees!");3294  return IndirectlyCallableFunctions;3295}3296 3297std::optional<unsigned> InformationCache::getFlatAddressSpace() const {3298  if (TargetTriple.isGPU())3299    return 0;3300  return std::nullopt;3301}3302 3303void Attributor::recordDependence(const AbstractAttribute &FromAA,3304                                  const AbstractAttribute &ToAA,3305                                  DepClassTy DepClass) {3306  if (DepClass == DepClassTy::NONE)3307    return;3308  // If we are outside of an update, thus before the actual fixpoint iteration3309  // started (= when we create AAs), we do not track dependences because we will3310  // put all AAs into the initial worklist anyway.3311  if (DependenceStack.empty())3312    return;3313  if (FromAA.getState().isAtFixpoint())3314    return;3315  DependenceStack.back()->push_back({&FromAA, &ToAA, DepClass});3316}3317 3318void Attributor::rememberDependences() {3319  assert(!DependenceStack.empty() && "No dependences to remember!");3320 3321  for (DepInfo &DI : *DependenceStack.back()) {3322    assert((DI.DepClass == DepClassTy::REQUIRED ||3323            DI.DepClass == DepClassTy::OPTIONAL) &&3324           "Expected required or optional dependence (1 bit)!");3325    auto &DepAAs = const_cast<AbstractAttribute &>(*DI.FromAA).Deps;3326    DepAAs.insert(AbstractAttribute::DepTy(3327        const_cast<AbstractAttribute *>(DI.ToAA), unsigned(DI.DepClass)));3328  }3329}3330 3331template <Attribute::AttrKind AK, typename AAType>3332void Attributor::checkAndQueryIRAttr(const IRPosition &IRP, AttributeSet Attrs,3333                                     bool SkipHasAttrCheck) {3334  bool IsKnown;3335  if (SkipHasAttrCheck || !Attrs.hasAttribute(AK))3336    if (!Configuration.Allowed || Configuration.Allowed->count(&AAType::ID))3337      if (!AA::hasAssumedIRAttr<AK>(*this, nullptr, IRP, DepClassTy::NONE,3338                                    IsKnown))3339        getOrCreateAAFor<AAType>(IRP);3340}3341 3342void Attributor::identifyDefaultAbstractAttributes(Function &F) {3343  if (!VisitedFunctions.insert(&F).second)3344    return;3345  if (F.isDeclaration())3346    return;3347 3348  // In non-module runs we need to look at the call sites of a function to3349  // determine if it is part of a must-tail call edge. This will influence what3350  // attributes we can derive.3351  InformationCache::FunctionInfo &FI = InfoCache.getFunctionInfo(F);3352  if (!isModulePass() && !FI.CalledViaMustTail) {3353    for (const Use &U : F.uses())3354      if (const auto *CB = dyn_cast<CallBase>(U.getUser()))3355        if (CB->isCallee(&U) && CB->isMustTailCall())3356          FI.CalledViaMustTail = true;3357  }3358 3359  IRPosition FPos = IRPosition::function(F);3360  bool IsIPOAmendable = isFunctionIPOAmendable(F);3361  auto Attrs = F.getAttributes();3362  auto FnAttrs = Attrs.getFnAttrs();3363 3364  // Check for dead BasicBlocks in every function.3365  // We need dead instruction detection because we do not want to deal with3366  // broken IR in which SSA rules do not apply.3367  getOrCreateAAFor<AAIsDead>(FPos);3368 3369  // Every function might contain instructions that cause "undefined3370  // behavior".3371  getOrCreateAAFor<AAUndefinedBehavior>(FPos);3372 3373  // Every function might be applicable for Heap-To-Stack conversion.3374  if (EnableHeapToStack)3375    getOrCreateAAFor<AAHeapToStack>(FPos);3376 3377  // Every function might be "must-progress".3378  checkAndQueryIRAttr<Attribute::MustProgress, AAMustProgress>(FPos, FnAttrs);3379 3380  // Every function might be "no-free".3381  checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(FPos, FnAttrs);3382 3383  // Every function might be "will-return".3384  checkAndQueryIRAttr<Attribute::WillReturn, AAWillReturn>(FPos, FnAttrs);3385 3386  // Every function might be marked "nosync"3387  checkAndQueryIRAttr<Attribute::NoSync, AANoSync>(FPos, FnAttrs);3388 3389  // Everything that is visible from the outside (=function, argument, return3390  // positions), cannot be changed if the function is not IPO amendable. We can3391  // however analyse the code inside.3392  if (IsIPOAmendable) {3393 3394    // Every function can be nounwind.3395    checkAndQueryIRAttr<Attribute::NoUnwind, AANoUnwind>(FPos, FnAttrs);3396 3397    // Every function might be "no-return".3398    checkAndQueryIRAttr<Attribute::NoReturn, AANoReturn>(FPos, FnAttrs);3399 3400    // Every function might be "no-recurse".3401    checkAndQueryIRAttr<Attribute::NoRecurse, AANoRecurse>(FPos, FnAttrs);3402 3403    // Every function can be "non-convergent".3404    if (Attrs.hasFnAttr(Attribute::Convergent))3405      getOrCreateAAFor<AANonConvergent>(FPos);3406 3407    // Every function might be "readnone/readonly/writeonly/...".3408    getOrCreateAAFor<AAMemoryBehavior>(FPos);3409 3410    // Every function can be "readnone/argmemonly/inaccessiblememonly/...".3411    getOrCreateAAFor<AAMemoryLocation>(FPos);3412 3413    // Every function can track active assumptions.3414    getOrCreateAAFor<AAAssumptionInfo>(FPos);3415 3416    // If we're not using a dynamic mode for float, there's nothing worthwhile3417    // to infer. This misses the edge case denormal-fp-math="dynamic" and3418    // denormal-fp-math-f32=something, but that likely has no real world use.3419    DenormalMode Mode = F.getDenormalMode(APFloat::IEEEsingle());3420    if (Mode.Input == DenormalMode::Dynamic ||3421        Mode.Output == DenormalMode::Dynamic)3422      getOrCreateAAFor<AADenormalFPMath>(FPos);3423 3424    // Return attributes are only appropriate if the return type is non void.3425    Type *ReturnType = F.getReturnType();3426    if (!ReturnType->isVoidTy()) {3427      IRPosition RetPos = IRPosition::returned(F);3428      AttributeSet RetAttrs = Attrs.getRetAttrs();3429 3430      // Every returned value might be dead.3431      getOrCreateAAFor<AAIsDead>(RetPos);3432 3433      // Every function might be simplified.3434      bool UsedAssumedInformation = false;3435      getAssumedSimplified(RetPos, nullptr, UsedAssumedInformation,3436                           AA::Intraprocedural);3437 3438      // Every returned value might be marked noundef.3439      checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(RetPos, RetAttrs);3440 3441      if (ReturnType->isPointerTy()) {3442 3443        // Every function with pointer return type might be marked align.3444        getOrCreateAAFor<AAAlign>(RetPos);3445 3446        // Every function with pointer return type might be marked nonnull.3447        checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(RetPos, RetAttrs);3448 3449        // Every function with pointer return type might be marked noalias.3450        checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(RetPos, RetAttrs);3451 3452        // Every function with pointer return type might be marked3453        // dereferenceable.3454        getOrCreateAAFor<AADereferenceable>(RetPos);3455      } else if (AttributeFuncs::isNoFPClassCompatibleType(ReturnType)) {3456        getOrCreateAAFor<AANoFPClass>(RetPos);3457      }3458    }3459  }3460 3461  for (Argument &Arg : F.args()) {3462    IRPosition ArgPos = IRPosition::argument(Arg);3463    auto ArgNo = Arg.getArgNo();3464    AttributeSet ArgAttrs = Attrs.getParamAttrs(ArgNo);3465 3466    if (!IsIPOAmendable) {3467      if (Arg.getType()->isPointerTy())3468        // Every argument with pointer type might be marked nofree.3469        checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);3470      continue;3471    }3472 3473    // Every argument might be simplified. We have to go through the3474    // Attributor interface though as outside AAs can register custom3475    // simplification callbacks.3476    bool UsedAssumedInformation = false;3477    getAssumedSimplified(ArgPos, /* AA */ nullptr, UsedAssumedInformation,3478                         AA::Intraprocedural);3479 3480    // Every argument might be dead.3481    getOrCreateAAFor<AAIsDead>(ArgPos);3482 3483    // Every argument might be marked noundef.3484    checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(ArgPos, ArgAttrs);3485 3486    if (Arg.getType()->isPointerTy()) {3487      // Every argument with pointer type might be marked nonnull.3488      checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(ArgPos, ArgAttrs);3489 3490      // Every argument with pointer type might be marked noalias.3491      checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(ArgPos, ArgAttrs);3492 3493      // Every argument with pointer type might be marked dereferenceable.3494      getOrCreateAAFor<AADereferenceable>(ArgPos);3495 3496      // Every argument with pointer type might be marked align.3497      getOrCreateAAFor<AAAlign>(ArgPos);3498 3499      // Every argument with pointer type might be marked nocapture.3500      checkAndQueryIRAttr<Attribute::Captures, AANoCapture>(3501          ArgPos, ArgAttrs, /*SkipHasAttrCheck=*/true);3502 3503      // Every argument with pointer type might be marked3504      // "readnone/readonly/writeonly/..."3505      getOrCreateAAFor<AAMemoryBehavior>(ArgPos);3506 3507      // Every argument with pointer type might be marked nofree.3508      checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);3509 3510      // Every argument with pointer type might be privatizable (or3511      // promotable)3512      getOrCreateAAFor<AAPrivatizablePtr>(ArgPos);3513    } else if (AttributeFuncs::isNoFPClassCompatibleType(Arg.getType())) {3514      getOrCreateAAFor<AANoFPClass>(ArgPos);3515    }3516  }3517 3518  auto CallSitePred = [&](Instruction &I) -> bool {3519    auto &CB = cast<CallBase>(I);3520    IRPosition CBInstPos = IRPosition::inst(CB);3521    IRPosition CBFnPos = IRPosition::callsite_function(CB);3522 3523    // Call sites might be dead if they do not have side effects and no live3524    // users. The return value might be dead if there are no live users.3525    getOrCreateAAFor<AAIsDead>(CBInstPos);3526 3527    Function *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());3528    // TODO: Even if the callee is not known now we might be able to simplify3529    //       the call/callee.3530    if (!Callee) {3531      getOrCreateAAFor<AAIndirectCallInfo>(CBFnPos);3532      return true;3533    }3534 3535    // Every call site can track active assumptions.3536    getOrCreateAAFor<AAAssumptionInfo>(CBFnPos);3537 3538    // Skip declarations except if annotations on their call sites were3539    // explicitly requested.3540    if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&3541        !Callee->hasMetadata(LLVMContext::MD_callback))3542      return true;3543 3544    if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {3545      IRPosition CBRetPos = IRPosition::callsite_returned(CB);3546      bool UsedAssumedInformation = false;3547      getAssumedSimplified(CBRetPos, nullptr, UsedAssumedInformation,3548                           AA::Intraprocedural);3549 3550      if (AttributeFuncs::isNoFPClassCompatibleType(Callee->getReturnType()))3551        getOrCreateAAFor<AANoFPClass>(CBInstPos);3552    }3553 3554    const AttributeList &CBAttrs = CBFnPos.getAttrList();3555    for (int I = 0, E = CB.arg_size(); I < E; ++I) {3556 3557      IRPosition CBArgPos = IRPosition::callsite_argument(CB, I);3558      AttributeSet CBArgAttrs = CBAttrs.getParamAttrs(I);3559 3560      // Every call site argument might be dead.3561      getOrCreateAAFor<AAIsDead>(CBArgPos);3562 3563      // Call site argument might be simplified. We have to go through the3564      // Attributor interface though as outside AAs can register custom3565      // simplification callbacks.3566      bool UsedAssumedInformation = false;3567      getAssumedSimplified(CBArgPos, /* AA */ nullptr, UsedAssumedInformation,3568                           AA::Intraprocedural);3569 3570      // Every call site argument might be marked "noundef".3571      checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(CBArgPos, CBArgAttrs);3572 3573      Type *ArgTy = CB.getArgOperand(I)->getType();3574 3575      if (!ArgTy->isPointerTy()) {3576        if (AttributeFuncs::isNoFPClassCompatibleType(ArgTy))3577          getOrCreateAAFor<AANoFPClass>(CBArgPos);3578 3579        continue;3580      }3581 3582      // Call site argument attribute "non-null".3583      checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(CBArgPos, CBArgAttrs);3584 3585      // Call site argument attribute "captures(none)".3586      checkAndQueryIRAttr<Attribute::Captures, AANoCapture>(3587          CBArgPos, CBArgAttrs, /*SkipHasAttrCheck=*/true);3588 3589      // Call site argument attribute "no-alias".3590      checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(CBArgPos, CBArgAttrs);3591 3592      // Call site argument attribute "dereferenceable".3593      getOrCreateAAFor<AADereferenceable>(CBArgPos);3594 3595      // Call site argument attribute "align".3596      getOrCreateAAFor<AAAlign>(CBArgPos);3597 3598      // Call site argument attribute3599      // "readnone/readonly/writeonly/..."3600      if (!CBAttrs.hasParamAttr(I, Attribute::ReadNone))3601        getOrCreateAAFor<AAMemoryBehavior>(CBArgPos);3602 3603      // Call site argument attribute "nofree".3604      checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(CBArgPos, CBArgAttrs);3605    }3606    return true;3607  };3608 3609  auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);3610  [[maybe_unused]] bool Success;3611  bool UsedAssumedInformation = false;3612  Success = checkForAllInstructionsImpl(3613      nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,3614      {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,3615       (unsigned)Instruction::Call},3616      UsedAssumedInformation);3617  assert(Success && "Expected the check call to be successful!");3618 3619  auto LoadStorePred = [&](Instruction &I) -> bool {3620    if (auto *LI = dyn_cast<LoadInst>(&I)) {3621      getOrCreateAAFor<AAAlign>(IRPosition::value(*LI->getPointerOperand()));3622      if (SimplifyAllLoads)3623        getAssumedSimplified(IRPosition::value(I), nullptr,3624                             UsedAssumedInformation, AA::Intraprocedural);3625      getOrCreateAAFor<AAInvariantLoadPointer>(3626          IRPosition::value(*LI->getPointerOperand()));3627      getOrCreateAAFor<AAAddressSpace>(3628          IRPosition::value(*LI->getPointerOperand()));3629    } else {3630      auto &SI = cast<StoreInst>(I);3631      getOrCreateAAFor<AAIsDead>(IRPosition::inst(I));3632      getAssumedSimplified(IRPosition::value(*SI.getValueOperand()), nullptr,3633                           UsedAssumedInformation, AA::Intraprocedural);3634      getOrCreateAAFor<AAAlign>(IRPosition::value(*SI.getPointerOperand()));3635      getOrCreateAAFor<AAAddressSpace>(3636          IRPosition::value(*SI.getPointerOperand()));3637    }3638    return true;3639  };3640  Success = checkForAllInstructionsImpl(3641      nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,3642      {(unsigned)Instruction::Load, (unsigned)Instruction::Store},3643      UsedAssumedInformation);3644  assert(Success && "Expected the check call to be successful!");3645 3646  // AllocaInstPredicate3647  auto AAAllocationInfoPred = [&](Instruction &I) -> bool {3648    getOrCreateAAFor<AAAllocationInfo>(IRPosition::value(I));3649    return true;3650  };3651 3652  Success = checkForAllInstructionsImpl(3653      nullptr, OpcodeInstMap, AAAllocationInfoPred, nullptr, nullptr,3654      {(unsigned)Instruction::Alloca}, UsedAssumedInformation);3655  assert(Success && "Expected the check call to be successful!");3656}3657 3658bool Attributor::isClosedWorldModule() const {3659  if (CloseWorldAssumption.getNumOccurrences())3660    return CloseWorldAssumption;3661  return isModulePass() && Configuration.IsClosedWorldModule;3662}3663 3664/// Helpers to ease debugging through output streams and print calls.3665///3666///{3667raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {3668  return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");3669}3670 3671raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {3672  switch (AP) {3673  case IRPosition::IRP_INVALID:3674    return OS << "inv";3675  case IRPosition::IRP_FLOAT:3676    return OS << "flt";3677  case IRPosition::IRP_RETURNED:3678    return OS << "fn_ret";3679  case IRPosition::IRP_CALL_SITE_RETURNED:3680    return OS << "cs_ret";3681  case IRPosition::IRP_FUNCTION:3682    return OS << "fn";3683  case IRPosition::IRP_CALL_SITE:3684    return OS << "cs";3685  case IRPosition::IRP_ARGUMENT:3686    return OS << "arg";3687  case IRPosition::IRP_CALL_SITE_ARGUMENT:3688    return OS << "cs_arg";3689  }3690  llvm_unreachable("Unknown attribute position!");3691}3692 3693raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {3694  const Value &AV = Pos.getAssociatedValue();3695  OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["3696     << Pos.getAnchorValue().getName() << "@" << Pos.getCallSiteArgNo() << "]";3697 3698  if (Pos.hasCallBaseContext())3699    OS << "[cb_context:" << *Pos.getCallBaseContext() << "]";3700  return OS << "}";3701}3702 3703raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerRangeState &S) {3704  OS << "range-state(" << S.getBitWidth() << ")<";3705  S.getKnown().print(OS);3706  OS << " / ";3707  S.getAssumed().print(OS);3708  OS << ">";3709 3710  return OS << static_cast<const AbstractState &>(S);3711}3712 3713raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {3714  return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));3715}3716 3717raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {3718  AA.print(OS);3719  return OS;3720}3721 3722raw_ostream &llvm::operator<<(raw_ostream &OS,3723                              const PotentialConstantIntValuesState &S) {3724  OS << "set-state(< {";3725  if (!S.isValidState())3726    OS << "full-set";3727  else {3728    for (const auto &It : S.getAssumedSet())3729      OS << It << ", ";3730    if (S.undefIsContained())3731      OS << "undef ";3732  }3733  OS << "} >)";3734 3735  return OS;3736}3737 3738raw_ostream &llvm::operator<<(raw_ostream &OS,3739                              const PotentialLLVMValuesState &S) {3740  OS << "set-state(< {";3741  if (!S.isValidState())3742    OS << "full-set";3743  else {3744    for (const auto &It : S.getAssumedSet()) {3745      if (auto *F = dyn_cast<Function>(It.first.getValue()))3746        OS << "@" << F->getName() << "[" << int(It.second) << "], ";3747      else3748        OS << *It.first.getValue() << "[" << int(It.second) << "], ";3749    }3750    if (S.undefIsContained())3751      OS << "undef ";3752  }3753  OS << "} >)";3754 3755  return OS;3756}3757 3758void AbstractAttribute::print(Attributor *A, raw_ostream &OS) const {3759  OS << "[";3760  OS << getName();3761  OS << "] for CtxI ";3762 3763  if (auto *I = getCtxI()) {3764    OS << "'";3765    I->print(OS);3766    OS << "'";3767  } else3768    OS << "<<null inst>>";3769 3770  OS << " at position " << getIRPosition() << " with state " << getAsStr(A)3771     << '\n';3772}3773 3774void AbstractAttribute::printWithDeps(raw_ostream &OS) const {3775  print(OS);3776 3777  for (const auto &DepAA : Deps) {3778    auto *AA = DepAA.getPointer();3779    OS << "  updates ";3780    AA->print(OS);3781  }3782 3783  OS << '\n';3784}3785 3786raw_ostream &llvm::operator<<(raw_ostream &OS,3787                              const AAPointerInfo::Access &Acc) {3788  OS << " [" << Acc.getKind() << "] " << *Acc.getRemoteInst();3789  if (Acc.getLocalInst() != Acc.getRemoteInst())3790    OS << " via " << *Acc.getLocalInst();3791  if (Acc.getContent()) {3792    if (*Acc.getContent())3793      OS << " [" << **Acc.getContent() << "]";3794    else3795      OS << " [ <unknown> ]";3796  }3797  return OS;3798}3799///}3800 3801/// ----------------------------------------------------------------------------3802///                       Pass (Manager) Boilerplate3803/// ----------------------------------------------------------------------------3804 3805static bool runAttributorOnFunctions(InformationCache &InfoCache,3806                                     SetVector<Function *> &Functions,3807                                     AnalysisGetter &AG,3808                                     CallGraphUpdater &CGUpdater,3809                                     bool DeleteFns, bool IsModulePass) {3810  if (Functions.empty())3811    return false;3812 3813  LLVM_DEBUG({3814    dbgs() << "[Attributor] Run on module with " << Functions.size()3815           << " functions:\n";3816    for (Function *Fn : Functions)3817      dbgs() << "  - " << Fn->getName() << "\n";3818  });3819 3820  // Create an Attributor and initially empty information cache that is filled3821  // while we identify default attribute opportunities.3822  AttributorConfig AC(CGUpdater);3823  AC.IsModulePass = IsModulePass;3824  AC.DeleteFns = DeleteFns;3825 3826  /// Tracking callback for specialization of indirect calls.3827  DenseMap<CallBase *, std::unique_ptr<SmallPtrSet<Function *, 8>>>3828      IndirectCalleeTrackingMap;3829  if (MaxSpecializationPerCB.getNumOccurrences()) {3830    AC.IndirectCalleeSpecializationCallback =3831        [&](Attributor &, const AbstractAttribute &AA, CallBase &CB,3832            Function &Callee, unsigned) {3833          if (MaxSpecializationPerCB == 0)3834            return false;3835          auto &Set = IndirectCalleeTrackingMap[&CB];3836          if (!Set)3837            Set = std::make_unique<SmallPtrSet<Function *, 8>>();3838          if (Set->size() >= MaxSpecializationPerCB)3839            return Set->contains(&Callee);3840          Set->insert(&Callee);3841          return true;3842        };3843  }3844 3845  Attributor A(Functions, InfoCache, AC);3846 3847  // Create shallow wrappers for all functions that are not IPO amendable3848  if (AllowShallowWrappers)3849    for (Function *F : Functions)3850      if (!A.isFunctionIPOAmendable(*F))3851        Attributor::createShallowWrapper(*F);3852 3853  // Internalize non-exact functions3854  // TODO: for now we eagerly internalize functions without calculating the3855  //       cost, we need a cost interface to determine whether internalizing3856  //       a function is "beneficial"3857  if (AllowDeepWrapper) {3858    unsigned FunSize = Functions.size();3859    for (unsigned u = 0; u < FunSize; u++) {3860      Function *F = Functions[u];3861      if (!F->isDeclaration() && !F->isDefinitionExact() && !F->use_empty() &&3862          !GlobalValue::isInterposableLinkage(F->getLinkage())) {3863        Function *NewF = Attributor::internalizeFunction(*F);3864        assert(NewF && "Could not internalize function.");3865        Functions.insert(NewF);3866 3867        // Update call graph3868        CGUpdater.replaceFunctionWith(*F, *NewF);3869        for (const Use &U : NewF->uses())3870          if (CallBase *CB = dyn_cast<CallBase>(U.getUser())) {3871            auto *CallerF = CB->getCaller();3872            CGUpdater.reanalyzeFunction(*CallerF);3873          }3874      }3875    }3876  }3877 3878  for (Function *F : Functions) {3879    if (F->hasExactDefinition())3880      NumFnWithExactDefinition++;3881    else3882      NumFnWithoutExactDefinition++;3883 3884    // We look at internal functions only on-demand but if any use is not a3885    // direct call or outside the current set of analyzed functions, we have3886    // to do it eagerly.3887    if (F->hasLocalLinkage()) {3888      if (llvm::all_of(F->uses(), [&Functions](const Use &U) {3889            const auto *CB = dyn_cast<CallBase>(U.getUser());3890            return CB && CB->isCallee(&U) &&3891                   Functions.count(const_cast<Function *>(CB->getCaller()));3892          }))3893        continue;3894    }3895 3896    // Populate the Attributor with abstract attribute opportunities in the3897    // function and the information cache with IR information.3898    A.identifyDefaultAbstractAttributes(*F);3899  }3900 3901  ChangeStatus Changed = A.run();3902 3903  LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()3904                    << " functions, result: " << Changed << ".\n");3905  return Changed == ChangeStatus::CHANGED;3906}3907 3908static bool runAttributorLightOnFunctions(InformationCache &InfoCache,3909                                          SetVector<Function *> &Functions,3910                                          AnalysisGetter &AG,3911                                          CallGraphUpdater &CGUpdater,3912                                          FunctionAnalysisManager &FAM,3913                                          bool IsModulePass) {3914  if (Functions.empty())3915    return false;3916 3917  LLVM_DEBUG({3918    dbgs() << "[AttributorLight] Run on module with " << Functions.size()3919           << " functions:\n";3920    for (Function *Fn : Functions)3921      dbgs() << "  - " << Fn->getName() << "\n";3922  });3923 3924  // Create an Attributor and initially empty information cache that is filled3925  // while we identify default attribute opportunities.3926  AttributorConfig AC(CGUpdater);3927  AC.IsModulePass = IsModulePass;3928  AC.DeleteFns = false;3929  DenseSet<const char *> Allowed(3930      {&AAWillReturn::ID, &AANoUnwind::ID, &AANoRecurse::ID, &AANoSync::ID,3931       &AANoFree::ID, &AANoReturn::ID, &AAMemoryLocation::ID,3932       &AAMemoryBehavior::ID, &AAUnderlyingObjects::ID, &AANoCapture::ID,3933       &AAInterFnReachability::ID, &AAIntraFnReachability::ID, &AACallEdges::ID,3934       &AANoFPClass::ID, &AAMustProgress::ID, &AANonNull::ID});3935  AC.Allowed = &Allowed;3936  AC.UseLiveness = false;3937 3938  Attributor A(Functions, InfoCache, AC);3939 3940  for (Function *F : Functions) {3941    if (F->hasExactDefinition())3942      NumFnWithExactDefinition++;3943    else3944      NumFnWithoutExactDefinition++;3945 3946    // We look at internal functions only on-demand but if any use is not a3947    // direct call or outside the current set of analyzed functions, we have3948    // to do it eagerly.3949    if (AC.UseLiveness && F->hasLocalLinkage()) {3950      if (llvm::all_of(F->uses(), [&Functions](const Use &U) {3951            const auto *CB = dyn_cast<CallBase>(U.getUser());3952            return CB && CB->isCallee(&U) &&3953                   Functions.count(const_cast<Function *>(CB->getCaller()));3954          }))3955        continue;3956    }3957 3958    // Populate the Attributor with abstract attribute opportunities in the3959    // function and the information cache with IR information.3960    A.identifyDefaultAbstractAttributes(*F);3961  }3962 3963  ChangeStatus Changed = A.run();3964 3965  if (Changed == ChangeStatus::CHANGED) {3966    // Invalidate analyses for modified functions so that we don't have to3967    // invalidate all analyses for all functions in this SCC.3968    PreservedAnalyses FuncPA;3969    // We haven't changed the CFG for modified functions.3970    FuncPA.preserveSet<CFGAnalyses>();3971    for (Function *Changed : A.getModifiedFunctions()) {3972      FAM.invalidate(*Changed, FuncPA);3973      // Also invalidate any direct callers of changed functions since analyses3974      // may care about attributes of direct callees. For example, MemorySSA3975      // cares about whether or not a call's callee modifies memory and queries3976      // that through function attributes.3977      for (auto *U : Changed->users()) {3978        if (auto *Call = dyn_cast<CallBase>(U)) {3979          if (Call->getCalledFunction() == Changed)3980            FAM.invalidate(*Call->getFunction(), FuncPA);3981        }3982      }3983    }3984  }3985  LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()3986                    << " functions, result: " << Changed << ".\n");3987  return Changed == ChangeStatus::CHANGED;3988}3989 3990void AADepGraph::viewGraph() { llvm::ViewGraph(this, "Dependency Graph"); }3991 3992void AADepGraph::dumpGraph() {3993  static std::atomic<int> CallTimes;3994  std::string Prefix;3995 3996  if (!DepGraphDotFileNamePrefix.empty())3997    Prefix = DepGraphDotFileNamePrefix;3998  else3999    Prefix = "dep_graph";4000  std::string Filename =4001      Prefix + "_" + std::to_string(CallTimes.load()) + ".dot";4002 4003  outs() << "Dependency graph dump to " << Filename << ".\n";4004 4005  std::error_code EC;4006 4007  raw_fd_ostream File(Filename, EC, sys::fs::OF_TextWithCRLF);4008  if (!EC)4009    llvm::WriteGraph(File, this);4010 4011  CallTimes++;4012}4013 4014void AADepGraph::print() {4015  for (auto DepAA : SyntheticRoot.Deps)4016    cast<AbstractAttribute>(DepAA.getPointer())->printWithDeps(outs());4017}4018 4019PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {4020  FunctionAnalysisManager &FAM =4021      AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();4022  AnalysisGetter AG(FAM);4023 4024  SetVector<Function *> Functions;4025  for (Function &F : M)4026    Functions.insert(&F);4027 4028  CallGraphUpdater CGUpdater;4029  BumpPtrAllocator Allocator;4030  InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);4031  if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater,4032                               /* DeleteFns */ true, /* IsModulePass */ true)) {4033    // FIXME: Think about passes we will preserve and add them here.4034    return PreservedAnalyses::none();4035  }4036  return PreservedAnalyses::all();4037}4038 4039PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C,4040                                           CGSCCAnalysisManager &AM,4041                                           LazyCallGraph &CG,4042                                           CGSCCUpdateResult &UR) {4043  FunctionAnalysisManager &FAM =4044      AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();4045  AnalysisGetter AG(FAM);4046 4047  SetVector<Function *> Functions;4048  for (LazyCallGraph::Node &N : C)4049    Functions.insert(&N.getFunction());4050 4051  if (Functions.empty())4052    return PreservedAnalyses::all();4053 4054  Module &M = *Functions.back()->getParent();4055  CallGraphUpdater CGUpdater;4056  CGUpdater.initialize(CG, C, AM, UR);4057  BumpPtrAllocator Allocator;4058  InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);4059  if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater,4060                               /* DeleteFns */ false,4061                               /* IsModulePass */ false)) {4062    // FIXME: Think about passes we will preserve and add them here.4063    PreservedAnalyses PA;4064    PA.preserve<FunctionAnalysisManagerCGSCCProxy>();4065    return PA;4066  }4067  return PreservedAnalyses::all();4068}4069 4070PreservedAnalyses AttributorLightPass::run(Module &M,4071                                           ModuleAnalysisManager &AM) {4072  FunctionAnalysisManager &FAM =4073      AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();4074  AnalysisGetter AG(FAM, /* CachedOnly */ true);4075 4076  SetVector<Function *> Functions;4077  for (Function &F : M)4078    Functions.insert(&F);4079 4080  CallGraphUpdater CGUpdater;4081  BumpPtrAllocator Allocator;4082  InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);4083  if (runAttributorLightOnFunctions(InfoCache, Functions, AG, CGUpdater, FAM,4084                                    /* IsModulePass */ true)) {4085    PreservedAnalyses PA;4086    // We have not added or removed functions.4087    PA.preserve<FunctionAnalysisManagerCGSCCProxy>();4088    // We already invalidated all relevant function analyses above.4089    PA.preserveSet<AllAnalysesOn<Function>>();4090    return PA;4091  }4092  return PreservedAnalyses::all();4093}4094 4095PreservedAnalyses AttributorLightCGSCCPass::run(LazyCallGraph::SCC &C,4096                                                CGSCCAnalysisManager &AM,4097                                                LazyCallGraph &CG,4098                                                CGSCCUpdateResult &UR) {4099  FunctionAnalysisManager &FAM =4100      AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();4101  AnalysisGetter AG(FAM);4102 4103  SetVector<Function *> Functions;4104  for (LazyCallGraph::Node &N : C)4105    Functions.insert(&N.getFunction());4106 4107  if (Functions.empty())4108    return PreservedAnalyses::all();4109 4110  Module &M = *Functions.back()->getParent();4111  CallGraphUpdater CGUpdater;4112  CGUpdater.initialize(CG, C, AM, UR);4113  BumpPtrAllocator Allocator;4114  InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);4115  if (runAttributorLightOnFunctions(InfoCache, Functions, AG, CGUpdater, FAM,4116                                    /* IsModulePass */ false)) {4117    PreservedAnalyses PA;4118    // We have not added or removed functions.4119    PA.preserve<FunctionAnalysisManagerCGSCCProxy>();4120    // We already invalidated all relevant function analyses above.4121    PA.preserveSet<AllAnalysesOn<Function>>();4122    return PA;4123  }4124  return PreservedAnalyses::all();4125}4126namespace llvm {4127 4128template <> struct GraphTraits<AADepGraphNode *> {4129  using NodeRef = AADepGraphNode *;4130  using DepTy = PointerIntPair<AADepGraphNode *, 1>;4131  using EdgeRef = PointerIntPair<AADepGraphNode *, 1>;4132 4133  static NodeRef getEntryNode(AADepGraphNode *DGN) { return DGN; }4134  static NodeRef DepGetVal(const DepTy &DT) { return DT.getPointer(); }4135 4136  using ChildIteratorType =4137      mapped_iterator<AADepGraphNode::DepSetTy::iterator, decltype(&DepGetVal)>;4138  using ChildEdgeIteratorType = AADepGraphNode::DepSetTy::iterator;4139 4140  static ChildIteratorType child_begin(NodeRef N) { return N->child_begin(); }4141 4142  static ChildIteratorType child_end(NodeRef N) { return N->child_end(); }4143};4144 4145template <>4146struct GraphTraits<AADepGraph *> : public GraphTraits<AADepGraphNode *> {4147  static NodeRef getEntryNode(AADepGraph *DG) { return DG->GetEntryNode(); }4148 4149  using nodes_iterator =4150      mapped_iterator<AADepGraphNode::DepSetTy::iterator, decltype(&DepGetVal)>;4151 4152  static nodes_iterator nodes_begin(AADepGraph *DG) { return DG->begin(); }4153 4154  static nodes_iterator nodes_end(AADepGraph *DG) { return DG->end(); }4155};4156 4157template <> struct DOTGraphTraits<AADepGraph *> : public DefaultDOTGraphTraits {4158  DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}4159 4160  static std::string getNodeLabel(const AADepGraphNode *Node,4161                                  const AADepGraph *DG) {4162    std::string AAString;4163    raw_string_ostream O(AAString);4164    Node->print(O);4165    return AAString;4166  }4167};4168 4169} // end namespace llvm4170