Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/IPO/Attributor.cpp
35269 views
//===- Attributor.cpp - Module-wide attribute deduction -------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements an interprocedural pass that deduces and/or propagates9// attributes. This is done in an abstract interpretation style fixpoint10// iteration. See the Attributor.h file comment and the class descriptions in11// that file for more information.12//13//===----------------------------------------------------------------------===//1415#include "llvm/Transforms/IPO/Attributor.h"1617#include "llvm/ADT/ArrayRef.h"18#include "llvm/ADT/PointerIntPair.h"19#include "llvm/ADT/STLExtras.h"20#include "llvm/ADT/SmallPtrSet.h"21#include "llvm/ADT/Statistic.h"22#include "llvm/Analysis/AliasAnalysis.h"23#include "llvm/Analysis/CallGraph.h"24#include "llvm/Analysis/CallGraphSCCPass.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>5455#ifdef EXPENSIVE_CHECKS56#include "llvm/IR/Verifier.h"57#endif5859#include <cassert>60#include <optional>61#include <string>6263using namespace llvm;6465#define DEBUG_TYPE "attributor"66#define VERBOSE_DEBUG_TYPE DEBUG_TYPE "-verbose"6768DEBUG_COUNTER(ManifestDBGCounter, "attributor-manifest",69"Determine what attributes are manifested in the IR");7071STATISTIC(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");8384// 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>93SetFixpointIterations("attributor-max-iterations", cl::Hidden,94cl::desc("Maximal number of fixpoint iterations."),95cl::init(32));9697static cl::opt<unsigned>98MaxSpecializationPerCB("attributor-max-specializations-per-call-base",99cl::Hidden,100cl::desc("Maximal number of callees specialized for "101"a call base"),102cl::init(UINT32_MAX));103104static cl::opt<unsigned, true> MaxInitializationChainLengthX(105"attributor-max-initialization-chain-length", cl::Hidden,106cl::desc(107"Maximal number of chained initializations (to avoid stack overflows)"),108cl::location(MaxInitializationChainLength), cl::init(1024));109unsigned llvm::MaxInitializationChainLength;110111static cl::opt<bool> AnnotateDeclarationCallSites(112"attributor-annotate-decl-cs", cl::Hidden,113cl::desc("Annotate call sites of function declarations."), cl::init(false));114115static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",116cl::init(true), cl::Hidden);117118static cl::opt<bool>119AllowShallowWrappers("attributor-allow-shallow-wrappers", cl::Hidden,120cl::desc("Allow the Attributor to create shallow "121"wrappers for non-exact definitions."),122cl::init(false));123124static cl::opt<bool>125AllowDeepWrapper("attributor-allow-deep-wrappers", cl::Hidden,126cl::desc("Allow the Attributor to use IP information "127"derived from non-exact functions via cloning"),128cl::init(false));129130// These options can only used for debug builds.131#ifndef NDEBUG132static cl::list<std::string>133SeedAllowList("attributor-seed-allow-list", cl::Hidden,134cl::desc("Comma separated list of attribute names that are "135"allowed to be seeded."),136cl::CommaSeparated);137138static cl::list<std::string> FunctionSeedAllowList(139"attributor-function-seed-allow-list", cl::Hidden,140cl::desc("Comma separated list of function names that are "141"allowed to be seeded."),142cl::CommaSeparated);143#endif144145static cl::opt<bool>146DumpDepGraph("attributor-dump-dep-graph", cl::Hidden,147cl::desc("Dump the dependency graph to dot files."),148cl::init(false));149150static cl::opt<std::string> DepGraphDotFileNamePrefix(151"attributor-depgraph-dot-filename-prefix", cl::Hidden,152cl::desc("The prefix used for the CallGraph dot file names."));153154static cl::opt<bool> ViewDepGraph("attributor-view-dep-graph", cl::Hidden,155cl::desc("View the dependency graph."),156cl::init(false));157158static cl::opt<bool> PrintDependencies("attributor-print-dep", cl::Hidden,159cl::desc("Print attribute dependencies"),160cl::init(false));161162static cl::opt<bool> EnableCallSiteSpecific(163"attributor-enable-call-site-specific-deduction", cl::Hidden,164cl::desc("Allow the Attributor to do call site specific analysis"),165cl::init(false));166167static cl::opt<bool>168PrintCallGraph("attributor-print-call-graph", cl::Hidden,169cl::desc("Print Attributor's internal call graph"),170cl::init(false));171172static cl::opt<bool> SimplifyAllLoads("attributor-simplify-all-loads",173cl::Hidden,174cl::desc("Try to simplify all loads."),175cl::init(true));176177static cl::opt<bool> CloseWorldAssumption(178"attributor-assume-closed-world", cl::Hidden,179cl::desc("Should a closed world be assumed, or not. Default if not set."));180181/// Logic operators for the change status enum class.182///183///{184ChangeStatus llvm::operator|(ChangeStatus L, ChangeStatus R) {185return L == ChangeStatus::CHANGED ? L : R;186}187ChangeStatus &llvm::operator|=(ChangeStatus &L, ChangeStatus R) {188L = L | R;189return L;190}191ChangeStatus llvm::operator&(ChangeStatus L, ChangeStatus R) {192return L == ChangeStatus::UNCHANGED ? L : R;193}194ChangeStatus &llvm::operator&=(ChangeStatus &L, ChangeStatus R) {195L = L & R;196return L;197}198///}199200bool AA::isGPU(const Module &M) {201Triple T(M.getTargetTriple());202return T.isAMDGPU() || T.isNVPTX();203}204205bool AA::isNoSyncInst(Attributor &A, const Instruction &I,206const AbstractAttribute &QueryingAA) {207// We are looking for volatile instructions or non-relaxed atomics.208if (const auto *CB = dyn_cast<CallBase>(&I)) {209if (CB->hasFnAttr(Attribute::NoSync))210return true;211212// Non-convergent and readnone imply nosync.213if (!CB->isConvergent() && !CB->mayReadOrWriteMemory())214return true;215216if (AANoSync::isNoSyncIntrinsic(&I))217return true;218219bool IsKnownNoSync;220return AA::hasAssumedIRAttr<Attribute::NoSync>(221A, &QueryingAA, IRPosition::callsite_function(*CB),222DepClassTy::OPTIONAL, IsKnownNoSync);223}224225if (!I.mayReadOrWriteMemory())226return true;227228return !I.isVolatile() && !AANoSync::isNonRelaxedAtomic(&I);229}230231bool AA::isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA,232const Value &V, bool ForAnalysisOnly) {233// TODO: See the AAInstanceInfo class comment.234if (!ForAnalysisOnly)235return false;236auto *InstanceInfoAA = A.getAAFor<AAInstanceInfo>(237QueryingAA, IRPosition::value(V), DepClassTy::OPTIONAL);238return InstanceInfoAA && InstanceInfoAA->isAssumedUniqueForAnalysis();239}240241Constant *242AA::getInitialValueForObj(Attributor &A, const AbstractAttribute &QueryingAA,243Value &Obj, Type &Ty, const TargetLibraryInfo *TLI,244const DataLayout &DL, AA::RangeTy *RangePtr) {245if (isa<AllocaInst>(Obj))246return UndefValue::get(&Ty);247if (Constant *Init = getInitialValueOfAllocation(&Obj, TLI, &Ty))248return Init;249auto *GV = dyn_cast<GlobalVariable>(&Obj);250if (!GV)251return nullptr;252253bool UsedAssumedInformation = false;254Constant *Initializer = nullptr;255if (A.hasGlobalVariableSimplificationCallback(*GV)) {256auto AssumedGV = A.getAssumedInitializerFromCallBack(257*GV, &QueryingAA, UsedAssumedInformation);258Initializer = *AssumedGV;259if (!Initializer)260return nullptr;261} else {262if (!GV->hasLocalLinkage() &&263(GV->isInterposable() || !(GV->isConstant() && GV->hasInitializer())))264return nullptr;265if (!GV->hasInitializer())266return UndefValue::get(&Ty);267268if (!Initializer)269Initializer = GV->getInitializer();270}271272if (RangePtr && !RangePtr->offsetOrSizeAreUnknown()) {273APInt Offset = APInt(64, RangePtr->Offset);274return ConstantFoldLoadFromConst(Initializer, &Ty, Offset, DL);275}276277return ConstantFoldLoadFromUniformValue(Initializer, &Ty, DL);278}279280bool AA::isValidInScope(const Value &V, const Function *Scope) {281if (isa<Constant>(V))282return true;283if (auto *I = dyn_cast<Instruction>(&V))284return I->getFunction() == Scope;285if (auto *A = dyn_cast<Argument>(&V))286return A->getParent() == Scope;287return false;288}289290bool AA::isValidAtPosition(const AA::ValueAndContext &VAC,291InformationCache &InfoCache) {292if (isa<Constant>(VAC.getValue()) || VAC.getValue() == VAC.getCtxI())293return true;294const Function *Scope = nullptr;295const Instruction *CtxI = VAC.getCtxI();296if (CtxI)297Scope = CtxI->getFunction();298if (auto *A = dyn_cast<Argument>(VAC.getValue()))299return A->getParent() == Scope;300if (auto *I = dyn_cast<Instruction>(VAC.getValue())) {301if (I->getFunction() == Scope) {302if (const DominatorTree *DT =303InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(304*Scope))305return DT->dominates(I, CtxI);306// Local dominance check mostly for the old PM passes.307if (CtxI && I->getParent() == CtxI->getParent())308return llvm::any_of(309make_range(I->getIterator(), I->getParent()->end()),310[&](const Instruction &AfterI) { return &AfterI == CtxI; });311}312}313return false;314}315316Value *AA::getWithType(Value &V, Type &Ty) {317if (V.getType() == &Ty)318return &V;319if (isa<PoisonValue>(V))320return PoisonValue::get(&Ty);321if (isa<UndefValue>(V))322return UndefValue::get(&Ty);323if (auto *C = dyn_cast<Constant>(&V)) {324if (C->isNullValue())325return Constant::getNullValue(&Ty);326if (C->getType()->isPointerTy() && Ty.isPointerTy())327return ConstantExpr::getPointerCast(C, &Ty);328if (C->getType()->getPrimitiveSizeInBits() >= Ty.getPrimitiveSizeInBits()) {329if (C->getType()->isIntegerTy() && Ty.isIntegerTy())330return ConstantExpr::getTrunc(C, &Ty, /* OnlyIfReduced */ true);331if (C->getType()->isFloatingPointTy() && Ty.isFloatingPointTy())332return ConstantFoldCastInstruction(Instruction::FPTrunc, C, &Ty);333}334}335return nullptr;336}337338std::optional<Value *>339AA::combineOptionalValuesInAAValueLatice(const std::optional<Value *> &A,340const std::optional<Value *> &B,341Type *Ty) {342if (A == B)343return A;344if (!B)345return A;346if (*B == nullptr)347return nullptr;348if (!A)349return Ty ? getWithType(**B, *Ty) : nullptr;350if (*A == nullptr)351return nullptr;352if (!Ty)353Ty = (*A)->getType();354if (isa_and_nonnull<UndefValue>(*A))355return getWithType(**B, *Ty);356if (isa<UndefValue>(*B))357return A;358if (*A && *B && *A == getWithType(**B, *Ty))359return A;360return nullptr;361}362363template <bool IsLoad, typename Ty>364static bool getPotentialCopiesOfMemoryValue(365Attributor &A, Ty &I, SmallSetVector<Value *, 4> &PotentialCopies,366SmallSetVector<Instruction *, 4> *PotentialValueOrigins,367const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,368bool OnlyExact) {369LLVM_DEBUG(dbgs() << "Trying to determine the potential copies of " << I370<< " (only exact: " << OnlyExact << ")\n";);371372Value &Ptr = *I.getPointerOperand();373// Containers to remember the pointer infos and new copies while we are not374// sure that we can find all of them. If we abort we want to avoid spurious375// dependences and potential copies in the provided container.376SmallVector<const AAPointerInfo *> PIs;377SmallSetVector<Value *, 8> NewCopies;378SmallSetVector<Instruction *, 8> NewCopyOrigins;379380const auto *TLI =381A.getInfoCache().getTargetLibraryInfoForFunction(*I.getFunction());382383auto Pred = [&](Value &Obj) {384LLVM_DEBUG(dbgs() << "Visit underlying object " << Obj << "\n");385if (isa<UndefValue>(&Obj))386return true;387if (isa<ConstantPointerNull>(&Obj)) {388// A null pointer access can be undefined but any offset from null may389// be OK. We do not try to optimize the latter.390if (!NullPointerIsDefined(I.getFunction(),391Ptr.getType()->getPointerAddressSpace()) &&392A.getAssumedSimplified(Ptr, QueryingAA, UsedAssumedInformation,393AA::Interprocedural) == &Obj)394return true;395LLVM_DEBUG(396dbgs() << "Underlying object is a valid nullptr, giving up.\n";);397return false;398}399// TODO: Use assumed noalias return.400if (!isa<AllocaInst>(&Obj) && !isa<GlobalVariable>(&Obj) &&401!(IsLoad ? isAllocationFn(&Obj, TLI) : isNoAliasCall(&Obj))) {402LLVM_DEBUG(dbgs() << "Underlying object is not supported yet: " << Obj403<< "\n";);404return false;405}406if (auto *GV = dyn_cast<GlobalVariable>(&Obj))407if (!GV->hasLocalLinkage() &&408!(GV->isConstant() && GV->hasInitializer())) {409LLVM_DEBUG(dbgs() << "Underlying object is global with external "410"linkage, not supported yet: "411<< Obj << "\n";);412return false;413}414415bool NullOnly = true;416bool NullRequired = false;417auto CheckForNullOnlyAndUndef = [&](std::optional<Value *> V,418bool IsExact) {419if (!V || *V == nullptr)420NullOnly = false;421else if (isa<UndefValue>(*V))422/* No op */;423else if (isa<Constant>(*V) && cast<Constant>(*V)->isNullValue())424NullRequired = !IsExact;425else426NullOnly = false;427};428429auto AdjustWrittenValueType = [&](const AAPointerInfo::Access &Acc,430Value &V) {431Value *AdjV = AA::getWithType(V, *I.getType());432if (!AdjV) {433LLVM_DEBUG(dbgs() << "Underlying object written but stored value "434"cannot be converted to read type: "435<< *Acc.getRemoteInst() << " : " << *I.getType()436<< "\n";);437}438return AdjV;439};440441auto SkipCB = [&](const AAPointerInfo::Access &Acc) {442if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))443return true;444if (IsLoad) {445if (Acc.isWrittenValueYetUndetermined())446return true;447if (PotentialValueOrigins && !isa<AssumeInst>(Acc.getRemoteInst()))448return false;449if (!Acc.isWrittenValueUnknown())450if (Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue()))451if (NewCopies.count(V)) {452NewCopyOrigins.insert(Acc.getRemoteInst());453return true;454}455if (auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst()))456if (Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand()))457if (NewCopies.count(V)) {458NewCopyOrigins.insert(Acc.getRemoteInst());459return true;460}461}462return false;463};464465auto CheckAccess = [&](const AAPointerInfo::Access &Acc, bool IsExact) {466if ((IsLoad && !Acc.isWriteOrAssumption()) || (!IsLoad && !Acc.isRead()))467return true;468if (IsLoad && Acc.isWrittenValueYetUndetermined())469return true;470CheckForNullOnlyAndUndef(Acc.getContent(), IsExact);471if (OnlyExact && !IsExact && !NullOnly &&472!isa_and_nonnull<UndefValue>(Acc.getWrittenValue())) {473LLVM_DEBUG(dbgs() << "Non exact access " << *Acc.getRemoteInst()474<< ", abort!\n");475return false;476}477if (NullRequired && !NullOnly) {478LLVM_DEBUG(dbgs() << "Required all `null` accesses due to non exact "479"one, however found non-null one: "480<< *Acc.getRemoteInst() << ", abort!\n");481return false;482}483if (IsLoad) {484assert(isa<LoadInst>(I) && "Expected load or store instruction only!");485if (!Acc.isWrittenValueUnknown()) {486Value *V = AdjustWrittenValueType(Acc, *Acc.getWrittenValue());487if (!V)488return false;489NewCopies.insert(V);490if (PotentialValueOrigins)491NewCopyOrigins.insert(Acc.getRemoteInst());492return true;493}494auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst());495if (!SI) {496LLVM_DEBUG(dbgs() << "Underlying object written through a non-store "497"instruction not supported yet: "498<< *Acc.getRemoteInst() << "\n";);499return false;500}501Value *V = AdjustWrittenValueType(Acc, *SI->getValueOperand());502if (!V)503return false;504NewCopies.insert(V);505if (PotentialValueOrigins)506NewCopyOrigins.insert(SI);507} else {508assert(isa<StoreInst>(I) && "Expected load or store instruction only!");509auto *LI = dyn_cast<LoadInst>(Acc.getRemoteInst());510if (!LI && OnlyExact) {511LLVM_DEBUG(dbgs() << "Underlying object read through a non-load "512"instruction not supported yet: "513<< *Acc.getRemoteInst() << "\n";);514return false;515}516NewCopies.insert(Acc.getRemoteInst());517}518return true;519};520521// If the value has been written to we don't need the initial value of the522// object.523bool HasBeenWrittenTo = false;524525AA::RangeTy Range;526auto *PI = A.getAAFor<AAPointerInfo>(QueryingAA, IRPosition::value(Obj),527DepClassTy::NONE);528if (!PI || !PI->forallInterferingAccesses(529A, QueryingAA, I,530/* FindInterferingWrites */ IsLoad,531/* FindInterferingReads */ !IsLoad, CheckAccess,532HasBeenWrittenTo, Range, SkipCB)) {533LLVM_DEBUG(534dbgs()535<< "Failed to verify all interfering accesses for underlying object: "536<< Obj << "\n");537return false;538}539540if (IsLoad && !HasBeenWrittenTo && !Range.isUnassigned()) {541const DataLayout &DL = A.getDataLayout();542Value *InitialValue = AA::getInitialValueForObj(543A, QueryingAA, Obj, *I.getType(), TLI, DL, &Range);544if (!InitialValue) {545LLVM_DEBUG(dbgs() << "Could not determine required initial value of "546"underlying object, abort!\n");547return false;548}549CheckForNullOnlyAndUndef(InitialValue, /* IsExact */ true);550if (NullRequired && !NullOnly) {551LLVM_DEBUG(dbgs() << "Non exact access but initial value that is not "552"null or undef, abort!\n");553return false;554}555556NewCopies.insert(InitialValue);557if (PotentialValueOrigins)558NewCopyOrigins.insert(nullptr);559}560561PIs.push_back(PI);562563return true;564};565566const auto *AAUO = A.getAAFor<AAUnderlyingObjects>(567QueryingAA, IRPosition::value(Ptr), DepClassTy::OPTIONAL);568if (!AAUO || !AAUO->forallUnderlyingObjects(Pred)) {569LLVM_DEBUG(570dbgs() << "Underlying objects stored into could not be determined\n";);571return false;572}573574// Only if we were successful collection all potential copies we record575// dependences (on non-fix AAPointerInfo AAs). We also only then modify the576// given PotentialCopies container.577for (const auto *PI : PIs) {578if (!PI->getState().isAtFixpoint())579UsedAssumedInformation = true;580A.recordDependence(*PI, QueryingAA, DepClassTy::OPTIONAL);581}582PotentialCopies.insert(NewCopies.begin(), NewCopies.end());583if (PotentialValueOrigins)584PotentialValueOrigins->insert(NewCopyOrigins.begin(), NewCopyOrigins.end());585586return true;587}588589bool AA::getPotentiallyLoadedValues(590Attributor &A, LoadInst &LI, SmallSetVector<Value *, 4> &PotentialValues,591SmallSetVector<Instruction *, 4> &PotentialValueOrigins,592const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,593bool OnlyExact) {594return getPotentialCopiesOfMemoryValue</* IsLoad */ true>(595A, LI, PotentialValues, &PotentialValueOrigins, QueryingAA,596UsedAssumedInformation, OnlyExact);597}598599bool AA::getPotentialCopiesOfStoredValue(600Attributor &A, StoreInst &SI, SmallSetVector<Value *, 4> &PotentialCopies,601const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,602bool OnlyExact) {603return getPotentialCopiesOfMemoryValue</* IsLoad */ false>(604A, SI, PotentialCopies, nullptr, QueryingAA, UsedAssumedInformation,605OnlyExact);606}607608static bool isAssumedReadOnlyOrReadNone(Attributor &A, const IRPosition &IRP,609const AbstractAttribute &QueryingAA,610bool RequireReadNone, bool &IsKnown) {611if (RequireReadNone) {612if (AA::hasAssumedIRAttr<Attribute::ReadNone>(613A, &QueryingAA, IRP, DepClassTy::OPTIONAL, IsKnown,614/* IgnoreSubsumingPositions */ true))615return true;616} else if (AA::hasAssumedIRAttr<Attribute::ReadOnly>(617A, &QueryingAA, IRP, DepClassTy::OPTIONAL, IsKnown,618/* IgnoreSubsumingPositions */ true))619return true;620621IRPosition::Kind Kind = IRP.getPositionKind();622if (Kind == IRPosition::IRP_FUNCTION || Kind == IRPosition::IRP_CALL_SITE) {623const auto *MemLocAA =624A.getAAFor<AAMemoryLocation>(QueryingAA, IRP, DepClassTy::NONE);625if (MemLocAA && MemLocAA->isAssumedReadNone()) {626IsKnown = MemLocAA->isKnownReadNone();627if (!IsKnown)628A.recordDependence(*MemLocAA, QueryingAA, DepClassTy::OPTIONAL);629return true;630}631}632633const auto *MemBehaviorAA =634A.getAAFor<AAMemoryBehavior>(QueryingAA, IRP, DepClassTy::NONE);635if (MemBehaviorAA &&636(MemBehaviorAA->isAssumedReadNone() ||637(!RequireReadNone && MemBehaviorAA->isAssumedReadOnly()))) {638IsKnown = RequireReadNone ? MemBehaviorAA->isKnownReadNone()639: MemBehaviorAA->isKnownReadOnly();640if (!IsKnown)641A.recordDependence(*MemBehaviorAA, QueryingAA, DepClassTy::OPTIONAL);642return true;643}644645return false;646}647648bool AA::isAssumedReadOnly(Attributor &A, const IRPosition &IRP,649const AbstractAttribute &QueryingAA, bool &IsKnown) {650return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,651/* RequireReadNone */ false, IsKnown);652}653bool AA::isAssumedReadNone(Attributor &A, const IRPosition &IRP,654const AbstractAttribute &QueryingAA, bool &IsKnown) {655return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,656/* RequireReadNone */ true, IsKnown);657}658659static bool660isPotentiallyReachable(Attributor &A, const Instruction &FromI,661const Instruction *ToI, const Function &ToFn,662const AbstractAttribute &QueryingAA,663const AA::InstExclusionSetTy *ExclusionSet,664std::function<bool(const Function &F)> GoBackwardsCB) {665DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, {666dbgs() << "[AA] isPotentiallyReachable @" << ToFn.getName() << " from "667<< FromI << " [GBCB: " << bool(GoBackwardsCB) << "][#ExS: "668<< (ExclusionSet ? std::to_string(ExclusionSet->size()) : "none")669<< "]\n";670if (ExclusionSet)671for (auto *ES : *ExclusionSet)672dbgs() << *ES << "\n";673});674675// We know kernels (generally) cannot be called from within the module. Thus,676// for reachability we would need to step back from a kernel which would allow677// us to reach anything anyway. Even if a kernel is invoked from another678// kernel, values like allocas and shared memory are not accessible. We679// implicitly check for this situation to avoid costly lookups.680if (GoBackwardsCB && &ToFn != FromI.getFunction() &&681!GoBackwardsCB(*FromI.getFunction()) && ToFn.hasFnAttribute("kernel") &&682FromI.getFunction()->hasFnAttribute("kernel")) {683LLVM_DEBUG(dbgs() << "[AA] assume kernel cannot be reached from within the "684"module; success\n";);685return false;686}687688// If we can go arbitrarily backwards we will eventually reach an entry point689// that can reach ToI. Only if a set of blocks through which we cannot go is690// provided, or once we track internal functions not accessible from the691// outside, it makes sense to perform backwards analysis in the absence of a692// GoBackwardsCB.693if (!GoBackwardsCB && !ExclusionSet) {694LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI695<< " is not checked backwards and does not have an "696"exclusion set, abort\n");697return true;698}699700SmallPtrSet<const Instruction *, 8> Visited;701SmallVector<const Instruction *> Worklist;702Worklist.push_back(&FromI);703704while (!Worklist.empty()) {705const Instruction *CurFromI = Worklist.pop_back_val();706if (!Visited.insert(CurFromI).second)707continue;708709const Function *FromFn = CurFromI->getFunction();710if (FromFn == &ToFn) {711if (!ToI)712return true;713LLVM_DEBUG(dbgs() << "[AA] check " << *ToI << " from " << *CurFromI714<< " intraprocedurally\n");715const auto *ReachabilityAA = A.getAAFor<AAIntraFnReachability>(716QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);717bool Result = !ReachabilityAA || ReachabilityAA->isAssumedReachable(718A, *CurFromI, *ToI, ExclusionSet);719LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " "720<< (Result ? "can potentially " : "cannot ") << "reach "721<< *ToI << " [Intra]\n");722if (Result)723return true;724}725726bool Result = true;727if (!ToFn.isDeclaration() && ToI) {728const auto *ToReachabilityAA = A.getAAFor<AAIntraFnReachability>(729QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);730const Instruction &EntryI = ToFn.getEntryBlock().front();731Result = !ToReachabilityAA || ToReachabilityAA->isAssumedReachable(732A, EntryI, *ToI, ExclusionSet);733LLVM_DEBUG(dbgs() << "[AA] Entry " << EntryI << " of @" << ToFn.getName()734<< " " << (Result ? "can potentially " : "cannot ")735<< "reach @" << *ToI << " [ToFn]\n");736}737738if (Result) {739// The entry of the ToFn can reach the instruction ToI. If the current740// instruction is already known to reach the ToFn.741const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(742QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);743Result = !FnReachabilityAA || FnReachabilityAA->instructionCanReach(744A, *CurFromI, ToFn, ExclusionSet);745LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " in @" << FromFn->getName()746<< " " << (Result ? "can potentially " : "cannot ")747<< "reach @" << ToFn.getName() << " [FromFn]\n");748if (Result)749return true;750}751752// TODO: Check assumed nounwind.753const auto *ReachabilityAA = A.getAAFor<AAIntraFnReachability>(754QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);755auto ReturnInstCB = [&](Instruction &Ret) {756bool Result = !ReachabilityAA || ReachabilityAA->isAssumedReachable(757A, *CurFromI, Ret, ExclusionSet);758LLVM_DEBUG(dbgs() << "[AA][Ret] " << *CurFromI << " "759<< (Result ? "can potentially " : "cannot ") << "reach "760<< Ret << " [Intra]\n");761return !Result;762};763764// Check if we can reach returns.765bool UsedAssumedInformation = false;766if (A.checkForAllInstructions(ReturnInstCB, FromFn, &QueryingAA,767{Instruction::Ret}, UsedAssumedInformation)) {768LLVM_DEBUG(dbgs() << "[AA] No return is reachable, done\n");769continue;770}771772if (!GoBackwardsCB) {773LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI774<< " is not checked backwards, abort\n");775return true;776}777778// If we do not go backwards from the FromFn we are done here and so far we779// could not find a way to reach ToFn/ToI.780if (!GoBackwardsCB(*FromFn))781continue;782783LLVM_DEBUG(dbgs() << "Stepping backwards to the call sites of @"784<< FromFn->getName() << "\n");785786auto CheckCallSite = [&](AbstractCallSite ACS) {787CallBase *CB = ACS.getInstruction();788if (!CB)789return false;790791if (isa<InvokeInst>(CB))792return false;793794Instruction *Inst = CB->getNextNonDebugInstruction();795Worklist.push_back(Inst);796return true;797};798799Result = !A.checkForAllCallSites(CheckCallSite, *FromFn,800/* RequireAllCallSites */ true,801&QueryingAA, UsedAssumedInformation);802if (Result) {803LLVM_DEBUG(dbgs() << "[AA] stepping back to call sites from " << *CurFromI804<< " in @" << FromFn->getName()805<< " failed, give up\n");806return true;807}808809LLVM_DEBUG(dbgs() << "[AA] stepped back to call sites from " << *CurFromI810<< " in @" << FromFn->getName()811<< " worklist size is: " << Worklist.size() << "\n");812}813return false;814}815816bool AA::isPotentiallyReachable(817Attributor &A, const Instruction &FromI, const Instruction &ToI,818const AbstractAttribute &QueryingAA,819const AA::InstExclusionSetTy *ExclusionSet,820std::function<bool(const Function &F)> GoBackwardsCB) {821const Function *ToFn = ToI.getFunction();822return ::isPotentiallyReachable(A, FromI, &ToI, *ToFn, QueryingAA,823ExclusionSet, GoBackwardsCB);824}825826bool AA::isPotentiallyReachable(827Attributor &A, const Instruction &FromI, const Function &ToFn,828const AbstractAttribute &QueryingAA,829const AA::InstExclusionSetTy *ExclusionSet,830std::function<bool(const Function &F)> GoBackwardsCB) {831return ::isPotentiallyReachable(A, FromI, /* ToI */ nullptr, ToFn, QueryingAA,832ExclusionSet, GoBackwardsCB);833}834835bool AA::isAssumedThreadLocalObject(Attributor &A, Value &Obj,836const AbstractAttribute &QueryingAA) {837if (isa<UndefValue>(Obj))838return true;839if (isa<AllocaInst>(Obj)) {840InformationCache &InfoCache = A.getInfoCache();841if (!InfoCache.stackIsAccessibleByOtherThreads()) {842LLVM_DEBUG(843dbgs() << "[AA] Object '" << Obj844<< "' is thread local; stack objects are thread local.\n");845return true;846}847bool IsKnownNoCapture;848bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(849A, &QueryingAA, IRPosition::value(Obj), DepClassTy::OPTIONAL,850IsKnownNoCapture);851LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj << "' is "852<< (IsAssumedNoCapture ? "" : "not") << " thread local; "853<< (IsAssumedNoCapture ? "non-" : "")854<< "captured stack object.\n");855return IsAssumedNoCapture;856}857if (auto *GV = dyn_cast<GlobalVariable>(&Obj)) {858if (GV->isConstant()) {859LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj860<< "' is thread local; constant global\n");861return true;862}863if (GV->isThreadLocal()) {864LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj865<< "' is thread local; thread local global\n");866return true;867}868}869870if (A.getInfoCache().targetIsGPU()) {871if (Obj.getType()->getPointerAddressSpace() ==872(int)AA::GPUAddressSpace::Local) {873LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj874<< "' is thread local; GPU local memory\n");875return true;876}877if (Obj.getType()->getPointerAddressSpace() ==878(int)AA::GPUAddressSpace::Constant) {879LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj880<< "' is thread local; GPU constant memory\n");881return true;882}883}884885LLVM_DEBUG(dbgs() << "[AA] Object '" << Obj << "' is not thread local\n");886return false;887}888889bool AA::isPotentiallyAffectedByBarrier(Attributor &A, const Instruction &I,890const AbstractAttribute &QueryingAA) {891if (!I.mayHaveSideEffects() && !I.mayReadFromMemory())892return false;893894SmallSetVector<const Value *, 8> Ptrs;895896auto AddLocationPtr = [&](std::optional<MemoryLocation> Loc) {897if (!Loc || !Loc->Ptr) {898LLVM_DEBUG(899dbgs() << "[AA] Access to unknown location; -> requires barriers\n");900return false;901}902Ptrs.insert(Loc->Ptr);903return true;904};905906if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&I)) {907if (!AddLocationPtr(MemoryLocation::getForDest(MI)))908return true;909if (const MemTransferInst *MTI = dyn_cast<MemTransferInst>(&I))910if (!AddLocationPtr(MemoryLocation::getForSource(MTI)))911return true;912} else if (!AddLocationPtr(MemoryLocation::getOrNone(&I)))913return true;914915return isPotentiallyAffectedByBarrier(A, Ptrs.getArrayRef(), QueryingAA, &I);916}917918bool AA::isPotentiallyAffectedByBarrier(Attributor &A,919ArrayRef<const Value *> Ptrs,920const AbstractAttribute &QueryingAA,921const Instruction *CtxI) {922for (const Value *Ptr : Ptrs) {923if (!Ptr) {924LLVM_DEBUG(dbgs() << "[AA] nullptr; -> requires barriers\n");925return true;926}927928auto Pred = [&](Value &Obj) {929if (AA::isAssumedThreadLocalObject(A, Obj, QueryingAA))930return true;931LLVM_DEBUG(dbgs() << "[AA] Access to '" << Obj << "' via '" << *Ptr932<< "'; -> requires barrier\n");933return false;934};935936const auto *UnderlyingObjsAA = A.getAAFor<AAUnderlyingObjects>(937QueryingAA, IRPosition::value(*Ptr), DepClassTy::OPTIONAL);938if (!UnderlyingObjsAA || !UnderlyingObjsAA->forallUnderlyingObjects(Pred))939return true;940}941return false;942}943944/// Return true if \p New is equal or worse than \p Old.945static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {946if (!Old.isIntAttribute())947return true;948949return Old.getValueAsInt() >= New.getValueAsInt();950}951952/// Return true if the information provided by \p Attr was added to the953/// attribute set \p AttrSet. This is only the case if it was not already954/// present in \p AttrSet.955static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,956AttributeSet AttrSet, bool ForceReplace,957AttrBuilder &AB) {958959if (Attr.isEnumAttribute()) {960Attribute::AttrKind Kind = Attr.getKindAsEnum();961if (AttrSet.hasAttribute(Kind))962return false;963AB.addAttribute(Kind);964return true;965}966if (Attr.isStringAttribute()) {967StringRef Kind = Attr.getKindAsString();968if (AttrSet.hasAttribute(Kind)) {969if (!ForceReplace)970return false;971}972AB.addAttribute(Kind, Attr.getValueAsString());973return true;974}975if (Attr.isIntAttribute()) {976Attribute::AttrKind Kind = Attr.getKindAsEnum();977if (!ForceReplace && Kind == Attribute::Memory) {978MemoryEffects ME = Attr.getMemoryEffects() & AttrSet.getMemoryEffects();979if (ME == AttrSet.getMemoryEffects())980return false;981AB.addMemoryAttr(ME);982return true;983}984if (AttrSet.hasAttribute(Kind)) {985if (!ForceReplace && isEqualOrWorse(Attr, AttrSet.getAttribute(Kind)))986return false;987}988AB.addAttribute(Attr);989return true;990}991992llvm_unreachable("Expected enum or string attribute!");993}994995Argument *IRPosition::getAssociatedArgument() const {996if (getPositionKind() == IRP_ARGUMENT)997return cast<Argument>(&getAnchorValue());998999// Not an Argument and no argument number means this is not a call site1000// argument, thus we cannot find a callback argument to return.1001int ArgNo = getCallSiteArgNo();1002if (ArgNo < 0)1003return nullptr;10041005// Use abstract call sites to make the connection between the call site1006// values and the ones in callbacks. If a callback was found that makes use1007// of the underlying call site operand, we want the corresponding callback1008// callee argument and not the direct callee argument.1009std::optional<Argument *> CBCandidateArg;1010SmallVector<const Use *, 4> CallbackUses;1011const auto &CB = cast<CallBase>(getAnchorValue());1012AbstractCallSite::getCallbackUses(CB, CallbackUses);1013for (const Use *U : CallbackUses) {1014AbstractCallSite ACS(U);1015assert(ACS && ACS.isCallbackCall());1016if (!ACS.getCalledFunction())1017continue;10181019for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {10201021// Test if the underlying call site operand is argument number u of the1022// callback callee.1023if (ACS.getCallArgOperandNo(u) != ArgNo)1024continue;10251026assert(ACS.getCalledFunction()->arg_size() > u &&1027"ACS mapped into var-args arguments!");1028if (CBCandidateArg) {1029CBCandidateArg = nullptr;1030break;1031}1032CBCandidateArg = ACS.getCalledFunction()->getArg(u);1033}1034}10351036// If we found a unique callback candidate argument, return it.1037if (CBCandidateArg && *CBCandidateArg)1038return *CBCandidateArg;10391040// If no callbacks were found, or none used the underlying call site operand1041// exclusively, use the direct callee argument if available.1042auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());1043if (Callee && Callee->arg_size() > unsigned(ArgNo))1044return Callee->getArg(ArgNo);10451046return nullptr;1047}10481049ChangeStatus AbstractAttribute::update(Attributor &A) {1050ChangeStatus HasChanged = ChangeStatus::UNCHANGED;1051if (getState().isAtFixpoint())1052return HasChanged;10531054LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");10551056HasChanged = updateImpl(A);10571058LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this1059<< "\n");10601061return HasChanged;1062}10631064Attributor::Attributor(SetVector<Function *> &Functions,1065InformationCache &InfoCache,1066AttributorConfig Configuration)1067: Allocator(InfoCache.Allocator), Functions(Functions),1068InfoCache(InfoCache), Configuration(Configuration) {1069if (!isClosedWorldModule())1070return;1071for (Function *Fn : Functions)1072if (Fn->hasAddressTaken(/*PutOffender=*/nullptr,1073/*IgnoreCallbackUses=*/false,1074/*IgnoreAssumeLikeCalls=*/true,1075/*IgnoreLLVMUsed=*/true,1076/*IgnoreARCAttachedCall=*/false,1077/*IgnoreCastedDirectCall=*/true))1078InfoCache.IndirectlyCallableFunctions.push_back(Fn);1079}10801081bool Attributor::getAttrsFromAssumes(const IRPosition &IRP,1082Attribute::AttrKind AK,1083SmallVectorImpl<Attribute> &Attrs) {1084assert(IRP.getPositionKind() != IRPosition::IRP_INVALID &&1085"Did expect a valid position!");1086MustBeExecutedContextExplorer *Explorer =1087getInfoCache().getMustBeExecutedContextExplorer();1088if (!Explorer)1089return false;10901091Value &AssociatedValue = IRP.getAssociatedValue();10921093const Assume2KnowledgeMap &A2K =1094getInfoCache().getKnowledgeMap().lookup({&AssociatedValue, AK});10951096// Check if we found any potential assume use, if not we don't need to create1097// explorer iterators.1098if (A2K.empty())1099return false;11001101LLVMContext &Ctx = AssociatedValue.getContext();1102unsigned AttrsSize = Attrs.size();1103auto EIt = Explorer->begin(IRP.getCtxI()),1104EEnd = Explorer->end(IRP.getCtxI());1105for (const auto &It : A2K)1106if (Explorer->findInContextOf(It.first, EIt, EEnd))1107Attrs.push_back(Attribute::get(Ctx, AK, It.second.Max));1108return AttrsSize != Attrs.size();1109}11101111template <typename DescTy>1112ChangeStatus1113Attributor::updateAttrMap(const IRPosition &IRP, ArrayRef<DescTy> AttrDescs,1114function_ref<bool(const DescTy &, AttributeSet,1115AttributeMask &, AttrBuilder &)>1116CB) {1117if (AttrDescs.empty())1118return ChangeStatus::UNCHANGED;1119switch (IRP.getPositionKind()) {1120case IRPosition::IRP_FLOAT:1121case IRPosition::IRP_INVALID:1122return ChangeStatus::UNCHANGED;1123default:1124break;1125};11261127AttributeList AL;1128Value *AttrListAnchor = IRP.getAttrListAnchor();1129auto It = AttrsMap.find(AttrListAnchor);1130if (It == AttrsMap.end())1131AL = IRP.getAttrList();1132else1133AL = It->getSecond();11341135LLVMContext &Ctx = IRP.getAnchorValue().getContext();1136auto AttrIdx = IRP.getAttrIdx();1137AttributeSet AS = AL.getAttributes(AttrIdx);1138AttributeMask AM;1139AttrBuilder AB(Ctx);11401141ChangeStatus HasChanged = ChangeStatus::UNCHANGED;1142for (const DescTy &AttrDesc : AttrDescs)1143if (CB(AttrDesc, AS, AM, AB))1144HasChanged = ChangeStatus::CHANGED;11451146if (HasChanged == ChangeStatus::UNCHANGED)1147return ChangeStatus::UNCHANGED;11481149AL = AL.removeAttributesAtIndex(Ctx, AttrIdx, AM);1150AL = AL.addAttributesAtIndex(Ctx, AttrIdx, AB);1151AttrsMap[AttrListAnchor] = AL;1152return ChangeStatus::CHANGED;1153}11541155bool Attributor::hasAttr(const IRPosition &IRP,1156ArrayRef<Attribute::AttrKind> AttrKinds,1157bool IgnoreSubsumingPositions,1158Attribute::AttrKind ImpliedAttributeKind) {1159bool Implied = false;1160bool HasAttr = false;1161auto HasAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,1162AttributeMask &, AttrBuilder &) {1163if (AttrSet.hasAttribute(Kind)) {1164Implied |= Kind != ImpliedAttributeKind;1165HasAttr = true;1166}1167return false;1168};1169for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {1170updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, HasAttrCB);1171if (HasAttr)1172break;1173// The first position returned by the SubsumingPositionIterator is1174// always the position itself. If we ignore subsuming positions we1175// are done after the first iteration.1176if (IgnoreSubsumingPositions)1177break;1178Implied = true;1179}1180if (!HasAttr) {1181Implied = true;1182SmallVector<Attribute> Attrs;1183for (Attribute::AttrKind AK : AttrKinds)1184if (getAttrsFromAssumes(IRP, AK, Attrs)) {1185HasAttr = true;1186break;1187}1188}11891190// Check if we should manifest the implied attribute kind at the IRP.1191if (ImpliedAttributeKind != Attribute::None && HasAttr && Implied)1192manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),1193ImpliedAttributeKind)});1194return HasAttr;1195}11961197void Attributor::getAttrs(const IRPosition &IRP,1198ArrayRef<Attribute::AttrKind> AttrKinds,1199SmallVectorImpl<Attribute> &Attrs,1200bool IgnoreSubsumingPositions) {1201auto CollectAttrCB = [&](const Attribute::AttrKind &Kind,1202AttributeSet AttrSet, AttributeMask &,1203AttrBuilder &) {1204if (AttrSet.hasAttribute(Kind))1205Attrs.push_back(AttrSet.getAttribute(Kind));1206return false;1207};1208for (const IRPosition &EquivIRP : SubsumingPositionIterator(IRP)) {1209updateAttrMap<Attribute::AttrKind>(EquivIRP, AttrKinds, CollectAttrCB);1210// The first position returned by the SubsumingPositionIterator is1211// always the position itself. If we ignore subsuming positions we1212// are done after the first iteration.1213if (IgnoreSubsumingPositions)1214break;1215}1216for (Attribute::AttrKind AK : AttrKinds)1217getAttrsFromAssumes(IRP, AK, Attrs);1218}12191220ChangeStatus Attributor::removeAttrs(const IRPosition &IRP,1221ArrayRef<Attribute::AttrKind> AttrKinds) {1222auto RemoveAttrCB = [&](const Attribute::AttrKind &Kind, AttributeSet AttrSet,1223AttributeMask &AM, AttrBuilder &) {1224if (!AttrSet.hasAttribute(Kind))1225return false;1226AM.addAttribute(Kind);1227return true;1228};1229return updateAttrMap<Attribute::AttrKind>(IRP, AttrKinds, RemoveAttrCB);1230}12311232ChangeStatus Attributor::removeAttrs(const IRPosition &IRP,1233ArrayRef<StringRef> Attrs) {1234auto RemoveAttrCB = [&](StringRef Attr, AttributeSet AttrSet,1235AttributeMask &AM, AttrBuilder &) -> bool {1236if (!AttrSet.hasAttribute(Attr))1237return false;1238AM.addAttribute(Attr);1239return true;1240};12411242return updateAttrMap<StringRef>(IRP, Attrs, RemoveAttrCB);1243}12441245ChangeStatus Attributor::manifestAttrs(const IRPosition &IRP,1246ArrayRef<Attribute> Attrs,1247bool ForceReplace) {1248LLVMContext &Ctx = IRP.getAnchorValue().getContext();1249auto AddAttrCB = [&](const Attribute &Attr, AttributeSet AttrSet,1250AttributeMask &, AttrBuilder &AB) {1251return addIfNotExistent(Ctx, Attr, AttrSet, ForceReplace, AB);1252};1253return updateAttrMap<Attribute>(IRP, Attrs, AddAttrCB);1254}12551256const IRPosition IRPosition::EmptyKey(DenseMapInfo<void *>::getEmptyKey());1257const IRPosition1258IRPosition::TombstoneKey(DenseMapInfo<void *>::getTombstoneKey());12591260SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {1261IRPositions.emplace_back(IRP);12621263// Helper to determine if operand bundles on a call site are benign or1264// potentially problematic. We handle only llvm.assume for now.1265auto CanIgnoreOperandBundles = [](const CallBase &CB) {1266return (isa<IntrinsicInst>(CB) &&1267cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);1268};12691270const auto *CB = dyn_cast<CallBase>(&IRP.getAnchorValue());1271switch (IRP.getPositionKind()) {1272case IRPosition::IRP_INVALID:1273case IRPosition::IRP_FLOAT:1274case IRPosition::IRP_FUNCTION:1275return;1276case IRPosition::IRP_ARGUMENT:1277case IRPosition::IRP_RETURNED:1278IRPositions.emplace_back(IRPosition::function(*IRP.getAnchorScope()));1279return;1280case IRPosition::IRP_CALL_SITE:1281assert(CB && "Expected call site!");1282// TODO: We need to look at the operand bundles similar to the redirection1283// in CallBase.1284if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))1285if (auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand()))1286IRPositions.emplace_back(IRPosition::function(*Callee));1287return;1288case IRPosition::IRP_CALL_SITE_RETURNED:1289assert(CB && "Expected call site!");1290// TODO: We need to look at the operand bundles similar to the redirection1291// in CallBase.1292if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {1293if (auto *Callee =1294dyn_cast_if_present<Function>(CB->getCalledOperand())) {1295IRPositions.emplace_back(IRPosition::returned(*Callee));1296IRPositions.emplace_back(IRPosition::function(*Callee));1297for (const Argument &Arg : Callee->args())1298if (Arg.hasReturnedAttr()) {1299IRPositions.emplace_back(1300IRPosition::callsite_argument(*CB, Arg.getArgNo()));1301IRPositions.emplace_back(1302IRPosition::value(*CB->getArgOperand(Arg.getArgNo())));1303IRPositions.emplace_back(IRPosition::argument(Arg));1304}1305}1306}1307IRPositions.emplace_back(IRPosition::callsite_function(*CB));1308return;1309case IRPosition::IRP_CALL_SITE_ARGUMENT: {1310assert(CB && "Expected call site!");1311// TODO: We need to look at the operand bundles similar to the redirection1312// in CallBase.1313if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {1314auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());1315if (Callee) {1316if (Argument *Arg = IRP.getAssociatedArgument())1317IRPositions.emplace_back(IRPosition::argument(*Arg));1318IRPositions.emplace_back(IRPosition::function(*Callee));1319}1320}1321IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));1322return;1323}1324}1325}13261327void IRPosition::verify() {1328#ifdef EXPENSIVE_CHECKS1329switch (getPositionKind()) {1330case IRP_INVALID:1331assert((CBContext == nullptr) &&1332"Invalid position must not have CallBaseContext!");1333assert(!Enc.getOpaqueValue() &&1334"Expected a nullptr for an invalid position!");1335return;1336case IRP_FLOAT:1337assert((!isa<Argument>(&getAssociatedValue())) &&1338"Expected specialized kind for argument values!");1339return;1340case IRP_RETURNED:1341assert(isa<Function>(getAsValuePtr()) &&1342"Expected function for a 'returned' position!");1343assert(getAsValuePtr() == &getAssociatedValue() &&1344"Associated value mismatch!");1345return;1346case IRP_CALL_SITE_RETURNED:1347assert((CBContext == nullptr) &&1348"'call site returned' position must not have CallBaseContext!");1349assert((isa<CallBase>(getAsValuePtr())) &&1350"Expected call base for 'call site returned' position!");1351assert(getAsValuePtr() == &getAssociatedValue() &&1352"Associated value mismatch!");1353return;1354case IRP_CALL_SITE:1355assert((CBContext == nullptr) &&1356"'call site function' position must not have CallBaseContext!");1357assert((isa<CallBase>(getAsValuePtr())) &&1358"Expected call base for 'call site function' position!");1359assert(getAsValuePtr() == &getAssociatedValue() &&1360"Associated value mismatch!");1361return;1362case IRP_FUNCTION:1363assert(isa<Function>(getAsValuePtr()) &&1364"Expected function for a 'function' position!");1365assert(getAsValuePtr() == &getAssociatedValue() &&1366"Associated value mismatch!");1367return;1368case IRP_ARGUMENT:1369assert(isa<Argument>(getAsValuePtr()) &&1370"Expected argument for a 'argument' position!");1371assert(getAsValuePtr() == &getAssociatedValue() &&1372"Associated value mismatch!");1373return;1374case IRP_CALL_SITE_ARGUMENT: {1375assert((CBContext == nullptr) &&1376"'call site argument' position must not have CallBaseContext!");1377Use *U = getAsUsePtr();1378(void)U; // Silence unused variable warning.1379assert(U && "Expected use for a 'call site argument' position!");1380assert(isa<CallBase>(U->getUser()) &&1381"Expected call base user for a 'call site argument' position!");1382assert(cast<CallBase>(U->getUser())->isArgOperand(U) &&1383"Expected call base argument operand for a 'call site argument' "1384"position");1385assert(cast<CallBase>(U->getUser())->getArgOperandNo(U) ==1386unsigned(getCallSiteArgNo()) &&1387"Argument number mismatch!");1388assert(U->get() == &getAssociatedValue() && "Associated value mismatch!");1389return;1390}1391}1392#endif1393}13941395std::optional<Constant *>1396Attributor::getAssumedConstant(const IRPosition &IRP,1397const AbstractAttribute &AA,1398bool &UsedAssumedInformation) {1399// First check all callbacks provided by outside AAs. If any of them returns1400// a non-null value that is different from the associated value, or1401// std::nullopt, we assume it's simplified.1402for (auto &CB : SimplificationCallbacks.lookup(IRP)) {1403std::optional<Value *> SimplifiedV = CB(IRP, &AA, UsedAssumedInformation);1404if (!SimplifiedV)1405return std::nullopt;1406if (isa_and_nonnull<Constant>(*SimplifiedV))1407return cast<Constant>(*SimplifiedV);1408return nullptr;1409}1410if (auto *C = dyn_cast<Constant>(&IRP.getAssociatedValue()))1411return C;1412SmallVector<AA::ValueAndContext> Values;1413if (getAssumedSimplifiedValues(IRP, &AA, Values,1414AA::ValueScope::Interprocedural,1415UsedAssumedInformation)) {1416if (Values.empty())1417return std::nullopt;1418if (auto *C = dyn_cast_or_null<Constant>(1419AAPotentialValues::getSingleValue(*this, AA, IRP, Values)))1420return C;1421}1422return nullptr;1423}14241425std::optional<Value *> Attributor::getAssumedSimplified(1426const IRPosition &IRP, const AbstractAttribute *AA,1427bool &UsedAssumedInformation, AA::ValueScope S) {1428// First check all callbacks provided by outside AAs. If any of them returns1429// a non-null value that is different from the associated value, or1430// std::nullopt, we assume it's simplified.1431for (auto &CB : SimplificationCallbacks.lookup(IRP))1432return CB(IRP, AA, UsedAssumedInformation);14331434SmallVector<AA::ValueAndContext> Values;1435if (!getAssumedSimplifiedValues(IRP, AA, Values, S, UsedAssumedInformation))1436return &IRP.getAssociatedValue();1437if (Values.empty())1438return std::nullopt;1439if (AA)1440if (Value *V = AAPotentialValues::getSingleValue(*this, *AA, IRP, Values))1441return V;1442if (IRP.getPositionKind() == IRPosition::IRP_RETURNED ||1443IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_RETURNED)1444return nullptr;1445return &IRP.getAssociatedValue();1446}14471448bool Attributor::getAssumedSimplifiedValues(1449const IRPosition &InitialIRP, const AbstractAttribute *AA,1450SmallVectorImpl<AA::ValueAndContext> &Values, AA::ValueScope S,1451bool &UsedAssumedInformation, bool RecurseForSelectAndPHI) {1452SmallPtrSet<Value *, 8> Seen;1453SmallVector<IRPosition, 8> Worklist;1454Worklist.push_back(InitialIRP);1455while (!Worklist.empty()) {1456const IRPosition &IRP = Worklist.pop_back_val();14571458// First check all callbacks provided by outside AAs. If any of them returns1459// a non-null value that is different from the associated value, or1460// std::nullopt, we assume it's simplified.1461int NV = Values.size();1462const auto &SimplificationCBs = SimplificationCallbacks.lookup(IRP);1463for (const auto &CB : SimplificationCBs) {1464std::optional<Value *> CBResult = CB(IRP, AA, UsedAssumedInformation);1465if (!CBResult.has_value())1466continue;1467Value *V = *CBResult;1468if (!V)1469return false;1470if ((S & AA::ValueScope::Interprocedural) ||1471AA::isValidInScope(*V, IRP.getAnchorScope()))1472Values.push_back(AA::ValueAndContext{*V, nullptr});1473else1474return false;1475}1476if (SimplificationCBs.empty()) {1477// If no high-level/outside simplification occurred, use1478// AAPotentialValues.1479const auto *PotentialValuesAA =1480getOrCreateAAFor<AAPotentialValues>(IRP, AA, DepClassTy::OPTIONAL);1481if (PotentialValuesAA && PotentialValuesAA->getAssumedSimplifiedValues(*this, Values, S)) {1482UsedAssumedInformation |= !PotentialValuesAA->isAtFixpoint();1483} else if (IRP.getPositionKind() != IRPosition::IRP_RETURNED) {1484Values.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});1485} else {1486// TODO: We could visit all returns and add the operands.1487return false;1488}1489}14901491if (!RecurseForSelectAndPHI)1492break;14931494for (int I = NV, E = Values.size(); I < E; ++I) {1495Value *V = Values[I].getValue();1496if (!isa<PHINode>(V) && !isa<SelectInst>(V))1497continue;1498if (!Seen.insert(V).second)1499continue;1500// Move the last element to this slot.1501Values[I] = Values[E - 1];1502// Eliminate the last slot, adjust the indices.1503Values.pop_back();1504--E;1505--I;1506// Add a new value (select or phi) to the worklist.1507Worklist.push_back(IRPosition::value(*V));1508}1509}1510return true;1511}15121513std::optional<Value *> Attributor::translateArgumentToCallSiteContent(1514std::optional<Value *> V, CallBase &CB, const AbstractAttribute &AA,1515bool &UsedAssumedInformation) {1516if (!V)1517return V;1518if (*V == nullptr || isa<Constant>(*V))1519return V;1520if (auto *Arg = dyn_cast<Argument>(*V))1521if (CB.getCalledOperand() == Arg->getParent() &&1522CB.arg_size() > Arg->getArgNo())1523if (!Arg->hasPointeeInMemoryValueAttr())1524return getAssumedSimplified(1525IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,1526UsedAssumedInformation, AA::Intraprocedural);1527return nullptr;1528}15291530Attributor::~Attributor() {1531// The abstract attributes are allocated via the BumpPtrAllocator Allocator,1532// thus we cannot delete them. We can, and want to, destruct them though.1533for (auto &It : AAMap) {1534AbstractAttribute *AA = It.getSecond();1535AA->~AbstractAttribute();1536}1537}15381539bool Attributor::isAssumedDead(const AbstractAttribute &AA,1540const AAIsDead *FnLivenessAA,1541bool &UsedAssumedInformation,1542bool CheckBBLivenessOnly, DepClassTy DepClass) {1543if (!Configuration.UseLiveness)1544return false;1545const IRPosition &IRP = AA.getIRPosition();1546if (!Functions.count(IRP.getAnchorScope()))1547return false;1548return isAssumedDead(IRP, &AA, FnLivenessAA, UsedAssumedInformation,1549CheckBBLivenessOnly, DepClass);1550}15511552bool Attributor::isAssumedDead(const Use &U,1553const AbstractAttribute *QueryingAA,1554const AAIsDead *FnLivenessAA,1555bool &UsedAssumedInformation,1556bool CheckBBLivenessOnly, DepClassTy DepClass) {1557if (!Configuration.UseLiveness)1558return false;1559Instruction *UserI = dyn_cast<Instruction>(U.getUser());1560if (!UserI)1561return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,1562UsedAssumedInformation, CheckBBLivenessOnly, DepClass);15631564if (auto *CB = dyn_cast<CallBase>(UserI)) {1565// For call site argument uses we can check if the argument is1566// unused/dead.1567if (CB->isArgOperand(&U)) {1568const IRPosition &CSArgPos =1569IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));1570return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,1571UsedAssumedInformation, CheckBBLivenessOnly,1572DepClass);1573}1574} else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {1575const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());1576return isAssumedDead(RetPos, QueryingAA, FnLivenessAA,1577UsedAssumedInformation, CheckBBLivenessOnly, DepClass);1578} else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {1579BasicBlock *IncomingBB = PHI->getIncomingBlock(U);1580return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,1581UsedAssumedInformation, CheckBBLivenessOnly, DepClass);1582} else if (StoreInst *SI = dyn_cast<StoreInst>(UserI)) {1583if (!CheckBBLivenessOnly && SI->getPointerOperand() != U.get()) {1584const IRPosition IRP = IRPosition::inst(*SI);1585const AAIsDead *IsDeadAA =1586getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);1587if (IsDeadAA && IsDeadAA->isRemovableStore()) {1588if (QueryingAA)1589recordDependence(*IsDeadAA, *QueryingAA, DepClass);1590if (!IsDeadAA->isKnown(AAIsDead::IS_REMOVABLE))1591UsedAssumedInformation = true;1592return true;1593}1594}1595}15961597return isAssumedDead(IRPosition::inst(*UserI), QueryingAA, FnLivenessAA,1598UsedAssumedInformation, CheckBBLivenessOnly, DepClass);1599}16001601bool Attributor::isAssumedDead(const Instruction &I,1602const AbstractAttribute *QueryingAA,1603const AAIsDead *FnLivenessAA,1604bool &UsedAssumedInformation,1605bool CheckBBLivenessOnly, DepClassTy DepClass,1606bool CheckForDeadStore) {1607if (!Configuration.UseLiveness)1608return false;1609const IRPosition::CallBaseContext *CBCtx =1610QueryingAA ? QueryingAA->getCallBaseContext() : nullptr;16111612if (ManifestAddedBlocks.contains(I.getParent()))1613return false;16141615const Function &F = *I.getFunction();1616if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)1617FnLivenessAA = getOrCreateAAFor<AAIsDead>(IRPosition::function(F, CBCtx),1618QueryingAA, DepClassTy::NONE);16191620// Don't use recursive reasoning.1621if (!FnLivenessAA || QueryingAA == FnLivenessAA)1622return false;16231624// If we have a context instruction and a liveness AA we use it.1625if (CheckBBLivenessOnly ? FnLivenessAA->isAssumedDead(I.getParent())1626: FnLivenessAA->isAssumedDead(&I)) {1627if (QueryingAA)1628recordDependence(*FnLivenessAA, *QueryingAA, DepClass);1629if (!FnLivenessAA->isKnownDead(&I))1630UsedAssumedInformation = true;1631return true;1632}16331634if (CheckBBLivenessOnly)1635return false;16361637const IRPosition IRP = IRPosition::inst(I, CBCtx);1638const AAIsDead *IsDeadAA =1639getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);16401641// Don't use recursive reasoning.1642if (!IsDeadAA || QueryingAA == IsDeadAA)1643return false;16441645if (IsDeadAA->isAssumedDead()) {1646if (QueryingAA)1647recordDependence(*IsDeadAA, *QueryingAA, DepClass);1648if (!IsDeadAA->isKnownDead())1649UsedAssumedInformation = true;1650return true;1651}16521653if (CheckForDeadStore && isa<StoreInst>(I) && IsDeadAA->isRemovableStore()) {1654if (QueryingAA)1655recordDependence(*IsDeadAA, *QueryingAA, DepClass);1656if (!IsDeadAA->isKnownDead())1657UsedAssumedInformation = true;1658return true;1659}16601661return false;1662}16631664bool Attributor::isAssumedDead(const IRPosition &IRP,1665const AbstractAttribute *QueryingAA,1666const AAIsDead *FnLivenessAA,1667bool &UsedAssumedInformation,1668bool CheckBBLivenessOnly, DepClassTy DepClass) {1669if (!Configuration.UseLiveness)1670return false;1671// Don't check liveness for constants, e.g. functions, used as (floating)1672// values since the context instruction and such is here meaningless.1673if (IRP.getPositionKind() == IRPosition::IRP_FLOAT &&1674isa<Constant>(IRP.getAssociatedValue())) {1675return false;1676}16771678Instruction *CtxI = IRP.getCtxI();1679if (CtxI &&1680isAssumedDead(*CtxI, QueryingAA, FnLivenessAA, UsedAssumedInformation,1681/* CheckBBLivenessOnly */ true,1682CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))1683return true;16841685if (CheckBBLivenessOnly)1686return false;16871688// If we haven't succeeded we query the specific liveness info for the IRP.1689const AAIsDead *IsDeadAA;1690if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE)1691IsDeadAA = getOrCreateAAFor<AAIsDead>(1692IRPosition::callsite_returned(cast<CallBase>(IRP.getAssociatedValue())),1693QueryingAA, DepClassTy::NONE);1694else1695IsDeadAA = getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);16961697// Don't use recursive reasoning.1698if (!IsDeadAA || QueryingAA == IsDeadAA)1699return false;17001701if (IsDeadAA->isAssumedDead()) {1702if (QueryingAA)1703recordDependence(*IsDeadAA, *QueryingAA, DepClass);1704if (!IsDeadAA->isKnownDead())1705UsedAssumedInformation = true;1706return true;1707}17081709return false;1710}17111712bool Attributor::isAssumedDead(const BasicBlock &BB,1713const AbstractAttribute *QueryingAA,1714const AAIsDead *FnLivenessAA,1715DepClassTy DepClass) {1716if (!Configuration.UseLiveness)1717return false;1718const Function &F = *BB.getParent();1719if (!FnLivenessAA || FnLivenessAA->getAnchorScope() != &F)1720FnLivenessAA = getOrCreateAAFor<AAIsDead>(IRPosition::function(F),1721QueryingAA, DepClassTy::NONE);17221723// Don't use recursive reasoning.1724if (!FnLivenessAA || QueryingAA == FnLivenessAA)1725return false;17261727if (FnLivenessAA->isAssumedDead(&BB)) {1728if (QueryingAA)1729recordDependence(*FnLivenessAA, *QueryingAA, DepClass);1730return true;1731}17321733return false;1734}17351736bool Attributor::checkForAllCallees(1737function_ref<bool(ArrayRef<const Function *>)> Pred,1738const AbstractAttribute &QueryingAA, const CallBase &CB) {1739if (const Function *Callee = dyn_cast<Function>(CB.getCalledOperand()))1740return Pred(Callee);17411742const auto *CallEdgesAA = getAAFor<AACallEdges>(1743QueryingAA, IRPosition::callsite_function(CB), DepClassTy::OPTIONAL);1744if (!CallEdgesAA || CallEdgesAA->hasUnknownCallee())1745return false;17461747const auto &Callees = CallEdgesAA->getOptimisticEdges();1748return Pred(Callees.getArrayRef());1749}17501751bool canMarkAsVisited(const User *Usr) {1752return isa<PHINode>(Usr) || !isa<Instruction>(Usr);1753}17541755bool Attributor::checkForAllUses(1756function_ref<bool(const Use &, bool &)> Pred,1757const AbstractAttribute &QueryingAA, const Value &V,1758bool CheckBBLivenessOnly, DepClassTy LivenessDepClass,1759bool IgnoreDroppableUses,1760function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB) {17611762// Check virtual uses first.1763for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&V))1764if (!CB(*this, &QueryingAA))1765return false;17661767// Check the trivial case first as it catches void values.1768if (V.use_empty())1769return true;17701771const IRPosition &IRP = QueryingAA.getIRPosition();1772SmallVector<const Use *, 16> Worklist;1773SmallPtrSet<const Use *, 16> Visited;17741775auto AddUsers = [&](const Value &V, const Use *OldUse) {1776for (const Use &UU : V.uses()) {1777if (OldUse && EquivalentUseCB && !EquivalentUseCB(*OldUse, UU)) {1778LLVM_DEBUG(dbgs() << "[Attributor] Potential copy was "1779"rejected by the equivalence call back: "1780<< *UU << "!\n");1781return false;1782}17831784Worklist.push_back(&UU);1785}1786return true;1787};17881789AddUsers(V, /* OldUse */ nullptr);17901791LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()1792<< " initial uses to check\n");17931794const Function *ScopeFn = IRP.getAnchorScope();1795const auto *LivenessAA =1796ScopeFn ? getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),1797DepClassTy::NONE)1798: nullptr;17991800while (!Worklist.empty()) {1801const Use *U = Worklist.pop_back_val();1802if (canMarkAsVisited(U->getUser()) && !Visited.insert(U).second)1803continue;1804DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, {1805if (auto *Fn = dyn_cast<Function>(U->getUser()))1806dbgs() << "[Attributor] Check use: " << **U << " in " << Fn->getName()1807<< "\n";1808else1809dbgs() << "[Attributor] Check use: " << **U << " in " << *U->getUser()1810<< "\n";1811});1812bool UsedAssumedInformation = false;1813if (isAssumedDead(*U, &QueryingAA, LivenessAA, UsedAssumedInformation,1814CheckBBLivenessOnly, LivenessDepClass)) {1815DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,1816dbgs() << "[Attributor] Dead use, skip!\n");1817continue;1818}1819if (IgnoreDroppableUses && U->getUser()->isDroppable()) {1820DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,1821dbgs() << "[Attributor] Droppable user, skip!\n");1822continue;1823}18241825if (auto *SI = dyn_cast<StoreInst>(U->getUser())) {1826if (&SI->getOperandUse(0) == U) {1827if (!Visited.insert(U).second)1828continue;1829SmallSetVector<Value *, 4> PotentialCopies;1830if (AA::getPotentialCopiesOfStoredValue(1831*this, *SI, PotentialCopies, QueryingAA, UsedAssumedInformation,1832/* OnlyExact */ true)) {1833DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,1834dbgs()1835<< "[Attributor] Value is stored, continue with "1836<< PotentialCopies.size()1837<< " potential copies instead!\n");1838for (Value *PotentialCopy : PotentialCopies)1839if (!AddUsers(*PotentialCopy, U))1840return false;1841continue;1842}1843}1844}18451846bool Follow = false;1847if (!Pred(*U, Follow))1848return false;1849if (!Follow)1850continue;18511852User &Usr = *U->getUser();1853AddUsers(Usr, /* OldUse */ nullptr);18541855auto *RI = dyn_cast<ReturnInst>(&Usr);1856if (!RI)1857continue;18581859Function &F = *RI->getFunction();1860auto CallSitePred = [&](AbstractCallSite ACS) {1861return AddUsers(*ACS.getInstruction(), U);1862};1863if (!checkForAllCallSites(CallSitePred, F, /* RequireAllCallSites */ true,1864&QueryingAA, UsedAssumedInformation)) {1865LLVM_DEBUG(dbgs() << "[Attributor] Could not follow return instruction "1866"to all call sites: "1867<< *RI << "\n");1868return false;1869}1870}18711872return true;1873}18741875bool Attributor::checkForAllCallSites(function_ref<bool(AbstractCallSite)> Pred,1876const AbstractAttribute &QueryingAA,1877bool RequireAllCallSites,1878bool &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.1882const IRPosition &IRP = QueryingAA.getIRPosition();1883const Function *AssociatedFunction = IRP.getAssociatedFunction();1884if (!AssociatedFunction) {1885LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP1886<< "\n");1887return false;1888}18891890return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,1891&QueryingAA, UsedAssumedInformation);1892}18931894bool Attributor::checkForAllCallSites(function_ref<bool(AbstractCallSite)> Pred,1895const Function &Fn,1896bool RequireAllCallSites,1897const AbstractAttribute *QueryingAA,1898bool &UsedAssumedInformation,1899bool CheckPotentiallyDead) {1900if (RequireAllCallSites && !Fn.hasLocalLinkage()) {1901LLVM_DEBUG(1902dbgs()1903<< "[Attributor] Function " << Fn.getName()1904<< " has no internal linkage, hence not all call sites are known\n");1905return false;1906}1907// Check virtual uses first.1908for (VirtualUseCallbackTy &CB : VirtualUseCallbacks.lookup(&Fn))1909if (!CB(*this, QueryingAA))1910return false;19111912SmallVector<const Use *, 8> Uses(make_pointer_range(Fn.uses()));1913for (unsigned u = 0; u < Uses.size(); ++u) {1914const Use &U = *Uses[u];1915DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, {1916if (auto *Fn = dyn_cast<Function>(U))1917dbgs() << "[Attributor] Check use: " << Fn->getName() << " in "1918<< *U.getUser() << "\n";1919else1920dbgs() << "[Attributor] Check use: " << *U << " in " << *U.getUser()1921<< "\n";1922});1923if (!CheckPotentiallyDead &&1924isAssumedDead(U, QueryingAA, nullptr, UsedAssumedInformation,1925/* CheckBBLivenessOnly */ true)) {1926DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,1927dbgs() << "[Attributor] Dead use, skip!\n");1928continue;1929}1930if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {1931if (CE->isCast() && CE->getType()->isPointerTy()) {1932DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, {1933dbgs() << "[Attributor] Use, is constant cast expression, add "1934<< CE->getNumUses() << " uses of that expression instead!\n";1935});1936for (const Use &CEU : CE->uses())1937Uses.push_back(&CEU);1938continue;1939}1940}19411942AbstractCallSite ACS(&U);1943if (!ACS) {1944LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()1945<< " has non call site use " << *U.get() << " in "1946<< *U.getUser() << "\n");1947// BlockAddress users are allowed.1948if (isa<BlockAddress>(U.getUser()))1949continue;1950return false;1951}19521953const Use *EffectiveUse =1954ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;1955if (!ACS.isCallee(EffectiveUse)) {1956if (!RequireAllCallSites) {1957LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()1958<< " is not a call of " << Fn.getName()1959<< ", skip use\n");1960continue;1961}1962LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()1963<< " is an invalid use of " << Fn.getName() << "\n");1964return false;1965}19661967// Make sure the arguments that can be matched between the call site and the1968// callee argee on their type. It is unlikely they do not and it doesn't1969// make sense for all attributes to know/care about this.1970assert(&Fn == ACS.getCalledFunction() && "Expected known callee");1971unsigned MinArgsParams =1972std::min(size_t(ACS.getNumArgOperands()), Fn.arg_size());1973for (unsigned u = 0; u < MinArgsParams; ++u) {1974Value *CSArgOp = ACS.getCallArgOperand(u);1975if (CSArgOp && Fn.getArg(u)->getType() != CSArgOp->getType()) {1976LLVM_DEBUG(1977dbgs() << "[Attributor] Call site / callee argument type mismatch ["1978<< u << "@" << Fn.getName() << ": "1979<< *Fn.getArg(u)->getType() << " vs. "1980<< *ACS.getCallArgOperand(u)->getType() << "\n");1981return false;1982}1983}19841985if (Pred(ACS))1986continue;19871988LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "1989<< *ACS.getInstruction() << "\n");1990return false;1991}19921993return true;1994}19951996bool Attributor::shouldPropagateCallBaseContext(const IRPosition &IRP) {1997// TODO: Maintain a cache of Values that are1998// on the pathway from a Argument to a Instruction that would effect the1999// liveness/return state etc.2000return EnableCallSiteSpecific;2001}20022003bool Attributor::checkForAllReturnedValues(function_ref<bool(Value &)> Pred,2004const AbstractAttribute &QueryingAA,2005AA::ValueScope S,2006bool RecurseForSelectAndPHI) {20072008const IRPosition &IRP = QueryingAA.getIRPosition();2009const Function *AssociatedFunction = IRP.getAssociatedFunction();2010if (!AssociatedFunction)2011return false;20122013bool UsedAssumedInformation = false;2014SmallVector<AA::ValueAndContext> Values;2015if (!getAssumedSimplifiedValues(2016IRPosition::returned(*AssociatedFunction), &QueryingAA, Values, S,2017UsedAssumedInformation, RecurseForSelectAndPHI))2018return false;20192020return llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {2021return Pred(*VAC.getValue());2022});2023}20242025static bool checkForAllInstructionsImpl(2026Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap,2027function_ref<bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA,2028const AAIsDead *LivenessAA, ArrayRef<unsigned> Opcodes,2029bool &UsedAssumedInformation, bool CheckBBLivenessOnly = false,2030bool CheckPotentiallyDead = false) {2031for (unsigned Opcode : Opcodes) {2032// Check if we have instructions with this opcode at all first.2033auto *Insts = OpcodeInstMap.lookup(Opcode);2034if (!Insts)2035continue;20362037for (Instruction *I : *Insts) {2038// Skip dead instructions.2039if (A && !CheckPotentiallyDead &&2040A->isAssumedDead(IRPosition::inst(*I), QueryingAA, LivenessAA,2041UsedAssumedInformation, CheckBBLivenessOnly)) {2042DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,2043dbgs() << "[Attributor] Instruction " << *I2044<< " is potentially dead, skip!\n";);2045continue;2046}20472048if (!Pred(*I))2049return false;2050}2051}2052return true;2053}20542055bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,2056const Function *Fn,2057const AbstractAttribute *QueryingAA,2058ArrayRef<unsigned> Opcodes,2059bool &UsedAssumedInformation,2060bool CheckBBLivenessOnly,2061bool CheckPotentiallyDead) {2062// Since we need to provide instructions we have to have an exact definition.2063if (!Fn || Fn->isDeclaration())2064return false;20652066const IRPosition &QueryIRP = IRPosition::function(*Fn);2067const auto *LivenessAA =2068CheckPotentiallyDead && QueryingAA2069? (getAAFor<AAIsDead>(*QueryingAA, QueryIRP, DepClassTy::NONE))2070: nullptr;20712072auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);2073if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, QueryingAA,2074LivenessAA, Opcodes, UsedAssumedInformation,2075CheckBBLivenessOnly, CheckPotentiallyDead))2076return false;20772078return true;2079}20802081bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,2082const AbstractAttribute &QueryingAA,2083ArrayRef<unsigned> Opcodes,2084bool &UsedAssumedInformation,2085bool CheckBBLivenessOnly,2086bool CheckPotentiallyDead) {2087const IRPosition &IRP = QueryingAA.getIRPosition();2088const Function *AssociatedFunction = IRP.getAssociatedFunction();2089return checkForAllInstructions(Pred, AssociatedFunction, &QueryingAA, Opcodes,2090UsedAssumedInformation, CheckBBLivenessOnly,2091CheckPotentiallyDead);2092}20932094bool Attributor::checkForAllReadWriteInstructions(2095function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA,2096bool &UsedAssumedInformation) {2097TimeTraceScope TS("checkForAllReadWriteInstructions");20982099const Function *AssociatedFunction =2100QueryingAA.getIRPosition().getAssociatedFunction();2101if (!AssociatedFunction)2102return false;21032104const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);2105const auto *LivenessAA =2106getAAFor<AAIsDead>(QueryingAA, QueryIRP, DepClassTy::NONE);21072108for (Instruction *I :2109InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {2110// Skip dead instructions.2111if (isAssumedDead(IRPosition::inst(*I), &QueryingAA, LivenessAA,2112UsedAssumedInformation))2113continue;21142115if (!Pred(*I))2116return false;2117}21182119return true;2120}21212122void Attributor::runTillFixpoint() {2123TimeTraceScope TimeScope("Attributor::runTillFixpoint");2124LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "2125<< DG.SyntheticRoot.Deps.size()2126<< " abstract attributes.\n");21272128// Now that all abstract attributes are collected and initialized we start2129// the abstract analysis.21302131unsigned IterationCounter = 1;2132unsigned MaxIterations =2133Configuration.MaxFixpointIterations.value_or(SetFixpointIterations);21342135SmallVector<AbstractAttribute *, 32> ChangedAAs;2136SetVector<AbstractAttribute *> Worklist, InvalidAAs;2137Worklist.insert(DG.SyntheticRoot.begin(), DG.SyntheticRoot.end());21382139do {2140// Remember the size to determine new attributes.2141size_t NumAAs = DG.SyntheticRoot.Deps.size();2142LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter2143<< ", Worklist size: " << Worklist.size() << "\n");21442145// For invalid AAs we can fix dependent AAs that have a required dependence,2146// thereby folding long dependence chains in a single step without the need2147// to run updates.2148for (unsigned u = 0; u < InvalidAAs.size(); ++u) {2149AbstractAttribute *InvalidAA = InvalidAAs[u];21502151// Check the dependences to fast track invalidation.2152DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,2153dbgs() << "[Attributor] InvalidAA: " << *InvalidAA2154<< " has " << InvalidAA->Deps.size()2155<< " required & optional dependences\n");2156for (auto &DepIt : InvalidAA->Deps) {2157AbstractAttribute *DepAA = cast<AbstractAttribute>(DepIt.getPointer());2158if (DepIt.getInt() == unsigned(DepClassTy::OPTIONAL)) {2159DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE,2160dbgs() << " - recompute: " << *DepAA);2161Worklist.insert(DepAA);2162continue;2163}2164DEBUG_WITH_TYPE(VERBOSE_DEBUG_TYPE, dbgs()2165<< " - invalidate: " << *DepAA);2166DepAA->getState().indicatePessimisticFixpoint();2167assert(DepAA->getState().isAtFixpoint() && "Expected fixpoint state!");2168if (!DepAA->getState().isValidState())2169InvalidAAs.insert(DepAA);2170else2171ChangedAAs.push_back(DepAA);2172}2173InvalidAA->Deps.clear();2174}21752176// Add all abstract attributes that are potentially dependent on one that2177// changed to the work list.2178for (AbstractAttribute *ChangedAA : ChangedAAs) {2179for (auto &DepIt : ChangedAA->Deps)2180Worklist.insert(cast<AbstractAttribute>(DepIt.getPointer()));2181ChangedAA->Deps.clear();2182}21832184LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter2185<< ", Worklist+Dependent size: " << Worklist.size()2186<< "\n");21872188// Reset the changed and invalid set.2189ChangedAAs.clear();2190InvalidAAs.clear();21912192// Update all abstract attribute in the work list and record the ones that2193// changed.2194for (AbstractAttribute *AA : Worklist) {2195const auto &AAState = AA->getState();2196if (!AAState.isAtFixpoint())2197if (updateAA(*AA) == ChangeStatus::CHANGED)2198ChangedAAs.push_back(AA);21992200// Use the InvalidAAs vector to propagate invalid states fast transitively2201// without requiring updates.2202if (!AAState.isValidState())2203InvalidAAs.insert(AA);2204}22052206// Add attributes to the changed set if they have been created in the last2207// iteration.2208ChangedAAs.append(DG.SyntheticRoot.begin() + NumAAs,2209DG.SyntheticRoot.end());22102211// Reset the work list and repopulate with the changed abstract attributes.2212// Note that dependent ones are added above.2213Worklist.clear();2214Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());2215Worklist.insert(QueryAAsAwaitingUpdate.begin(),2216QueryAAsAwaitingUpdate.end());2217QueryAAsAwaitingUpdate.clear();22182219} while (!Worklist.empty() && (IterationCounter++ < MaxIterations));22202221if (IterationCounter > MaxIterations && !Functions.empty()) {2222auto Remark = [&](OptimizationRemarkMissed ORM) {2223return ORM << "Attributor did not reach a fixpoint after "2224<< ore::NV("Iterations", MaxIterations) << " iterations.";2225};2226Function *F = Functions.front();2227emitRemark<OptimizationRemarkMissed>(F, "FixedPoint", Remark);2228}22292230LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "2231<< IterationCounter << "/" << MaxIterations2232<< " iterations\n");22332234// Reset abstract arguments not settled in a sound fixpoint by now. This2235// happens when we stopped the fixpoint iteration early. Note that only the2236// ones marked as "changed" *and* the ones transitively depending on them2237// need to be reverted to a pessimistic state. Others might not be in a2238// fixpoint state but we can use the optimistic results for them anyway.2239SmallPtrSet<AbstractAttribute *, 32> Visited;2240for (unsigned u = 0; u < ChangedAAs.size(); u++) {2241AbstractAttribute *ChangedAA = ChangedAAs[u];2242if (!Visited.insert(ChangedAA).second)2243continue;22442245AbstractState &State = ChangedAA->getState();2246if (!State.isAtFixpoint()) {2247State.indicatePessimisticFixpoint();22482249NumAttributesTimedOut++;2250}22512252for (auto &DepIt : ChangedAA->Deps)2253ChangedAAs.push_back(cast<AbstractAttribute>(DepIt.getPointer()));2254ChangedAA->Deps.clear();2255}22562257LLVM_DEBUG({2258if (!Visited.empty())2259dbgs() << "\n[Attributor] Finalized " << Visited.size()2260<< " abstract attributes.\n";2261});2262}22632264void Attributor::registerForUpdate(AbstractAttribute &AA) {2265assert(AA.isQueryAA() &&2266"Non-query AAs should not be required to register for updates!");2267QueryAAsAwaitingUpdate.insert(&AA);2268}22692270ChangeStatus Attributor::manifestAttributes() {2271TimeTraceScope TimeScope("Attributor::manifestAttributes");2272size_t NumFinalAAs = DG.SyntheticRoot.Deps.size();22732274unsigned NumManifested = 0;2275unsigned NumAtFixpoint = 0;2276ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;2277for (auto &DepAA : DG.SyntheticRoot.Deps) {2278AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());2279AbstractState &State = AA->getState();22802281// If there is not already a fixpoint reached, we can now take the2282// optimistic state. This is correct because we enforced a pessimistic one2283// on abstract attributes that were transitively dependent on a changed one2284// already above.2285if (!State.isAtFixpoint())2286State.indicateOptimisticFixpoint();22872288// We must not manifest Attributes that use Callbase info.2289if (AA->hasCallBaseContext())2290continue;2291// If the state is invalid, we do not try to manifest it.2292if (!State.isValidState())2293continue;22942295if (AA->getCtxI() && !isRunOn(*AA->getAnchorScope()))2296continue;22972298// Skip dead code.2299bool UsedAssumedInformation = false;2300if (isAssumedDead(*AA, nullptr, UsedAssumedInformation,2301/* CheckBBLivenessOnly */ true))2302continue;2303// Check if the manifest debug counter that allows skipping manifestation of2304// AAs2305if (!DebugCounter::shouldExecute(ManifestDBGCounter))2306continue;2307// Manifest the state and record if we changed the IR.2308ChangeStatus LocalChange = AA->manifest(*this);2309if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())2310AA->trackStatistics();2311LLVM_DEBUG(dbgs() << "[Attributor] Manifest " << LocalChange << " : " << *AA2312<< "\n");23132314ManifestChange = ManifestChange | LocalChange;23152316NumAtFixpoint++;2317NumManifested += (LocalChange == ChangeStatus::CHANGED);2318}23192320(void)NumManifested;2321(void)NumAtFixpoint;2322LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested2323<< " arguments while " << NumAtFixpoint2324<< " were in a valid fixpoint state\n");23252326NumAttributesManifested += NumManifested;2327NumAttributesValidFixpoint += NumAtFixpoint;23282329(void)NumFinalAAs;2330if (NumFinalAAs != DG.SyntheticRoot.Deps.size()) {2331auto DepIt = DG.SyntheticRoot.Deps.begin();2332for (unsigned u = 0; u < NumFinalAAs; ++u)2333++DepIt;2334for (unsigned u = NumFinalAAs; u < DG.SyntheticRoot.Deps.size();2335++u, ++DepIt) {2336errs() << "Unexpected abstract attribute: "2337<< cast<AbstractAttribute>(DepIt->getPointer()) << " :: "2338<< cast<AbstractAttribute>(DepIt->getPointer())2339->getIRPosition()2340.getAssociatedValue()2341<< "\n";2342}2343llvm_unreachable("Expected the final number of abstract attributes to "2344"remain unchanged!");2345}23462347for (auto &It : AttrsMap) {2348AttributeList &AL = It.getSecond();2349const IRPosition &IRP =2350isa<Function>(It.getFirst())2351? IRPosition::function(*cast<Function>(It.getFirst()))2352: IRPosition::callsite_function(*cast<CallBase>(It.getFirst()));2353IRP.setAttrList(AL);2354}23552356return ManifestChange;2357}23582359void Attributor::identifyDeadInternalFunctions() {2360// Early exit if we don't intend to delete functions.2361if (!Configuration.DeleteFns)2362return;23632364// To avoid triggering an assertion in the lazy call graph we will not delete2365// any internal library functions. We should modify the assertion though and2366// allow internals to be deleted.2367const auto *TLI =2368isModulePass()2369? nullptr2370: getInfoCache().getTargetLibraryInfoForFunction(*Functions.back());2371LibFunc LF;23722373// Identify dead internal functions and delete them. This happens outside2374// the other fixpoint analysis as we might treat potentially dead functions2375// as live to lower the number of iterations. If they happen to be dead, the2376// below fixpoint loop will identify and eliminate them.23772378SmallVector<Function *, 8> InternalFns;2379for (Function *F : Functions)2380if (F->hasLocalLinkage() && (isModulePass() || !TLI->getLibFunc(*F, LF)))2381InternalFns.push_back(F);23822383SmallPtrSet<Function *, 8> LiveInternalFns;2384bool FoundLiveInternal = true;2385while (FoundLiveInternal) {2386FoundLiveInternal = false;2387for (Function *&F : InternalFns) {2388if (!F)2389continue;23902391bool UsedAssumedInformation = false;2392if (checkForAllCallSites(2393[&](AbstractCallSite ACS) {2394Function *Callee = ACS.getInstruction()->getFunction();2395return ToBeDeletedFunctions.count(Callee) ||2396(Functions.count(Callee) && Callee->hasLocalLinkage() &&2397!LiveInternalFns.count(Callee));2398},2399*F, true, nullptr, UsedAssumedInformation)) {2400continue;2401}24022403LiveInternalFns.insert(F);2404F = nullptr;2405FoundLiveInternal = true;2406}2407}24082409for (Function *F : InternalFns)2410if (F)2411ToBeDeletedFunctions.insert(F);2412}24132414ChangeStatus Attributor::cleanupIR() {2415TimeTraceScope TimeScope("Attributor::cleanupIR");2416// Delete stuff at the end to avoid invalid references and a nice order.2417LLVM_DEBUG(dbgs() << "\n[Attributor] Delete/replace at least "2418<< ToBeDeletedFunctions.size() << " functions and "2419<< ToBeDeletedBlocks.size() << " blocks and "2420<< ToBeDeletedInsts.size() << " instructions and "2421<< ToBeChangedValues.size() << " values and "2422<< ToBeChangedUses.size() << " uses. To insert "2423<< ToBeChangedToUnreachableInsts.size()2424<< " unreachables.\n"2425<< "Preserve manifest added " << ManifestAddedBlocks.size()2426<< " blocks\n");24272428SmallVector<WeakTrackingVH, 32> DeadInsts;2429SmallVector<Instruction *, 32> TerminatorsToFold;24302431auto ReplaceUse = [&](Use *U, Value *NewV) {2432Value *OldV = U->get();24332434// If we plan to replace NewV we need to update it at this point.2435do {2436const auto &Entry = ToBeChangedValues.lookup(NewV);2437if (!get<0>(Entry))2438break;2439NewV = get<0>(Entry);2440} while (true);24412442Instruction *I = dyn_cast<Instruction>(U->getUser());2443assert((!I || isRunOn(*I->getFunction())) &&2444"Cannot replace an instruction outside the current SCC!");24452446// Do not replace uses in returns if the value is a must-tail call we will2447// not delete.2448if (auto *RI = dyn_cast_or_null<ReturnInst>(I)) {2449if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))2450if (CI->isMustTailCall() && !ToBeDeletedInsts.count(CI))2451return;2452// If we rewrite a return and the new value is not an argument, strip the2453// `returned` attribute as it is wrong now.2454if (!isa<Argument>(NewV))2455for (auto &Arg : RI->getFunction()->args())2456Arg.removeAttr(Attribute::Returned);2457}24582459LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()2460<< " instead of " << *OldV << "\n");2461U->set(NewV);24622463if (Instruction *I = dyn_cast<Instruction>(OldV)) {2464CGModifiedFunctions.insert(I->getFunction());2465if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&2466isInstructionTriviallyDead(I))2467DeadInsts.push_back(I);2468}2469if (isa<UndefValue>(NewV) && isa<CallBase>(U->getUser())) {2470auto *CB = cast<CallBase>(U->getUser());2471if (CB->isArgOperand(U)) {2472unsigned Idx = CB->getArgOperandNo(U);2473CB->removeParamAttr(Idx, Attribute::NoUndef);2474auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());2475if (Callee && Callee->arg_size() > Idx)2476Callee->removeParamAttr(Idx, Attribute::NoUndef);2477}2478}2479if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {2480Instruction *UserI = cast<Instruction>(U->getUser());2481if (isa<UndefValue>(NewV)) {2482ToBeChangedToUnreachableInsts.insert(UserI);2483} else {2484TerminatorsToFold.push_back(UserI);2485}2486}2487};24882489for (auto &It : ToBeChangedUses) {2490Use *U = It.first;2491Value *NewV = It.second;2492ReplaceUse(U, NewV);2493}24942495SmallVector<Use *, 4> Uses;2496for (auto &It : ToBeChangedValues) {2497Value *OldV = It.first;2498auto [NewV, Done] = It.second;2499Uses.clear();2500for (auto &U : OldV->uses())2501if (Done || !U.getUser()->isDroppable())2502Uses.push_back(&U);2503for (Use *U : Uses) {2504if (auto *I = dyn_cast<Instruction>(U->getUser()))2505if (!isRunOn(*I->getFunction()))2506continue;2507ReplaceUse(U, NewV);2508}2509}25102511for (const auto &V : InvokeWithDeadSuccessor)2512if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {2513assert(isRunOn(*II->getFunction()) &&2514"Cannot replace an invoke outside the current SCC!");2515bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);2516bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);2517bool Invoke2CallAllowed =2518!AAIsDead::mayCatchAsynchronousExceptions(*II->getFunction());2519assert((UnwindBBIsDead || NormalBBIsDead) &&2520"Invoke does not have dead successors!");2521BasicBlock *BB = II->getParent();2522BasicBlock *NormalDestBB = II->getNormalDest();2523if (UnwindBBIsDead) {2524Instruction *NormalNextIP = &NormalDestBB->front();2525if (Invoke2CallAllowed) {2526changeToCall(II);2527NormalNextIP = BB->getTerminator();2528}2529if (NormalBBIsDead)2530ToBeChangedToUnreachableInsts.insert(NormalNextIP);2531} else {2532assert(NormalBBIsDead && "Broken invariant!");2533if (!NormalDestBB->getUniquePredecessor())2534NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");2535ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());2536}2537}2538for (Instruction *I : TerminatorsToFold) {2539assert(isRunOn(*I->getFunction()) &&2540"Cannot replace a terminator outside the current SCC!");2541CGModifiedFunctions.insert(I->getFunction());2542ConstantFoldTerminator(I->getParent());2543}2544for (const auto &V : ToBeChangedToUnreachableInsts)2545if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {2546LLVM_DEBUG(dbgs() << "[Attributor] Change to unreachable: " << *I2547<< "\n");2548assert(isRunOn(*I->getFunction()) &&2549"Cannot replace an instruction outside the current SCC!");2550CGModifiedFunctions.insert(I->getFunction());2551changeToUnreachable(I);2552}25532554for (const auto &V : ToBeDeletedInsts) {2555if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {2556assert((!isa<CallBase>(I) || isa<IntrinsicInst>(I) ||2557isRunOn(*I->getFunction())) &&2558"Cannot delete an instruction outside the current SCC!");2559I->dropDroppableUses();2560CGModifiedFunctions.insert(I->getFunction());2561if (!I->getType()->isVoidTy())2562I->replaceAllUsesWith(UndefValue::get(I->getType()));2563if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))2564DeadInsts.push_back(I);2565else2566I->eraseFromParent();2567}2568}25692570llvm::erase_if(DeadInsts, [&](WeakTrackingVH I) { return !I; });25712572LLVM_DEBUG({2573dbgs() << "[Attributor] DeadInsts size: " << DeadInsts.size() << "\n";2574for (auto &I : DeadInsts)2575if (I)2576dbgs() << " - " << *I << "\n";2577});25782579RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);25802581if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {2582SmallVector<BasicBlock *, 8> ToBeDeletedBBs;2583ToBeDeletedBBs.reserve(NumDeadBlocks);2584for (BasicBlock *BB : ToBeDeletedBlocks) {2585assert(isRunOn(*BB->getParent()) &&2586"Cannot delete a block outside the current SCC!");2587CGModifiedFunctions.insert(BB->getParent());2588// Do not delete BBs added during manifests of AAs.2589if (ManifestAddedBlocks.contains(BB))2590continue;2591ToBeDeletedBBs.push_back(BB);2592}2593// Actually we do not delete the blocks but squash them into a single2594// unreachable but untangling branches that jump here is something we need2595// to do in a more generic way.2596detachDeadBlocks(ToBeDeletedBBs, nullptr);2597}25982599identifyDeadInternalFunctions();26002601// Rewrite the functions as requested during manifest.2602ChangeStatus ManifestChange = rewriteFunctionSignatures(CGModifiedFunctions);26032604for (Function *Fn : CGModifiedFunctions)2605if (!ToBeDeletedFunctions.count(Fn) && Functions.count(Fn))2606Configuration.CGUpdater.reanalyzeFunction(*Fn);26072608for (Function *Fn : ToBeDeletedFunctions) {2609if (!Functions.count(Fn))2610continue;2611Configuration.CGUpdater.removeFunction(*Fn);2612}26132614if (!ToBeChangedUses.empty())2615ManifestChange = ChangeStatus::CHANGED;26162617if (!ToBeChangedToUnreachableInsts.empty())2618ManifestChange = ChangeStatus::CHANGED;26192620if (!ToBeDeletedFunctions.empty())2621ManifestChange = ChangeStatus::CHANGED;26222623if (!ToBeDeletedBlocks.empty())2624ManifestChange = ChangeStatus::CHANGED;26252626if (!ToBeDeletedInsts.empty())2627ManifestChange = ChangeStatus::CHANGED;26282629if (!InvokeWithDeadSuccessor.empty())2630ManifestChange = ChangeStatus::CHANGED;26312632if (!DeadInsts.empty())2633ManifestChange = ChangeStatus::CHANGED;26342635NumFnDeleted += ToBeDeletedFunctions.size();26362637LLVM_DEBUG(dbgs() << "[Attributor] Deleted " << ToBeDeletedFunctions.size()2638<< " functions after manifest.\n");26392640#ifdef EXPENSIVE_CHECKS2641for (Function *F : Functions) {2642if (ToBeDeletedFunctions.count(F))2643continue;2644assert(!verifyFunction(*F, &errs()) && "Module verification failed!");2645}2646#endif26472648return ManifestChange;2649}26502651ChangeStatus Attributor::run() {2652TimeTraceScope TimeScope("Attributor::run");2653AttributorCallGraph ACallGraph(*this);26542655if (PrintCallGraph)2656ACallGraph.populateAll();26572658Phase = AttributorPhase::UPDATE;2659runTillFixpoint();26602661// dump graphs on demand2662if (DumpDepGraph)2663DG.dumpGraph();26642665if (ViewDepGraph)2666DG.viewGraph();26672668if (PrintDependencies)2669DG.print();26702671Phase = AttributorPhase::MANIFEST;2672ChangeStatus ManifestChange = manifestAttributes();26732674Phase = AttributorPhase::CLEANUP;2675ChangeStatus CleanupChange = cleanupIR();26762677if (PrintCallGraph)2678ACallGraph.print();26792680return ManifestChange | CleanupChange;2681}26822683ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {2684TimeTraceScope TimeScope("updateAA", [&]() {2685return AA.getName() + std::to_string(AA.getIRPosition().getPositionKind());2686});2687assert(Phase == AttributorPhase::UPDATE &&2688"We can update AA only in the update stage!");26892690// Use a new dependence vector for this update.2691DependenceVector DV;2692DependenceStack.push_back(&DV);26932694auto &AAState = AA.getState();2695ChangeStatus CS = ChangeStatus::UNCHANGED;2696bool UsedAssumedInformation = false;2697if (!isAssumedDead(AA, nullptr, UsedAssumedInformation,2698/* CheckBBLivenessOnly */ true))2699CS = AA.update(*this);27002701if (!AA.isQueryAA() && DV.empty() && !AA.getState().isAtFixpoint()) {2702// If the AA did not rely on outside information but changed, we run it2703// again to see if it found a fixpoint. Most AAs do but we don't require2704// them to. Hence, it might take the AA multiple iterations to get to a2705// fixpoint even if it does not rely on outside information, which is fine.2706ChangeStatus RerunCS = ChangeStatus::UNCHANGED;2707if (CS == ChangeStatus::CHANGED)2708RerunCS = AA.update(*this);27092710// If the attribute did not change during the run or rerun, and it still did2711// not query any non-fix information, the state will not change and we can2712// indicate that right at this point.2713if (RerunCS == ChangeStatus::UNCHANGED && !AA.isQueryAA() && DV.empty())2714AAState.indicateOptimisticFixpoint();2715}27162717if (!AAState.isAtFixpoint())2718rememberDependences();27192720// Verify the stack was used properly, that is we pop the dependence vector we2721// put there earlier.2722DependenceVector *PoppedDV = DependenceStack.pop_back_val();2723(void)PoppedDV;2724assert(PoppedDV == &DV && "Inconsistent usage of the dependence stack!");27252726return CS;2727}27282729void Attributor::createShallowWrapper(Function &F) {2730assert(!F.isDeclaration() && "Cannot create a wrapper around a declaration!");27312732Module &M = *F.getParent();2733LLVMContext &Ctx = M.getContext();2734FunctionType *FnTy = F.getFunctionType();27352736Function *Wrapper =2737Function::Create(FnTy, F.getLinkage(), F.getAddressSpace(), F.getName());2738F.setName(""); // set the inside function anonymous2739M.getFunctionList().insert(F.getIterator(), Wrapper);2740// Flag whether the function is using new-debug-info or not.2741Wrapper->IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;27422743F.setLinkage(GlobalValue::InternalLinkage);27442745F.replaceAllUsesWith(Wrapper);2746assert(F.use_empty() && "Uses remained after wrapper was created!");27472748// Move the COMDAT section to the wrapper.2749// TODO: Check if we need to keep it for F as well.2750Wrapper->setComdat(F.getComdat());2751F.setComdat(nullptr);27522753// Copy all metadata and attributes but keep them on F as well.2754SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;2755F.getAllMetadata(MDs);2756for (auto MDIt : MDs)2757Wrapper->addMetadata(MDIt.first, *MDIt.second);2758Wrapper->setAttributes(F.getAttributes());27592760// Create the call in the wrapper.2761BasicBlock *EntryBB = BasicBlock::Create(Ctx, "entry", Wrapper);27622763SmallVector<Value *, 8> Args;2764Argument *FArgIt = F.arg_begin();2765for (Argument &Arg : Wrapper->args()) {2766Args.push_back(&Arg);2767Arg.setName((FArgIt++)->getName());2768}27692770CallInst *CI = CallInst::Create(&F, Args, "", EntryBB);2771CI->setTailCall(true);2772CI->addFnAttr(Attribute::NoInline);2773ReturnInst::Create(Ctx, CI->getType()->isVoidTy() ? nullptr : CI, EntryBB);27742775NumFnShallowWrappersCreated++;2776}27772778bool Attributor::isInternalizable(Function &F) {2779if (F.isDeclaration() || F.hasLocalLinkage() ||2780GlobalValue::isInterposableLinkage(F.getLinkage()))2781return false;2782return true;2783}27842785Function *Attributor::internalizeFunction(Function &F, bool Force) {2786if (!AllowDeepWrapper && !Force)2787return nullptr;2788if (!isInternalizable(F))2789return nullptr;27902791SmallPtrSet<Function *, 2> FnSet = {&F};2792DenseMap<Function *, Function *> InternalizedFns;2793internalizeFunctions(FnSet, InternalizedFns);27942795return InternalizedFns[&F];2796}27972798bool Attributor::internalizeFunctions(SmallPtrSetImpl<Function *> &FnSet,2799DenseMap<Function *, Function *> &FnMap) {2800for (Function *F : FnSet)2801if (!Attributor::isInternalizable(*F))2802return false;28032804FnMap.clear();2805// Generate the internalized version of each function.2806for (Function *F : FnSet) {2807Module &M = *F->getParent();2808FunctionType *FnTy = F->getFunctionType();28092810// Create a copy of the current function2811Function *Copied =2812Function::Create(FnTy, F->getLinkage(), F->getAddressSpace(),2813F->getName() + ".internalized");2814ValueToValueMapTy VMap;2815auto *NewFArgIt = Copied->arg_begin();2816for (auto &Arg : F->args()) {2817auto ArgName = Arg.getName();2818NewFArgIt->setName(ArgName);2819VMap[&Arg] = &(*NewFArgIt++);2820}2821SmallVector<ReturnInst *, 8> Returns;2822// Flag whether the function is using new-debug-info or not.2823Copied->IsNewDbgInfoFormat = F->IsNewDbgInfoFormat;28242825// Copy the body of the original function to the new one2826CloneFunctionInto(Copied, F, VMap,2827CloneFunctionChangeType::LocalChangesOnly, Returns);28282829// Set the linakage and visibility late as CloneFunctionInto has some2830// implicit requirements.2831Copied->setVisibility(GlobalValue::DefaultVisibility);2832Copied->setLinkage(GlobalValue::PrivateLinkage);28332834// Copy metadata2835SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;2836F->getAllMetadata(MDs);2837for (auto MDIt : MDs)2838if (!Copied->hasMetadata())2839Copied->addMetadata(MDIt.first, *MDIt.second);28402841M.getFunctionList().insert(F->getIterator(), Copied);2842Copied->setDSOLocal(true);2843FnMap[F] = Copied;2844}28452846// Replace all uses of the old function with the new internalized function2847// unless the caller is a function that was just internalized.2848for (Function *F : FnSet) {2849auto &InternalizedFn = FnMap[F];2850auto IsNotInternalized = [&](Use &U) -> bool {2851if (auto *CB = dyn_cast<CallBase>(U.getUser()))2852return !FnMap.lookup(CB->getCaller());2853return false;2854};2855F->replaceUsesWithIf(InternalizedFn, IsNotInternalized);2856}28572858return true;2859}28602861bool Attributor::isValidFunctionSignatureRewrite(2862Argument &Arg, ArrayRef<Type *> ReplacementTypes) {28632864if (!Configuration.RewriteSignatures)2865return false;28662867Function *Fn = Arg.getParent();2868auto CallSiteCanBeChanged = [Fn](AbstractCallSite ACS) {2869// Forbid the call site to cast the function return type. If we need to2870// rewrite these functions we need to re-create a cast for the new call site2871// (if the old had uses).2872if (!ACS.getCalledFunction() ||2873ACS.getInstruction()->getType() !=2874ACS.getCalledFunction()->getReturnType())2875return false;2876if (cast<CallBase>(ACS.getInstruction())->getCalledOperand()->getType() !=2877Fn->getType())2878return false;2879if (ACS.getNumArgOperands() != Fn->arg_size())2880return false;2881// Forbid must-tail calls for now.2882return !ACS.isCallbackCall() && !ACS.getInstruction()->isMustTailCall();2883};28842885// Avoid var-arg functions for now.2886if (Fn->isVarArg()) {2887LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");2888return false;2889}28902891// Avoid functions with complicated argument passing semantics.2892AttributeList FnAttributeList = Fn->getAttributes();2893if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||2894FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||2895FnAttributeList.hasAttrSomewhere(Attribute::InAlloca) ||2896FnAttributeList.hasAttrSomewhere(Attribute::Preallocated)) {2897LLVM_DEBUG(2898dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");2899return false;2900}29012902// Avoid callbacks for now.2903bool UsedAssumedInformation = false;2904if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,2905UsedAssumedInformation,2906/* CheckPotentiallyDead */ true)) {2907LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");2908return false;2909}29102911auto InstPred = [](Instruction &I) {2912if (auto *CI = dyn_cast<CallInst>(&I))2913return !CI->isMustTailCall();2914return true;2915};29162917// Forbid must-tail calls for now.2918// TODO:2919auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);2920if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,2921nullptr, {Instruction::Call},2922UsedAssumedInformation)) {2923LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");2924return false;2925}29262927return true;2928}29292930bool Attributor::registerFunctionSignatureRewrite(2931Argument &Arg, ArrayRef<Type *> ReplacementTypes,2932ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,2933ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {2934LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "2935<< Arg.getParent()->getName() << " with "2936<< ReplacementTypes.size() << " replacements\n");2937assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&2938"Cannot register an invalid rewrite");29392940Function *Fn = Arg.getParent();2941SmallVectorImpl<std::unique_ptr<ArgumentReplacementInfo>> &ARIs =2942ArgumentReplacementMap[Fn];2943if (ARIs.empty())2944ARIs.resize(Fn->arg_size());29452946// If we have a replacement already with less than or equal new arguments,2947// ignore this request.2948std::unique_ptr<ArgumentReplacementInfo> &ARI = ARIs[Arg.getArgNo()];2949if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {2950LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");2951return false;2952}29532954// If we have a replacement already but we like the new one better, delete2955// the old.2956ARI.reset();29572958LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "2959<< Arg.getParent()->getName() << " with "2960<< ReplacementTypes.size() << " replacements\n");29612962// Remember the replacement.2963ARI.reset(new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,2964std::move(CalleeRepairCB),2965std::move(ACSRepairCB)));29662967return true;2968}29692970bool Attributor::shouldSeedAttribute(AbstractAttribute &AA) {2971bool Result = true;2972#ifndef NDEBUG2973if (SeedAllowList.size() != 0)2974Result = llvm::is_contained(SeedAllowList, AA.getName());2975Function *Fn = AA.getAnchorScope();2976if (FunctionSeedAllowList.size() != 0 && Fn)2977Result &= llvm::is_contained(FunctionSeedAllowList, Fn->getName());2978#endif2979return Result;2980}29812982ChangeStatus Attributor::rewriteFunctionSignatures(2983SmallSetVector<Function *, 8> &ModifiedFns) {2984ChangeStatus Changed = ChangeStatus::UNCHANGED;29852986for (auto &It : ArgumentReplacementMap) {2987Function *OldFn = It.getFirst();29882989// Deleted functions do not require rewrites.2990if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn))2991continue;29922993const SmallVectorImpl<std::unique_ptr<ArgumentReplacementInfo>> &ARIs =2994It.getSecond();2995assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");29962997SmallVector<Type *, 16> NewArgumentTypes;2998SmallVector<AttributeSet, 16> NewArgumentAttributes;29993000// Collect replacement argument types and copy over existing attributes.3001AttributeList OldFnAttributeList = OldFn->getAttributes();3002for (Argument &Arg : OldFn->args()) {3003if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =3004ARIs[Arg.getArgNo()]) {3005NewArgumentTypes.append(ARI->ReplacementTypes.begin(),3006ARI->ReplacementTypes.end());3007NewArgumentAttributes.append(ARI->getNumReplacementArgs(),3008AttributeSet());3009} else {3010NewArgumentTypes.push_back(Arg.getType());3011NewArgumentAttributes.push_back(3012OldFnAttributeList.getParamAttrs(Arg.getArgNo()));3013}3014}30153016uint64_t LargestVectorWidth = 0;3017for (auto *I : NewArgumentTypes)3018if (auto *VT = dyn_cast<llvm::VectorType>(I))3019LargestVectorWidth =3020std::max(LargestVectorWidth,3021VT->getPrimitiveSizeInBits().getKnownMinValue());30223023FunctionType *OldFnTy = OldFn->getFunctionType();3024Type *RetTy = OldFnTy->getReturnType();30253026// Construct the new function type using the new arguments types.3027FunctionType *NewFnTy =3028FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());30293030LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()3031<< "' from " << *OldFn->getFunctionType() << " to "3032<< *NewFnTy << "\n");30333034// Create the new function body and insert it into the module.3035Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),3036OldFn->getAddressSpace(), "");3037Functions.insert(NewFn);3038OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);3039NewFn->takeName(OldFn);3040NewFn->copyAttributesFrom(OldFn);3041// Flag whether the function is using new-debug-info or not.3042NewFn->IsNewDbgInfoFormat = OldFn->IsNewDbgInfoFormat;30433044// Patch the pointer to LLVM function in debug info descriptor.3045NewFn->setSubprogram(OldFn->getSubprogram());3046OldFn->setSubprogram(nullptr);30473048// Recompute the parameter attributes list based on the new arguments for3049// the function.3050LLVMContext &Ctx = OldFn->getContext();3051NewFn->setAttributes(AttributeList::get(3052Ctx, OldFnAttributeList.getFnAttrs(), OldFnAttributeList.getRetAttrs(),3053NewArgumentAttributes));3054AttributeFuncs::updateMinLegalVectorWidthAttr(*NewFn, LargestVectorWidth);30553056// Remove argmem from the memory effects if we have no more pointer3057// arguments, or they are readnone.3058MemoryEffects ME = NewFn->getMemoryEffects();3059int ArgNo = -1;3060if (ME.doesAccessArgPointees() && all_of(NewArgumentTypes, [&](Type *T) {3061++ArgNo;3062return !T->isPtrOrPtrVectorTy() ||3063NewFn->hasParamAttribute(ArgNo, Attribute::ReadNone);3064})) {3065NewFn->setMemoryEffects(ME - MemoryEffects::argMemOnly());3066}30673068// Since we have now created the new function, splice the body of the old3069// function right into the new function, leaving the old rotting hulk of the3070// function empty.3071NewFn->splice(NewFn->begin(), OldFn);30723073// Fixup block addresses to reference new function.3074SmallVector<BlockAddress *, 8u> BlockAddresses;3075for (User *U : OldFn->users())3076if (auto *BA = dyn_cast<BlockAddress>(U))3077BlockAddresses.push_back(BA);3078for (auto *BA : BlockAddresses)3079BA->replaceAllUsesWith(BlockAddress::get(NewFn, BA->getBasicBlock()));30803081// Set of all "call-like" instructions that invoke the old function mapped3082// to their new replacements.3083SmallVector<std::pair<CallBase *, CallBase *>, 8> CallSitePairs;30843085// Callback to create a new "call-like" instruction for a given one.3086auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {3087CallBase *OldCB = cast<CallBase>(ACS.getInstruction());3088const AttributeList &OldCallAttributeList = OldCB->getAttributes();30893090// Collect the new argument operands for the replacement call site.3091SmallVector<Value *, 16> NewArgOperands;3092SmallVector<AttributeSet, 16> NewArgOperandAttributes;3093for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {3094unsigned NewFirstArgNum = NewArgOperands.size();3095(void)NewFirstArgNum; // only used inside assert.3096if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =3097ARIs[OldArgNum]) {3098if (ARI->ACSRepairCB)3099ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);3100assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==3101NewArgOperands.size() &&3102"ACS repair callback did not provide as many operand as new "3103"types were registered!");3104// TODO: Exose the attribute set to the ACS repair callback3105NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),3106AttributeSet());3107} else {3108NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));3109NewArgOperandAttributes.push_back(3110OldCallAttributeList.getParamAttrs(OldArgNum));3111}3112}31133114assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&3115"Mismatch # argument operands vs. # argument operand attributes!");3116assert(NewArgOperands.size() == NewFn->arg_size() &&3117"Mismatch # argument operands vs. # function arguments!");31183119SmallVector<OperandBundleDef, 4> OperandBundleDefs;3120OldCB->getOperandBundlesAsDefs(OperandBundleDefs);31213122// Create a new call or invoke instruction to replace the old one.3123CallBase *NewCB;3124if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {3125NewCB = InvokeInst::Create(NewFn, II->getNormalDest(),3126II->getUnwindDest(), NewArgOperands,3127OperandBundleDefs, "", OldCB->getIterator());3128} else {3129auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,3130"", OldCB->getIterator());3131NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());3132NewCB = NewCI;3133}31343135// Copy over various properties and the new attributes.3136NewCB->copyMetadata(*OldCB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});3137NewCB->setCallingConv(OldCB->getCallingConv());3138NewCB->takeName(OldCB);3139NewCB->setAttributes(AttributeList::get(3140Ctx, OldCallAttributeList.getFnAttrs(),3141OldCallAttributeList.getRetAttrs(), NewArgOperandAttributes));31423143AttributeFuncs::updateMinLegalVectorWidthAttr(*NewCB->getCaller(),3144LargestVectorWidth);31453146CallSitePairs.push_back({OldCB, NewCB});3147return true;3148};31493150// Use the CallSiteReplacementCreator to create replacement call sites.3151bool UsedAssumedInformation = false;3152bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,3153true, nullptr, UsedAssumedInformation,3154/* CheckPotentiallyDead */ true);3155(void)Success;3156assert(Success && "Assumed call site replacement to succeed!");31573158// Rewire the arguments.3159Argument *OldFnArgIt = OldFn->arg_begin();3160Argument *NewFnArgIt = NewFn->arg_begin();3161for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();3162++OldArgNum, ++OldFnArgIt) {3163if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =3164ARIs[OldArgNum]) {3165if (ARI->CalleeRepairCB)3166ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);3167if (ARI->ReplacementTypes.empty())3168OldFnArgIt->replaceAllUsesWith(3169PoisonValue::get(OldFnArgIt->getType()));3170NewFnArgIt += ARI->ReplacementTypes.size();3171} else {3172NewFnArgIt->takeName(&*OldFnArgIt);3173OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);3174++NewFnArgIt;3175}3176}31773178// Eliminate the instructions *after* we visited all of them.3179for (auto &CallSitePair : CallSitePairs) {3180CallBase &OldCB = *CallSitePair.first;3181CallBase &NewCB = *CallSitePair.second;3182assert(OldCB.getType() == NewCB.getType() &&3183"Cannot handle call sites with different types!");3184ModifiedFns.insert(OldCB.getFunction());3185OldCB.replaceAllUsesWith(&NewCB);3186OldCB.eraseFromParent();3187}31883189// Replace the function in the call graph (if any).3190Configuration.CGUpdater.replaceFunctionWith(*OldFn, *NewFn);31913192// If the old function was modified and needed to be reanalyzed, the new one3193// does now.3194if (ModifiedFns.remove(OldFn))3195ModifiedFns.insert(NewFn);31963197Changed = ChangeStatus::CHANGED;3198}31993200return Changed;3201}32023203void InformationCache::initializeInformationCache(const Function &CF,3204FunctionInfo &FI) {3205// As we do not modify the function here we can remove the const3206// withouth breaking implicit assumptions. At the end of the day, we could3207// initialize the cache eagerly which would look the same to the users.3208Function &F = const_cast<Function &>(CF);32093210// Walk all instructions to find interesting instructions that might be3211// queried by abstract attributes during their initialization or update.3212// This has to happen before we create attributes.32133214DenseMap<const Value *, std::optional<short>> AssumeUsesMap;32153216// Add \p V to the assume uses map which track the number of uses outside of3217// "visited" assumes. If no outside uses are left the value is added to the3218// assume only use vector.3219auto AddToAssumeUsesMap = [&](const Value &V) -> void {3220SmallVector<const Instruction *> Worklist;3221if (auto *I = dyn_cast<Instruction>(&V))3222Worklist.push_back(I);3223while (!Worklist.empty()) {3224const Instruction *I = Worklist.pop_back_val();3225std::optional<short> &NumUses = AssumeUsesMap[I];3226if (!NumUses)3227NumUses = I->getNumUses();3228NumUses = *NumUses - /* this assume */ 1;3229if (*NumUses != 0)3230continue;3231AssumeOnlyValues.insert(I);3232for (const Value *Op : I->operands())3233if (auto *OpI = dyn_cast<Instruction>(Op))3234Worklist.push_back(OpI);3235}3236};32373238for (Instruction &I : instructions(&F)) {3239bool IsInterestingOpcode = false;32403241// To allow easy access to all instructions in a function with a given3242// opcode we store them in the InfoCache. As not all opcodes are interesting3243// to concrete attributes we only cache the ones that are as identified in3244// the following switch.3245// Note: There are no concrete attributes now so this is initially empty.3246switch (I.getOpcode()) {3247default:3248assert(!isa<CallBase>(&I) &&3249"New call base instruction type needs to be known in the "3250"Attributor.");3251break;3252case Instruction::Call:3253// Calls are interesting on their own, additionally:3254// For `llvm.assume` calls we also fill the KnowledgeMap as we find them.3255// For `must-tail` calls we remember the caller and callee.3256if (auto *Assume = dyn_cast<AssumeInst>(&I)) {3257AssumeOnlyValues.insert(Assume);3258fillMapFromAssume(*Assume, KnowledgeMap);3259AddToAssumeUsesMap(*Assume->getArgOperand(0));3260} else if (cast<CallInst>(I).isMustTailCall()) {3261FI.ContainsMustTailCall = true;3262if (auto *Callee = dyn_cast_if_present<Function>(3263cast<CallInst>(I).getCalledOperand()))3264getFunctionInfo(*Callee).CalledViaMustTail = true;3265}3266[[fallthrough]];3267case Instruction::CallBr:3268case Instruction::Invoke:3269case Instruction::CleanupRet:3270case Instruction::CatchSwitch:3271case Instruction::AtomicRMW:3272case Instruction::AtomicCmpXchg:3273case Instruction::Br:3274case Instruction::Resume:3275case Instruction::Ret:3276case Instruction::Load:3277// The alignment of a pointer is interesting for loads.3278case Instruction::Store:3279// The alignment of a pointer is interesting for stores.3280case Instruction::Alloca:3281case Instruction::AddrSpaceCast:3282IsInterestingOpcode = true;3283}3284if (IsInterestingOpcode) {3285auto *&Insts = FI.OpcodeInstMap[I.getOpcode()];3286if (!Insts)3287Insts = new (Allocator) InstructionVectorTy();3288Insts->push_back(&I);3289}3290if (I.mayReadOrWriteMemory())3291FI.RWInsts.push_back(&I);3292}32933294if (F.hasFnAttribute(Attribute::AlwaysInline) &&3295isInlineViable(F).isSuccess())3296InlineableFunctions.insert(&F);3297}32983299InformationCache::FunctionInfo::~FunctionInfo() {3300// The instruction vectors are allocated using a BumpPtrAllocator, we need to3301// manually destroy them.3302for (auto &It : OpcodeInstMap)3303It.getSecond()->~InstructionVectorTy();3304}33053306const ArrayRef<Function *>3307InformationCache::getIndirectlyCallableFunctions(Attributor &A) const {3308assert(A.isClosedWorldModule() && "Cannot see all indirect callees!");3309return IndirectlyCallableFunctions;3310}33113312void Attributor::recordDependence(const AbstractAttribute &FromAA,3313const AbstractAttribute &ToAA,3314DepClassTy DepClass) {3315if (DepClass == DepClassTy::NONE)3316return;3317// If we are outside of an update, thus before the actual fixpoint iteration3318// started (= when we create AAs), we do not track dependences because we will3319// put all AAs into the initial worklist anyway.3320if (DependenceStack.empty())3321return;3322if (FromAA.getState().isAtFixpoint())3323return;3324DependenceStack.back()->push_back({&FromAA, &ToAA, DepClass});3325}33263327void Attributor::rememberDependences() {3328assert(!DependenceStack.empty() && "No dependences to remember!");33293330for (DepInfo &DI : *DependenceStack.back()) {3331assert((DI.DepClass == DepClassTy::REQUIRED ||3332DI.DepClass == DepClassTy::OPTIONAL) &&3333"Expected required or optional dependence (1 bit)!");3334auto &DepAAs = const_cast<AbstractAttribute &>(*DI.FromAA).Deps;3335DepAAs.insert(AbstractAttribute::DepTy(3336const_cast<AbstractAttribute *>(DI.ToAA), unsigned(DI.DepClass)));3337}3338}33393340template <Attribute::AttrKind AK, typename AAType>3341void Attributor::checkAndQueryIRAttr(const IRPosition &IRP,3342AttributeSet Attrs) {3343bool IsKnown;3344if (!Attrs.hasAttribute(AK))3345if (!Configuration.Allowed || Configuration.Allowed->count(&AAType::ID))3346if (!AA::hasAssumedIRAttr<AK>(*this, nullptr, IRP, DepClassTy::NONE,3347IsKnown))3348getOrCreateAAFor<AAType>(IRP);3349}33503351void Attributor::identifyDefaultAbstractAttributes(Function &F) {3352if (!VisitedFunctions.insert(&F).second)3353return;3354if (F.isDeclaration())3355return;33563357// In non-module runs we need to look at the call sites of a function to3358// determine if it is part of a must-tail call edge. This will influence what3359// attributes we can derive.3360InformationCache::FunctionInfo &FI = InfoCache.getFunctionInfo(F);3361if (!isModulePass() && !FI.CalledViaMustTail) {3362for (const Use &U : F.uses())3363if (const auto *CB = dyn_cast<CallBase>(U.getUser()))3364if (CB->isCallee(&U) && CB->isMustTailCall())3365FI.CalledViaMustTail = true;3366}33673368IRPosition FPos = IRPosition::function(F);3369bool IsIPOAmendable = isFunctionIPOAmendable(F);3370auto Attrs = F.getAttributes();3371auto FnAttrs = Attrs.getFnAttrs();33723373// Check for dead BasicBlocks in every function.3374// We need dead instruction detection because we do not want to deal with3375// broken IR in which SSA rules do not apply.3376getOrCreateAAFor<AAIsDead>(FPos);33773378// Every function might contain instructions that cause "undefined3379// behavior".3380getOrCreateAAFor<AAUndefinedBehavior>(FPos);33813382// Every function might be applicable for Heap-To-Stack conversion.3383if (EnableHeapToStack)3384getOrCreateAAFor<AAHeapToStack>(FPos);33853386// Every function might be "must-progress".3387checkAndQueryIRAttr<Attribute::MustProgress, AAMustProgress>(FPos, FnAttrs);33883389// Every function might be "no-free".3390checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(FPos, FnAttrs);33913392// Every function might be "will-return".3393checkAndQueryIRAttr<Attribute::WillReturn, AAWillReturn>(FPos, FnAttrs);33943395// Every function might be marked "nosync"3396checkAndQueryIRAttr<Attribute::NoSync, AANoSync>(FPos, FnAttrs);33973398// Everything that is visible from the outside (=function, argument, return3399// positions), cannot be changed if the function is not IPO amendable. We can3400// however analyse the code inside.3401if (IsIPOAmendable) {34023403// Every function can be nounwind.3404checkAndQueryIRAttr<Attribute::NoUnwind, AANoUnwind>(FPos, FnAttrs);34053406// Every function might be "no-return".3407checkAndQueryIRAttr<Attribute::NoReturn, AANoReturn>(FPos, FnAttrs);34083409// Every function might be "no-recurse".3410checkAndQueryIRAttr<Attribute::NoRecurse, AANoRecurse>(FPos, FnAttrs);34113412// Every function can be "non-convergent".3413if (Attrs.hasFnAttr(Attribute::Convergent))3414getOrCreateAAFor<AANonConvergent>(FPos);34153416// Every function might be "readnone/readonly/writeonly/...".3417getOrCreateAAFor<AAMemoryBehavior>(FPos);34183419// Every function can be "readnone/argmemonly/inaccessiblememonly/...".3420getOrCreateAAFor<AAMemoryLocation>(FPos);34213422// Every function can track active assumptions.3423getOrCreateAAFor<AAAssumptionInfo>(FPos);34243425// If we're not using a dynamic mode for float, there's nothing worthwhile3426// to infer. This misses the edge case denormal-fp-math="dynamic" and3427// denormal-fp-math-f32=something, but that likely has no real world use.3428DenormalMode Mode = F.getDenormalMode(APFloat::IEEEsingle());3429if (Mode.Input == DenormalMode::Dynamic ||3430Mode.Output == DenormalMode::Dynamic)3431getOrCreateAAFor<AADenormalFPMath>(FPos);34323433// Return attributes are only appropriate if the return type is non void.3434Type *ReturnType = F.getReturnType();3435if (!ReturnType->isVoidTy()) {3436IRPosition RetPos = IRPosition::returned(F);3437AttributeSet RetAttrs = Attrs.getRetAttrs();34383439// Every returned value might be dead.3440getOrCreateAAFor<AAIsDead>(RetPos);34413442// Every function might be simplified.3443bool UsedAssumedInformation = false;3444getAssumedSimplified(RetPos, nullptr, UsedAssumedInformation,3445AA::Intraprocedural);34463447// Every returned value might be marked noundef.3448checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(RetPos, RetAttrs);34493450if (ReturnType->isPointerTy()) {34513452// Every function with pointer return type might be marked align.3453getOrCreateAAFor<AAAlign>(RetPos);34543455// Every function with pointer return type might be marked nonnull.3456checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(RetPos, RetAttrs);34573458// Every function with pointer return type might be marked noalias.3459checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(RetPos, RetAttrs);34603461// Every function with pointer return type might be marked3462// dereferenceable.3463getOrCreateAAFor<AADereferenceable>(RetPos);3464} else if (AttributeFuncs::isNoFPClassCompatibleType(ReturnType)) {3465getOrCreateAAFor<AANoFPClass>(RetPos);3466}3467}3468}34693470for (Argument &Arg : F.args()) {3471IRPosition ArgPos = IRPosition::argument(Arg);3472auto ArgNo = Arg.getArgNo();3473AttributeSet ArgAttrs = Attrs.getParamAttrs(ArgNo);34743475if (!IsIPOAmendable) {3476if (Arg.getType()->isPointerTy())3477// Every argument with pointer type might be marked nofree.3478checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);3479continue;3480}34813482// Every argument might be simplified. We have to go through the3483// Attributor interface though as outside AAs can register custom3484// simplification callbacks.3485bool UsedAssumedInformation = false;3486getAssumedSimplified(ArgPos, /* AA */ nullptr, UsedAssumedInformation,3487AA::Intraprocedural);34883489// Every argument might be dead.3490getOrCreateAAFor<AAIsDead>(ArgPos);34913492// Every argument might be marked noundef.3493checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(ArgPos, ArgAttrs);34943495if (Arg.getType()->isPointerTy()) {3496// Every argument with pointer type might be marked nonnull.3497checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(ArgPos, ArgAttrs);34983499// Every argument with pointer type might be marked noalias.3500checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(ArgPos, ArgAttrs);35013502// Every argument with pointer type might be marked dereferenceable.3503getOrCreateAAFor<AADereferenceable>(ArgPos);35043505// Every argument with pointer type might be marked align.3506getOrCreateAAFor<AAAlign>(ArgPos);35073508// Every argument with pointer type might be marked nocapture.3509checkAndQueryIRAttr<Attribute::NoCapture, AANoCapture>(ArgPos, ArgAttrs);35103511// Every argument with pointer type might be marked3512// "readnone/readonly/writeonly/..."3513getOrCreateAAFor<AAMemoryBehavior>(ArgPos);35143515// Every argument with pointer type might be marked nofree.3516checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(ArgPos, ArgAttrs);35173518// Every argument with pointer type might be privatizable (or3519// promotable)3520getOrCreateAAFor<AAPrivatizablePtr>(ArgPos);3521} else if (AttributeFuncs::isNoFPClassCompatibleType(Arg.getType())) {3522getOrCreateAAFor<AANoFPClass>(ArgPos);3523}3524}35253526auto CallSitePred = [&](Instruction &I) -> bool {3527auto &CB = cast<CallBase>(I);3528IRPosition CBInstPos = IRPosition::inst(CB);3529IRPosition CBFnPos = IRPosition::callsite_function(CB);35303531// Call sites might be dead if they do not have side effects and no live3532// users. The return value might be dead if there are no live users.3533getOrCreateAAFor<AAIsDead>(CBInstPos);35343535Function *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());3536// TODO: Even if the callee is not known now we might be able to simplify3537// the call/callee.3538if (!Callee) {3539getOrCreateAAFor<AAIndirectCallInfo>(CBFnPos);3540return true;3541}35423543// Every call site can track active assumptions.3544getOrCreateAAFor<AAAssumptionInfo>(CBFnPos);35453546// Skip declarations except if annotations on their call sites were3547// explicitly requested.3548if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&3549!Callee->hasMetadata(LLVMContext::MD_callback))3550return true;35513552if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {3553IRPosition CBRetPos = IRPosition::callsite_returned(CB);3554bool UsedAssumedInformation = false;3555getAssumedSimplified(CBRetPos, nullptr, UsedAssumedInformation,3556AA::Intraprocedural);35573558if (AttributeFuncs::isNoFPClassCompatibleType(Callee->getReturnType()))3559getOrCreateAAFor<AANoFPClass>(CBInstPos);3560}35613562const AttributeList &CBAttrs = CBFnPos.getAttrList();3563for (int I = 0, E = CB.arg_size(); I < E; ++I) {35643565IRPosition CBArgPos = IRPosition::callsite_argument(CB, I);3566AttributeSet CBArgAttrs = CBAttrs.getParamAttrs(I);35673568// Every call site argument might be dead.3569getOrCreateAAFor<AAIsDead>(CBArgPos);35703571// Call site argument might be simplified. We have to go through the3572// Attributor interface though as outside AAs can register custom3573// simplification callbacks.3574bool UsedAssumedInformation = false;3575getAssumedSimplified(CBArgPos, /* AA */ nullptr, UsedAssumedInformation,3576AA::Intraprocedural);35773578// Every call site argument might be marked "noundef".3579checkAndQueryIRAttr<Attribute::NoUndef, AANoUndef>(CBArgPos, CBArgAttrs);35803581Type *ArgTy = CB.getArgOperand(I)->getType();35823583if (!ArgTy->isPointerTy()) {3584if (AttributeFuncs::isNoFPClassCompatibleType(ArgTy))3585getOrCreateAAFor<AANoFPClass>(CBArgPos);35863587continue;3588}35893590// Call site argument attribute "non-null".3591checkAndQueryIRAttr<Attribute::NonNull, AANonNull>(CBArgPos, CBArgAttrs);35923593// Call site argument attribute "nocapture".3594checkAndQueryIRAttr<Attribute::NoCapture, AANoCapture>(CBArgPos,3595CBArgAttrs);35963597// Call site argument attribute "no-alias".3598checkAndQueryIRAttr<Attribute::NoAlias, AANoAlias>(CBArgPos, CBArgAttrs);35993600// Call site argument attribute "dereferenceable".3601getOrCreateAAFor<AADereferenceable>(CBArgPos);36023603// Call site argument attribute "align".3604getOrCreateAAFor<AAAlign>(CBArgPos);36053606// Call site argument attribute3607// "readnone/readonly/writeonly/..."3608if (!CBAttrs.hasParamAttr(I, Attribute::ReadNone))3609getOrCreateAAFor<AAMemoryBehavior>(CBArgPos);36103611// Call site argument attribute "nofree".3612checkAndQueryIRAttr<Attribute::NoFree, AANoFree>(CBArgPos, CBArgAttrs);3613}3614return true;3615};36163617auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);3618[[maybe_unused]] bool Success;3619bool UsedAssumedInformation = false;3620Success = checkForAllInstructionsImpl(3621nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,3622{(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,3623(unsigned)Instruction::Call},3624UsedAssumedInformation);3625assert(Success && "Expected the check call to be successful!");36263627auto LoadStorePred = [&](Instruction &I) -> bool {3628if (auto *LI = dyn_cast<LoadInst>(&I)) {3629getOrCreateAAFor<AAAlign>(IRPosition::value(*LI->getPointerOperand()));3630if (SimplifyAllLoads)3631getAssumedSimplified(IRPosition::value(I), nullptr,3632UsedAssumedInformation, AA::Intraprocedural);3633getOrCreateAAFor<AAAddressSpace>(3634IRPosition::value(*LI->getPointerOperand()));3635} else {3636auto &SI = cast<StoreInst>(I);3637getOrCreateAAFor<AAIsDead>(IRPosition::inst(I));3638getAssumedSimplified(IRPosition::value(*SI.getValueOperand()), nullptr,3639UsedAssumedInformation, AA::Intraprocedural);3640getOrCreateAAFor<AAAlign>(IRPosition::value(*SI.getPointerOperand()));3641getOrCreateAAFor<AAAddressSpace>(3642IRPosition::value(*SI.getPointerOperand()));3643}3644return true;3645};3646Success = checkForAllInstructionsImpl(3647nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,3648{(unsigned)Instruction::Load, (unsigned)Instruction::Store},3649UsedAssumedInformation);3650assert(Success && "Expected the check call to be successful!");36513652// AllocaInstPredicate3653auto AAAllocationInfoPred = [&](Instruction &I) -> bool {3654getOrCreateAAFor<AAAllocationInfo>(IRPosition::value(I));3655return true;3656};36573658Success = checkForAllInstructionsImpl(3659nullptr, OpcodeInstMap, AAAllocationInfoPred, nullptr, nullptr,3660{(unsigned)Instruction::Alloca}, UsedAssumedInformation);3661assert(Success && "Expected the check call to be successful!");3662}36633664bool Attributor::isClosedWorldModule() const {3665if (CloseWorldAssumption.getNumOccurrences())3666return CloseWorldAssumption;3667return isModulePass() && Configuration.IsClosedWorldModule;3668}36693670/// Helpers to ease debugging through output streams and print calls.3671///3672///{3673raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {3674return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");3675}36763677raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {3678switch (AP) {3679case IRPosition::IRP_INVALID:3680return OS << "inv";3681case IRPosition::IRP_FLOAT:3682return OS << "flt";3683case IRPosition::IRP_RETURNED:3684return OS << "fn_ret";3685case IRPosition::IRP_CALL_SITE_RETURNED:3686return OS << "cs_ret";3687case IRPosition::IRP_FUNCTION:3688return OS << "fn";3689case IRPosition::IRP_CALL_SITE:3690return OS << "cs";3691case IRPosition::IRP_ARGUMENT:3692return OS << "arg";3693case IRPosition::IRP_CALL_SITE_ARGUMENT:3694return OS << "cs_arg";3695}3696llvm_unreachable("Unknown attribute position!");3697}36983699raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {3700const Value &AV = Pos.getAssociatedValue();3701OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["3702<< Pos.getAnchorValue().getName() << "@" << Pos.getCallSiteArgNo() << "]";37033704if (Pos.hasCallBaseContext())3705OS << "[cb_context:" << *Pos.getCallBaseContext() << "]";3706return OS << "}";3707}37083709raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerRangeState &S) {3710OS << "range-state(" << S.getBitWidth() << ")<";3711S.getKnown().print(OS);3712OS << " / ";3713S.getAssumed().print(OS);3714OS << ">";37153716return OS << static_cast<const AbstractState &>(S);3717}37183719raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {3720return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));3721}37223723raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {3724AA.print(OS);3725return OS;3726}37273728raw_ostream &llvm::operator<<(raw_ostream &OS,3729const PotentialConstantIntValuesState &S) {3730OS << "set-state(< {";3731if (!S.isValidState())3732OS << "full-set";3733else {3734for (const auto &It : S.getAssumedSet())3735OS << It << ", ";3736if (S.undefIsContained())3737OS << "undef ";3738}3739OS << "} >)";37403741return OS;3742}37433744raw_ostream &llvm::operator<<(raw_ostream &OS,3745const PotentialLLVMValuesState &S) {3746OS << "set-state(< {";3747if (!S.isValidState())3748OS << "full-set";3749else {3750for (const auto &It : S.getAssumedSet()) {3751if (auto *F = dyn_cast<Function>(It.first.getValue()))3752OS << "@" << F->getName() << "[" << int(It.second) << "], ";3753else3754OS << *It.first.getValue() << "[" << int(It.second) << "], ";3755}3756if (S.undefIsContained())3757OS << "undef ";3758}3759OS << "} >)";37603761return OS;3762}37633764void AbstractAttribute::print(Attributor *A, raw_ostream &OS) const {3765OS << "[";3766OS << getName();3767OS << "] for CtxI ";37683769if (auto *I = getCtxI()) {3770OS << "'";3771I->print(OS);3772OS << "'";3773} else3774OS << "<<null inst>>";37753776OS << " at position " << getIRPosition() << " with state " << getAsStr(A)3777<< '\n';3778}37793780void AbstractAttribute::printWithDeps(raw_ostream &OS) const {3781print(OS);37823783for (const auto &DepAA : Deps) {3784auto *AA = DepAA.getPointer();3785OS << " updates ";3786AA->print(OS);3787}37883789OS << '\n';3790}37913792raw_ostream &llvm::operator<<(raw_ostream &OS,3793const AAPointerInfo::Access &Acc) {3794OS << " [" << Acc.getKind() << "] " << *Acc.getRemoteInst();3795if (Acc.getLocalInst() != Acc.getRemoteInst())3796OS << " via " << *Acc.getLocalInst();3797if (Acc.getContent()) {3798if (*Acc.getContent())3799OS << " [" << **Acc.getContent() << "]";3800else3801OS << " [ <unknown> ]";3802}3803return OS;3804}3805///}38063807/// ----------------------------------------------------------------------------3808/// Pass (Manager) Boilerplate3809/// ----------------------------------------------------------------------------38103811static bool runAttributorOnFunctions(InformationCache &InfoCache,3812SetVector<Function *> &Functions,3813AnalysisGetter &AG,3814CallGraphUpdater &CGUpdater,3815bool DeleteFns, bool IsModulePass) {3816if (Functions.empty())3817return false;38183819LLVM_DEBUG({3820dbgs() << "[Attributor] Run on module with " << Functions.size()3821<< " functions:\n";3822for (Function *Fn : Functions)3823dbgs() << " - " << Fn->getName() << "\n";3824});38253826// Create an Attributor and initially empty information cache that is filled3827// while we identify default attribute opportunities.3828AttributorConfig AC(CGUpdater);3829AC.IsModulePass = IsModulePass;3830AC.DeleteFns = DeleteFns;38313832/// Tracking callback for specialization of indirect calls.3833DenseMap<CallBase *, std::unique_ptr<SmallPtrSet<Function *, 8>>>3834IndirectCalleeTrackingMap;3835if (MaxSpecializationPerCB.getNumOccurrences()) {3836AC.IndirectCalleeSpecializationCallback =3837[&](Attributor &, const AbstractAttribute &AA, CallBase &CB,3838Function &Callee) {3839if (MaxSpecializationPerCB == 0)3840return false;3841auto &Set = IndirectCalleeTrackingMap[&CB];3842if (!Set)3843Set = std::make_unique<SmallPtrSet<Function *, 8>>();3844if (Set->size() >= MaxSpecializationPerCB)3845return Set->contains(&Callee);3846Set->insert(&Callee);3847return true;3848};3849}38503851Attributor A(Functions, InfoCache, AC);38523853// Create shallow wrappers for all functions that are not IPO amendable3854if (AllowShallowWrappers)3855for (Function *F : Functions)3856if (!A.isFunctionIPOAmendable(*F))3857Attributor::createShallowWrapper(*F);38583859// Internalize non-exact functions3860// TODO: for now we eagerly internalize functions without calculating the3861// cost, we need a cost interface to determine whether internalizing3862// a function is "beneficial"3863if (AllowDeepWrapper) {3864unsigned FunSize = Functions.size();3865for (unsigned u = 0; u < FunSize; u++) {3866Function *F = Functions[u];3867if (!F->isDeclaration() && !F->isDefinitionExact() && F->getNumUses() &&3868!GlobalValue::isInterposableLinkage(F->getLinkage())) {3869Function *NewF = Attributor::internalizeFunction(*F);3870assert(NewF && "Could not internalize function.");3871Functions.insert(NewF);38723873// Update call graph3874CGUpdater.replaceFunctionWith(*F, *NewF);3875for (const Use &U : NewF->uses())3876if (CallBase *CB = dyn_cast<CallBase>(U.getUser())) {3877auto *CallerF = CB->getCaller();3878CGUpdater.reanalyzeFunction(*CallerF);3879}3880}3881}3882}38833884for (Function *F : Functions) {3885if (F->hasExactDefinition())3886NumFnWithExactDefinition++;3887else3888NumFnWithoutExactDefinition++;38893890// We look at internal functions only on-demand but if any use is not a3891// direct call or outside the current set of analyzed functions, we have3892// to do it eagerly.3893if (F->hasLocalLinkage()) {3894if (llvm::all_of(F->uses(), [&Functions](const Use &U) {3895const auto *CB = dyn_cast<CallBase>(U.getUser());3896return CB && CB->isCallee(&U) &&3897Functions.count(const_cast<Function *>(CB->getCaller()));3898}))3899continue;3900}39013902// Populate the Attributor with abstract attribute opportunities in the3903// function and the information cache with IR information.3904A.identifyDefaultAbstractAttributes(*F);3905}39063907ChangeStatus Changed = A.run();39083909LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()3910<< " functions, result: " << Changed << ".\n");3911return Changed == ChangeStatus::CHANGED;3912}39133914static bool runAttributorLightOnFunctions(InformationCache &InfoCache,3915SetVector<Function *> &Functions,3916AnalysisGetter &AG,3917CallGraphUpdater &CGUpdater,3918FunctionAnalysisManager &FAM,3919bool IsModulePass) {3920if (Functions.empty())3921return false;39223923LLVM_DEBUG({3924dbgs() << "[AttributorLight] Run on module with " << Functions.size()3925<< " functions:\n";3926for (Function *Fn : Functions)3927dbgs() << " - " << Fn->getName() << "\n";3928});39293930// Create an Attributor and initially empty information cache that is filled3931// while we identify default attribute opportunities.3932AttributorConfig AC(CGUpdater);3933AC.IsModulePass = IsModulePass;3934AC.DeleteFns = false;3935DenseSet<const char *> Allowed(3936{&AAWillReturn::ID, &AANoUnwind::ID, &AANoRecurse::ID, &AANoSync::ID,3937&AANoFree::ID, &AANoReturn::ID, &AAMemoryLocation::ID,3938&AAMemoryBehavior::ID, &AAUnderlyingObjects::ID, &AANoCapture::ID,3939&AAInterFnReachability::ID, &AAIntraFnReachability::ID, &AACallEdges::ID,3940&AANoFPClass::ID, &AAMustProgress::ID, &AANonNull::ID});3941AC.Allowed = &Allowed;3942AC.UseLiveness = false;39433944Attributor A(Functions, InfoCache, AC);39453946for (Function *F : Functions) {3947if (F->hasExactDefinition())3948NumFnWithExactDefinition++;3949else3950NumFnWithoutExactDefinition++;39513952// We look at internal functions only on-demand but if any use is not a3953// direct call or outside the current set of analyzed functions, we have3954// to do it eagerly.3955if (AC.UseLiveness && F->hasLocalLinkage()) {3956if (llvm::all_of(F->uses(), [&Functions](const Use &U) {3957const auto *CB = dyn_cast<CallBase>(U.getUser());3958return CB && CB->isCallee(&U) &&3959Functions.count(const_cast<Function *>(CB->getCaller()));3960}))3961continue;3962}39633964// Populate the Attributor with abstract attribute opportunities in the3965// function and the information cache with IR information.3966A.identifyDefaultAbstractAttributes(*F);3967}39683969ChangeStatus Changed = A.run();39703971if (Changed == ChangeStatus::CHANGED) {3972// Invalidate analyses for modified functions so that we don't have to3973// invalidate all analyses for all functions in this SCC.3974PreservedAnalyses FuncPA;3975// We haven't changed the CFG for modified functions.3976FuncPA.preserveSet<CFGAnalyses>();3977for (Function *Changed : A.getModifiedFunctions()) {3978FAM.invalidate(*Changed, FuncPA);3979// Also invalidate any direct callers of changed functions since analyses3980// may care about attributes of direct callees. For example, MemorySSA3981// cares about whether or not a call's callee modifies memory and queries3982// that through function attributes.3983for (auto *U : Changed->users()) {3984if (auto *Call = dyn_cast<CallBase>(U)) {3985if (Call->getCalledFunction() == Changed)3986FAM.invalidate(*Call->getFunction(), FuncPA);3987}3988}3989}3990}3991LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()3992<< " functions, result: " << Changed << ".\n");3993return Changed == ChangeStatus::CHANGED;3994}39953996void AADepGraph::viewGraph() { llvm::ViewGraph(this, "Dependency Graph"); }39973998void AADepGraph::dumpGraph() {3999static std::atomic<int> CallTimes;4000std::string Prefix;40014002if (!DepGraphDotFileNamePrefix.empty())4003Prefix = DepGraphDotFileNamePrefix;4004else4005Prefix = "dep_graph";4006std::string Filename =4007Prefix + "_" + std::to_string(CallTimes.load()) + ".dot";40084009outs() << "Dependency graph dump to " << Filename << ".\n";40104011std::error_code EC;40124013raw_fd_ostream File(Filename, EC, sys::fs::OF_TextWithCRLF);4014if (!EC)4015llvm::WriteGraph(File, this);40164017CallTimes++;4018}40194020void AADepGraph::print() {4021for (auto DepAA : SyntheticRoot.Deps)4022cast<AbstractAttribute>(DepAA.getPointer())->printWithDeps(outs());4023}40244025PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {4026FunctionAnalysisManager &FAM =4027AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();4028AnalysisGetter AG(FAM);40294030SetVector<Function *> Functions;4031for (Function &F : M)4032Functions.insert(&F);40334034CallGraphUpdater CGUpdater;4035BumpPtrAllocator Allocator;4036InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);4037if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater,4038/* DeleteFns */ true, /* IsModulePass */ true)) {4039// FIXME: Think about passes we will preserve and add them here.4040return PreservedAnalyses::none();4041}4042return PreservedAnalyses::all();4043}40444045PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C,4046CGSCCAnalysisManager &AM,4047LazyCallGraph &CG,4048CGSCCUpdateResult &UR) {4049FunctionAnalysisManager &FAM =4050AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();4051AnalysisGetter AG(FAM);40524053SetVector<Function *> Functions;4054for (LazyCallGraph::Node &N : C)4055Functions.insert(&N.getFunction());40564057if (Functions.empty())4058return PreservedAnalyses::all();40594060Module &M = *Functions.back()->getParent();4061CallGraphUpdater CGUpdater;4062CGUpdater.initialize(CG, C, AM, UR);4063BumpPtrAllocator Allocator;4064InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);4065if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater,4066/* DeleteFns */ false,4067/* IsModulePass */ false)) {4068// FIXME: Think about passes we will preserve and add them here.4069PreservedAnalyses PA;4070PA.preserve<FunctionAnalysisManagerCGSCCProxy>();4071return PA;4072}4073return PreservedAnalyses::all();4074}40754076PreservedAnalyses AttributorLightPass::run(Module &M,4077ModuleAnalysisManager &AM) {4078FunctionAnalysisManager &FAM =4079AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();4080AnalysisGetter AG(FAM, /* CachedOnly */ true);40814082SetVector<Function *> Functions;4083for (Function &F : M)4084Functions.insert(&F);40854086CallGraphUpdater CGUpdater;4087BumpPtrAllocator Allocator;4088InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);4089if (runAttributorLightOnFunctions(InfoCache, Functions, AG, CGUpdater, FAM,4090/* IsModulePass */ true)) {4091PreservedAnalyses PA;4092// We have not added or removed functions.4093PA.preserve<FunctionAnalysisManagerCGSCCProxy>();4094// We already invalidated all relevant function analyses above.4095PA.preserveSet<AllAnalysesOn<Function>>();4096return PA;4097}4098return PreservedAnalyses::all();4099}41004101PreservedAnalyses AttributorLightCGSCCPass::run(LazyCallGraph::SCC &C,4102CGSCCAnalysisManager &AM,4103LazyCallGraph &CG,4104CGSCCUpdateResult &UR) {4105FunctionAnalysisManager &FAM =4106AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();4107AnalysisGetter AG(FAM);41084109SetVector<Function *> Functions;4110for (LazyCallGraph::Node &N : C)4111Functions.insert(&N.getFunction());41124113if (Functions.empty())4114return PreservedAnalyses::all();41154116Module &M = *Functions.back()->getParent();4117CallGraphUpdater CGUpdater;4118CGUpdater.initialize(CG, C, AM, UR);4119BumpPtrAllocator Allocator;4120InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);4121if (runAttributorLightOnFunctions(InfoCache, Functions, AG, CGUpdater, FAM,4122/* IsModulePass */ false)) {4123PreservedAnalyses PA;4124// We have not added or removed functions.4125PA.preserve<FunctionAnalysisManagerCGSCCProxy>();4126// We already invalidated all relevant function analyses above.4127PA.preserveSet<AllAnalysesOn<Function>>();4128return PA;4129}4130return PreservedAnalyses::all();4131}4132namespace llvm {41334134template <> struct GraphTraits<AADepGraphNode *> {4135using NodeRef = AADepGraphNode *;4136using DepTy = PointerIntPair<AADepGraphNode *, 1>;4137using EdgeRef = PointerIntPair<AADepGraphNode *, 1>;41384139static NodeRef getEntryNode(AADepGraphNode *DGN) { return DGN; }4140static NodeRef DepGetVal(const DepTy &DT) { return DT.getPointer(); }41414142using ChildIteratorType =4143mapped_iterator<AADepGraphNode::DepSetTy::iterator, decltype(&DepGetVal)>;4144using ChildEdgeIteratorType = AADepGraphNode::DepSetTy::iterator;41454146static ChildIteratorType child_begin(NodeRef N) { return N->child_begin(); }41474148static ChildIteratorType child_end(NodeRef N) { return N->child_end(); }4149};41504151template <>4152struct GraphTraits<AADepGraph *> : public GraphTraits<AADepGraphNode *> {4153static NodeRef getEntryNode(AADepGraph *DG) { return DG->GetEntryNode(); }41544155using nodes_iterator =4156mapped_iterator<AADepGraphNode::DepSetTy::iterator, decltype(&DepGetVal)>;41574158static nodes_iterator nodes_begin(AADepGraph *DG) { return DG->begin(); }41594160static nodes_iterator nodes_end(AADepGraph *DG) { return DG->end(); }4161};41624163template <> struct DOTGraphTraits<AADepGraph *> : public DefaultDOTGraphTraits {4164DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}41654166static std::string getNodeLabel(const AADepGraphNode *Node,4167const AADepGraph *DG) {4168std::string AAString;4169raw_string_ostream O(AAString);4170Node->print(O);4171return AAString;4172}4173};41744175} // end namespace llvm417641774178