1aade782aSJohannes Doerfert //===- Attributor.cpp - Module-wide attribute deduction -------------------===//
2aade782aSJohannes Doerfert //
3aade782aSJohannes Doerfert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4aade782aSJohannes Doerfert // See https://llvm.org/LICENSE.txt for license information.
5aade782aSJohannes Doerfert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6aade782aSJohannes Doerfert //
7aade782aSJohannes Doerfert //===----------------------------------------------------------------------===//
8aade782aSJohannes Doerfert //
906066c40SUday Bondhugula // This file implements an interprocedural pass that deduces and/or propagates
10aade782aSJohannes Doerfert // attributes. This is done in an abstract interpretation style fixpoint
11aade782aSJohannes Doerfert // iteration. See the Attributor.h file comment and the class descriptions in
12aade782aSJohannes Doerfert // that file for more information.
13aade782aSJohannes Doerfert //
14aade782aSJohannes Doerfert //===----------------------------------------------------------------------===//
15aade782aSJohannes Doerfert 
16aade782aSJohannes Doerfert #include "llvm/Transforms/IPO/Attributor.h"
17aade782aSJohannes Doerfert 
185ee07dc5SLuofan Chen #include "llvm/ADT/PointerIntPair.h"
191ba2929bSJohannes Doerfert #include "llvm/ADT/STLExtras.h"
20aade782aSJohannes Doerfert #include "llvm/ADT/Statistic.h"
215ee07dc5SLuofan Chen #include "llvm/ADT/TinyPtrVector.h"
22f1985a3fSserge-sans-paille #include "llvm/Analysis/AliasAnalysis.h"
23a494ae43Sserge-sans-paille #include "llvm/Analysis/CallGraph.h"
24f1985a3fSserge-sans-paille #include "llvm/Analysis/CallGraphSCCPass.h"
256316b002SSimon Pilgrim #include "llvm/Analysis/InlineCost.h"
265602c866SJohannes Doerfert #include "llvm/Analysis/MemoryBuiltins.h"
27b285b333Somarahmed1111 #include "llvm/Analysis/MustExecute.h"
2881429abdSJohannes Doerfert #include "llvm/IR/Attributes.h"
295ef18e24SJohannes Doerfert #include "llvm/IR/Constant.h"
30d9194b6eSJohannes Doerfert #include "llvm/IR/Constants.h"
3187a85f3dSLuofan Chen #include "llvm/IR/GlobalValue.h"
32adddd3dbSJohannes Doerfert #include "llvm/IR/GlobalVariable.h"
331ba2929bSJohannes Doerfert #include "llvm/IR/Instruction.h"
3496da6dd6SJohannes Doerfert #include "llvm/IR/Instructions.h"
350c0eb767SJohannes Doerfert #include "llvm/IR/IntrinsicInst.h"
361ba2929bSJohannes Doerfert #include "llvm/IR/ValueHandle.h"
3705da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
38233af895SLuofan Chen #include "llvm/Support/Casting.h"
3936bc10e7SSimon Pilgrim #include "llvm/Support/CommandLine.h"
405ee07dc5SLuofan Chen #include "llvm/Support/Debug.h"
4150d34958SJohannes Doerfert #include "llvm/Support/DebugCounter.h"
425ee07dc5SLuofan Chen #include "llvm/Support/FileSystem.h"
435ee07dc5SLuofan Chen #include "llvm/Support/GraphWriter.h"
445ee07dc5SLuofan Chen #include "llvm/Support/raw_ostream.h"
456058b863SStefan Stipanovic #include "llvm/Transforms/Utils/BasicBlockUtils.h"
4687a85f3dSLuofan Chen #include "llvm/Transforms/Utils/Cloning.h"
476058b863SStefan Stipanovic #include "llvm/Transforms/Utils/Local.h"
486058b863SStefan Stipanovic 
49a53b689fSserge-sans-paille #ifdef EXPENSIVE_CHECKS
50a53b689fSserge-sans-paille #include "llvm/IR/Verifier.h"
51a53b689fSserge-sans-paille #endif
52a53b689fSserge-sans-paille 
53aade782aSJohannes Doerfert #include <cassert>
545ee07dc5SLuofan Chen #include <string>
55aade782aSJohannes Doerfert 
56aade782aSJohannes Doerfert using namespace llvm;
57aade782aSJohannes Doerfert 
58aade782aSJohannes Doerfert #define DEBUG_TYPE "attributor"
59aade782aSJohannes Doerfert 
6050d34958SJohannes Doerfert DEBUG_COUNTER(ManifestDBGCounter, "attributor-manifest",
6150d34958SJohannes Doerfert               "Determine what attributes are manifested in the IR");
6250d34958SJohannes Doerfert 
63898bbc25SJohannes Doerfert STATISTIC(NumFnDeleted, "Number of function deleted");
64aade782aSJohannes Doerfert STATISTIC(NumFnWithExactDefinition,
6506066c40SUday Bondhugula           "Number of functions with exact definitions");
66aade782aSJohannes Doerfert STATISTIC(NumFnWithoutExactDefinition,
6706066c40SUday Bondhugula           "Number of functions without exact definitions");
68ce16be25Ssstefan1 STATISTIC(NumFnShallowWrappersCreated, "Number of shallow wrappers created");
69aade782aSJohannes Doerfert STATISTIC(NumAttributesTimedOut,
70aade782aSJohannes Doerfert           "Number of abstract attributes timed out before fixpoint");
71aade782aSJohannes Doerfert STATISTIC(NumAttributesValidFixpoint,
72aade782aSJohannes Doerfert           "Number of abstract attributes in a valid fixpoint state");
73aade782aSJohannes Doerfert STATISTIC(NumAttributesManifested,
74aade782aSJohannes Doerfert           "Number of abstract attributes manifested in IR");
75aade782aSJohannes Doerfert 
76aade782aSJohannes Doerfert // TODO: Determine a good default value.
77aade782aSJohannes Doerfert //
78aade782aSJohannes Doerfert // In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
79aade782aSJohannes Doerfert // (when run with the first 5 abstract attributes). The results also indicate
80aade782aSJohannes Doerfert // that we never reach 32 iterations but always find a fixpoint sooner.
81aade782aSJohannes Doerfert //
82aade782aSJohannes Doerfert // This will become more evolved once we perform two interleaved fixpoint
83aade782aSJohannes Doerfert // iterations: bottom-up and top-down.
84aade782aSJohannes Doerfert static cl::opt<unsigned>
85b54ccab5SJoseph Huber     SetFixpointIterations("attributor-max-iterations", cl::Hidden,
86aade782aSJohannes Doerfert                           cl::desc("Maximal number of fixpoint iterations."),
87aade782aSJohannes Doerfert                           cl::init(32));
88d5d75f61SJohannes Doerfert 
89d5d75f61SJohannes Doerfert static cl::opt<unsigned, true> MaxInitializationChainLengthX(
90d5d75f61SJohannes Doerfert     "attributor-max-initialization-chain-length", cl::Hidden,
91d5d75f61SJohannes Doerfert     cl::desc(
92d5d75f61SJohannes Doerfert         "Maximal number of chained initializations (to avoid stack overflows)"),
93d5d75f61SJohannes Doerfert     cl::location(MaxInitializationChainLength), cl::init(1024));
94d5d75f61SJohannes Doerfert unsigned llvm::MaxInitializationChainLength;
95d5d75f61SJohannes Doerfert 
96b504eb8bSJohannes Doerfert static cl::opt<bool> VerifyMaxFixpointIterations(
97b504eb8bSJohannes Doerfert     "attributor-max-iterations-verify", cl::Hidden,
98b504eb8bSJohannes Doerfert     cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
99b504eb8bSJohannes Doerfert     cl::init(false));
100aade782aSJohannes Doerfert 
101c36e2ebfSJohannes Doerfert static cl::opt<bool> AnnotateDeclarationCallSites(
102c36e2ebfSJohannes Doerfert     "attributor-annotate-decl-cs", cl::Hidden,
103d68904f9SJames Henderson     cl::desc("Annotate call sites of function declarations."), cl::init(false));
104c36e2ebfSJohannes Doerfert 
105431141c5SStefan Stipanovic static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
106431141c5SStefan Stipanovic                                        cl::init(true), cl::Hidden);
107431141c5SStefan Stipanovic 
108eec6d876SLuofan Chen static cl::opt<bool>
109eec6d876SLuofan Chen     AllowShallowWrappers("attributor-allow-shallow-wrappers", cl::Hidden,
110eec6d876SLuofan Chen                          cl::desc("Allow the Attributor to create shallow "
111eec6d876SLuofan Chen                                   "wrappers for non-exact definitions."),
112eec6d876SLuofan Chen                          cl::init(false));
113eec6d876SLuofan Chen 
11487a85f3dSLuofan Chen static cl::opt<bool>
11587a85f3dSLuofan Chen     AllowDeepWrapper("attributor-allow-deep-wrappers", cl::Hidden,
11687a85f3dSLuofan Chen                      cl::desc("Allow the Attributor to use IP information "
11787a85f3dSLuofan Chen                               "derived from non-exact functions via cloning"),
11887a85f3dSLuofan Chen                      cl::init(false));
11987a85f3dSLuofan Chen 
12065fcc0eeSkuterd // These options can only used for debug builds.
12165fcc0eeSkuterd #ifndef NDEBUG
1224dbe82eeSkuter static cl::list<std::string>
1234dbe82eeSkuter     SeedAllowList("attributor-seed-allow-list", cl::Hidden,
12465fcc0eeSkuterd                   cl::desc("Comma seperated list of attribute names that are "
1254dbe82eeSkuter                            "allowed to be seeded."),
126d86a206fSFangrui Song                   cl::CommaSeparated);
1274dbe82eeSkuter 
12865fcc0eeSkuterd static cl::list<std::string> FunctionSeedAllowList(
12965fcc0eeSkuterd     "attributor-function-seed-allow-list", cl::Hidden,
13065fcc0eeSkuterd     cl::desc("Comma seperated list of function names that are "
13165fcc0eeSkuterd              "allowed to be seeded."),
13295a13425SFangrui Song     cl::CommaSeparated);
13365fcc0eeSkuterd #endif
13465fcc0eeSkuterd 
1355ee07dc5SLuofan Chen static cl::opt<bool>
1365ee07dc5SLuofan Chen     DumpDepGraph("attributor-dump-dep-graph", cl::Hidden,
1375ee07dc5SLuofan Chen                  cl::desc("Dump the dependency graph to dot files."),
1385ee07dc5SLuofan Chen                  cl::init(false));
1395ee07dc5SLuofan Chen 
1405ee07dc5SLuofan Chen static cl::opt<std::string> DepGraphDotFileNamePrefix(
1415ee07dc5SLuofan Chen     "attributor-depgraph-dot-filename-prefix", cl::Hidden,
1425ee07dc5SLuofan Chen     cl::desc("The prefix used for the CallGraph dot file names."));
1435ee07dc5SLuofan Chen 
1445ee07dc5SLuofan Chen static cl::opt<bool> ViewDepGraph("attributor-view-dep-graph", cl::Hidden,
1455ee07dc5SLuofan Chen                                   cl::desc("View the dependency graph."),
1465ee07dc5SLuofan Chen                                   cl::init(false));
1475ee07dc5SLuofan Chen 
1485ee07dc5SLuofan Chen static cl::opt<bool> PrintDependencies("attributor-print-dep", cl::Hidden,
1495ee07dc5SLuofan Chen                                        cl::desc("Print attribute dependencies"),
1505ee07dc5SLuofan Chen                                        cl::init(false));
1515ee07dc5SLuofan Chen 
152d75c9e61Skuterd static cl::opt<bool> EnableCallSiteSpecific(
153d75c9e61Skuterd     "attributor-enable-call-site-specific-deduction", cl::Hidden,
154d75c9e61Skuterd     cl::desc("Allow the Attributor to do call site specific analysis"),
155d75c9e61Skuterd     cl::init(false));
156d75c9e61Skuterd 
157eaf1b681SKuter Dinel static cl::opt<bool>
158eaf1b681SKuter Dinel     PrintCallGraph("attributor-print-call-graph", cl::Hidden,
159eaf1b681SKuter Dinel                    cl::desc("Print Attributor's internal call graph"),
160eaf1b681SKuter Dinel                    cl::init(false));
161eaf1b681SKuter Dinel 
162c2281f15SJohannes Doerfert static cl::opt<bool> SimplifyAllLoads("attributor-simplify-all-loads",
163c2281f15SJohannes Doerfert                                       cl::Hidden,
164c2281f15SJohannes Doerfert                                       cl::desc("Try to simplify all loads."),
165c2281f15SJohannes Doerfert                                       cl::init(true));
166c2281f15SJohannes Doerfert 
167aade782aSJohannes Doerfert /// Logic operators for the change status enum class.
168aade782aSJohannes Doerfert ///
169aade782aSJohannes Doerfert ///{
operator |(ChangeStatus L,ChangeStatus R)170e6208849SJohannes Doerfert ChangeStatus llvm::operator|(ChangeStatus L, ChangeStatus R) {
171e6208849SJohannes Doerfert   return L == ChangeStatus::CHANGED ? L : R;
172aade782aSJohannes Doerfert }
operator |=(ChangeStatus & L,ChangeStatus R)173c23da666SShilei Tian ChangeStatus &llvm::operator|=(ChangeStatus &L, ChangeStatus R) {
174c23da666SShilei Tian   L = L | R;
175c23da666SShilei Tian   return L;
176c23da666SShilei Tian }
operator &(ChangeStatus L,ChangeStatus R)177e6208849SJohannes Doerfert ChangeStatus llvm::operator&(ChangeStatus L, ChangeStatus R) {
178e6208849SJohannes Doerfert   return L == ChangeStatus::UNCHANGED ? L : R;
179aade782aSJohannes Doerfert }
operator &=(ChangeStatus & L,ChangeStatus R)180c23da666SShilei Tian ChangeStatus &llvm::operator&=(ChangeStatus &L, ChangeStatus R) {
181c23da666SShilei Tian   L = L & R;
182c23da666SShilei Tian   return L;
183c23da666SShilei Tian }
184aade782aSJohannes Doerfert ///}
185aade782aSJohannes Doerfert 
isNoSyncInst(Attributor & A,const Instruction & I,const AbstractAttribute & QueryingAA)1863f0e6704SJohannes Doerfert bool AA::isNoSyncInst(Attributor &A, const Instruction &I,
1873f0e6704SJohannes Doerfert                       const AbstractAttribute &QueryingAA) {
1883f0e6704SJohannes Doerfert   // We are looking for volatile instructions or non-relaxed atomics.
1893f0e6704SJohannes Doerfert   if (const auto *CB = dyn_cast<CallBase>(&I)) {
1903f0e6704SJohannes Doerfert     if (CB->hasFnAttr(Attribute::NoSync))
1913f0e6704SJohannes Doerfert       return true;
1923f0e6704SJohannes Doerfert 
1933f0e6704SJohannes Doerfert     // Non-convergent and readnone imply nosync.
1943f0e6704SJohannes Doerfert     if (!CB->isConvergent() && !CB->mayReadOrWriteMemory())
1953f0e6704SJohannes Doerfert       return true;
1963f0e6704SJohannes Doerfert 
1973f0e6704SJohannes Doerfert     if (AANoSync::isNoSyncIntrinsic(&I))
1983f0e6704SJohannes Doerfert       return true;
1993f0e6704SJohannes Doerfert 
2003f0e6704SJohannes Doerfert     const auto &NoSyncAA = A.getAAFor<AANoSync>(
2013f0e6704SJohannes Doerfert         QueryingAA, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
2023f0e6704SJohannes Doerfert     return NoSyncAA.isAssumedNoSync();
2033f0e6704SJohannes Doerfert   }
2043f0e6704SJohannes Doerfert 
2053f0e6704SJohannes Doerfert   if (!I.mayReadOrWriteMemory())
2063f0e6704SJohannes Doerfert     return true;
2073f0e6704SJohannes Doerfert 
2083f0e6704SJohannes Doerfert   return !I.isVolatile() && !AANoSync::isNonRelaxedAtomic(&I);
2093f0e6704SJohannes Doerfert }
2103f0e6704SJohannes Doerfert 
isDynamicallyUnique(Attributor & A,const AbstractAttribute & QueryingAA,const Value & V,bool ForAnalysisOnly)21194d3b59cSJohannes Doerfert bool AA::isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA,
212af30de77SJohannes Doerfert                              const Value &V, bool ForAnalysisOnly) {
213af30de77SJohannes Doerfert   // TODO: See the AAInstanceInfo class comment.
214af30de77SJohannes Doerfert   if (!ForAnalysisOnly)
21594d3b59cSJohannes Doerfert     return false;
216af30de77SJohannes Doerfert   auto &InstanceInfoAA = A.getAAFor<AAInstanceInfo>(
217af30de77SJohannes Doerfert       QueryingAA, IRPosition::value(V), DepClassTy::OPTIONAL);
218af30de77SJohannes Doerfert   return InstanceInfoAA.isAssumedUniqueForAnalysis();
21994d3b59cSJohannes Doerfert }
22094d3b59cSJohannes Doerfert 
getInitialValueForObj(Value & Obj,Type & Ty,const TargetLibraryInfo * TLI)2215602c866SJohannes Doerfert Constant *AA::getInitialValueForObj(Value &Obj, Type &Ty,
2225602c866SJohannes Doerfert                                     const TargetLibraryInfo *TLI) {
22328c78a9eSJohannes Doerfert   if (isa<AllocaInst>(Obj))
22428c78a9eSJohannes Doerfert     return UndefValue::get(&Ty);
225871197d0SNikita Popov   if (Constant *Init = getInitialValueOfAllocation(&Obj, TLI, &Ty))
226871197d0SNikita Popov     return Init;
22728c78a9eSJohannes Doerfert   auto *GV = dyn_cast<GlobalVariable>(&Obj);
228cb8adf76SJohannes Doerfert   if (!GV)
229cb8adf76SJohannes Doerfert     return nullptr;
230cb8adf76SJohannes Doerfert   if (!GV->hasLocalLinkage() && !(GV->isConstant() && GV->hasInitializer()))
23128c78a9eSJohannes Doerfert     return nullptr;
23228c78a9eSJohannes Doerfert   if (!GV->hasInitializer())
23328c78a9eSJohannes Doerfert     return UndefValue::get(&Ty);
23428c78a9eSJohannes Doerfert   return dyn_cast_or_null<Constant>(getWithType(*GV->getInitializer(), Ty));
23528c78a9eSJohannes Doerfert }
23628c78a9eSJohannes Doerfert 
isValidInScope(const Value & V,const Function * Scope)237fc82409bSJohannes Doerfert bool AA::isValidInScope(const Value &V, const Function *Scope) {
238fc82409bSJohannes Doerfert   if (isa<Constant>(V))
239fc82409bSJohannes Doerfert     return true;
240fc82409bSJohannes Doerfert   if (auto *I = dyn_cast<Instruction>(&V))
241fc82409bSJohannes Doerfert     return I->getFunction() == Scope;
242fc82409bSJohannes Doerfert   if (auto *A = dyn_cast<Argument>(&V))
243fc82409bSJohannes Doerfert     return A->getParent() == Scope;
244fc82409bSJohannes Doerfert   return false;
245fc82409bSJohannes Doerfert }
246fc82409bSJohannes Doerfert 
isValidAtPosition(const AA::ValueAndContext & VAC,InformationCache & InfoCache)247481b8f31SJohannes Doerfert bool AA::isValidAtPosition(const AA::ValueAndContext &VAC,
248dbb3a65fSJohannes Doerfert                            InformationCache &InfoCache) {
249481b8f31SJohannes Doerfert   if (isa<Constant>(VAC.getValue()) || VAC.getValue() == VAC.getCtxI())
250dbb3a65fSJohannes Doerfert     return true;
251481b8f31SJohannes Doerfert   const Function *Scope = nullptr;
252481b8f31SJohannes Doerfert   const Instruction *CtxI = VAC.getCtxI();
253481b8f31SJohannes Doerfert   if (CtxI)
254481b8f31SJohannes Doerfert     Scope = CtxI->getFunction();
255481b8f31SJohannes Doerfert   if (auto *A = dyn_cast<Argument>(VAC.getValue()))
256dbb3a65fSJohannes Doerfert     return A->getParent() == Scope;
257481b8f31SJohannes Doerfert   if (auto *I = dyn_cast<Instruction>(VAC.getValue())) {
258dbb3a65fSJohannes Doerfert     if (I->getFunction() == Scope) {
259acb37734SJohannes Doerfert       if (const DominatorTree *DT =
260acb37734SJohannes Doerfert               InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
261acb37734SJohannes Doerfert                   *Scope))
262481b8f31SJohannes Doerfert         return DT->dominates(I, CtxI);
263acb37734SJohannes Doerfert       // Local dominance check mostly for the old PM passes.
264481b8f31SJohannes Doerfert       if (CtxI && I->getParent() == CtxI->getParent())
265acb37734SJohannes Doerfert         return llvm::any_of(
266acb37734SJohannes Doerfert             make_range(I->getIterator(), I->getParent()->end()),
267481b8f31SJohannes Doerfert             [&](const Instruction &AfterI) { return &AfterI == CtxI; });
268acb37734SJohannes Doerfert     }
269dbb3a65fSJohannes Doerfert   }
270dbb3a65fSJohannes Doerfert   return false;
271dbb3a65fSJohannes Doerfert }
272dbb3a65fSJohannes Doerfert 
getWithType(Value & V,Type & Ty)2736caea8a7SJohannes Doerfert Value *AA::getWithType(Value &V, Type &Ty) {
2746caea8a7SJohannes Doerfert   if (V.getType() == &Ty)
2756caea8a7SJohannes Doerfert     return &V;
276d9194b6eSJohannes Doerfert   if (isa<PoisonValue>(V))
277d9194b6eSJohannes Doerfert     return PoisonValue::get(&Ty);
2786caea8a7SJohannes Doerfert   if (isa<UndefValue>(V))
2796caea8a7SJohannes Doerfert     return UndefValue::get(&Ty);
2806caea8a7SJohannes Doerfert   if (auto *C = dyn_cast<Constant>(&V)) {
2816caea8a7SJohannes Doerfert     if (C->isNullValue())
2826caea8a7SJohannes Doerfert       return Constant::getNullValue(&Ty);
2836caea8a7SJohannes Doerfert     if (C->getType()->isPointerTy() && Ty.isPointerTy())
2846caea8a7SJohannes Doerfert       return ConstantExpr::getPointerCast(C, &Ty);
2855f543919SJohannes Doerfert     if (C->getType()->getPrimitiveSizeInBits() >= Ty.getPrimitiveSizeInBits()) {
2866caea8a7SJohannes Doerfert       if (C->getType()->isIntegerTy() && Ty.isIntegerTy())
2876caea8a7SJohannes Doerfert         return ConstantExpr::getTrunc(C, &Ty, /* OnlyIfReduced */ true);
2886caea8a7SJohannes Doerfert       if (C->getType()->isFloatingPointTy() && Ty.isFloatingPointTy())
2896caea8a7SJohannes Doerfert         return ConstantExpr::getFPTrunc(C, &Ty, /* OnlyIfReduced */ true);
2906caea8a7SJohannes Doerfert     }
2915f543919SJohannes Doerfert   }
2926caea8a7SJohannes Doerfert   return nullptr;
2936caea8a7SJohannes Doerfert }
2946caea8a7SJohannes Doerfert 
295aa376827SJohannes Doerfert Optional<Value *>
combineOptionalValuesInAAValueLatice(const Optional<Value * > & A,const Optional<Value * > & B,Type * Ty)296aa376827SJohannes Doerfert AA::combineOptionalValuesInAAValueLatice(const Optional<Value *> &A,
297aa376827SJohannes Doerfert                                          const Optional<Value *> &B, Type *Ty) {
298aa376827SJohannes Doerfert   if (A == B)
299aa376827SJohannes Doerfert     return A;
300a7938c74SKazu Hirata   if (!B)
301aa376827SJohannes Doerfert     return A;
302aa376827SJohannes Doerfert   if (*B == nullptr)
303aa376827SJohannes Doerfert     return nullptr;
304a7938c74SKazu Hirata   if (!A)
305aa376827SJohannes Doerfert     return Ty ? getWithType(**B, *Ty) : nullptr;
306aa376827SJohannes Doerfert   if (*A == nullptr)
307aa376827SJohannes Doerfert     return nullptr;
308aa376827SJohannes Doerfert   if (!Ty)
309aa376827SJohannes Doerfert     Ty = (*A)->getType();
310aa376827SJohannes Doerfert   if (isa_and_nonnull<UndefValue>(*A))
311aa376827SJohannes Doerfert     return getWithType(**B, *Ty);
312aa376827SJohannes Doerfert   if (isa<UndefValue>(*B))
313aa376827SJohannes Doerfert     return A;
314aa376827SJohannes Doerfert   if (*A && *B && *A == getWithType(**B, *Ty))
315aa376827SJohannes Doerfert     return A;
316aa376827SJohannes Doerfert   return nullptr;
317aa376827SJohannes Doerfert }
318aa376827SJohannes Doerfert 
3195af11ec3SJohannes Doerfert template <bool IsLoad, typename Ty>
getPotentialCopiesOfMemoryValue(Attributor & A,Ty & I,SmallSetVector<Value *,4> & PotentialCopies,SmallSetVector<Instruction *,4> & PotentialValueOrigins,const AbstractAttribute & QueryingAA,bool & UsedAssumedInformation,bool OnlyExact)320c42aa1beSJohannes Doerfert static bool getPotentialCopiesOfMemoryValue(
321c42aa1beSJohannes Doerfert     Attributor &A, Ty &I, SmallSetVector<Value *, 4> &PotentialCopies,
322c42aa1beSJohannes Doerfert     SmallSetVector<Instruction *, 4> &PotentialValueOrigins,
323c42aa1beSJohannes Doerfert     const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
324c42aa1beSJohannes Doerfert     bool OnlyExact) {
3255af11ec3SJohannes Doerfert   LLVM_DEBUG(dbgs() << "Trying to determine the potential copies of " << I
3265af11ec3SJohannes Doerfert                     << " (only exact: " << OnlyExact << ")\n";);
327adddd3dbSJohannes Doerfert 
3285af11ec3SJohannes Doerfert   Value &Ptr = *I.getPointerOperand();
329bf789b19SJohannes Doerfert   SmallSetVector<Value *, 8> Objects;
3305af11ec3SJohannes Doerfert   if (!AA::getAssumedUnderlyingObjects(A, Ptr, Objects, QueryingAA, &I,
3316ed1ef06SJohannes Doerfert                                        UsedAssumedInformation)) {
332adddd3dbSJohannes Doerfert     LLVM_DEBUG(
333adddd3dbSJohannes Doerfert         dbgs() << "Underlying objects stored into could not be determined\n";);
334adddd3dbSJohannes Doerfert     return false;
335adddd3dbSJohannes Doerfert   }
336adddd3dbSJohannes Doerfert 
3375af11ec3SJohannes Doerfert   // Containers to remember the pointer infos and new copies while we are not
3385af11ec3SJohannes Doerfert   // sure that we can find all of them. If we abort we want to avoid spurious
3395af11ec3SJohannes Doerfert   // dependences and potential copies in the provided container.
340adddd3dbSJohannes Doerfert   SmallVector<const AAPointerInfo *> PIs;
341adddd3dbSJohannes Doerfert   SmallVector<Value *> NewCopies;
342c42aa1beSJohannes Doerfert   SmallVector<Instruction *> NewCopyOrigins;
343adddd3dbSJohannes Doerfert 
3445af11ec3SJohannes Doerfert   const auto *TLI =
3455af11ec3SJohannes Doerfert       A.getInfoCache().getTargetLibraryInfoForFunction(*I.getFunction());
3464f2ccdd0SJohannes Doerfert   LLVM_DEBUG(dbgs() << "Visit " << Objects.size() << " objects:\n");
347adddd3dbSJohannes Doerfert   for (Value *Obj : Objects) {
348adddd3dbSJohannes Doerfert     LLVM_DEBUG(dbgs() << "Visit underlying object " << *Obj << "\n");
349adddd3dbSJohannes Doerfert     if (isa<UndefValue>(Obj))
350adddd3dbSJohannes Doerfert       continue;
351adddd3dbSJohannes Doerfert     if (isa<ConstantPointerNull>(Obj)) {
352adddd3dbSJohannes Doerfert       // A null pointer access can be undefined but any offset from null may
353adddd3dbSJohannes Doerfert       // be OK. We do not try to optimize the latter.
3545af11ec3SJohannes Doerfert       if (!NullPointerIsDefined(I.getFunction(),
355adddd3dbSJohannes Doerfert                                 Ptr.getType()->getPointerAddressSpace()) &&
356bf789b19SJohannes Doerfert           A.getAssumedSimplified(Ptr, QueryingAA, UsedAssumedInformation,
357bf789b19SJohannes Doerfert                                  AA::Interprocedural) == Obj)
358adddd3dbSJohannes Doerfert         continue;
359adddd3dbSJohannes Doerfert       LLVM_DEBUG(
360adddd3dbSJohannes Doerfert           dbgs() << "Underlying object is a valid nullptr, giving up.\n";);
361adddd3dbSJohannes Doerfert       return false;
362adddd3dbSJohannes Doerfert     }
3635af11ec3SJohannes Doerfert     // TODO: Use assumed noalias return.
3645602c866SJohannes Doerfert     if (!isa<AllocaInst>(Obj) && !isa<GlobalVariable>(Obj) &&
3655af11ec3SJohannes Doerfert         !(IsLoad ? isAllocationFn(Obj, TLI) : isNoAliasCall(Obj))) {
366adddd3dbSJohannes Doerfert       LLVM_DEBUG(dbgs() << "Underlying object is not supported yet: " << *Obj
367adddd3dbSJohannes Doerfert                         << "\n";);
368adddd3dbSJohannes Doerfert       return false;
369adddd3dbSJohannes Doerfert     }
370adddd3dbSJohannes Doerfert     if (auto *GV = dyn_cast<GlobalVariable>(Obj))
371cb8adf76SJohannes Doerfert       if (!GV->hasLocalLinkage() &&
372cb8adf76SJohannes Doerfert           !(GV->isConstant() && GV->hasInitializer())) {
373adddd3dbSJohannes Doerfert         LLVM_DEBUG(dbgs() << "Underlying object is global with external "
374adddd3dbSJohannes Doerfert                              "linkage, not supported yet: "
375adddd3dbSJohannes Doerfert                           << *Obj << "\n";);
376adddd3dbSJohannes Doerfert         return false;
377adddd3dbSJohannes Doerfert       }
378adddd3dbSJohannes Doerfert 
379bf789b19SJohannes Doerfert     bool NullOnly = true;
380bf789b19SJohannes Doerfert     bool NullRequired = false;
381142897ddSJohannes Doerfert     auto CheckForNullOnlyAndUndef = [&](Optional<Value *> V, bool IsExact) {
382bf789b19SJohannes Doerfert       if (!V || *V == nullptr)
383bf789b19SJohannes Doerfert         NullOnly = false;
384bf789b19SJohannes Doerfert       else if (isa<UndefValue>(*V))
385bf789b19SJohannes Doerfert         /* No op */;
386bf789b19SJohannes Doerfert       else if (isa<Constant>(*V) && cast<Constant>(*V)->isNullValue())
387142897ddSJohannes Doerfert         NullRequired = !IsExact;
388bf789b19SJohannes Doerfert       else
389bf789b19SJohannes Doerfert         NullOnly = false;
390bf789b19SJohannes Doerfert     };
391bf789b19SJohannes Doerfert 
392adddd3dbSJohannes Doerfert     auto CheckAccess = [&](const AAPointerInfo::Access &Acc, bool IsExact) {
3935af11ec3SJohannes Doerfert       if ((IsLoad && !Acc.isWrite()) || (!IsLoad && !Acc.isRead()))
394adddd3dbSJohannes Doerfert         return true;
395857bf306SJohannes Doerfert       if (IsLoad && Acc.isWrittenValueYetUndetermined())
396857bf306SJohannes Doerfert         return true;
397142897ddSJohannes Doerfert       CheckForNullOnlyAndUndef(Acc.getContent(), IsExact);
398bf789b19SJohannes Doerfert       if (OnlyExact && !IsExact && !NullOnly &&
399857bf306SJohannes Doerfert           !isa_and_nonnull<UndefValue>(Acc.getWrittenValue())) {
4005af11ec3SJohannes Doerfert         LLVM_DEBUG(dbgs() << "Non exact access " << *Acc.getRemoteInst()
4015af11ec3SJohannes Doerfert                           << ", abort!\n");
4025af11ec3SJohannes Doerfert         return false;
4035af11ec3SJohannes Doerfert       }
404bf789b19SJohannes Doerfert       if (NullRequired && !NullOnly) {
405bf789b19SJohannes Doerfert         LLVM_DEBUG(dbgs() << "Required all `null` accesses due to non exact "
406bf789b19SJohannes Doerfert                              "one, however found non-null one: "
407bf789b19SJohannes Doerfert                           << *Acc.getRemoteInst() << ", abort!\n");
408bf789b19SJohannes Doerfert         return false;
409bf789b19SJohannes Doerfert       }
4105af11ec3SJohannes Doerfert       if (IsLoad) {
4115af11ec3SJohannes Doerfert         assert(isa<LoadInst>(I) && "Expected load or store instruction only!");
4125af11ec3SJohannes Doerfert         if (!Acc.isWrittenValueUnknown()) {
4135af11ec3SJohannes Doerfert           NewCopies.push_back(Acc.getWrittenValue());
414c42aa1beSJohannes Doerfert           NewCopyOrigins.push_back(Acc.getRemoteInst());
4155af11ec3SJohannes Doerfert           return true;
4165af11ec3SJohannes Doerfert         }
4175af11ec3SJohannes Doerfert         auto *SI = dyn_cast<StoreInst>(Acc.getRemoteInst());
4185af11ec3SJohannes Doerfert         if (!SI) {
4195af11ec3SJohannes Doerfert           LLVM_DEBUG(dbgs() << "Underlying object written through a non-store "
4205af11ec3SJohannes Doerfert                                "instruction not supported yet: "
4215af11ec3SJohannes Doerfert                             << *Acc.getRemoteInst() << "\n";);
4225af11ec3SJohannes Doerfert           return false;
4235af11ec3SJohannes Doerfert         }
4245af11ec3SJohannes Doerfert         NewCopies.push_back(SI->getValueOperand());
425c42aa1beSJohannes Doerfert         NewCopyOrigins.push_back(SI);
4265af11ec3SJohannes Doerfert       } else {
4275af11ec3SJohannes Doerfert         assert(isa<StoreInst>(I) && "Expected load or store instruction only!");
428adddd3dbSJohannes Doerfert         auto *LI = dyn_cast<LoadInst>(Acc.getRemoteInst());
4295af11ec3SJohannes Doerfert         if (!LI && OnlyExact) {
430adddd3dbSJohannes Doerfert           LLVM_DEBUG(dbgs() << "Underlying object read through a non-load "
431adddd3dbSJohannes Doerfert                                "instruction not supported yet: "
432adddd3dbSJohannes Doerfert                             << *Acc.getRemoteInst() << "\n";);
433adddd3dbSJohannes Doerfert           return false;
434adddd3dbSJohannes Doerfert         }
4355af11ec3SJohannes Doerfert         NewCopies.push_back(Acc.getRemoteInst());
4365af11ec3SJohannes Doerfert       }
437adddd3dbSJohannes Doerfert       return true;
438adddd3dbSJohannes Doerfert     };
439adddd3dbSJohannes Doerfert 
44062f7888dSJohannes Doerfert     // If the value has been written to we don't need the initial value of the
44162f7888dSJohannes Doerfert     // object.
44262f7888dSJohannes Doerfert     bool HasBeenWrittenTo = false;
44362f7888dSJohannes Doerfert 
444adddd3dbSJohannes Doerfert     auto &PI = A.getAAFor<AAPointerInfo>(QueryingAA, IRPosition::value(*Obj),
445adddd3dbSJohannes Doerfert                                          DepClassTy::NONE);
44662f7888dSJohannes Doerfert     if (!PI.forallInterferingAccesses(A, QueryingAA, I, CheckAccess,
44762f7888dSJohannes Doerfert                                       HasBeenWrittenTo)) {
448adddd3dbSJohannes Doerfert       LLVM_DEBUG(
449adddd3dbSJohannes Doerfert           dbgs()
450adddd3dbSJohannes Doerfert           << "Failed to verify all interfering accesses for underlying object: "
451adddd3dbSJohannes Doerfert           << *Obj << "\n");
452adddd3dbSJohannes Doerfert       return false;
453adddd3dbSJohannes Doerfert     }
45462f7888dSJohannes Doerfert 
45562f7888dSJohannes Doerfert     if (IsLoad && !HasBeenWrittenTo) {
45662f7888dSJohannes Doerfert       Value *InitialValue = AA::getInitialValueForObj(*Obj, *I.getType(), TLI);
45762f7888dSJohannes Doerfert       if (!InitialValue)
45862f7888dSJohannes Doerfert         return false;
45962f7888dSJohannes Doerfert       CheckForNullOnlyAndUndef(InitialValue, /* IsExact */ true);
46062f7888dSJohannes Doerfert       if (NullRequired && !NullOnly) {
46162f7888dSJohannes Doerfert         LLVM_DEBUG(dbgs() << "Non exact access but initial value that is not "
46262f7888dSJohannes Doerfert                              "null or undef, abort!\n");
46362f7888dSJohannes Doerfert         return false;
46462f7888dSJohannes Doerfert       }
46562f7888dSJohannes Doerfert 
46662f7888dSJohannes Doerfert       NewCopies.push_back(InitialValue);
46762f7888dSJohannes Doerfert       NewCopyOrigins.push_back(nullptr);
46862f7888dSJohannes Doerfert     }
46962f7888dSJohannes Doerfert 
470adddd3dbSJohannes Doerfert     PIs.push_back(&PI);
471adddd3dbSJohannes Doerfert   }
472adddd3dbSJohannes Doerfert 
4735af11ec3SJohannes Doerfert   // Only if we were successful collection all potential copies we record
4745af11ec3SJohannes Doerfert   // dependences (on non-fix AAPointerInfo AAs). We also only then modify the
4755af11ec3SJohannes Doerfert   // given PotentialCopies container.
476adddd3dbSJohannes Doerfert   for (auto *PI : PIs) {
477adddd3dbSJohannes Doerfert     if (!PI->getState().isAtFixpoint())
478adddd3dbSJohannes Doerfert       UsedAssumedInformation = true;
479adddd3dbSJohannes Doerfert     A.recordDependence(*PI, QueryingAA, DepClassTy::OPTIONAL);
480adddd3dbSJohannes Doerfert   }
481adddd3dbSJohannes Doerfert   PotentialCopies.insert(NewCopies.begin(), NewCopies.end());
482c42aa1beSJohannes Doerfert   PotentialValueOrigins.insert(NewCopyOrigins.begin(), NewCopyOrigins.end());
483adddd3dbSJohannes Doerfert 
484adddd3dbSJohannes Doerfert   return true;
485adddd3dbSJohannes Doerfert }
486adddd3dbSJohannes Doerfert 
getPotentiallyLoadedValues(Attributor & A,LoadInst & LI,SmallSetVector<Value *,4> & PotentialValues,SmallSetVector<Instruction *,4> & PotentialValueOrigins,const AbstractAttribute & QueryingAA,bool & UsedAssumedInformation,bool OnlyExact)487c42aa1beSJohannes Doerfert bool AA::getPotentiallyLoadedValues(
488c42aa1beSJohannes Doerfert     Attributor &A, LoadInst &LI, SmallSetVector<Value *, 4> &PotentialValues,
489c42aa1beSJohannes Doerfert     SmallSetVector<Instruction *, 4> &PotentialValueOrigins,
490c42aa1beSJohannes Doerfert     const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
4915af11ec3SJohannes Doerfert     bool OnlyExact) {
4925af11ec3SJohannes Doerfert   return getPotentialCopiesOfMemoryValue</* IsLoad */ true>(
493c42aa1beSJohannes Doerfert       A, LI, PotentialValues, PotentialValueOrigins, QueryingAA,
494c42aa1beSJohannes Doerfert       UsedAssumedInformation, OnlyExact);
4955af11ec3SJohannes Doerfert }
4965af11ec3SJohannes Doerfert 
getPotentialCopiesOfStoredValue(Attributor & A,StoreInst & SI,SmallSetVector<Value *,4> & PotentialCopies,const AbstractAttribute & QueryingAA,bool & UsedAssumedInformation,bool OnlyExact)4975af11ec3SJohannes Doerfert bool AA::getPotentialCopiesOfStoredValue(
4985af11ec3SJohannes Doerfert     Attributor &A, StoreInst &SI, SmallSetVector<Value *, 4> &PotentialCopies,
4995af11ec3SJohannes Doerfert     const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation,
5005af11ec3SJohannes Doerfert     bool OnlyExact) {
501c42aa1beSJohannes Doerfert   SmallSetVector<Instruction *, 4> PotentialValueOrigins;
5025af11ec3SJohannes Doerfert   return getPotentialCopiesOfMemoryValue</* IsLoad */ false>(
503c42aa1beSJohannes Doerfert       A, SI, PotentialCopies, PotentialValueOrigins, QueryingAA,
504c42aa1beSJohannes Doerfert       UsedAssumedInformation, OnlyExact);
5055af11ec3SJohannes Doerfert }
5065af11ec3SJohannes Doerfert 
isAssumedReadOnlyOrReadNone(Attributor & A,const IRPosition & IRP,const AbstractAttribute & QueryingAA,bool RequireReadNone,bool & IsKnown)507adf0d57fSJohannes Doerfert static bool isAssumedReadOnlyOrReadNone(Attributor &A, const IRPosition &IRP,
508adf0d57fSJohannes Doerfert                                         const AbstractAttribute &QueryingAA,
509adf0d57fSJohannes Doerfert                                         bool RequireReadNone, bool &IsKnown) {
510adf0d57fSJohannes Doerfert 
511adf0d57fSJohannes Doerfert   IRPosition::Kind Kind = IRP.getPositionKind();
512adf0d57fSJohannes Doerfert   if (Kind == IRPosition::IRP_FUNCTION || Kind == IRPosition::IRP_CALL_SITE) {
513adf0d57fSJohannes Doerfert     const auto &MemLocAA =
514adf0d57fSJohannes Doerfert         A.getAAFor<AAMemoryLocation>(QueryingAA, IRP, DepClassTy::NONE);
515adf0d57fSJohannes Doerfert     if (MemLocAA.isAssumedReadNone()) {
516adf0d57fSJohannes Doerfert       IsKnown = MemLocAA.isKnownReadNone();
517adf0d57fSJohannes Doerfert       if (!IsKnown)
518adf0d57fSJohannes Doerfert         A.recordDependence(MemLocAA, QueryingAA, DepClassTy::OPTIONAL);
519adf0d57fSJohannes Doerfert       return true;
520adf0d57fSJohannes Doerfert     }
521adf0d57fSJohannes Doerfert   }
522adf0d57fSJohannes Doerfert 
523adf0d57fSJohannes Doerfert   const auto &MemBehaviorAA =
524adf0d57fSJohannes Doerfert       A.getAAFor<AAMemoryBehavior>(QueryingAA, IRP, DepClassTy::NONE);
525adf0d57fSJohannes Doerfert   if (MemBehaviorAA.isAssumedReadNone() ||
526adf0d57fSJohannes Doerfert       (!RequireReadNone && MemBehaviorAA.isAssumedReadOnly())) {
527adf0d57fSJohannes Doerfert     IsKnown = RequireReadNone ? MemBehaviorAA.isKnownReadNone()
528adf0d57fSJohannes Doerfert                               : MemBehaviorAA.isKnownReadOnly();
529adf0d57fSJohannes Doerfert     if (!IsKnown)
530adf0d57fSJohannes Doerfert       A.recordDependence(MemBehaviorAA, QueryingAA, DepClassTy::OPTIONAL);
531adf0d57fSJohannes Doerfert     return true;
532adf0d57fSJohannes Doerfert   }
533adf0d57fSJohannes Doerfert 
534adf0d57fSJohannes Doerfert   return false;
535adf0d57fSJohannes Doerfert }
536adf0d57fSJohannes Doerfert 
isAssumedReadOnly(Attributor & A,const IRPosition & IRP,const AbstractAttribute & QueryingAA,bool & IsKnown)537adf0d57fSJohannes Doerfert bool AA::isAssumedReadOnly(Attributor &A, const IRPosition &IRP,
538adf0d57fSJohannes Doerfert                            const AbstractAttribute &QueryingAA, bool &IsKnown) {
539adf0d57fSJohannes Doerfert   return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,
540adf0d57fSJohannes Doerfert                                      /* RequireReadNone */ false, IsKnown);
541adf0d57fSJohannes Doerfert }
isAssumedReadNone(Attributor & A,const IRPosition & IRP,const AbstractAttribute & QueryingAA,bool & IsKnown)542adf0d57fSJohannes Doerfert bool AA::isAssumedReadNone(Attributor &A, const IRPosition &IRP,
543adf0d57fSJohannes Doerfert                            const AbstractAttribute &QueryingAA, bool &IsKnown) {
544adf0d57fSJohannes Doerfert   return isAssumedReadOnlyOrReadNone(A, IRP, QueryingAA,
545adf0d57fSJohannes Doerfert                                      /* RequireReadNone */ true, IsKnown);
546adf0d57fSJohannes Doerfert }
547adf0d57fSJohannes Doerfert 
548a265cf22SJohannes Doerfert static bool
isPotentiallyReachable(Attributor & A,const Instruction & FromI,const Instruction * ToI,const Function & ToFn,const AbstractAttribute & QueryingAA,std::function<bool (const Function & F)> GoBackwardsCB)549a265cf22SJohannes Doerfert isPotentiallyReachable(Attributor &A, const Instruction &FromI,
550a265cf22SJohannes Doerfert                        const Instruction *ToI, const Function &ToFn,
551a265cf22SJohannes Doerfert                        const AbstractAttribute &QueryingAA,
552a265cf22SJohannes Doerfert                        std::function<bool(const Function &F)> GoBackwardsCB) {
553a265cf22SJohannes Doerfert   LLVM_DEBUG(dbgs() << "[AA] isPotentiallyReachable @" << ToFn.getName()
554a265cf22SJohannes Doerfert                     << " from " << FromI << " [GBCB: " << bool(GoBackwardsCB)
555a265cf22SJohannes Doerfert                     << "]\n");
556a265cf22SJohannes Doerfert 
557*a50b9f9fSJohannes Doerfert   // TODO: If we can go arbitrarily backwards we will eventually reach an
558*a50b9f9fSJohannes Doerfert   // entry point that can reach ToI. Only once this takes a set of blocks
559*a50b9f9fSJohannes Doerfert   // through which we cannot go, or once we track internal functions not
560*a50b9f9fSJohannes Doerfert   // accessible from the outside, it makes sense to perform backwards analysis
561*a50b9f9fSJohannes Doerfert   // in the absence of a GoBackwardsCB.
562*a50b9f9fSJohannes Doerfert   if (!GoBackwardsCB) {
563*a50b9f9fSJohannes Doerfert     LLVM_DEBUG(dbgs() << "[AA] check @" << ToFn.getName() << " from " << FromI
564*a50b9f9fSJohannes Doerfert                       << " is not checked backwards, abort\n");
565*a50b9f9fSJohannes Doerfert     return true;
566*a50b9f9fSJohannes Doerfert   }
567*a50b9f9fSJohannes Doerfert 
568a265cf22SJohannes Doerfert   SmallPtrSet<const Instruction *, 8> Visited;
569a265cf22SJohannes Doerfert   SmallVector<const Instruction *> Worklist;
570a265cf22SJohannes Doerfert   Worklist.push_back(&FromI);
571a265cf22SJohannes Doerfert 
572a265cf22SJohannes Doerfert   while (!Worklist.empty()) {
573a265cf22SJohannes Doerfert     const Instruction *CurFromI = Worklist.pop_back_val();
574a265cf22SJohannes Doerfert     if (!Visited.insert(CurFromI).second)
575a265cf22SJohannes Doerfert       continue;
576a265cf22SJohannes Doerfert 
577a265cf22SJohannes Doerfert     const Function *FromFn = CurFromI->getFunction();
578a265cf22SJohannes Doerfert     if (FromFn == &ToFn) {
579a265cf22SJohannes Doerfert       if (!ToI)
580a265cf22SJohannes Doerfert         return true;
581a265cf22SJohannes Doerfert       LLVM_DEBUG(dbgs() << "[AA] check " << *ToI << " from " << *CurFromI
582a265cf22SJohannes Doerfert                         << " intraprocedurally\n");
583a265cf22SJohannes Doerfert       const auto &ReachabilityAA = A.getAAFor<AAReachability>(
584a265cf22SJohannes Doerfert           QueryingAA, IRPosition::function(ToFn), DepClassTy::OPTIONAL);
585a265cf22SJohannes Doerfert       bool Result = ReachabilityAA.isAssumedReachable(A, *CurFromI, *ToI);
586a265cf22SJohannes Doerfert       LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " "
587a265cf22SJohannes Doerfert                         << (Result ? "can potentially " : "cannot ") << "reach "
588a265cf22SJohannes Doerfert                         << *ToI << " [Intra]\n");
589a265cf22SJohannes Doerfert       if (Result)
590a265cf22SJohannes Doerfert         return true;
591a265cf22SJohannes Doerfert     }
592a265cf22SJohannes Doerfert 
593a265cf22SJohannes Doerfert     // Check if the current instruction is already known to reach the ToFn.
594a265cf22SJohannes Doerfert     const auto &FnReachabilityAA = A.getAAFor<AAFunctionReachability>(
595a265cf22SJohannes Doerfert         QueryingAA, IRPosition::function(*FromFn), DepClassTy::OPTIONAL);
596a265cf22SJohannes Doerfert     bool Result = FnReachabilityAA.instructionCanReach(
597*a50b9f9fSJohannes Doerfert         A, *CurFromI, ToFn);
598a265cf22SJohannes Doerfert     LLVM_DEBUG(dbgs() << "[AA] " << *CurFromI << " in @" << FromFn->getName()
599a265cf22SJohannes Doerfert                       << " " << (Result ? "can potentially " : "cannot ")
600a265cf22SJohannes Doerfert                       << "reach @" << ToFn.getName() << " [FromFn]\n");
601a265cf22SJohannes Doerfert     if (Result)
602a265cf22SJohannes Doerfert       return true;
603a265cf22SJohannes Doerfert 
604a265cf22SJohannes Doerfert     // If we do not go backwards from the FromFn we are done here and so far we
605a265cf22SJohannes Doerfert     // could not find a way to reach ToFn/ToI.
606a265cf22SJohannes Doerfert     if (!GoBackwardsCB(*FromFn))
607a265cf22SJohannes Doerfert       continue;
608a265cf22SJohannes Doerfert 
609a265cf22SJohannes Doerfert     LLVM_DEBUG(dbgs() << "Stepping backwards to the call sites of @"
610a265cf22SJohannes Doerfert                       << FromFn->getName() << "\n");
611a265cf22SJohannes Doerfert 
612a265cf22SJohannes Doerfert     auto CheckCallSite = [&](AbstractCallSite ACS) {
613a265cf22SJohannes Doerfert       CallBase *CB = ACS.getInstruction();
614a265cf22SJohannes Doerfert       if (!CB)
615a265cf22SJohannes Doerfert         return false;
616a265cf22SJohannes Doerfert 
617a265cf22SJohannes Doerfert       if (isa<InvokeInst>(CB))
618a265cf22SJohannes Doerfert         return false;
619a265cf22SJohannes Doerfert 
620a265cf22SJohannes Doerfert       Instruction *Inst = CB->getNextNonDebugInstruction();
621a265cf22SJohannes Doerfert       Worklist.push_back(Inst);
622a265cf22SJohannes Doerfert       return true;
623a265cf22SJohannes Doerfert     };
624a265cf22SJohannes Doerfert 
6256ed1ef06SJohannes Doerfert     bool UsedAssumedInformation = false;
626a265cf22SJohannes Doerfert     Result = !A.checkForAllCallSites(CheckCallSite, *FromFn,
627a265cf22SJohannes Doerfert                                      /* RequireAllCallSites */ true,
6286ed1ef06SJohannes Doerfert                                      &QueryingAA, UsedAssumedInformation);
629a265cf22SJohannes Doerfert     if (Result) {
630a265cf22SJohannes Doerfert       LLVM_DEBUG(dbgs() << "[AA] stepping back to call sites from " << *CurFromI
631a265cf22SJohannes Doerfert                         << " in @" << FromFn->getName()
632a265cf22SJohannes Doerfert                         << " failed, give up\n");
633a265cf22SJohannes Doerfert       return true;
634a265cf22SJohannes Doerfert     }
635a265cf22SJohannes Doerfert 
636a265cf22SJohannes Doerfert     LLVM_DEBUG(dbgs() << "[AA] stepped back to call sites from " << *CurFromI
637a265cf22SJohannes Doerfert                       << " in @" << FromFn->getName()
638a265cf22SJohannes Doerfert                       << " worklist size is: " << Worklist.size() << "\n");
639a265cf22SJohannes Doerfert   }
640a265cf22SJohannes Doerfert   return false;
641a265cf22SJohannes Doerfert }
642a265cf22SJohannes Doerfert 
isPotentiallyReachable(Attributor & A,const Instruction & FromI,const Instruction & ToI,const AbstractAttribute & QueryingAA,std::function<bool (const Function & F)> GoBackwardsCB)643a265cf22SJohannes Doerfert bool AA::isPotentiallyReachable(
644a265cf22SJohannes Doerfert     Attributor &A, const Instruction &FromI, const Instruction &ToI,
645a265cf22SJohannes Doerfert     const AbstractAttribute &QueryingAA,
646a265cf22SJohannes Doerfert     std::function<bool(const Function &F)> GoBackwardsCB) {
647a265cf22SJohannes Doerfert   LLVM_DEBUG(dbgs() << "[AA] isPotentiallyReachable " << ToI << " from "
648a265cf22SJohannes Doerfert                     << FromI << " [GBCB: " << bool(GoBackwardsCB) << "]\n");
649a265cf22SJohannes Doerfert   const Function *ToFn = ToI.getFunction();
650a265cf22SJohannes Doerfert   return ::isPotentiallyReachable(A, FromI, &ToI, *ToFn, QueryingAA,
651a265cf22SJohannes Doerfert                                   GoBackwardsCB);
652a265cf22SJohannes Doerfert }
653a265cf22SJohannes Doerfert 
isPotentiallyReachable(Attributor & A,const Instruction & FromI,const Function & ToFn,const AbstractAttribute & QueryingAA,std::function<bool (const Function & F)> GoBackwardsCB)654a265cf22SJohannes Doerfert bool AA::isPotentiallyReachable(
655a265cf22SJohannes Doerfert     Attributor &A, const Instruction &FromI, const Function &ToFn,
656a265cf22SJohannes Doerfert     const AbstractAttribute &QueryingAA,
657a265cf22SJohannes Doerfert     std::function<bool(const Function &F)> GoBackwardsCB) {
658a265cf22SJohannes Doerfert   return ::isPotentiallyReachable(A, FromI, /* ToI */ nullptr, ToFn, QueryingAA,
659a265cf22SJohannes Doerfert                                   GoBackwardsCB);
660a265cf22SJohannes Doerfert }
661a265cf22SJohannes Doerfert 
6620985554bSJohannes Doerfert /// Return true if \p New is equal or worse than \p Old.
isEqualOrWorse(const Attribute & New,const Attribute & Old)6630985554bSJohannes Doerfert static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
6640985554bSJohannes Doerfert   if (!Old.isIntAttribute())
6650985554bSJohannes Doerfert     return true;
6660985554bSJohannes Doerfert 
6670985554bSJohannes Doerfert   return Old.getValueAsInt() >= New.getValueAsInt();
6680985554bSJohannes Doerfert }
6690985554bSJohannes Doerfert 
6700985554bSJohannes Doerfert /// Return true if the information provided by \p Attr was added to the
6710985554bSJohannes Doerfert /// attribute list \p Attrs. This is only the case if it was not already present
6720985554bSJohannes Doerfert /// in \p Attrs at the position describe by \p PK and \p AttrIdx.
addIfNotExistent(LLVMContext & Ctx,const Attribute & Attr,AttributeList & Attrs,int AttrIdx,bool ForceReplace=false)6730985554bSJohannes Doerfert static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
67496709823SKuter Dinel                              AttributeList &Attrs, int AttrIdx,
67596709823SKuter Dinel                              bool ForceReplace = false) {
6760985554bSJohannes Doerfert 
6770985554bSJohannes Doerfert   if (Attr.isEnumAttribute()) {
6780985554bSJohannes Doerfert     Attribute::AttrKind Kind = Attr.getKindAsEnum();
67952e6d70cSArthur Eubanks     if (Attrs.hasAttributeAtIndex(AttrIdx, Kind))
68096709823SKuter Dinel       if (!ForceReplace &&
68152e6d70cSArthur Eubanks           isEqualOrWorse(Attr, Attrs.getAttributeAtIndex(AttrIdx, Kind)))
6820985554bSJohannes Doerfert         return false;
68352e6d70cSArthur Eubanks     Attrs = Attrs.addAttributeAtIndex(Ctx, AttrIdx, Attr);
6840985554bSJohannes Doerfert     return true;
6850985554bSJohannes Doerfert   }
6860985554bSJohannes Doerfert   if (Attr.isStringAttribute()) {
6870985554bSJohannes Doerfert     StringRef Kind = Attr.getKindAsString();
68852e6d70cSArthur Eubanks     if (Attrs.hasAttributeAtIndex(AttrIdx, Kind))
68996709823SKuter Dinel       if (!ForceReplace &&
69052e6d70cSArthur Eubanks           isEqualOrWorse(Attr, Attrs.getAttributeAtIndex(AttrIdx, Kind)))
6910985554bSJohannes Doerfert         return false;
69252e6d70cSArthur Eubanks     Attrs = Attrs.addAttributeAtIndex(Ctx, AttrIdx, Attr);
6930985554bSJohannes Doerfert     return true;
6940985554bSJohannes Doerfert   }
6950985554bSJohannes Doerfert   if (Attr.isIntAttribute()) {
6960985554bSJohannes Doerfert     Attribute::AttrKind Kind = Attr.getKindAsEnum();
69752e6d70cSArthur Eubanks     if (Attrs.hasAttributeAtIndex(AttrIdx, Kind))
69896709823SKuter Dinel       if (!ForceReplace &&
69952e6d70cSArthur Eubanks           isEqualOrWorse(Attr, Attrs.getAttributeAtIndex(AttrIdx, Kind)))
7000985554bSJohannes Doerfert         return false;
70152e6d70cSArthur Eubanks     Attrs = Attrs.removeAttributeAtIndex(Ctx, AttrIdx, Kind);
70252e6d70cSArthur Eubanks     Attrs = Attrs.addAttributeAtIndex(Ctx, AttrIdx, Attr);
7030985554bSJohannes Doerfert     return true;
7040985554bSJohannes Doerfert   }
7050985554bSJohannes Doerfert 
7060985554bSJohannes Doerfert   llvm_unreachable("Expected enum or string attribute!");
7070985554bSJohannes Doerfert }
7080985554bSJohannes Doerfert 
getAssociatedArgument() const709b1b441d2SJohannes Doerfert Argument *IRPosition::getAssociatedArgument() const {
710b1b441d2SJohannes Doerfert   if (getPositionKind() == IRP_ARGUMENT)
711b1b441d2SJohannes Doerfert     return cast<Argument>(&getAnchorValue());
712b1b441d2SJohannes Doerfert 
713b1b441d2SJohannes Doerfert   // Not an Argument and no argument number means this is not a call site
714b1b441d2SJohannes Doerfert   // argument, thus we cannot find a callback argument to return.
715cefd2a2cSJohannes Doerfert   int ArgNo = getCallSiteArgNo();
716b1b441d2SJohannes Doerfert   if (ArgNo < 0)
717b1b441d2SJohannes Doerfert     return nullptr;
718b1b441d2SJohannes Doerfert 
719b1b441d2SJohannes Doerfert   // Use abstract call sites to make the connection between the call site
720b1b441d2SJohannes Doerfert   // values and the ones in callbacks. If a callback was found that makes use
721b1b441d2SJohannes Doerfert   // of the underlying call site operand, we want the corresponding callback
722b1b441d2SJohannes Doerfert   // callee argument and not the direct callee argument.
723b1b441d2SJohannes Doerfert   Optional<Argument *> CBCandidateArg;
724798b262cSCraig Topper   SmallVector<const Use *, 4> CallbackUses;
725798b262cSCraig Topper   const auto &CB = cast<CallBase>(getAnchorValue());
726798b262cSCraig Topper   AbstractCallSite::getCallbackUses(CB, CallbackUses);
727798b262cSCraig Topper   for (const Use *U : CallbackUses) {
728b1b441d2SJohannes Doerfert     AbstractCallSite ACS(U);
729b1b441d2SJohannes Doerfert     assert(ACS && ACS.isCallbackCall());
730b1b441d2SJohannes Doerfert     if (!ACS.getCalledFunction())
731b1b441d2SJohannes Doerfert       continue;
732b1b441d2SJohannes Doerfert 
733b1b441d2SJohannes Doerfert     for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {
734b1b441d2SJohannes Doerfert 
735b1b441d2SJohannes Doerfert       // Test if the underlying call site operand is argument number u of the
736b1b441d2SJohannes Doerfert       // callback callee.
737b1b441d2SJohannes Doerfert       if (ACS.getCallArgOperandNo(u) != ArgNo)
738b1b441d2SJohannes Doerfert         continue;
739b1b441d2SJohannes Doerfert 
740b1b441d2SJohannes Doerfert       assert(ACS.getCalledFunction()->arg_size() > u &&
741b1b441d2SJohannes Doerfert              "ACS mapped into var-args arguments!");
742e0e687a6SKazu Hirata       if (CBCandidateArg) {
743b1b441d2SJohannes Doerfert         CBCandidateArg = nullptr;
744b1b441d2SJohannes Doerfert         break;
745b1b441d2SJohannes Doerfert       }
746b1b441d2SJohannes Doerfert       CBCandidateArg = ACS.getCalledFunction()->getArg(u);
747b1b441d2SJohannes Doerfert     }
748b1b441d2SJohannes Doerfert   }
749b1b441d2SJohannes Doerfert 
750b1b441d2SJohannes Doerfert   // If we found a unique callback candidate argument, return it.
751611ffcf4SKazu Hirata   if (CBCandidateArg && CBCandidateArg.value())
752611ffcf4SKazu Hirata     return CBCandidateArg.value();
753b1b441d2SJohannes Doerfert 
754b1b441d2SJohannes Doerfert   // If no callbacks were found, or none used the underlying call site operand
755b1b441d2SJohannes Doerfert   // exclusively, use the direct callee argument if available.
756798b262cSCraig Topper   const Function *Callee = CB.getCalledFunction();
757b1b441d2SJohannes Doerfert   if (Callee && Callee->arg_size() > unsigned(ArgNo))
758b1b441d2SJohannes Doerfert     return Callee->getArg(ArgNo);
759b1b441d2SJohannes Doerfert 
760b1b441d2SJohannes Doerfert   return nullptr;
761b1b441d2SJohannes Doerfert }
762b1b441d2SJohannes Doerfert 
update(Attributor & A)763ece81904SJohannes Doerfert ChangeStatus AbstractAttribute::update(Attributor &A) {
764aade782aSJohannes Doerfert   ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
765aade782aSJohannes Doerfert   if (getState().isAtFixpoint())
766aade782aSJohannes Doerfert     return HasChanged;
767aade782aSJohannes Doerfert 
768aade782aSJohannes Doerfert   LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
769aade782aSJohannes Doerfert 
770ece81904SJohannes Doerfert   HasChanged = updateImpl(A);
771aade782aSJohannes Doerfert 
772aade782aSJohannes Doerfert   LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
773aade782aSJohannes Doerfert                     << "\n");
774aade782aSJohannes Doerfert 
775aade782aSJohannes Doerfert   return HasChanged;
776aade782aSJohannes Doerfert }
777aade782aSJohannes Doerfert 
778d1b79e07SJohannes Doerfert ChangeStatus
manifestAttrs(Attributor & A,const IRPosition & IRP,const ArrayRef<Attribute> & DeducedAttrs,bool ForceReplace)779b2083c53SJohannes Doerfert IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
78096709823SKuter Dinel                                    const ArrayRef<Attribute> &DeducedAttrs,
78196709823SKuter Dinel                                    bool ForceReplace) {
782a650d555SStefanos Baziotis   Function *ScopeFn = IRP.getAnchorScope();
78326e60f06SKristina Brooks   IRPosition::Kind PK = IRP.getPositionKind();
784aade782aSJohannes Doerfert 
785aade782aSJohannes Doerfert   // In the following some generic code that will manifest attributes in
786aade782aSJohannes Doerfert   // DeducedAttrs if they improve the current IR. Due to the different
787aade782aSJohannes Doerfert   // annotation positions we use the underlying AttributeList interface.
788aade782aSJohannes Doerfert 
789fb69f768SJohannes Doerfert   AttributeList Attrs;
790fb69f768SJohannes Doerfert   switch (PK) {
791710ebb03SJohannes Doerfert   case IRPosition::IRP_INVALID:
792710ebb03SJohannes Doerfert   case IRPosition::IRP_FLOAT:
79312cbbab9SJohannes Doerfert     return ChangeStatus::UNCHANGED;
794fb69f768SJohannes Doerfert   case IRPosition::IRP_ARGUMENT:
795fb69f768SJohannes Doerfert   case IRPosition::IRP_FUNCTION:
796fb69f768SJohannes Doerfert   case IRPosition::IRP_RETURNED:
797710ebb03SJohannes Doerfert     Attrs = ScopeFn->getAttributes();
798aade782aSJohannes Doerfert     break;
799710ebb03SJohannes Doerfert   case IRPosition::IRP_CALL_SITE:
800710ebb03SJohannes Doerfert   case IRPosition::IRP_CALL_SITE_RETURNED:
801fb69f768SJohannes Doerfert   case IRPosition::IRP_CALL_SITE_ARGUMENT:
8025f6d93c7SCraig Topper     Attrs = cast<CallBase>(IRP.getAnchorValue()).getAttributes();
803aade782aSJohannes Doerfert     break;
804aade782aSJohannes Doerfert   }
805aade782aSJohannes Doerfert 
80612cbbab9SJohannes Doerfert   ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
807710ebb03SJohannes Doerfert   LLVMContext &Ctx = IRP.getAnchorValue().getContext();
808aade782aSJohannes Doerfert   for (const Attribute &Attr : DeducedAttrs) {
80996709823SKuter Dinel     if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx(), ForceReplace))
810aade782aSJohannes Doerfert       continue;
811aade782aSJohannes Doerfert 
812aade782aSJohannes Doerfert     HasChanged = ChangeStatus::CHANGED;
813aade782aSJohannes Doerfert   }
814aade782aSJohannes Doerfert 
815aade782aSJohannes Doerfert   if (HasChanged == ChangeStatus::UNCHANGED)
816aade782aSJohannes Doerfert     return HasChanged;
817aade782aSJohannes Doerfert 
818fb69f768SJohannes Doerfert   switch (PK) {
819fb69f768SJohannes Doerfert   case IRPosition::IRP_ARGUMENT:
820fb69f768SJohannes Doerfert   case IRPosition::IRP_FUNCTION:
821fb69f768SJohannes Doerfert   case IRPosition::IRP_RETURNED:
822710ebb03SJohannes Doerfert     ScopeFn->setAttributes(Attrs);
823aade782aSJohannes Doerfert     break;
824710ebb03SJohannes Doerfert   case IRPosition::IRP_CALL_SITE:
825710ebb03SJohannes Doerfert   case IRPosition::IRP_CALL_SITE_RETURNED:
826fb69f768SJohannes Doerfert   case IRPosition::IRP_CALL_SITE_ARGUMENT:
8275f6d93c7SCraig Topper     cast<CallBase>(IRP.getAnchorValue()).setAttributes(Attrs);
8284395b31dSJohannes Doerfert     break;
829710ebb03SJohannes Doerfert   case IRPosition::IRP_INVALID:
8304395b31dSJohannes Doerfert   case IRPosition::IRP_FLOAT:
831710ebb03SJohannes Doerfert     break;
832aade782aSJohannes Doerfert   }
833aade782aSJohannes Doerfert 
834aade782aSJohannes Doerfert   return HasChanged;
835aade782aSJohannes Doerfert }
836aade782aSJohannes Doerfert 
8378228153fSJohannes Doerfert const IRPosition IRPosition::EmptyKey(DenseMapInfo<void *>::getEmptyKey());
8388228153fSJohannes Doerfert const IRPosition
8398228153fSJohannes Doerfert     IRPosition::TombstoneKey(DenseMapInfo<void *>::getTombstoneKey());
840710ebb03SJohannes Doerfert 
SubsumingPositionIterator(const IRPosition & IRP)841710ebb03SJohannes Doerfert SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
842710ebb03SJohannes Doerfert   IRPositions.emplace_back(IRP);
843710ebb03SJohannes Doerfert 
844c0ab901bSJohannes Doerfert   // Helper to determine if operand bundles on a call site are benin or
845c0ab901bSJohannes Doerfert   // potentially problematic. We handle only llvm.assume for now.
846c0ab901bSJohannes Doerfert   auto CanIgnoreOperandBundles = [](const CallBase &CB) {
847c0ab901bSJohannes Doerfert     return (isa<IntrinsicInst>(CB) &&
848c0ab901bSJohannes Doerfert             cast<IntrinsicInst>(CB).getIntrinsicID() == Intrinsic ::assume);
849c0ab901bSJohannes Doerfert   };
850c0ab901bSJohannes Doerfert 
8515f6d93c7SCraig Topper   const auto *CB = dyn_cast<CallBase>(&IRP.getAnchorValue());
852710ebb03SJohannes Doerfert   switch (IRP.getPositionKind()) {
853710ebb03SJohannes Doerfert   case IRPosition::IRP_INVALID:
854710ebb03SJohannes Doerfert   case IRPosition::IRP_FLOAT:
855710ebb03SJohannes Doerfert   case IRPosition::IRP_FUNCTION:
856710ebb03SJohannes Doerfert     return;
857710ebb03SJohannes Doerfert   case IRPosition::IRP_ARGUMENT:
858710ebb03SJohannes Doerfert   case IRPosition::IRP_RETURNED:
859a650d555SStefanos Baziotis     IRPositions.emplace_back(IRPosition::function(*IRP.getAnchorScope()));
860710ebb03SJohannes Doerfert     return;
861710ebb03SJohannes Doerfert   case IRPosition::IRP_CALL_SITE:
8625f6d93c7SCraig Topper     assert(CB && "Expected call site!");
863710ebb03SJohannes Doerfert     // TODO: We need to look at the operand bundles similar to the redirection
864710ebb03SJohannes Doerfert     //       in CallBase.
865c0ab901bSJohannes Doerfert     if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB))
8665f6d93c7SCraig Topper       if (const Function *Callee = CB->getCalledFunction())
867710ebb03SJohannes Doerfert         IRPositions.emplace_back(IRPosition::function(*Callee));
868710ebb03SJohannes Doerfert     return;
869710ebb03SJohannes Doerfert   case IRPosition::IRP_CALL_SITE_RETURNED:
8705f6d93c7SCraig Topper     assert(CB && "Expected call site!");
871710ebb03SJohannes Doerfert     // TODO: We need to look at the operand bundles similar to the redirection
872710ebb03SJohannes Doerfert     //       in CallBase.
873c0ab901bSJohannes Doerfert     if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
8745f6d93c7SCraig Topper       if (const Function *Callee = CB->getCalledFunction()) {
875710ebb03SJohannes Doerfert         IRPositions.emplace_back(IRPosition::returned(*Callee));
876710ebb03SJohannes Doerfert         IRPositions.emplace_back(IRPosition::function(*Callee));
877f8ad7357SJohannes Doerfert         for (const Argument &Arg : Callee->args())
878f8ad7357SJohannes Doerfert           if (Arg.hasReturnedAttr()) {
879f8ad7357SJohannes Doerfert             IRPositions.emplace_back(
8805f6d93c7SCraig Topper                 IRPosition::callsite_argument(*CB, Arg.getArgNo()));
881f8ad7357SJohannes Doerfert             IRPositions.emplace_back(
8825f6d93c7SCraig Topper                 IRPosition::value(*CB->getArgOperand(Arg.getArgNo())));
883f8ad7357SJohannes Doerfert             IRPositions.emplace_back(IRPosition::argument(Arg));
884f8ad7357SJohannes Doerfert           }
885710ebb03SJohannes Doerfert       }
886710ebb03SJohannes Doerfert     }
8875f6d93c7SCraig Topper     IRPositions.emplace_back(IRPosition::callsite_function(*CB));
888710ebb03SJohannes Doerfert     return;
889710ebb03SJohannes Doerfert   case IRPosition::IRP_CALL_SITE_ARGUMENT: {
890cefd2a2cSJohannes Doerfert     assert(CB && "Expected call site!");
891710ebb03SJohannes Doerfert     // TODO: We need to look at the operand bundles similar to the redirection
892710ebb03SJohannes Doerfert     //       in CallBase.
893c0ab901bSJohannes Doerfert     if (!CB->hasOperandBundles() || CanIgnoreOperandBundles(*CB)) {
8945f6d93c7SCraig Topper       const Function *Callee = CB->getCalledFunction();
895cefd2a2cSJohannes Doerfert       if (Callee) {
896cefd2a2cSJohannes Doerfert         if (Argument *Arg = IRP.getAssociatedArgument())
897cefd2a2cSJohannes Doerfert           IRPositions.emplace_back(IRPosition::argument(*Arg));
898710ebb03SJohannes Doerfert         IRPositions.emplace_back(IRPosition::function(*Callee));
899710ebb03SJohannes Doerfert       }
900cefd2a2cSJohannes Doerfert     }
901710ebb03SJohannes Doerfert     IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
902710ebb03SJohannes Doerfert     return;
903710ebb03SJohannes Doerfert   }
904710ebb03SJohannes Doerfert   }
905710ebb03SJohannes Doerfert }
906710ebb03SJohannes Doerfert 
hasAttr(ArrayRef<Attribute::AttrKind> AKs,bool IgnoreSubsumingPositions,Attributor * A) const9071097fab1SJohannes Doerfert bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
9085699d08bSJohannes Doerfert                          bool IgnoreSubsumingPositions, Attributor *A) const {
9096185fb13SJohannes Doerfert   SmallVector<Attribute, 4> Attrs;
9101097fab1SJohannes Doerfert   for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
911710ebb03SJohannes Doerfert     for (Attribute::AttrKind AK : AKs)
9126185fb13SJohannes Doerfert       if (EquivIRP.getAttrsFromIRAttr(AK, Attrs))
913710ebb03SJohannes Doerfert         return true;
9141097fab1SJohannes Doerfert     // The first position returned by the SubsumingPositionIterator is
9151097fab1SJohannes Doerfert     // always the position itself. If we ignore subsuming positions we
9161097fab1SJohannes Doerfert     // are done after the first iteration.
9171097fab1SJohannes Doerfert     if (IgnoreSubsumingPositions)
9181097fab1SJohannes Doerfert       break;
9191097fab1SJohannes Doerfert   }
9205699d08bSJohannes Doerfert   if (A)
9215699d08bSJohannes Doerfert     for (Attribute::AttrKind AK : AKs)
9225699d08bSJohannes Doerfert       if (getAttrsFromAssumes(AK, Attrs, *A))
9235699d08bSJohannes Doerfert         return true;
924710ebb03SJohannes Doerfert   return false;
925710ebb03SJohannes Doerfert }
926710ebb03SJohannes Doerfert 
getAttrs(ArrayRef<Attribute::AttrKind> AKs,SmallVectorImpl<Attribute> & Attrs,bool IgnoreSubsumingPositions,Attributor * A) const927710ebb03SJohannes Doerfert void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
9286abd01e4SJohannes Doerfert                           SmallVectorImpl<Attribute> &Attrs,
9295699d08bSJohannes Doerfert                           bool IgnoreSubsumingPositions, Attributor *A) const {
9306abd01e4SJohannes Doerfert   for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
9316185fb13SJohannes Doerfert     for (Attribute::AttrKind AK : AKs)
9326185fb13SJohannes Doerfert       EquivIRP.getAttrsFromIRAttr(AK, Attrs);
9336abd01e4SJohannes Doerfert     // The first position returned by the SubsumingPositionIterator is
9346abd01e4SJohannes Doerfert     // always the position itself. If we ignore subsuming positions we
9356abd01e4SJohannes Doerfert     // are done after the first iteration.
9366abd01e4SJohannes Doerfert     if (IgnoreSubsumingPositions)
9376abd01e4SJohannes Doerfert       break;
9386abd01e4SJohannes Doerfert   }
9395699d08bSJohannes Doerfert   if (A)
9405699d08bSJohannes Doerfert     for (Attribute::AttrKind AK : AKs)
9415699d08bSJohannes Doerfert       getAttrsFromAssumes(AK, Attrs, *A);
942710ebb03SJohannes Doerfert }
943710ebb03SJohannes Doerfert 
getAttrsFromIRAttr(Attribute::AttrKind AK,SmallVectorImpl<Attribute> & Attrs) const9446185fb13SJohannes Doerfert bool IRPosition::getAttrsFromIRAttr(Attribute::AttrKind AK,
9456185fb13SJohannes Doerfert                                     SmallVectorImpl<Attribute> &Attrs) const {
9466185fb13SJohannes Doerfert   if (getPositionKind() == IRP_INVALID || getPositionKind() == IRP_FLOAT)
9476185fb13SJohannes Doerfert     return false;
9486185fb13SJohannes Doerfert 
9496185fb13SJohannes Doerfert   AttributeList AttrList;
9505f6d93c7SCraig Topper   if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
9515f6d93c7SCraig Topper     AttrList = CB->getAttributes();
9526185fb13SJohannes Doerfert   else
9536185fb13SJohannes Doerfert     AttrList = getAssociatedFunction()->getAttributes();
9546185fb13SJohannes Doerfert 
95552e6d70cSArthur Eubanks   bool HasAttr = AttrList.hasAttributeAtIndex(getAttrIdx(), AK);
9566185fb13SJohannes Doerfert   if (HasAttr)
95752e6d70cSArthur Eubanks     Attrs.push_back(AttrList.getAttributeAtIndex(getAttrIdx(), AK));
9586185fb13SJohannes Doerfert   return HasAttr;
9596185fb13SJohannes Doerfert }
9606185fb13SJohannes Doerfert 
getAttrsFromAssumes(Attribute::AttrKind AK,SmallVectorImpl<Attribute> & Attrs,Attributor & A) const9615699d08bSJohannes Doerfert bool IRPosition::getAttrsFromAssumes(Attribute::AttrKind AK,
9625699d08bSJohannes Doerfert                                      SmallVectorImpl<Attribute> &Attrs,
9635699d08bSJohannes Doerfert                                      Attributor &A) const {
9645699d08bSJohannes Doerfert   assert(getPositionKind() != IRP_INVALID && "Did expect a valid position!");
9655699d08bSJohannes Doerfert   Value &AssociatedValue = getAssociatedValue();
9665699d08bSJohannes Doerfert 
9675699d08bSJohannes Doerfert   const Assume2KnowledgeMap &A2K =
9685699d08bSJohannes Doerfert       A.getInfoCache().getKnowledgeMap().lookup({&AssociatedValue, AK});
9695699d08bSJohannes Doerfert 
9705699d08bSJohannes Doerfert   // Check if we found any potential assume use, if not we don't need to create
9715699d08bSJohannes Doerfert   // explorer iterators.
9725699d08bSJohannes Doerfert   if (A2K.empty())
9735699d08bSJohannes Doerfert     return false;
9745699d08bSJohannes Doerfert 
9755699d08bSJohannes Doerfert   LLVMContext &Ctx = AssociatedValue.getContext();
9765699d08bSJohannes Doerfert   unsigned AttrsSize = Attrs.size();
9775699d08bSJohannes Doerfert   MustBeExecutedContextExplorer &Explorer =
9785699d08bSJohannes Doerfert       A.getInfoCache().getMustBeExecutedContextExplorer();
9795699d08bSJohannes Doerfert   auto EIt = Explorer.begin(getCtxI()), EEnd = Explorer.end(getCtxI());
9805699d08bSJohannes Doerfert   for (auto &It : A2K)
9815699d08bSJohannes Doerfert     if (Explorer.findInContextOf(It.first, EIt, EEnd))
9825699d08bSJohannes Doerfert       Attrs.push_back(Attribute::get(Ctx, AK, It.second.Max));
9835699d08bSJohannes Doerfert   return AttrsSize != Attrs.size();
9845699d08bSJohannes Doerfert }
9855699d08bSJohannes Doerfert 
verify()986710ebb03SJohannes Doerfert void IRPosition::verify() {
987f20ff4b1SJohannes Doerfert #ifdef EXPENSIVE_CHECKS
9888228153fSJohannes Doerfert   switch (getPositionKind()) {
989710ebb03SJohannes Doerfert   case IRP_INVALID:
990d75c9e61Skuterd     assert((CBContext == nullptr) &&
991d75c9e61Skuterd            "Invalid position must not have CallBaseContext!");
9928228153fSJohannes Doerfert     assert(!Enc.getOpaqueValue() &&
9938228153fSJohannes Doerfert            "Expected a nullptr for an invalid position!");
9948228153fSJohannes Doerfert     return;
995710ebb03SJohannes Doerfert   case IRP_FLOAT:
9963b8ffe66SJohannes Doerfert     assert((!isa<Argument>(&getAssociatedValue())) &&
9973b8ffe66SJohannes Doerfert            "Expected specialized kind for argument values!");
9988228153fSJohannes Doerfert     return;
999710ebb03SJohannes Doerfert   case IRP_RETURNED:
10008228153fSJohannes Doerfert     assert(isa<Function>(getAsValuePtr()) &&
1001710ebb03SJohannes Doerfert            "Expected function for a 'returned' position!");
10028228153fSJohannes Doerfert     assert(getAsValuePtr() == &getAssociatedValue() &&
10038228153fSJohannes Doerfert            "Associated value mismatch!");
10048228153fSJohannes Doerfert     return;
1005710ebb03SJohannes Doerfert   case IRP_CALL_SITE_RETURNED:
1006d75c9e61Skuterd     assert((CBContext == nullptr) &&
1007d75c9e61Skuterd            "'call site returned' position must not have CallBaseContext!");
10088228153fSJohannes Doerfert     assert((isa<CallBase>(getAsValuePtr())) &&
1009710ebb03SJohannes Doerfert            "Expected call base for 'call site returned' position!");
10108228153fSJohannes Doerfert     assert(getAsValuePtr() == &getAssociatedValue() &&
10118228153fSJohannes Doerfert            "Associated value mismatch!");
10128228153fSJohannes Doerfert     return;
1013710ebb03SJohannes Doerfert   case IRP_CALL_SITE:
1014d75c9e61Skuterd     assert((CBContext == nullptr) &&
1015d75c9e61Skuterd            "'call site function' position must not have CallBaseContext!");
10168228153fSJohannes Doerfert     assert((isa<CallBase>(getAsValuePtr())) &&
1017710ebb03SJohannes Doerfert            "Expected call base for 'call site function' position!");
10188228153fSJohannes Doerfert     assert(getAsValuePtr() == &getAssociatedValue() &&
10198228153fSJohannes Doerfert            "Associated value mismatch!");
10208228153fSJohannes Doerfert     return;
1021710ebb03SJohannes Doerfert   case IRP_FUNCTION:
10228228153fSJohannes Doerfert     assert(isa<Function>(getAsValuePtr()) &&
1023710ebb03SJohannes Doerfert            "Expected function for a 'function' position!");
10248228153fSJohannes Doerfert     assert(getAsValuePtr() == &getAssociatedValue() &&
10258228153fSJohannes Doerfert            "Associated value mismatch!");
10268228153fSJohannes Doerfert     return;
10278228153fSJohannes Doerfert   case IRP_ARGUMENT:
10288228153fSJohannes Doerfert     assert(isa<Argument>(getAsValuePtr()) &&
10298228153fSJohannes Doerfert            "Expected argument for a 'argument' position!");
10308228153fSJohannes Doerfert     assert(getAsValuePtr() == &getAssociatedValue() &&
10318228153fSJohannes Doerfert            "Associated value mismatch!");
10328228153fSJohannes Doerfert     return;
10338228153fSJohannes Doerfert   case IRP_CALL_SITE_ARGUMENT: {
1034d75c9e61Skuterd     assert((CBContext == nullptr) &&
1035d75c9e61Skuterd            "'call site argument' position must not have CallBaseContext!");
10368228153fSJohannes Doerfert     Use *U = getAsUsePtr();
1037e550dfa4SSjoerd Meijer     (void)U; // Silence unused variable warning.
10388228153fSJohannes Doerfert     assert(U && "Expected use for a 'call site argument' position!");
10398228153fSJohannes Doerfert     assert(isa<CallBase>(U->getUser()) &&
10408228153fSJohannes Doerfert            "Expected call base user for a 'call site argument' position!");
10418228153fSJohannes Doerfert     assert(cast<CallBase>(U->getUser())->isArgOperand(U) &&
10428228153fSJohannes Doerfert            "Expected call base argument operand for a 'call site argument' "
10438228153fSJohannes Doerfert            "position");
10448228153fSJohannes Doerfert     assert(cast<CallBase>(U->getUser())->getArgOperandNo(U) ==
1045cefd2a2cSJohannes Doerfert                unsigned(getCallSiteArgNo()) &&
10468228153fSJohannes Doerfert            "Argument number mismatch!");
10478228153fSJohannes Doerfert     assert(U->get() == &getAssociatedValue() && "Associated value mismatch!");
10488228153fSJohannes Doerfert     return;
10498228153fSJohannes Doerfert   }
1050710ebb03SJohannes Doerfert   }
1051f20ff4b1SJohannes Doerfert #endif
1052710ebb03SJohannes Doerfert }
1053710ebb03SJohannes Doerfert 
10540985554bSJohannes Doerfert Optional<Constant *>
getAssumedConstant(const IRPosition & IRP,const AbstractAttribute & AA,bool & UsedAssumedInformation)1055c819266eSJohannes Doerfert Attributor::getAssumedConstant(const IRPosition &IRP,
1056c819266eSJohannes Doerfert                                const AbstractAttribute &AA,
10570985554bSJohannes Doerfert                                bool &UsedAssumedInformation) {
1058d9659bf6SJohannes Doerfert   // First check all callbacks provided by outside AAs. If any of them returns
1059d9659bf6SJohannes Doerfert   // a non-null value that is different from the associated value, or None, we
1060982053e8SJohannes Doerfert   // assume it's simplified.
10613dca8396SJohannes Doerfert   for (auto &CB : SimplificationCallbacks.lookup(IRP)) {
1062d9659bf6SJohannes Doerfert     Optional<Value *> SimplifiedV = CB(IRP, &AA, UsedAssumedInformation);
1063e0e687a6SKazu Hirata     if (!SimplifiedV)
1064d9659bf6SJohannes Doerfert       return llvm::None;
1065c819266eSJohannes Doerfert     if (isa_and_nonnull<Constant>(*SimplifiedV))
1066d9659bf6SJohannes Doerfert       return cast<Constant>(*SimplifiedV);
1067c819266eSJohannes Doerfert     return nullptr;
1068d9659bf6SJohannes Doerfert   }
1069ae10b8a5SJohannes Doerfert   if (auto *C = dyn_cast<Constant>(&IRP.getAssociatedValue()))
1070ae10b8a5SJohannes Doerfert     return C;
1071bf789b19SJohannes Doerfert   SmallVector<AA::ValueAndContext> Values;
1072bf789b19SJohannes Doerfert   if (getAssumedSimplifiedValues(IRP, &AA, Values,
1073bf789b19SJohannes Doerfert                                  AA::ValueScope::Interprocedural,
1074bf789b19SJohannes Doerfert                                  UsedAssumedInformation)) {
1075bf789b19SJohannes Doerfert     if (Values.empty())
1076ef4febd8SHideto Ueno       return llvm::None;
1077bf789b19SJohannes Doerfert     if (auto *C = dyn_cast_or_null<Constant>(
1078bf789b19SJohannes Doerfert             AAPotentialValues::getSingleValue(*this, AA, IRP, Values)))
1079bf789b19SJohannes Doerfert       return C;
1080ef4febd8SHideto Ueno   }
1081bf789b19SJohannes Doerfert   return nullptr;
1082188f9a34SHideto Ueno }
1083aade782aSJohannes Doerfert 
getAssumedSimplified(const IRPosition & IRP,const AbstractAttribute * AA,bool & UsedAssumedInformation,AA::ValueScope S)1084bf789b19SJohannes Doerfert Optional<Value *> Attributor::getAssumedSimplified(const IRPosition &IRP,
1085666dc6f1SJohannes Doerfert                                                    const AbstractAttribute *AA,
1086bf789b19SJohannes Doerfert                                                    bool &UsedAssumedInformation,
1087bf789b19SJohannes Doerfert                                                    AA::ValueScope S) {
1088666dc6f1SJohannes Doerfert   // First check all callbacks provided by outside AAs. If any of them returns
1089666dc6f1SJohannes Doerfert   // a non-null value that is different from the associated value, or None, we
1090982053e8SJohannes Doerfert   // assume it's simplified.
10913dca8396SJohannes Doerfert   for (auto &CB : SimplificationCallbacks.lookup(IRP))
10926ca96935SJohannes Doerfert     return CB(IRP, AA, UsedAssumedInformation);
1093666dc6f1SJohannes Doerfert 
1094bf789b19SJohannes Doerfert   SmallVector<AA::ValueAndContext> Values;
1095bf789b19SJohannes Doerfert   if (!getAssumedSimplifiedValues(IRP, AA, Values, S, UsedAssumedInformation))
1096bf789b19SJohannes Doerfert     return &IRP.getAssociatedValue();
1097bf789b19SJohannes Doerfert   if (Values.empty())
1098f6e0c05eSJohannes Doerfert     return llvm::None;
1099f6e0c05eSJohannes Doerfert   if (AA)
1100bf789b19SJohannes Doerfert     if (Value *V = AAPotentialValues::getSingleValue(*this, *AA, IRP, Values))
1101bf789b19SJohannes Doerfert       return V;
1102bf789b19SJohannes Doerfert   if (IRP.getPositionKind() == IRPosition::IRP_RETURNED ||
1103bf789b19SJohannes Doerfert       IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_RETURNED)
1104bf789b19SJohannes Doerfert     return nullptr;
1105bf789b19SJohannes Doerfert   return &IRP.getAssociatedValue();
1106f17639eaSJohannes Doerfert }
1107bf789b19SJohannes Doerfert 
getAssumedSimplifiedValues(const IRPosition & IRP,const AbstractAttribute * AA,SmallVectorImpl<AA::ValueAndContext> & Values,AA::ValueScope S,bool & UsedAssumedInformation)1108bf789b19SJohannes Doerfert bool Attributor::getAssumedSimplifiedValues(
1109bf789b19SJohannes Doerfert     const IRPosition &IRP, const AbstractAttribute *AA,
1110bf789b19SJohannes Doerfert     SmallVectorImpl<AA::ValueAndContext> &Values, AA::ValueScope S,
1111bf789b19SJohannes Doerfert     bool &UsedAssumedInformation) {
1112bf789b19SJohannes Doerfert   // First check all callbacks provided by outside AAs. If any of them returns
1113bf789b19SJohannes Doerfert   // a non-null value that is different from the associated value, or None, we
1114bf789b19SJohannes Doerfert   // assume it's simplified.
1115bf789b19SJohannes Doerfert   const auto &SimplificationCBs = SimplificationCallbacks.lookup(IRP);
1116bf789b19SJohannes Doerfert   for (auto &CB : SimplificationCBs) {
1117bf789b19SJohannes Doerfert     Optional<Value *> CBResult = CB(IRP, AA, UsedAssumedInformation);
111841ae78eaSKazu Hirata     if (!CBResult.has_value())
1119bf789b19SJohannes Doerfert       continue;
11200387da6fSKazu Hirata     Value *V = CBResult.value();
1121bf789b19SJohannes Doerfert     if (!V)
1122bf789b19SJohannes Doerfert       return false;
1123bf789b19SJohannes Doerfert     if ((S & AA::ValueScope::Interprocedural) ||
1124bf789b19SJohannes Doerfert         AA::isValidInScope(*V, IRP.getAnchorScope()))
1125bf789b19SJohannes Doerfert       Values.push_back(AA::ValueAndContext{*V, nullptr});
1126bf789b19SJohannes Doerfert     else
1127bf789b19SJohannes Doerfert       return false;
1128bf789b19SJohannes Doerfert   }
1129bf789b19SJohannes Doerfert   if (!SimplificationCBs.empty())
1130bf789b19SJohannes Doerfert     return true;
1131bf789b19SJohannes Doerfert 
1132bf789b19SJohannes Doerfert   // If no high-level/outside simplification occurred, use AAPotentialValues.
1133bf789b19SJohannes Doerfert   const auto &PotentialValuesAA =
1134bf789b19SJohannes Doerfert       getOrCreateAAFor<AAPotentialValues>(IRP, AA, DepClassTy::OPTIONAL);
1135bf789b19SJohannes Doerfert   if (!PotentialValuesAA.getAssumedSimplifiedValues(*this, Values, S))
1136bf789b19SJohannes Doerfert     return false;
1137bf789b19SJohannes Doerfert   UsedAssumedInformation |= !PotentialValuesAA.isAtFixpoint();
1138bf789b19SJohannes Doerfert   return true;
1139666dc6f1SJohannes Doerfert }
1140666dc6f1SJohannes Doerfert 
translateArgumentToCallSiteContent(Optional<Value * > V,CallBase & CB,const AbstractAttribute & AA,bool & UsedAssumedInformation)11415ef18e24SJohannes Doerfert Optional<Value *> Attributor::translateArgumentToCallSiteContent(
11425ef18e24SJohannes Doerfert     Optional<Value *> V, CallBase &CB, const AbstractAttribute &AA,
11435ef18e24SJohannes Doerfert     bool &UsedAssumedInformation) {
1144e0e687a6SKazu Hirata   if (!V)
11455ef18e24SJohannes Doerfert     return V;
11465ef18e24SJohannes Doerfert   if (*V == nullptr || isa<Constant>(*V))
11475ef18e24SJohannes Doerfert     return V;
11485ef18e24SJohannes Doerfert   if (auto *Arg = dyn_cast<Argument>(*V))
114928c78a9eSJohannes Doerfert     if (CB.getCalledFunction() == Arg->getParent())
11505ef18e24SJohannes Doerfert       if (!Arg->hasPointeeInMemoryValueAttr())
11515ef18e24SJohannes Doerfert         return getAssumedSimplified(
11525ef18e24SJohannes Doerfert             IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,
1153bf789b19SJohannes Doerfert             UsedAssumedInformation, AA::Intraprocedural);
11545ef18e24SJohannes Doerfert   return nullptr;
11555ef18e24SJohannes Doerfert }
11565ef18e24SJohannes Doerfert 
~Attributor()115741f2a57dSJohannes Doerfert Attributor::~Attributor() {
115841f2a57dSJohannes Doerfert   // The abstract attributes are allocated via the BumpPtrAllocator Allocator,
115941f2a57dSJohannes Doerfert   // thus we cannot delete them. We can, and want to, destruct them though.
11605ee07dc5SLuofan Chen   for (auto &DepAA : DG.SyntheticRoot.Deps) {
11615ee07dc5SLuofan Chen     AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());
116241f2a57dSJohannes Doerfert     AA->~AbstractAttribute();
116341f2a57dSJohannes Doerfert   }
11645ee07dc5SLuofan Chen }
116541f2a57dSJohannes Doerfert 
isAssumedDead(const AbstractAttribute & AA,const AAIsDead * FnLivenessAA,bool & UsedAssumedInformation,bool CheckBBLivenessOnly,DepClassTy DepClass)11669a1a1f96SJohannes Doerfert bool Attributor::isAssumedDead(const AbstractAttribute &AA,
116723f41f16SJohannes Doerfert                                const AAIsDead *FnLivenessAA,
1168792aac98SJohannes Doerfert                                bool &UsedAssumedInformation,
116923f41f16SJohannes Doerfert                                bool CheckBBLivenessOnly, DepClassTy DepClass) {
117023f41f16SJohannes Doerfert   const IRPosition &IRP = AA.getIRPosition();
117123f41f16SJohannes Doerfert   if (!Functions.count(IRP.getAnchorScope()))
11729a1a1f96SJohannes Doerfert     return false;
1173792aac98SJohannes Doerfert   return isAssumedDead(IRP, &AA, FnLivenessAA, UsedAssumedInformation,
1174792aac98SJohannes Doerfert                        CheckBBLivenessOnly, DepClass);
117523f41f16SJohannes Doerfert }
11769a1a1f96SJohannes Doerfert 
isAssumedDead(const Use & U,const AbstractAttribute * QueryingAA,const AAIsDead * FnLivenessAA,bool & UsedAssumedInformation,bool CheckBBLivenessOnly,DepClassTy DepClass)117723f41f16SJohannes Doerfert bool Attributor::isAssumedDead(const Use &U,
117823f41f16SJohannes Doerfert                                const AbstractAttribute *QueryingAA,
117923f41f16SJohannes Doerfert                                const AAIsDead *FnLivenessAA,
1180792aac98SJohannes Doerfert                                bool &UsedAssumedInformation,
118123f41f16SJohannes Doerfert                                bool CheckBBLivenessOnly, DepClassTy DepClass) {
118223f41f16SJohannes Doerfert   Instruction *UserI = dyn_cast<Instruction>(U.getUser());
118323f41f16SJohannes Doerfert   if (!UserI)
118423f41f16SJohannes Doerfert     return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,
1185792aac98SJohannes Doerfert                          UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
118623f41f16SJohannes Doerfert 
11875f6d93c7SCraig Topper   if (auto *CB = dyn_cast<CallBase>(UserI)) {
118823f41f16SJohannes Doerfert     // For call site argument uses we can check if the argument is
118923f41f16SJohannes Doerfert     // unused/dead.
11905f6d93c7SCraig Topper     if (CB->isArgOperand(&U)) {
119123f41f16SJohannes Doerfert       const IRPosition &CSArgPos =
11925f6d93c7SCraig Topper           IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
119323f41f16SJohannes Doerfert       return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,
1194792aac98SJohannes Doerfert                            UsedAssumedInformation, CheckBBLivenessOnly,
1195792aac98SJohannes Doerfert                            DepClass);
119623f41f16SJohannes Doerfert     }
119723f41f16SJohannes Doerfert   } else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
119823f41f16SJohannes Doerfert     const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
1199792aac98SJohannes Doerfert     return isAssumedDead(RetPos, QueryingAA, FnLivenessAA,
1200792aac98SJohannes Doerfert                          UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
120123f41f16SJohannes Doerfert   } else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
120223f41f16SJohannes Doerfert     BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
120323f41f16SJohannes Doerfert     return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,
1204792aac98SJohannes Doerfert                          UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
1205c42aa1beSJohannes Doerfert   } else if (StoreInst *SI = dyn_cast<StoreInst>(UserI)) {
1206c42aa1beSJohannes Doerfert     if (!CheckBBLivenessOnly && SI->getPointerOperand() != U.get()) {
1207c42aa1beSJohannes Doerfert       const IRPosition IRP = IRPosition::inst(*SI);
1208c42aa1beSJohannes Doerfert       const AAIsDead &IsDeadAA =
1209c42aa1beSJohannes Doerfert           getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);
1210c42aa1beSJohannes Doerfert       if (IsDeadAA.isRemovableStore()) {
1211c42aa1beSJohannes Doerfert         if (QueryingAA)
1212c42aa1beSJohannes Doerfert           recordDependence(IsDeadAA, *QueryingAA, DepClass);
1213c42aa1beSJohannes Doerfert         if (!IsDeadAA.isKnown(AAIsDead::IS_REMOVABLE))
1214c42aa1beSJohannes Doerfert           UsedAssumedInformation = true;
1215c42aa1beSJohannes Doerfert         return true;
1216c42aa1beSJohannes Doerfert       }
1217c42aa1beSJohannes Doerfert     }
121823f41f16SJohannes Doerfert   }
121923f41f16SJohannes Doerfert 
1220a1db0e52SJohannes Doerfert   return isAssumedDead(IRPosition::inst(*UserI), QueryingAA, FnLivenessAA,
1221792aac98SJohannes Doerfert                        UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
122223f41f16SJohannes Doerfert }
122323f41f16SJohannes Doerfert 
isAssumedDead(const Instruction & I,const AbstractAttribute * QueryingAA,const AAIsDead * FnLivenessAA,bool & UsedAssumedInformation,bool CheckBBLivenessOnly,DepClassTy DepClass)122423f41f16SJohannes Doerfert bool Attributor::isAssumedDead(const Instruction &I,
122523f41f16SJohannes Doerfert                                const AbstractAttribute *QueryingAA,
122623f41f16SJohannes Doerfert                                const AAIsDead *FnLivenessAA,
1227792aac98SJohannes Doerfert                                bool &UsedAssumedInformation,
122823f41f16SJohannes Doerfert                                bool CheckBBLivenessOnly, DepClassTy DepClass) {
122964ef29bcSKuter Dinel   const IRPosition::CallBaseContext *CBCtx =
123064ef29bcSKuter Dinel       QueryingAA ? QueryingAA->getCallBaseContext() : nullptr;
123164ef29bcSKuter Dinel 
12323f71b425SGiorgis Georgakoudis   if (ManifestAddedBlocks.contains(I.getParent()))
12333f71b425SGiorgis Georgakoudis     return false;
12343f71b425SGiorgis Georgakoudis 
12355011b4caSEvgenii Stepanov   if (!FnLivenessAA)
12365011b4caSEvgenii Stepanov     FnLivenessAA =
12375011b4caSEvgenii Stepanov         lookupAAFor<AAIsDead>(IRPosition::function(*I.getFunction(), CBCtx),
12385011b4caSEvgenii Stepanov                               QueryingAA, DepClassTy::NONE);
123926121ae4SStefan Stipanovic 
124023f41f16SJohannes Doerfert   // If we have a context instruction and a liveness AA we use it.
12415011b4caSEvgenii Stepanov   if (FnLivenessAA &&
12425011b4caSEvgenii Stepanov       FnLivenessAA->getIRPosition().getAnchorScope() == I.getFunction() &&
12435011b4caSEvgenii Stepanov       (CheckBBLivenessOnly ? FnLivenessAA->isAssumedDead(I.getParent())
12445011b4caSEvgenii Stepanov                            : FnLivenessAA->isAssumedDead(&I))) {
124523f41f16SJohannes Doerfert     if (QueryingAA)
124623f41f16SJohannes Doerfert       recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
1247792aac98SJohannes Doerfert     if (!FnLivenessAA->isKnownDead(&I))
1248792aac98SJohannes Doerfert       UsedAssumedInformation = true;
12499a1a1f96SJohannes Doerfert     return true;
12509a1a1f96SJohannes Doerfert   }
12519a1a1f96SJohannes Doerfert 
125223f41f16SJohannes Doerfert   if (CheckBBLivenessOnly)
125323f41f16SJohannes Doerfert     return false;
125423f41f16SJohannes Doerfert 
1255a1db0e52SJohannes Doerfert   const IRPosition IRP = IRPosition::inst(I, CBCtx);
1256a1db0e52SJohannes Doerfert   const AAIsDead &IsDeadAA =
1257a1db0e52SJohannes Doerfert       getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);
125823f41f16SJohannes Doerfert   // Don't check liveness for AAIsDead.
125923f41f16SJohannes Doerfert   if (QueryingAA == &IsDeadAA)
126023f41f16SJohannes Doerfert     return false;
126123f41f16SJohannes Doerfert 
126223f41f16SJohannes Doerfert   if (IsDeadAA.isAssumedDead()) {
126323f41f16SJohannes Doerfert     if (QueryingAA)
126423f41f16SJohannes Doerfert       recordDependence(IsDeadAA, *QueryingAA, DepClass);
1265792aac98SJohannes Doerfert     if (!IsDeadAA.isKnownDead())
1266792aac98SJohannes Doerfert       UsedAssumedInformation = true;
126723f41f16SJohannes Doerfert     return true;
126823f41f16SJohannes Doerfert   }
126923f41f16SJohannes Doerfert 
127023f41f16SJohannes Doerfert   return false;
127123f41f16SJohannes Doerfert }
127223f41f16SJohannes Doerfert 
isAssumedDead(const IRPosition & IRP,const AbstractAttribute * QueryingAA,const AAIsDead * FnLivenessAA,bool & UsedAssumedInformation,bool CheckBBLivenessOnly,DepClassTy DepClass)127323f41f16SJohannes Doerfert bool Attributor::isAssumedDead(const IRPosition &IRP,
127423f41f16SJohannes Doerfert                                const AbstractAttribute *QueryingAA,
127523f41f16SJohannes Doerfert                                const AAIsDead *FnLivenessAA,
1276792aac98SJohannes Doerfert                                bool &UsedAssumedInformation,
127723f41f16SJohannes Doerfert                                bool CheckBBLivenessOnly, DepClassTy DepClass) {
127823f41f16SJohannes Doerfert   Instruction *CtxI = IRP.getCtxI();
127923f41f16SJohannes Doerfert   if (CtxI &&
1280792aac98SJohannes Doerfert       isAssumedDead(*CtxI, QueryingAA, FnLivenessAA, UsedAssumedInformation,
128123f41f16SJohannes Doerfert                     /* CheckBBLivenessOnly */ true,
128223f41f16SJohannes Doerfert                     CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))
128323f41f16SJohannes Doerfert     return true;
128423f41f16SJohannes Doerfert 
128523f41f16SJohannes Doerfert   if (CheckBBLivenessOnly)
128623f41f16SJohannes Doerfert     return false;
128723f41f16SJohannes Doerfert 
128823f41f16SJohannes Doerfert   // If we haven't succeeded we query the specific liveness info for the IRP.
128923f41f16SJohannes Doerfert   const AAIsDead *IsDeadAA;
129023f41f16SJohannes Doerfert   if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE)
129123f41f16SJohannes Doerfert     IsDeadAA = &getOrCreateAAFor<AAIsDead>(
129223f41f16SJohannes Doerfert         IRPosition::callsite_returned(cast<CallBase>(IRP.getAssociatedValue())),
1293e592dad8SJohannes Doerfert         QueryingAA, DepClassTy::NONE);
129423f41f16SJohannes Doerfert   else
1295e592dad8SJohannes Doerfert     IsDeadAA = &getOrCreateAAFor<AAIsDead>(IRP, QueryingAA, DepClassTy::NONE);
129623f41f16SJohannes Doerfert   // Don't check liveness for AAIsDead.
129723f41f16SJohannes Doerfert   if (QueryingAA == IsDeadAA)
129823f41f16SJohannes Doerfert     return false;
129923f41f16SJohannes Doerfert 
130023f41f16SJohannes Doerfert   if (IsDeadAA->isAssumedDead()) {
130123f41f16SJohannes Doerfert     if (QueryingAA)
130223f41f16SJohannes Doerfert       recordDependence(*IsDeadAA, *QueryingAA, DepClass);
1303792aac98SJohannes Doerfert     if (!IsDeadAA->isKnownDead())
1304792aac98SJohannes Doerfert       UsedAssumedInformation = true;
130523f41f16SJohannes Doerfert     return true;
130623f41f16SJohannes Doerfert   }
130723f41f16SJohannes Doerfert 
130823f41f16SJohannes Doerfert   return false;
130923f41f16SJohannes Doerfert }
131023f41f16SJohannes Doerfert 
isAssumedDead(const BasicBlock & BB,const AbstractAttribute * QueryingAA,const AAIsDead * FnLivenessAA,DepClassTy DepClass)131196709823SKuter Dinel bool Attributor::isAssumedDead(const BasicBlock &BB,
131296709823SKuter Dinel                                const AbstractAttribute *QueryingAA,
131396709823SKuter Dinel                                const AAIsDead *FnLivenessAA,
131496709823SKuter Dinel                                DepClassTy DepClass) {
13155011b4caSEvgenii Stepanov   if (!FnLivenessAA)
13165011b4caSEvgenii Stepanov     FnLivenessAA = lookupAAFor<AAIsDead>(IRPosition::function(*BB.getParent()),
13175011b4caSEvgenii Stepanov                                          QueryingAA, DepClassTy::NONE);
131896709823SKuter Dinel   if (FnLivenessAA->isAssumedDead(&BB)) {
131996709823SKuter Dinel     if (QueryingAA)
132096709823SKuter Dinel       recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
132196709823SKuter Dinel     return true;
132296709823SKuter Dinel   }
132396709823SKuter Dinel 
132496709823SKuter Dinel   return false;
132596709823SKuter Dinel }
132696709823SKuter Dinel 
checkForAllUses(function_ref<bool (const Use &,bool &)> Pred,const AbstractAttribute & QueryingAA,const Value & V,bool CheckBBLivenessOnly,DepClassTy LivenessDepClass,bool IgnoreDroppableUses,function_ref<bool (const Use & OldU,const Use & NewU)> EquivalentUseCB)13276e2fcf85SJohannes Doerfert bool Attributor::checkForAllUses(
13286e2fcf85SJohannes Doerfert     function_ref<bool(const Use &, bool &)> Pred,
13296e2fcf85SJohannes Doerfert     const AbstractAttribute &QueryingAA, const Value &V,
13306e2fcf85SJohannes Doerfert     bool CheckBBLivenessOnly, DepClassTy LivenessDepClass,
13313e8c4366SJohannes Doerfert     bool IgnoreDroppableUses,
13326e2fcf85SJohannes Doerfert     function_ref<bool(const Use &OldU, const Use &NewU)> EquivalentUseCB) {
1333b2c76002SJohannes Doerfert 
1334b2c76002SJohannes Doerfert   // Check the trivial case first as it catches void values.
1335b2c76002SJohannes Doerfert   if (V.use_empty())
1336b2c76002SJohannes Doerfert     return true;
1337b2c76002SJohannes Doerfert 
1338cd4aab4aSJohannes Doerfert   const IRPosition &IRP = QueryingAA.getIRPosition();
1339cd4aab4aSJohannes Doerfert   SmallVector<const Use *, 16> Worklist;
1340cd4aab4aSJohannes Doerfert   SmallPtrSet<const Use *, 16> Visited;
1341cd4aab4aSJohannes Doerfert 
1342f84712f0SJohannes Doerfert   auto AddUsers = [&](const Value &V, const Use *OldUse) {
1343f84712f0SJohannes Doerfert     for (const Use &UU : V.uses()) {
1344f84712f0SJohannes Doerfert       if (OldUse && EquivalentUseCB && !EquivalentUseCB(*OldUse, UU)) {
1345f84712f0SJohannes Doerfert         LLVM_DEBUG(dbgs() << "[Attributor] Potential copy was "
1346f84712f0SJohannes Doerfert                              "rejected by the equivalence call back: "
1347f84712f0SJohannes Doerfert                           << *UU << "!\n");
1348f84712f0SJohannes Doerfert         return false;
1349f84712f0SJohannes Doerfert       }
1350f84712f0SJohannes Doerfert 
1351f84712f0SJohannes Doerfert       Worklist.push_back(&UU);
1352f84712f0SJohannes Doerfert     }
1353f84712f0SJohannes Doerfert     return true;
1354f84712f0SJohannes Doerfert   };
1355f84712f0SJohannes Doerfert 
1356f84712f0SJohannes Doerfert   AddUsers(V, /* OldUse */ nullptr);
1357cd4aab4aSJohannes Doerfert 
1358cd4aab4aSJohannes Doerfert   LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
1359cd4aab4aSJohannes Doerfert                     << " initial uses to check\n");
1360cd4aab4aSJohannes Doerfert 
1361cd4aab4aSJohannes Doerfert   const Function *ScopeFn = IRP.getAnchorScope();
1362cd4aab4aSJohannes Doerfert   const auto *LivenessAA =
1363cd4aab4aSJohannes Doerfert       ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
1364e592dad8SJohannes Doerfert                                     DepClassTy::NONE)
1365cd4aab4aSJohannes Doerfert               : nullptr;
1366cd4aab4aSJohannes Doerfert 
1367cd4aab4aSJohannes Doerfert   while (!Worklist.empty()) {
1368cd4aab4aSJohannes Doerfert     const Use *U = Worklist.pop_back_val();
136996da6dd6SJohannes Doerfert     if (isa<PHINode>(U->getUser()) && !Visited.insert(U).second)
1370cd4aab4aSJohannes Doerfert       continue;
1371191fa419SJohannes Doerfert     LLVM_DEBUG({
1372191fa419SJohannes Doerfert       if (auto *Fn = dyn_cast<Function>(U->getUser()))
1373191fa419SJohannes Doerfert         dbgs() << "[Attributor] Check use: " << **U << " in " << Fn->getName()
1374191fa419SJohannes Doerfert                << "\n";
1375191fa419SJohannes Doerfert       else
1376191fa419SJohannes Doerfert         dbgs() << "[Attributor] Check use: " << **U << " in " << *U->getUser()
1377191fa419SJohannes Doerfert                << "\n";
1378191fa419SJohannes Doerfert     });
1379792aac98SJohannes Doerfert     bool UsedAssumedInformation = false;
1380792aac98SJohannes Doerfert     if (isAssumedDead(*U, &QueryingAA, LivenessAA, UsedAssumedInformation,
1381c2281f15SJohannes Doerfert                       CheckBBLivenessOnly, LivenessDepClass)) {
138223f41f16SJohannes Doerfert       LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
1383cd4aab4aSJohannes Doerfert       continue;
1384cd4aab4aSJohannes Doerfert     }
13853e8c4366SJohannes Doerfert     if (IgnoreDroppableUses && U->getUser()->isDroppable()) {
13865699d08bSJohannes Doerfert       LLVM_DEBUG(dbgs() << "[Attributor] Droppable user, skip!\n");
13875699d08bSJohannes Doerfert       continue;
13885699d08bSJohannes Doerfert     }
1389cd4aab4aSJohannes Doerfert 
1390adddd3dbSJohannes Doerfert     if (auto *SI = dyn_cast<StoreInst>(U->getUser())) {
1391adddd3dbSJohannes Doerfert       if (&SI->getOperandUse(0) == U) {
1392e05940deSJohannes Doerfert         if (!Visited.insert(U).second)
1393e05940deSJohannes Doerfert           continue;
1394adddd3dbSJohannes Doerfert         SmallSetVector<Value *, 4> PotentialCopies;
139555a970fbSJohannes Doerfert         if (AA::getPotentialCopiesOfStoredValue(
139655a970fbSJohannes Doerfert                 *this, *SI, PotentialCopies, QueryingAA, UsedAssumedInformation,
139755a970fbSJohannes Doerfert                 /* OnlyExact */ true)) {
1398adddd3dbSJohannes Doerfert           LLVM_DEBUG(dbgs() << "[Attributor] Value is stored, continue with "
1399adddd3dbSJohannes Doerfert                             << PotentialCopies.size()
1400adddd3dbSJohannes Doerfert                             << " potential copies instead!\n");
1401adddd3dbSJohannes Doerfert           for (Value *PotentialCopy : PotentialCopies)
1402f84712f0SJohannes Doerfert             if (!AddUsers(*PotentialCopy, U))
14036e2fcf85SJohannes Doerfert               return false;
1404adddd3dbSJohannes Doerfert           continue;
1405adddd3dbSJohannes Doerfert         }
1406adddd3dbSJohannes Doerfert       }
1407adddd3dbSJohannes Doerfert     }
1408adddd3dbSJohannes Doerfert 
1409cd4aab4aSJohannes Doerfert     bool Follow = false;
1410cd4aab4aSJohannes Doerfert     if (!Pred(*U, Follow))
1411cd4aab4aSJohannes Doerfert       return false;
1412cd4aab4aSJohannes Doerfert     if (!Follow)
1413cd4aab4aSJohannes Doerfert       continue;
1414f84712f0SJohannes Doerfert 
1415f84712f0SJohannes Doerfert     User &Usr = *U->getUser();
1416f84712f0SJohannes Doerfert     AddUsers(Usr, /* OldUse */ nullptr);
1417f84712f0SJohannes Doerfert 
1418f84712f0SJohannes Doerfert     auto *RI = dyn_cast<ReturnInst>(&Usr);
1419f84712f0SJohannes Doerfert     if (!RI)
1420f84712f0SJohannes Doerfert       continue;
1421f84712f0SJohannes Doerfert 
1422f84712f0SJohannes Doerfert     Function &F = *RI->getFunction();
1423f84712f0SJohannes Doerfert     auto CallSitePred = [&](AbstractCallSite ACS) {
1424f84712f0SJohannes Doerfert       return AddUsers(*ACS.getInstruction(), U);
1425f84712f0SJohannes Doerfert     };
1426f84712f0SJohannes Doerfert     if (!checkForAllCallSites(CallSitePred, F, /* RequireAllCallSites */ true,
1427f84712f0SJohannes Doerfert                               &QueryingAA, UsedAssumedInformation)) {
1428f84712f0SJohannes Doerfert       LLVM_DEBUG(dbgs() << "[Attributor] Could not follow return instruction "
1429f84712f0SJohannes Doerfert                            "to all call sites: "
1430f84712f0SJohannes Doerfert                         << *RI << "\n");
1431f84712f0SJohannes Doerfert       return false;
1432f84712f0SJohannes Doerfert     }
1433cd4aab4aSJohannes Doerfert   }
1434cd4aab4aSJohannes Doerfert 
1435cd4aab4aSJohannes Doerfert   return true;
1436cd4aab4aSJohannes Doerfert }
1437cd4aab4aSJohannes Doerfert 
checkForAllCallSites(function_ref<bool (AbstractCallSite)> Pred,const AbstractAttribute & QueryingAA,bool RequireAllCallSites,bool & UsedAssumedInformation)1438c57689beSJohannes Doerfert bool Attributor::checkForAllCallSites(function_ref<bool(AbstractCallSite)> Pred,
1439c57689beSJohannes Doerfert                                       const AbstractAttribute &QueryingAA,
1440c57689beSJohannes Doerfert                                       bool RequireAllCallSites,
14416ed1ef06SJohannes Doerfert                                       bool &UsedAssumedInformation) {
144254869ec9SHideto Ueno   // We can try to determine information from
144354869ec9SHideto Ueno   // the call sites. However, this is only possible all call sites are known,
144454869ec9SHideto Ueno   // hence the function has internal linkage.
1445710ebb03SJohannes Doerfert   const IRPosition &IRP = QueryingAA.getIRPosition();
1446710ebb03SJohannes Doerfert   const Function *AssociatedFunction = IRP.getAssociatedFunction();
1447748538e1SJohannes Doerfert   if (!AssociatedFunction) {
1448748538e1SJohannes Doerfert     LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
1449748538e1SJohannes Doerfert                       << "\n");
1450710ebb03SJohannes Doerfert     return false;
1451748538e1SJohannes Doerfert   }
1452710ebb03SJohannes Doerfert 
14533753aa75SJohannes Doerfert   return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
14546ed1ef06SJohannes Doerfert                               &QueryingAA, UsedAssumedInformation);
14553753aa75SJohannes Doerfert }
14563753aa75SJohannes Doerfert 
checkForAllCallSites(function_ref<bool (AbstractCallSite)> Pred,const Function & Fn,bool RequireAllCallSites,const AbstractAttribute * QueryingAA,bool & UsedAssumedInformation)1457c57689beSJohannes Doerfert bool Attributor::checkForAllCallSites(function_ref<bool(AbstractCallSite)> Pred,
1458c57689beSJohannes Doerfert                                       const Function &Fn,
1459c57689beSJohannes Doerfert                                       bool RequireAllCallSites,
1460c57689beSJohannes Doerfert                                       const AbstractAttribute *QueryingAA,
14616ed1ef06SJohannes Doerfert                                       bool &UsedAssumedInformation) {
14623753aa75SJohannes Doerfert   if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
146354869ec9SHideto Ueno     LLVM_DEBUG(
146454869ec9SHideto Ueno         dbgs()
14653753aa75SJohannes Doerfert         << "[Attributor] Function " << Fn.getName()
146654869ec9SHideto Ueno         << " has no internal linkage, hence not all call sites are known\n");
146754869ec9SHideto Ueno     return false;
146854869ec9SHideto Ueno   }
146954869ec9SHideto Ueno 
1470c6ac717aSJohannes Doerfert   SmallVector<const Use *, 8> Uses(make_pointer_range(Fn.uses()));
1471c6ac717aSJohannes Doerfert   for (unsigned u = 0; u < Uses.size(); ++u) {
1472c6ac717aSJohannes Doerfert     const Use &U = *Uses[u];
1473191fa419SJohannes Doerfert     LLVM_DEBUG({
1474191fa419SJohannes Doerfert       if (auto *Fn = dyn_cast<Function>(U))
1475191fa419SJohannes Doerfert         dbgs() << "[Attributor] Check use: " << Fn->getName() << " in "
1476191fa419SJohannes Doerfert                << *U.getUser() << "\n";
1477191fa419SJohannes Doerfert       else
1478191fa419SJohannes Doerfert         dbgs() << "[Attributor] Check use: " << *U << " in " << *U.getUser()
1479191fa419SJohannes Doerfert                << "\n";
1480191fa419SJohannes Doerfert     });
1481792aac98SJohannes Doerfert     if (isAssumedDead(U, QueryingAA, nullptr, UsedAssumedInformation,
1482792aac98SJohannes Doerfert                       /* CheckBBLivenessOnly */ true)) {
148323f41f16SJohannes Doerfert       LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
148423f41f16SJohannes Doerfert       continue;
148523f41f16SJohannes Doerfert     }
1486c6ac717aSJohannes Doerfert     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {
14876b5b3678SNikita Popov       if (CE->isCast() && CE->getType()->isPointerTy()) {
1488734f9144SJohannes Doerfert         LLVM_DEBUG(
1489734f9144SJohannes Doerfert             dbgs() << "[Attributor] Use, is constant cast expression, add "
1490734f9144SJohannes Doerfert                    << CE->getNumUses()
1491734f9144SJohannes Doerfert                    << " uses of that expression instead!\n");
1492c6ac717aSJohannes Doerfert         for (const Use &CEU : CE->uses())
1493c6ac717aSJohannes Doerfert           Uses.push_back(&CEU);
1494c6ac717aSJohannes Doerfert         continue;
1495c6ac717aSJohannes Doerfert       }
1496c6ac717aSJohannes Doerfert     }
149723f41f16SJohannes Doerfert 
1498661db04bSJohannes Doerfert     AbstractCallSite ACS(&U);
1499661db04bSJohannes Doerfert     if (!ACS) {
1500f35740d6SStefan Stipanovic       LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
1501661db04bSJohannes Doerfert                         << " has non call site use " << *U.get() << " in "
1502661db04bSJohannes Doerfert                         << *U.getUser() << "\n");
15032d77b0caSJohannes Doerfert       // BlockAddress users are allowed.
15042d77b0caSJohannes Doerfert       if (isa<BlockAddress>(U.getUser()))
15052d77b0caSJohannes Doerfert         continue;
1506d98f9750SJohannes Doerfert       return false;
1507661db04bSJohannes Doerfert     }
1508d98f9750SJohannes Doerfert 
1509661db04bSJohannes Doerfert     const Use *EffectiveUse =
1510661db04bSJohannes Doerfert         ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
1511661db04bSJohannes Doerfert     if (!ACS.isCallee(EffectiveUse)) {
1512734f9144SJohannes Doerfert       if (!RequireAllCallSites) {
1513734f9144SJohannes Doerfert         LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()
1514734f9144SJohannes Doerfert                           << " is not a call of " << Fn.getName()
1515734f9144SJohannes Doerfert                           << ", skip use\n");
151654869ec9SHideto Ueno         continue;
1517734f9144SJohannes Doerfert       }
1518734f9144SJohannes Doerfert       LLVM_DEBUG(dbgs() << "[Attributor] User " << *EffectiveUse->getUser()
1519f35740d6SStefan Stipanovic                         << " is an invalid use of " << Fn.getName() << "\n");
152054869ec9SHideto Ueno       return false;
152154869ec9SHideto Ueno     }
152254869ec9SHideto Ueno 
15231e99fc9dSJohannes Doerfert     // Make sure the arguments that can be matched between the call site and the
15241e99fc9dSJohannes Doerfert     // callee argee on their type. It is unlikely they do not and it doesn't
15251e99fc9dSJohannes Doerfert     // make sense for all attributes to know/care about this.
15261e99fc9dSJohannes Doerfert     assert(&Fn == ACS.getCalledFunction() && "Expected known callee");
15271e99fc9dSJohannes Doerfert     unsigned MinArgsParams =
15281e99fc9dSJohannes Doerfert         std::min(size_t(ACS.getNumArgOperands()), Fn.arg_size());
15291e99fc9dSJohannes Doerfert     for (unsigned u = 0; u < MinArgsParams; ++u) {
15301e99fc9dSJohannes Doerfert       Value *CSArgOp = ACS.getCallArgOperand(u);
15311e99fc9dSJohannes Doerfert       if (CSArgOp && Fn.getArg(u)->getType() != CSArgOp->getType()) {
15321e99fc9dSJohannes Doerfert         LLVM_DEBUG(
15331e99fc9dSJohannes Doerfert             dbgs() << "[Attributor] Call site / callee argument type mismatch ["
15341e99fc9dSJohannes Doerfert                    << u << "@" << Fn.getName() << ": "
15351e99fc9dSJohannes Doerfert                    << *Fn.getArg(u)->getType() << " vs. "
15361e99fc9dSJohannes Doerfert                    << *ACS.getCallArgOperand(u)->getType() << "\n");
15371e99fc9dSJohannes Doerfert         return false;
15381e99fc9dSJohannes Doerfert       }
15391e99fc9dSJohannes Doerfert     }
15401e99fc9dSJohannes Doerfert 
1541661db04bSJohannes Doerfert     if (Pred(ACS))
154254869ec9SHideto Ueno       continue;
154354869ec9SHideto Ueno 
15445304b72aSJohannes Doerfert     LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
1545661db04bSJohannes Doerfert                       << *ACS.getInstruction() << "\n");
154654869ec9SHideto Ueno     return false;
154754869ec9SHideto Ueno   }
154854869ec9SHideto Ueno 
154954869ec9SHideto Ueno   return true;
155054869ec9SHideto Ueno }
155154869ec9SHideto Ueno 
shouldPropagateCallBaseContext(const IRPosition & IRP)1552d75c9e61Skuterd bool Attributor::shouldPropagateCallBaseContext(const IRPosition &IRP) {
1553d75c9e61Skuterd   // TODO: Maintain a cache of Values that are
1554d75c9e61Skuterd   // on the pathway from a Argument to a Instruction that would effect the
1555d75c9e61Skuterd   // liveness/return state etc.
1556d75c9e61Skuterd   return EnableCallSiteSpecific;
1557d75c9e61Skuterd }
1558d75c9e61Skuterd 
checkForAllReturnedValuesAndReturnInsts(function_ref<bool (Value &,const SmallSetVector<ReturnInst *,4> &)> Pred,const AbstractAttribute & QueryingAA)155914a0493aSJohannes Doerfert bool Attributor::checkForAllReturnedValuesAndReturnInsts(
1560c57689beSJohannes Doerfert     function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)> Pred,
156114a0493aSJohannes Doerfert     const AbstractAttribute &QueryingAA) {
156214a0493aSJohannes Doerfert 
1563710ebb03SJohannes Doerfert   const IRPosition &IRP = QueryingAA.getIRPosition();
1564710ebb03SJohannes Doerfert   // Since we need to provide return instructions we have to have an exact
1565710ebb03SJohannes Doerfert   // definition.
1566710ebb03SJohannes Doerfert   const Function *AssociatedFunction = IRP.getAssociatedFunction();
1567b0412e43SJohannes Doerfert   if (!AssociatedFunction)
156814a0493aSJohannes Doerfert     return false;
156914a0493aSJohannes Doerfert 
1570710ebb03SJohannes Doerfert   // If this is a call site query we use the call site specific return values
1571710ebb03SJohannes Doerfert   // and liveness information.
157207a5c129SJohannes Doerfert   // TODO: use the function scope once we have call site AAReturnedValues.
157307a5c129SJohannes Doerfert   const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
15745b70c12fSJohannes Doerfert   const auto &AARetVal =
15755b70c12fSJohannes Doerfert       getAAFor<AAReturnedValues>(QueryingAA, QueryIRP, DepClassTy::REQUIRED);
157612cbbab9SJohannes Doerfert   if (!AARetVal.getState().isValidState())
1577710ebb03SJohannes Doerfert     return false;
1578710ebb03SJohannes Doerfert 
157912cbbab9SJohannes Doerfert   return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
158014a0493aSJohannes Doerfert }
158114a0493aSJohannes Doerfert 
checkForAllReturnedValues(function_ref<bool (Value &)> Pred,const AbstractAttribute & QueryingAA)158214a0493aSJohannes Doerfert bool Attributor::checkForAllReturnedValues(
1583c57689beSJohannes Doerfert     function_ref<bool(Value &)> Pred, const AbstractAttribute &QueryingAA) {
158414a0493aSJohannes Doerfert 
1585710ebb03SJohannes Doerfert   const IRPosition &IRP = QueryingAA.getIRPosition();
1586710ebb03SJohannes Doerfert   const Function *AssociatedFunction = IRP.getAssociatedFunction();
1587b0412e43SJohannes Doerfert   if (!AssociatedFunction)
158814a0493aSJohannes Doerfert     return false;
158914a0493aSJohannes Doerfert 
159007a5c129SJohannes Doerfert   // TODO: use the function scope once we have call site AAReturnedValues.
159164ef29bcSKuter Dinel   const IRPosition &QueryIRP = IRPosition::function(
159264ef29bcSKuter Dinel       *AssociatedFunction, QueryingAA.getCallBaseContext());
15935b70c12fSJohannes Doerfert   const auto &AARetVal =
15945b70c12fSJohannes Doerfert       getAAFor<AAReturnedValues>(QueryingAA, QueryIRP, DepClassTy::REQUIRED);
159512cbbab9SJohannes Doerfert   if (!AARetVal.getState().isValidState())
1596710ebb03SJohannes Doerfert     return false;
1597710ebb03SJohannes Doerfert 
159812cbbab9SJohannes Doerfert   return AARetVal.checkForAllReturnedValuesAndReturnInsts(
1599695089ecSJohannes Doerfert       [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
160014a0493aSJohannes Doerfert         return Pred(RV);
160114a0493aSJohannes Doerfert       });
160214a0493aSJohannes Doerfert }
160314a0493aSJohannes Doerfert 
checkForAllInstructionsImpl(Attributor * A,InformationCache::OpcodeInstMapTy & OpcodeInstMap,function_ref<bool (Instruction &)> Pred,const AbstractAttribute * QueryingAA,const AAIsDead * LivenessAA,const ArrayRef<unsigned> & Opcodes,bool & UsedAssumedInformation,bool CheckBBLivenessOnly=false,bool CheckPotentiallyDead=false)160423f41f16SJohannes Doerfert static bool checkForAllInstructionsImpl(
160523f41f16SJohannes Doerfert     Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap,
1606c57689beSJohannes Doerfert     function_ref<bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA,
1607c57689beSJohannes Doerfert     const AAIsDead *LivenessAA, const ArrayRef<unsigned> &Opcodes,
1608792aac98SJohannes Doerfert     bool &UsedAssumedInformation, bool CheckBBLivenessOnly = false,
1609792aac98SJohannes Doerfert     bool CheckPotentiallyDead = false) {
16103ab9e8b8SJohannes Doerfert   for (unsigned Opcode : Opcodes) {
1611177c065eSJohannes Doerfert     // Check if we have instructions with this opcode at all first.
1612177c065eSJohannes Doerfert     auto *Insts = OpcodeInstMap.lookup(Opcode);
1613177c065eSJohannes Doerfert     if (!Insts)
1614177c065eSJohannes Doerfert       continue;
1615177c065eSJohannes Doerfert 
1616177c065eSJohannes Doerfert     for (Instruction *I : *Insts) {
16173ab9e8b8SJohannes Doerfert       // Skip dead instructions.
1618c1c1fe93SJohannes Doerfert       if (A && !CheckPotentiallyDead &&
1619a1db0e52SJohannes Doerfert           A->isAssumedDead(IRPosition::inst(*I), QueryingAA, LivenessAA,
1620a1db0e52SJohannes Doerfert                            UsedAssumedInformation, CheckBBLivenessOnly)) {
1621a1db0e52SJohannes Doerfert         LLVM_DEBUG(dbgs() << "[Attributor] Instruction " << *I
1622a1db0e52SJohannes Doerfert                           << " is potentially dead, skip!\n";);
16233ab9e8b8SJohannes Doerfert         continue;
1624a1db0e52SJohannes Doerfert       }
16253ab9e8b8SJohannes Doerfert 
16263ab9e8b8SJohannes Doerfert       if (!Pred(*I))
16273ab9e8b8SJohannes Doerfert         return false;
16283ab9e8b8SJohannes Doerfert     }
16293ab9e8b8SJohannes Doerfert   }
16303ab9e8b8SJohannes Doerfert   return true;
16313ab9e8b8SJohannes Doerfert }
16323ab9e8b8SJohannes Doerfert 
checkForAllInstructions(function_ref<bool (Instruction &)> Pred,const Function * Fn,const AbstractAttribute & QueryingAA,const ArrayRef<unsigned> & Opcodes,bool & UsedAssumedInformation,bool CheckBBLivenessOnly,bool CheckPotentiallyDead)1633c57689beSJohannes Doerfert bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
1634efedf70aSJohannes Doerfert                                          const Function *Fn,
1635c57689beSJohannes Doerfert                                          const AbstractAttribute &QueryingAA,
1636c57689beSJohannes Doerfert                                          const ArrayRef<unsigned> &Opcodes,
1637792aac98SJohannes Doerfert                                          bool &UsedAssumedInformation,
1638c1c1fe93SJohannes Doerfert                                          bool CheckBBLivenessOnly,
1639c1c1fe93SJohannes Doerfert                                          bool CheckPotentiallyDead) {
1640710ebb03SJohannes Doerfert   // Since we need to provide instructions we have to have an exact definition.
1641efedf70aSJohannes Doerfert   if (!Fn || Fn->isDeclaration())
16420cd964ffSKuter Dinel     return false;
16430cd964ffSKuter Dinel 
164407a5c129SJohannes Doerfert   // TODO: use the function scope once we have call site AAReturnedValues.
1645efedf70aSJohannes Doerfert   const IRPosition &QueryIRP = IRPosition::function(*Fn);
16465dfd7cc4Ssstefan1   const auto *LivenessAA =
1647c1c1fe93SJohannes Doerfert       (CheckBBLivenessOnly || CheckPotentiallyDead)
1648e592dad8SJohannes Doerfert           ? nullptr
1649e592dad8SJohannes Doerfert           : &(getAAFor<AAIsDead>(QueryingAA, QueryIRP, DepClassTy::NONE));
1650710ebb03SJohannes Doerfert 
1651efedf70aSJohannes Doerfert   auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
165223f41f16SJohannes Doerfert   if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, &QueryingAA,
1653792aac98SJohannes Doerfert                                    LivenessAA, Opcodes, UsedAssumedInformation,
1654792aac98SJohannes Doerfert                                    CheckBBLivenessOnly, CheckPotentiallyDead))
1655d0f64009SJohannes Doerfert     return false;
1656d0f64009SJohannes Doerfert 
1657d0f64009SJohannes Doerfert   return true;
1658d0f64009SJohannes Doerfert }
1659d0f64009SJohannes Doerfert 
checkForAllInstructions(function_ref<bool (Instruction &)> Pred,const AbstractAttribute & QueryingAA,const ArrayRef<unsigned> & Opcodes,bool & UsedAssumedInformation,bool CheckBBLivenessOnly,bool CheckPotentiallyDead)1660efedf70aSJohannes Doerfert bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
1661efedf70aSJohannes Doerfert                                          const AbstractAttribute &QueryingAA,
1662efedf70aSJohannes Doerfert                                          const ArrayRef<unsigned> &Opcodes,
1663efedf70aSJohannes Doerfert                                          bool &UsedAssumedInformation,
1664efedf70aSJohannes Doerfert                                          bool CheckBBLivenessOnly,
1665efedf70aSJohannes Doerfert                                          bool CheckPotentiallyDead) {
1666efedf70aSJohannes Doerfert   const IRPosition &IRP = QueryingAA.getIRPosition();
1667efedf70aSJohannes Doerfert   const Function *AssociatedFunction = IRP.getAssociatedFunction();
1668efedf70aSJohannes Doerfert   return checkForAllInstructions(Pred, AssociatedFunction, QueryingAA, Opcodes,
1669efedf70aSJohannes Doerfert                                  UsedAssumedInformation, CheckBBLivenessOnly,
1670efedf70aSJohannes Doerfert                                  CheckPotentiallyDead);
1671efedf70aSJohannes Doerfert }
1672efedf70aSJohannes Doerfert 
checkForAllReadWriteInstructions(function_ref<bool (Instruction &)> Pred,AbstractAttribute & QueryingAA,bool & UsedAssumedInformation)1673aaa5270cSStefan Stipanovic bool Attributor::checkForAllReadWriteInstructions(
1674792aac98SJohannes Doerfert     function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA,
1675792aac98SJohannes Doerfert     bool &UsedAssumedInformation) {
1676aaa5270cSStefan Stipanovic 
1677710ebb03SJohannes Doerfert   const Function *AssociatedFunction =
1678710ebb03SJohannes Doerfert       QueryingAA.getIRPosition().getAssociatedFunction();
1679710ebb03SJohannes Doerfert   if (!AssociatedFunction)
1680710ebb03SJohannes Doerfert     return false;
1681aaa5270cSStefan Stipanovic 
168207a5c129SJohannes Doerfert   // TODO: use the function scope once we have call site AAReturnedValues.
168307a5c129SJohannes Doerfert   const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
168407a5c129SJohannes Doerfert   const auto &LivenessAA =
1685e592dad8SJohannes Doerfert       getAAFor<AAIsDead>(QueryingAA, QueryIRP, DepClassTy::NONE);
1686710ebb03SJohannes Doerfert 
1687710ebb03SJohannes Doerfert   for (Instruction *I :
1688710ebb03SJohannes Doerfert        InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
1689aaa5270cSStefan Stipanovic     // Skip dead instructions.
1690a1db0e52SJohannes Doerfert     if (isAssumedDead(IRPosition::inst(*I), &QueryingAA, &LivenessAA,
1691792aac98SJohannes Doerfert                       UsedAssumedInformation))
1692aaa5270cSStefan Stipanovic       continue;
1693aaa5270cSStefan Stipanovic 
1694aaa5270cSStefan Stipanovic     if (!Pred(*I))
1695aaa5270cSStefan Stipanovic       return false;
1696aaa5270cSStefan Stipanovic   }
1697aaa5270cSStefan Stipanovic 
1698aaa5270cSStefan Stipanovic   return true;
1699aaa5270cSStefan Stipanovic }
1700aaa5270cSStefan Stipanovic 
runTillFixpoint()170170330edcSKuter Dinel void Attributor::runTillFixpoint() {
170249def10eSkuterd   TimeTraceScope TimeScope("Attributor::runTillFixpoint");
1703aade782aSJohannes Doerfert   LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
17045ee07dc5SLuofan Chen                     << DG.SyntheticRoot.Deps.size()
1705aade782aSJohannes Doerfert                     << " abstract attributes.\n");
1706aade782aSJohannes Doerfert 
17075360589bSStefan Stipanovic   // Now that all abstract attributes are collected and initialized we start
17085360589bSStefan Stipanovic   // the abstract analysis.
1709aade782aSJohannes Doerfert 
1710aade782aSJohannes Doerfert   unsigned IterationCounter = 1;
17113be3b401SJohannes Doerfert   unsigned MaxIterations =
1712129b531cSKazu Hirata       Configuration.MaxFixpointIterations.value_or(SetFixpointIterations);
1713b54ccab5SJoseph Huber 
1714a650d555SStefanos Baziotis   SmallVector<AbstractAttribute *, 32> ChangedAAs;
1715680f6380SJohannes Doerfert   SetVector<AbstractAttribute *> Worklist, InvalidAAs;
17165ee07dc5SLuofan Chen   Worklist.insert(DG.SyntheticRoot.begin(), DG.SyntheticRoot.end());
1717aade782aSJohannes Doerfert 
1718aade782aSJohannes Doerfert   do {
171912cbbab9SJohannes Doerfert     // Remember the size to determine new attributes.
17205ee07dc5SLuofan Chen     size_t NumAAs = DG.SyntheticRoot.Deps.size();
1721aade782aSJohannes Doerfert     LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
1722aade782aSJohannes Doerfert                       << ", Worklist size: " << Worklist.size() << "\n");
1723aade782aSJohannes Doerfert 
1724680f6380SJohannes Doerfert     // For invalid AAs we can fix dependent AAs that have a required dependence,
1725680f6380SJohannes Doerfert     // thereby folding long dependence chains in a single step without the need
1726680f6380SJohannes Doerfert     // to run updates.
1727680f6380SJohannes Doerfert     for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
1728680f6380SJohannes Doerfert       AbstractAttribute *InvalidAA = InvalidAAs[u];
172999662c22SJohannes Doerfert 
173099662c22SJohannes Doerfert       // Check the dependences to fast track invalidation.
1731680f6380SJohannes Doerfert       LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has "
17323a8740bdSJohannes Doerfert                         << InvalidAA->Deps.size()
17333a8740bdSJohannes Doerfert                         << " required & optional dependences\n");
17343a8740bdSJohannes Doerfert       while (!InvalidAA->Deps.empty()) {
17353a8740bdSJohannes Doerfert         const auto &Dep = InvalidAA->Deps.back();
17363a8740bdSJohannes Doerfert         InvalidAA->Deps.pop_back();
17375ee07dc5SLuofan Chen         AbstractAttribute *DepAA = cast<AbstractAttribute>(Dep.getPointer());
17383a8740bdSJohannes Doerfert         if (Dep.getInt() == unsigned(DepClassTy::OPTIONAL)) {
1739a265cf22SJohannes Doerfert           LLVM_DEBUG(dbgs() << " - recompute: " << *DepAA);
17403a8740bdSJohannes Doerfert           Worklist.insert(DepAA);
17413a8740bdSJohannes Doerfert           continue;
1742680f6380SJohannes Doerfert         }
1743a265cf22SJohannes Doerfert         LLVM_DEBUG(dbgs() << " - invalidate: " << *DepAA);
17443a8740bdSJohannes Doerfert         DepAA->getState().indicatePessimisticFixpoint();
17453a8740bdSJohannes Doerfert         assert(DepAA->getState().isAtFixpoint() && "Expected fixpoint state!");
17463a8740bdSJohannes Doerfert         if (!DepAA->getState().isValidState())
17473a8740bdSJohannes Doerfert           InvalidAAs.insert(DepAA);
17483a8740bdSJohannes Doerfert         else
17493a8740bdSJohannes Doerfert           ChangedAAs.push_back(DepAA);
17503a8740bdSJohannes Doerfert       }
1751f7ca0fe1SJohannes Doerfert     }
1752f7ca0fe1SJohannes Doerfert 
1753aade782aSJohannes Doerfert     // Add all abstract attributes that are potentially dependent on one that
1754aade782aSJohannes Doerfert     // changed to the work list.
17553a8740bdSJohannes Doerfert     for (AbstractAttribute *ChangedAA : ChangedAAs)
17563a8740bdSJohannes Doerfert       while (!ChangedAA->Deps.empty()) {
17575ee07dc5SLuofan Chen         Worklist.insert(
17585ee07dc5SLuofan Chen             cast<AbstractAttribute>(ChangedAA->Deps.back().getPointer()));
17593a8740bdSJohannes Doerfert         ChangedAA->Deps.pop_back();
1760aade782aSJohannes Doerfert       }
1761aade782aSJohannes Doerfert 
1762b504eb8bSJohannes Doerfert     LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
1763b504eb8bSJohannes Doerfert                       << ", Worklist+Dependent size: " << Worklist.size()
1764b504eb8bSJohannes Doerfert                       << "\n");
1765b504eb8bSJohannes Doerfert 
1766680f6380SJohannes Doerfert     // Reset the changed and invalid set.
1767aade782aSJohannes Doerfert     ChangedAAs.clear();
1768680f6380SJohannes Doerfert     InvalidAAs.clear();
1769aade782aSJohannes Doerfert 
1770aade782aSJohannes Doerfert     // Update all abstract attribute in the work list and record the ones that
1771aade782aSJohannes Doerfert     // changed.
177295e0d28bSJohannes Doerfert     for (AbstractAttribute *AA : Worklist) {
177395e0d28bSJohannes Doerfert       const auto &AAState = AA->getState();
1774edf03914SJohannes Doerfert       if (!AAState.isAtFixpoint())
1775edf03914SJohannes Doerfert         if (updateAA(*AA) == ChangeStatus::CHANGED)
1776aade782aSJohannes Doerfert           ChangedAAs.push_back(AA);
1777edf03914SJohannes Doerfert 
177895e0d28bSJohannes Doerfert       // Use the InvalidAAs vector to propagate invalid states fast transitively
177995e0d28bSJohannes Doerfert       // without requiring updates.
178095e0d28bSJohannes Doerfert       if (!AAState.isValidState())
1781680f6380SJohannes Doerfert         InvalidAAs.insert(AA);
17822dad729fSJohannes Doerfert     }
1783f7ca0fe1SJohannes Doerfert 
17849543f149SJohannes Doerfert     // Add attributes to the changed set if they have been created in the last
17859543f149SJohannes Doerfert     // iteration.
17865ee07dc5SLuofan Chen     ChangedAAs.append(DG.SyntheticRoot.begin() + NumAAs,
17875ee07dc5SLuofan Chen                       DG.SyntheticRoot.end());
17889543f149SJohannes Doerfert 
1789aade782aSJohannes Doerfert     // Reset the work list and repopulate with the changed abstract attributes.
1790aade782aSJohannes Doerfert     // Note that dependent ones are added above.
1791aade782aSJohannes Doerfert     Worklist.clear();
1792aade782aSJohannes Doerfert     Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
1793b51b83f6SJohannes Doerfert     Worklist.insert(QueryAAsAwaitingUpdate.begin(),
1794b51b83f6SJohannes Doerfert                     QueryAAsAwaitingUpdate.end());
1795b51b83f6SJohannes Doerfert     QueryAAsAwaitingUpdate.clear();
1796aade782aSJohannes Doerfert 
17973be3b401SJohannes Doerfert   } while (!Worklist.empty() &&
17983be3b401SJohannes Doerfert            (IterationCounter++ < MaxIterations || VerifyMaxFixpointIterations));
1799f7ca0fe1SJohannes Doerfert 
18003be3b401SJohannes Doerfert   if (IterationCounter > MaxIterations && !Functions.empty()) {
1801f074a6a0SJoseph Huber     auto Remark = [&](OptimizationRemarkMissed ORM) {
1802f074a6a0SJoseph Huber       return ORM << "Attributor did not reach a fixpoint after "
18033be3b401SJohannes Doerfert                  << ore::NV("Iterations", MaxIterations) << " iterations.";
1804f074a6a0SJoseph Huber     };
1805caf7f05cSJoseph Huber     Function *F = Functions.front();
1806f074a6a0SJoseph Huber     emitRemark<OptimizationRemarkMissed>(F, "FixedPoint", Remark);
1807f074a6a0SJoseph Huber   }
1808f074a6a0SJoseph Huber 
1809aade782aSJohannes Doerfert   LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
18103be3b401SJohannes Doerfert                     << IterationCounter << "/" << MaxIterations
1811aade782aSJohannes Doerfert                     << " iterations\n");
1812aade782aSJohannes Doerfert 
1813aade782aSJohannes Doerfert   // Reset abstract arguments not settled in a sound fixpoint by now. This
1814aade782aSJohannes Doerfert   // happens when we stopped the fixpoint iteration early. Note that only the
1815aade782aSJohannes Doerfert   // ones marked as "changed" *and* the ones transitively depending on them
1816aade782aSJohannes Doerfert   // need to be reverted to a pessimistic state. Others might not be in a
1817aade782aSJohannes Doerfert   // fixpoint state but we can use the optimistic results for them anyway.
1818aade782aSJohannes Doerfert   SmallPtrSet<AbstractAttribute *, 32> Visited;
1819aade782aSJohannes Doerfert   for (unsigned u = 0; u < ChangedAAs.size(); u++) {
1820aade782aSJohannes Doerfert     AbstractAttribute *ChangedAA = ChangedAAs[u];
1821aade782aSJohannes Doerfert     if (!Visited.insert(ChangedAA).second)
1822aade782aSJohannes Doerfert       continue;
1823aade782aSJohannes Doerfert 
1824aade782aSJohannes Doerfert     AbstractState &State = ChangedAA->getState();
1825aade782aSJohannes Doerfert     if (!State.isAtFixpoint()) {
1826aade782aSJohannes Doerfert       State.indicatePessimisticFixpoint();
1827aade782aSJohannes Doerfert 
1828aade782aSJohannes Doerfert       NumAttributesTimedOut++;
1829aade782aSJohannes Doerfert     }
1830aade782aSJohannes Doerfert 
18313a8740bdSJohannes Doerfert     while (!ChangedAA->Deps.empty()) {
18325ee07dc5SLuofan Chen       ChangedAAs.push_back(
18335ee07dc5SLuofan Chen           cast<AbstractAttribute>(ChangedAA->Deps.back().getPointer()));
18343a8740bdSJohannes Doerfert       ChangedAA->Deps.pop_back();
183599662c22SJohannes Doerfert     }
1836aade782aSJohannes Doerfert   }
1837aade782aSJohannes Doerfert 
1838aade782aSJohannes Doerfert   LLVM_DEBUG({
1839aade782aSJohannes Doerfert     if (!Visited.empty())
1840aade782aSJohannes Doerfert       dbgs() << "\n[Attributor] Finalized " << Visited.size()
1841aade782aSJohannes Doerfert              << " abstract attributes.\n";
1842aade782aSJohannes Doerfert   });
1843aade782aSJohannes Doerfert 
18443be3b401SJohannes Doerfert   if (VerifyMaxFixpointIterations && IterationCounter != MaxIterations) {
184570330edcSKuter Dinel     errs() << "\n[Attributor] Fixpoint iteration done after: "
18463be3b401SJohannes Doerfert            << IterationCounter << "/" << MaxIterations << " iterations\n";
184770330edcSKuter Dinel     llvm_unreachable("The fixpoint was not reached with exactly the number of "
184870330edcSKuter Dinel                      "specified iterations!");
184970330edcSKuter Dinel   }
185070330edcSKuter Dinel }
185170330edcSKuter Dinel 
registerForUpdate(AbstractAttribute & AA)1852b51b83f6SJohannes Doerfert void Attributor::registerForUpdate(AbstractAttribute &AA) {
1853b51b83f6SJohannes Doerfert   assert(AA.isQueryAA() &&
1854b51b83f6SJohannes Doerfert          "Non-query AAs should not be required to register for updates!");
1855b51b83f6SJohannes Doerfert   QueryAAsAwaitingUpdate.insert(&AA);
1856b51b83f6SJohannes Doerfert }
1857b51b83f6SJohannes Doerfert 
manifestAttributes()185870330edcSKuter Dinel ChangeStatus Attributor::manifestAttributes() {
185949def10eSkuterd   TimeTraceScope TimeScope("Attributor::manifestAttributes");
18605ee07dc5SLuofan Chen   size_t NumFinalAAs = DG.SyntheticRoot.Deps.size();
186170330edcSKuter Dinel 
1862aade782aSJohannes Doerfert   unsigned NumManifested = 0;
1863aade782aSJohannes Doerfert   unsigned NumAtFixpoint = 0;
1864aade782aSJohannes Doerfert   ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
18655ee07dc5SLuofan Chen   for (auto &DepAA : DG.SyntheticRoot.Deps) {
18665ee07dc5SLuofan Chen     AbstractAttribute *AA = cast<AbstractAttribute>(DepAA.getPointer());
1867aade782aSJohannes Doerfert     AbstractState &State = AA->getState();
1868aade782aSJohannes Doerfert 
1869aade782aSJohannes Doerfert     // If there is not already a fixpoint reached, we can now take the
1870aade782aSJohannes Doerfert     // optimistic state. This is correct because we enforced a pessimistic one
1871aade782aSJohannes Doerfert     // on abstract attributes that were transitively dependent on a changed one
1872aade782aSJohannes Doerfert     // already above.
1873aade782aSJohannes Doerfert     if (!State.isAtFixpoint())
1874aade782aSJohannes Doerfert       State.indicateOptimisticFixpoint();
1875aade782aSJohannes Doerfert 
1876d75c9e61Skuterd     // We must not manifest Attributes that use Callbase info.
1877d75c9e61Skuterd     if (AA->hasCallBaseContext())
1878d75c9e61Skuterd       continue;
1879aade782aSJohannes Doerfert     // If the state is invalid, we do not try to manifest it.
1880aade782aSJohannes Doerfert     if (!State.isValidState())
1881aade782aSJohannes Doerfert       continue;
1882aade782aSJohannes Doerfert 
1883f3ad8cf0SJohannes Doerfert     if (AA->getCtxI() && !isRunOn(*AA->getAnchorScope()))
1884f3ad8cf0SJohannes Doerfert       continue;
1885f3ad8cf0SJohannes Doerfert 
18869a1a1f96SJohannes Doerfert     // Skip dead code.
1887792aac98SJohannes Doerfert     bool UsedAssumedInformation = false;
1888792aac98SJohannes Doerfert     if (isAssumedDead(*AA, nullptr, UsedAssumedInformation,
1889792aac98SJohannes Doerfert                       /* CheckBBLivenessOnly */ true))
18909a1a1f96SJohannes Doerfert       continue;
189150d34958SJohannes Doerfert     // Check if the manifest debug counter that allows skipping manifestation of
189250d34958SJohannes Doerfert     // AAs
189350d34958SJohannes Doerfert     if (!DebugCounter::shouldExecute(ManifestDBGCounter))
189450d34958SJohannes Doerfert       continue;
1895aade782aSJohannes Doerfert     // Manifest the state and record if we changed the IR.
1896aade782aSJohannes Doerfert     ChangeStatus LocalChange = AA->manifest(*this);
1897d1b79e07SJohannes Doerfert     if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
1898d1b79e07SJohannes Doerfert       AA->trackStatistics();
18998e76fec0SJohannes Doerfert     LLVM_DEBUG(dbgs() << "[Attributor] Manifest " << LocalChange << " : " << *AA
19008e76fec0SJohannes Doerfert                       << "\n");
1901d1b79e07SJohannes Doerfert 
1902aade782aSJohannes Doerfert     ManifestChange = ManifestChange | LocalChange;
1903aade782aSJohannes Doerfert 
1904aade782aSJohannes Doerfert     NumAtFixpoint++;
1905aade782aSJohannes Doerfert     NumManifested += (LocalChange == ChangeStatus::CHANGED);
1906aade782aSJohannes Doerfert   }
1907aade782aSJohannes Doerfert 
1908aade782aSJohannes Doerfert   (void)NumManifested;
1909aade782aSJohannes Doerfert   (void)NumAtFixpoint;
1910aade782aSJohannes Doerfert   LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
1911aade782aSJohannes Doerfert                     << " arguments while " << NumAtFixpoint
1912aade782aSJohannes Doerfert                     << " were in a valid fixpoint state\n");
1913aade782aSJohannes Doerfert 
1914aade782aSJohannes Doerfert   NumAttributesManifested += NumManifested;
1915aade782aSJohannes Doerfert   NumAttributesValidFixpoint += NumAtFixpoint;
1916aade782aSJohannes Doerfert 
1917f1826173SFangrui Song   (void)NumFinalAAs;
19185ee07dc5SLuofan Chen   if (NumFinalAAs != DG.SyntheticRoot.Deps.size()) {
19195ee07dc5SLuofan Chen     for (unsigned u = NumFinalAAs; u < DG.SyntheticRoot.Deps.size(); ++u)
19205ee07dc5SLuofan Chen       errs() << "Unexpected abstract attribute: "
19215ee07dc5SLuofan Chen              << cast<AbstractAttribute>(DG.SyntheticRoot.Deps[u].getPointer())
1922b70297a3SJohannes Doerfert              << " :: "
19235ee07dc5SLuofan Chen              << cast<AbstractAttribute>(DG.SyntheticRoot.Deps[u].getPointer())
19245ee07dc5SLuofan Chen                     ->getIRPosition()
19255ee07dc5SLuofan Chen                     .getAssociatedValue()
1926b70297a3SJohannes Doerfert              << "\n";
1927b70297a3SJohannes Doerfert     llvm_unreachable("Expected the final number of abstract attributes to "
1928b70297a3SJohannes Doerfert                      "remain unchanged!");
1929b70297a3SJohannes Doerfert   }
193070330edcSKuter Dinel   return ManifestChange;
193170330edcSKuter Dinel }
193239681e73SJohannes Doerfert 
identifyDeadInternalFunctions()19331c2531c9SJohannes Doerfert void Attributor::identifyDeadInternalFunctions() {
1934b077d82bSWilliam S. Moses   // Early exit if we don't intend to delete functions.
19353be3b401SJohannes Doerfert   if (!Configuration.DeleteFns)
1936b077d82bSWilliam S. Moses     return;
1937b077d82bSWilliam S. Moses 
19381c2531c9SJohannes Doerfert   // Identify dead internal functions and delete them. This happens outside
19391c2531c9SJohannes Doerfert   // the other fixpoint analysis as we might treat potentially dead functions
19401c2531c9SJohannes Doerfert   // as live to lower the number of iterations. If they happen to be dead, the
19411c2531c9SJohannes Doerfert   // below fixpoint loop will identify and eliminate them.
19421c2531c9SJohannes Doerfert   SmallVector<Function *, 8> InternalFns;
19431c2531c9SJohannes Doerfert   for (Function *F : Functions)
19441c2531c9SJohannes Doerfert     if (F->hasLocalLinkage())
19451c2531c9SJohannes Doerfert       InternalFns.push_back(F);
19461c2531c9SJohannes Doerfert 
19471c2531c9SJohannes Doerfert   SmallPtrSet<Function *, 8> LiveInternalFns;
19481c2531c9SJohannes Doerfert   bool FoundLiveInternal = true;
19491c2531c9SJohannes Doerfert   while (FoundLiveInternal) {
19501c2531c9SJohannes Doerfert     FoundLiveInternal = false;
19511c2531c9SJohannes Doerfert     for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
19521c2531c9SJohannes Doerfert       Function *F = InternalFns[u];
19531c2531c9SJohannes Doerfert       if (!F)
19541c2531c9SJohannes Doerfert         continue;
19551c2531c9SJohannes Doerfert 
19566ed1ef06SJohannes Doerfert       bool UsedAssumedInformation = false;
19571c2531c9SJohannes Doerfert       if (checkForAllCallSites(
19581c2531c9SJohannes Doerfert               [&](AbstractCallSite ACS) {
19591c2531c9SJohannes Doerfert                 Function *Callee = ACS.getInstruction()->getFunction();
19601c2531c9SJohannes Doerfert                 return ToBeDeletedFunctions.count(Callee) ||
19611c2531c9SJohannes Doerfert                        (Functions.count(Callee) && Callee->hasLocalLinkage() &&
19621c2531c9SJohannes Doerfert                         !LiveInternalFns.count(Callee));
19631c2531c9SJohannes Doerfert               },
19646ed1ef06SJohannes Doerfert               *F, true, nullptr, UsedAssumedInformation)) {
19651c2531c9SJohannes Doerfert         continue;
19661c2531c9SJohannes Doerfert       }
19671c2531c9SJohannes Doerfert 
19681c2531c9SJohannes Doerfert       LiveInternalFns.insert(F);
19691c2531c9SJohannes Doerfert       InternalFns[u] = nullptr;
19701c2531c9SJohannes Doerfert       FoundLiveInternal = true;
19711c2531c9SJohannes Doerfert     }
19721c2531c9SJohannes Doerfert   }
19731c2531c9SJohannes Doerfert 
19741c2531c9SJohannes Doerfert   for (unsigned u = 0, e = InternalFns.size(); u < e; ++u)
19751c2531c9SJohannes Doerfert     if (Function *F = InternalFns[u])
19761c2531c9SJohannes Doerfert       ToBeDeletedFunctions.insert(F);
19771c2531c9SJohannes Doerfert }
19781c2531c9SJohannes Doerfert 
cleanupIR()197970330edcSKuter Dinel ChangeStatus Attributor::cleanupIR() {
198049def10eSkuterd   TimeTraceScope TimeScope("Attributor::cleanupIR");
198139681e73SJohannes Doerfert   // Delete stuff at the end to avoid invalid references and a nice order.
1982168a9234SJohannes Doerfert   LLVM_DEBUG(dbgs() << "\n[Attributor] Delete/replace at least "
19832f622063SJohannes Doerfert                     << ToBeDeletedFunctions.size() << " functions and "
19842f622063SJohannes Doerfert                     << ToBeDeletedBlocks.size() << " blocks and "
1985cd4aab4aSJohannes Doerfert                     << ToBeDeletedInsts.size() << " instructions and "
1986168a9234SJohannes Doerfert                     << ToBeChangedValues.size() << " values and "
1987982053e8SJohannes Doerfert                     << ToBeChangedUses.size() << " uses. To insert "
1988bf789b19SJohannes Doerfert                     << ToBeChangedToUnreachableInsts.size()
1989bf789b19SJohannes Doerfert                     << " unreachables.\n"
19903f71b425SGiorgis Georgakoudis                     << "Preserve manifest added " << ManifestAddedBlocks.size()
19913f71b425SGiorgis Georgakoudis                     << " blocks\n");
1992cd4aab4aSJohannes Doerfert 
19939e66c4ecSAlina Sbirlea   SmallVector<WeakTrackingVH, 32> DeadInsts;
1994cd4aab4aSJohannes Doerfert   SmallVector<Instruction *, 32> TerminatorsToFold;
1995cd4aab4aSJohannes Doerfert 
1996168a9234SJohannes Doerfert   auto ReplaceUse = [&](Use *U, Value *NewV) {
1997cd4aab4aSJohannes Doerfert     Value *OldV = U->get();
199854ec9b54SJohannes Doerfert 
1999168a9234SJohannes Doerfert     // If we plan to replace NewV we need to update it at this point.
2000168a9234SJohannes Doerfert     do {
2001168a9234SJohannes Doerfert       const auto &Entry = ToBeChangedValues.lookup(NewV);
2002168a9234SJohannes Doerfert       if (!Entry.first)
2003168a9234SJohannes Doerfert         break;
2004168a9234SJohannes Doerfert       NewV = Entry.first;
2005168a9234SJohannes Doerfert     } while (true);
2006168a9234SJohannes Doerfert 
2007f3ad8cf0SJohannes Doerfert     Instruction *I = dyn_cast<Instruction>(U->getUser());
2008f3ad8cf0SJohannes Doerfert     assert((!I || isRunOn(*I->getFunction())) &&
2009982053e8SJohannes Doerfert            "Cannot replace an instruction outside the current SCC!");
2010f3ad8cf0SJohannes Doerfert 
201154ec9b54SJohannes Doerfert     // Do not replace uses in returns if the value is a must-tail call we will
201254ec9b54SJohannes Doerfert     // not delete.
2013f3ad8cf0SJohannes Doerfert     if (auto *RI = dyn_cast_or_null<ReturnInst>(I)) {
201454ec9b54SJohannes Doerfert       if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))
2015f3ad8cf0SJohannes Doerfert         if (CI->isMustTailCall() && !ToBeDeletedInsts.count(CI))
2016168a9234SJohannes Doerfert           return;
20175ef18e24SJohannes Doerfert       // If we rewrite a return and the new value is not an argument, strip the
20185ef18e24SJohannes Doerfert       // `returned` attribute as it is wrong now.
20195ef18e24SJohannes Doerfert       if (!isa<Argument>(NewV))
20205ef18e24SJohannes Doerfert         for (auto &Arg : RI->getFunction()->args())
20215ef18e24SJohannes Doerfert           Arg.removeAttr(Attribute::Returned);
20225ef18e24SJohannes Doerfert     }
20231ba2929bSJohannes Doerfert 
20241ba2929bSJohannes Doerfert     // Do not perform call graph altering changes outside the SCC.
2025f3ad8cf0SJohannes Doerfert     if (auto *CB = dyn_cast_or_null<CallBase>(I))
2026f3ad8cf0SJohannes Doerfert       if (CB->isCallee(U))
2027168a9234SJohannes Doerfert         return;
202854ec9b54SJohannes Doerfert 
2029cd4aab4aSJohannes Doerfert     LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
2030cd4aab4aSJohannes Doerfert                       << " instead of " << *OldV << "\n");
2031cd4aab4aSJohannes Doerfert     U->set(NewV);
20321ba2929bSJohannes Doerfert 
2033b0c77c36SJohannes Doerfert     if (Instruction *I = dyn_cast<Instruction>(OldV)) {
2034b0c77c36SJohannes Doerfert       CGModifiedFunctions.insert(I->getFunction());
2035f35740d6SStefan Stipanovic       if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
2036b0c77c36SJohannes Doerfert           isInstructionTriviallyDead(I))
2037cd4aab4aSJohannes Doerfert         DeadInsts.push_back(I);
2038cd4aab4aSJohannes Doerfert     }
203981429abdSJohannes Doerfert     if (isa<UndefValue>(NewV) && isa<CallBase>(U->getUser())) {
204081429abdSJohannes Doerfert       auto *CB = cast<CallBase>(U->getUser());
204181429abdSJohannes Doerfert       if (CB->isArgOperand(U)) {
204281429abdSJohannes Doerfert         unsigned Idx = CB->getArgOperandNo(U);
204381429abdSJohannes Doerfert         CB->removeParamAttr(Idx, Attribute::NoUndef);
204481429abdSJohannes Doerfert         Function *Fn = CB->getCalledFunction();
204530c9d68aSJohannes Doerfert         if (Fn && Fn->arg_size() > Idx)
204681429abdSJohannes Doerfert           Fn->removeParamAttr(Idx, Attribute::NoUndef);
204781429abdSJohannes Doerfert       }
204881429abdSJohannes Doerfert     }
2049cd4aab4aSJohannes Doerfert     if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
2050cd4aab4aSJohannes Doerfert       Instruction *UserI = cast<Instruction>(U->getUser());
2051cd4aab4aSJohannes Doerfert       if (isa<UndefValue>(NewV)) {
2052cb5eb13eSHideto Ueno         ToBeChangedToUnreachableInsts.insert(UserI);
2053cd4aab4aSJohannes Doerfert       } else {
2054cd4aab4aSJohannes Doerfert         TerminatorsToFold.push_back(UserI);
2055cd4aab4aSJohannes Doerfert       }
2056cd4aab4aSJohannes Doerfert     }
2057168a9234SJohannes Doerfert   };
2058168a9234SJohannes Doerfert 
2059168a9234SJohannes Doerfert   for (auto &It : ToBeChangedUses) {
2060168a9234SJohannes Doerfert     Use *U = It.first;
2061168a9234SJohannes Doerfert     Value *NewV = It.second;
2062168a9234SJohannes Doerfert     ReplaceUse(U, NewV);
2063cd4aab4aSJohannes Doerfert   }
2064168a9234SJohannes Doerfert 
2065168a9234SJohannes Doerfert   SmallVector<Use *, 4> Uses;
2066168a9234SJohannes Doerfert   for (auto &It : ToBeChangedValues) {
2067168a9234SJohannes Doerfert     Value *OldV = It.first;
2068168a9234SJohannes Doerfert     auto &Entry = It.second;
2069168a9234SJohannes Doerfert     Value *NewV = Entry.first;
2070168a9234SJohannes Doerfert     Uses.clear();
2071168a9234SJohannes Doerfert     for (auto &U : OldV->uses())
2072168a9234SJohannes Doerfert       if (Entry.second || !U.getUser()->isDroppable())
2073168a9234SJohannes Doerfert         Uses.push_back(&U);
20740ece283fSJohannes Doerfert     for (Use *U : Uses) {
20750ece283fSJohannes Doerfert       if (auto *I = dyn_cast<Instruction>(U->getUser()))
20760ece283fSJohannes Doerfert         if (!isRunOn(*I->getFunction()))
20770ece283fSJohannes Doerfert           continue;
2078168a9234SJohannes Doerfert       ReplaceUse(U, NewV);
2079168a9234SJohannes Doerfert     }
20800ece283fSJohannes Doerfert   }
2081168a9234SJohannes Doerfert 
2082a4088c75SJohannes Doerfert   for (auto &V : InvokeWithDeadSuccessor)
2083a4088c75SJohannes Doerfert     if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
20841ba2929bSJohannes Doerfert       assert(isRunOn(*II->getFunction()) &&
20851ba2929bSJohannes Doerfert              "Cannot replace an invoke outside the current SCC!");
2086a4088c75SJohannes Doerfert       bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
2087a4088c75SJohannes Doerfert       bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
2088a4088c75SJohannes Doerfert       bool Invoke2CallAllowed =
20890985554bSJohannes Doerfert           !AAIsDead::mayCatchAsynchronousExceptions(*II->getFunction());
2090a4088c75SJohannes Doerfert       assert((UnwindBBIsDead || NormalBBIsDead) &&
2091a4088c75SJohannes Doerfert              "Invoke does not have dead successors!");
2092a4088c75SJohannes Doerfert       BasicBlock *BB = II->getParent();
2093a4088c75SJohannes Doerfert       BasicBlock *NormalDestBB = II->getNormalDest();
2094a4088c75SJohannes Doerfert       if (UnwindBBIsDead) {
2095a4088c75SJohannes Doerfert         Instruction *NormalNextIP = &NormalDestBB->front();
2096a4088c75SJohannes Doerfert         if (Invoke2CallAllowed) {
2097a4088c75SJohannes Doerfert           changeToCall(II);
2098a4088c75SJohannes Doerfert           NormalNextIP = BB->getTerminator();
2099a4088c75SJohannes Doerfert         }
2100a4088c75SJohannes Doerfert         if (NormalBBIsDead)
2101a4088c75SJohannes Doerfert           ToBeChangedToUnreachableInsts.insert(NormalNextIP);
2102a4088c75SJohannes Doerfert       } else {
2103a4088c75SJohannes Doerfert         assert(NormalBBIsDead && "Broken invariant!");
2104a4088c75SJohannes Doerfert         if (!NormalDestBB->getUniquePredecessor())
2105a4088c75SJohannes Doerfert           NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2106a4088c75SJohannes Doerfert         ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());
2107a4088c75SJohannes Doerfert       }
2108a4088c75SJohannes Doerfert     }
210901c48d7dSStefanos Baziotis   for (Instruction *I : TerminatorsToFold) {
2110f3ad8cf0SJohannes Doerfert     assert(isRunOn(*I->getFunction()) &&
2111f3ad8cf0SJohannes Doerfert            "Cannot replace a terminator outside the current SCC!");
211201c48d7dSStefanos Baziotis     CGModifiedFunctions.insert(I->getFunction());
211301c48d7dSStefanos Baziotis     ConstantFoldTerminator(I->getParent());
211401c48d7dSStefanos Baziotis   }
21151e46eb74SJohannes Doerfert   for (auto &V : ToBeChangedToUnreachableInsts)
2116b0c77c36SJohannes Doerfert     if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
2117bf789b19SJohannes Doerfert       LLVM_DEBUG(dbgs() << "[Attributor] Change to unreachable: " << *I
2118bf789b19SJohannes Doerfert                         << "\n");
2119f3ad8cf0SJohannes Doerfert       assert(isRunOn(*I->getFunction()) &&
2120f3ad8cf0SJohannes Doerfert              "Cannot replace an instruction outside the current SCC!");
2121b0c77c36SJohannes Doerfert       CGModifiedFunctions.insert(I->getFunction());
212225a3130dSJohannes Doerfert       changeToUnreachable(I);
2123b0c77c36SJohannes Doerfert     }
2124cd4aab4aSJohannes Doerfert 
21255429c82dSJohannes Doerfert   for (auto &V : ToBeDeletedInsts) {
21265429c82dSJohannes Doerfert     if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
21270c0eb767SJohannes Doerfert       if (auto *CB = dyn_cast<CallBase>(I)) {
2128f3ad8cf0SJohannes Doerfert         assert(isRunOn(*I->getFunction()) &&
2129f3ad8cf0SJohannes Doerfert                "Cannot delete an instruction outside the current SCC!");
21300c0eb767SJohannes Doerfert         if (!isa<IntrinsicInst>(CB))
21313be3b401SJohannes Doerfert           Configuration.CGUpdater.removeCallSite(*CB);
21320c0eb767SJohannes Doerfert       }
21330741dec2SJohannes Doerfert       I->dropDroppableUses();
2134b0c77c36SJohannes Doerfert       CGModifiedFunctions.insert(I->getFunction());
2135b4352e43SJohannes Doerfert       if (!I->getType()->isVoidTy())
213639681e73SJohannes Doerfert         I->replaceAllUsesWith(UndefValue::get(I->getType()));
2137cd4aab4aSJohannes Doerfert       if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
2138cd4aab4aSJohannes Doerfert         DeadInsts.push_back(I);
2139cd4aab4aSJohannes Doerfert       else
214039681e73SJohannes Doerfert         I->eraseFromParent();
214139681e73SJohannes Doerfert     }
21425429c82dSJohannes Doerfert   }
2143b19cd27bSJohannes Doerfert 
2144f3ad8cf0SJohannes Doerfert   llvm::erase_if(DeadInsts, [&](WeakTrackingVH I) { return !I; });
2145850b150cSsstefan1 
21462bc51d39SJohannes Doerfert   LLVM_DEBUG({
21472bc51d39SJohannes Doerfert     dbgs() << "[Attributor] DeadInsts size: " << DeadInsts.size() << "\n";
21482bc51d39SJohannes Doerfert     for (auto &I : DeadInsts)
21492bc51d39SJohannes Doerfert       if (I)
21502bc51d39SJohannes Doerfert         dbgs() << "  - " << *I << "\n";
21512bc51d39SJohannes Doerfert   });
21522bc51d39SJohannes Doerfert 
2153cd4aab4aSJohannes Doerfert   RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
2154cd4aab4aSJohannes Doerfert 
2155b19cd27bSJohannes Doerfert   if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
2156b19cd27bSJohannes Doerfert     SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
2157b19cd27bSJohannes Doerfert     ToBeDeletedBBs.reserve(NumDeadBlocks);
2158b0c77c36SJohannes Doerfert     for (BasicBlock *BB : ToBeDeletedBlocks) {
21591ba2929bSJohannes Doerfert       assert(isRunOn(*BB->getParent()) &&
21601ba2929bSJohannes Doerfert              "Cannot delete a block outside the current SCC!");
2161b0c77c36SJohannes Doerfert       CGModifiedFunctions.insert(BB->getParent());
21623f71b425SGiorgis Georgakoudis       // Do not delete BBs added during manifests of AAs.
21633f71b425SGiorgis Georgakoudis       if (ManifestAddedBlocks.contains(BB))
21643f71b425SGiorgis Georgakoudis         continue;
2165b0c77c36SJohannes Doerfert       ToBeDeletedBBs.push_back(BB);
2166b0c77c36SJohannes Doerfert     }
21675e442a51SJohannes Doerfert     // Actually we do not delete the blocks but squash them into a single
21685e442a51SJohannes Doerfert     // unreachable but untangling branches that jump here is something we need
21695e442a51SJohannes Doerfert     // to do in a more generic way.
2170cf0357a5SNikita Popov     detachDeadBlocks(ToBeDeletedBBs, nullptr);
217139681e73SJohannes Doerfert   }
2172b19cd27bSJohannes Doerfert 
21731c2531c9SJohannes Doerfert   identifyDeadInternalFunctions();
217439681e73SJohannes Doerfert 
2175b0c77c36SJohannes Doerfert   // Rewrite the functions as requested during manifest.
217610b05397Sclfbbn   ChangeStatus ManifestChange = rewriteFunctionSignatures(CGModifiedFunctions);
2177b0c77c36SJohannes Doerfert 
2178b0c77c36SJohannes Doerfert   for (Function *Fn : CGModifiedFunctions)
21791ba2929bSJohannes Doerfert     if (!ToBeDeletedFunctions.count(Fn) && Functions.count(Fn))
21803be3b401SJohannes Doerfert       Configuration.CGUpdater.reanalyzeFunction(*Fn);
2181b0c77c36SJohannes Doerfert 
21828d8ce85bSsstefan1   for (Function *Fn : ToBeDeletedFunctions) {
21838d8ce85bSsstefan1     if (!Functions.count(Fn))
21848d8ce85bSsstefan1       continue;
21853be3b401SJohannes Doerfert     Configuration.CGUpdater.removeFunction(*Fn);
21868d8ce85bSsstefan1   }
21876b9ee2d6SJohannes Doerfert 
218879651265SJohannes Doerfert   if (!ToBeChangedUses.empty())
218979651265SJohannes Doerfert     ManifestChange = ChangeStatus::CHANGED;
219079651265SJohannes Doerfert 
219179651265SJohannes Doerfert   if (!ToBeChangedToUnreachableInsts.empty())
219279651265SJohannes Doerfert     ManifestChange = ChangeStatus::CHANGED;
219379651265SJohannes Doerfert 
21945621571fSserge-sans-paille   if (!ToBeDeletedFunctions.empty())
21955621571fSserge-sans-paille     ManifestChange = ChangeStatus::CHANGED;
21965621571fSserge-sans-paille 
219779651265SJohannes Doerfert   if (!ToBeDeletedBlocks.empty())
219879651265SJohannes Doerfert     ManifestChange = ChangeStatus::CHANGED;
219979651265SJohannes Doerfert 
220079651265SJohannes Doerfert   if (!ToBeDeletedInsts.empty())
220179651265SJohannes Doerfert     ManifestChange = ChangeStatus::CHANGED;
220279651265SJohannes Doerfert 
220379651265SJohannes Doerfert   if (!InvokeWithDeadSuccessor.empty())
220479651265SJohannes Doerfert     ManifestChange = ChangeStatus::CHANGED;
220579651265SJohannes Doerfert 
220679651265SJohannes Doerfert   if (!DeadInsts.empty())
220779651265SJohannes Doerfert     ManifestChange = ChangeStatus::CHANGED;
220879651265SJohannes Doerfert 
22090985554bSJohannes Doerfert   NumFnDeleted += ToBeDeletedFunctions.size();
22100985554bSJohannes Doerfert 
22111d57b7f5SJohannes Doerfert   LLVM_DEBUG(dbgs() << "[Attributor] Deleted " << ToBeDeletedFunctions.size()
2212850b150cSsstefan1                     << " functions after manifest.\n");
2213850b150cSsstefan1 
2214ad9c284cSJohannes Doerfert #ifdef EXPENSIVE_CHECKS
2215ad9c284cSJohannes Doerfert   for (Function *F : Functions) {
2216ad9c284cSJohannes Doerfert     if (ToBeDeletedFunctions.count(F))
2217ad9c284cSJohannes Doerfert       continue;
2218ad9c284cSJohannes Doerfert     assert(!verifyFunction(*F, &errs()) && "Module verification failed!");
2219ad9c284cSJohannes Doerfert   }
2220ad9c284cSJohannes Doerfert #endif
2221ad9c284cSJohannes Doerfert 
2222aade782aSJohannes Doerfert   return ManifestChange;
2223aade782aSJohannes Doerfert }
2224aade782aSJohannes Doerfert 
run()222570330edcSKuter Dinel ChangeStatus Attributor::run() {
222649def10eSkuterd   TimeTraceScope TimeScope("Attributor::run");
2227eaf1b681SKuter Dinel   AttributorCallGraph ACallGraph(*this);
2228eaf1b681SKuter Dinel 
2229eaf1b681SKuter Dinel   if (PrintCallGraph)
2230eaf1b681SKuter Dinel     ACallGraph.populateAll();
223149def10eSkuterd 
22327a68f0f1SShinji Okumura   Phase = AttributorPhase::UPDATE;
223370330edcSKuter Dinel   runTillFixpoint();
22345ee07dc5SLuofan Chen 
22355ee07dc5SLuofan Chen   // dump graphs on demand
22365ee07dc5SLuofan Chen   if (DumpDepGraph)
22375ee07dc5SLuofan Chen     DG.dumpGraph();
22385ee07dc5SLuofan Chen 
22395ee07dc5SLuofan Chen   if (ViewDepGraph)
22405ee07dc5SLuofan Chen     DG.viewGraph();
22415ee07dc5SLuofan Chen 
22425ee07dc5SLuofan Chen   if (PrintDependencies)
22435ee07dc5SLuofan Chen     DG.print();
22445ee07dc5SLuofan Chen 
22457a68f0f1SShinji Okumura   Phase = AttributorPhase::MANIFEST;
224670330edcSKuter Dinel   ChangeStatus ManifestChange = manifestAttributes();
22477a68f0f1SShinji Okumura 
22487a68f0f1SShinji Okumura   Phase = AttributorPhase::CLEANUP;
224970330edcSKuter Dinel   ChangeStatus CleanupChange = cleanupIR();
22507a68f0f1SShinji Okumura 
2251eaf1b681SKuter Dinel   if (PrintCallGraph)
2252eaf1b681SKuter Dinel     ACallGraph.print();
2253eaf1b681SKuter Dinel 
225470330edcSKuter Dinel   return ManifestChange | CleanupChange;
225570330edcSKuter Dinel }
225670330edcSKuter Dinel 
updateAA(AbstractAttribute & AA)225795e0d28bSJohannes Doerfert ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {
2258cb813ab6SJohannes Doerfert   TimeTraceScope TimeScope(
2259cb813ab6SJohannes Doerfert       AA.getName() + std::to_string(AA.getIRPosition().getPositionKind()) +
2260cb813ab6SJohannes Doerfert       "::updateAA");
2261c5e6872eSShinji Okumura   assert(Phase == AttributorPhase::UPDATE &&
2262c5e6872eSShinji Okumura          "We can update AA only in the update stage!");
226349def10eSkuterd 
226495e0d28bSJohannes Doerfert   // Use a new dependence vector for this update.
226595e0d28bSJohannes Doerfert   DependenceVector DV;
226695e0d28bSJohannes Doerfert   DependenceStack.push_back(&DV);
226795e0d28bSJohannes Doerfert 
226895e0d28bSJohannes Doerfert   auto &AAState = AA.getState();
2269edf03914SJohannes Doerfert   ChangeStatus CS = ChangeStatus::UNCHANGED;
2270792aac98SJohannes Doerfert   bool UsedAssumedInformation = false;
2271792aac98SJohannes Doerfert   if (!isAssumedDead(AA, nullptr, UsedAssumedInformation,
2272792aac98SJohannes Doerfert                      /* CheckBBLivenessOnly */ true))
2273edf03914SJohannes Doerfert     CS = AA.update(*this);
2274edf03914SJohannes Doerfert 
2275b51b83f6SJohannes Doerfert   if (!AA.isQueryAA() && DV.empty()) {
227695e0d28bSJohannes Doerfert     // If the attribute did not query any non-fix information, the state
227795e0d28bSJohannes Doerfert     // will not change and we can indicate that right away.
227895e0d28bSJohannes Doerfert     AAState.indicateOptimisticFixpoint();
227995e0d28bSJohannes Doerfert   }
228095e0d28bSJohannes Doerfert 
228195e0d28bSJohannes Doerfert   if (!AAState.isAtFixpoint())
228295e0d28bSJohannes Doerfert     rememberDependences();
228395e0d28bSJohannes Doerfert 
228495e0d28bSJohannes Doerfert   // Verify the stack was used properly, that is we pop the dependence vector we
228595e0d28bSJohannes Doerfert   // put there earlier.
228695e0d28bSJohannes Doerfert   DependenceVector *PoppedDV = DependenceStack.pop_back_val();
228795e0d28bSJohannes Doerfert   (void)PoppedDV;
228895e0d28bSJohannes Doerfert   assert(PoppedDV == &DV && "Inconsistent usage of the dependence stack!");
228995e0d28bSJohannes Doerfert 
229095e0d28bSJohannes Doerfert   return CS;
229195e0d28bSJohannes Doerfert }
229295e0d28bSJohannes Doerfert 
createShallowWrapper(Function & F)2293ce16be25Ssstefan1 void Attributor::createShallowWrapper(Function &F) {
2294eec6d876SLuofan Chen   assert(!F.isDeclaration() && "Cannot create a wrapper around a declaration!");
2295eec6d876SLuofan Chen 
2296eec6d876SLuofan Chen   Module &M = *F.getParent();
2297eec6d876SLuofan Chen   LLVMContext &Ctx = M.getContext();
2298eec6d876SLuofan Chen   FunctionType *FnTy = F.getFunctionType();
2299eec6d876SLuofan Chen 
2300eec6d876SLuofan Chen   Function *Wrapper =
2301eec6d876SLuofan Chen       Function::Create(FnTy, F.getLinkage(), F.getAddressSpace(), F.getName());
2302eec6d876SLuofan Chen   F.setName(""); // set the inside function anonymous
2303eec6d876SLuofan Chen   M.getFunctionList().insert(F.getIterator(), Wrapper);
2304eec6d876SLuofan Chen 
2305eec6d876SLuofan Chen   F.setLinkage(GlobalValue::InternalLinkage);
2306eec6d876SLuofan Chen 
2307eec6d876SLuofan Chen   F.replaceAllUsesWith(Wrapper);
2308b7e23582SNikita Popov   assert(F.use_empty() && "Uses remained after wrapper was created!");
2309eec6d876SLuofan Chen 
2310eec6d876SLuofan Chen   // Move the COMDAT section to the wrapper.
2311eec6d876SLuofan Chen   // TODO: Check if we need to keep it for F as well.
2312eec6d876SLuofan Chen   Wrapper->setComdat(F.getComdat());
2313eec6d876SLuofan Chen   F.setComdat(nullptr);
2314eec6d876SLuofan Chen 
2315eec6d876SLuofan Chen   // Copy all metadata and attributes but keep them on F as well.
2316eec6d876SLuofan Chen   SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
2317eec6d876SLuofan Chen   F.getAllMetadata(MDs);
2318eec6d876SLuofan Chen   for (auto MDIt : MDs)
2319eec6d876SLuofan Chen     Wrapper->addMetadata(MDIt.first, *MDIt.second);
2320eec6d876SLuofan Chen   Wrapper->setAttributes(F.getAttributes());
2321eec6d876SLuofan Chen 
2322eec6d876SLuofan Chen   // Create the call in the wrapper.
2323eec6d876SLuofan Chen   BasicBlock *EntryBB = BasicBlock::Create(Ctx, "entry", Wrapper);
2324eec6d876SLuofan Chen 
2325eec6d876SLuofan Chen   SmallVector<Value *, 8> Args;
2326ff70c25dSJohannes Doerfert   Argument *FArgIt = F.arg_begin();
2327eec6d876SLuofan Chen   for (Argument &Arg : Wrapper->args()) {
2328eec6d876SLuofan Chen     Args.push_back(&Arg);
2329eec6d876SLuofan Chen     Arg.setName((FArgIt++)->getName());
2330eec6d876SLuofan Chen   }
2331eec6d876SLuofan Chen 
2332eec6d876SLuofan Chen   CallInst *CI = CallInst::Create(&F, Args, "", EntryBB);
2333eec6d876SLuofan Chen   CI->setTailCall(true);
23343f4d00bcSArthur Eubanks   CI->addFnAttr(Attribute::NoInline);
2335eec6d876SLuofan Chen   ReturnInst::Create(Ctx, CI->getType()->isVoidTy() ? nullptr : CI, EntryBB);
2336eec6d876SLuofan Chen 
2337ce16be25Ssstefan1   NumFnShallowWrappersCreated++;
2338eec6d876SLuofan Chen }
2339eec6d876SLuofan Chen 
isInternalizable(Function & F)2340adbaa39dSJoseph Huber bool Attributor::isInternalizable(Function &F) {
2341adbaa39dSJoseph Huber   if (F.isDeclaration() || F.hasLocalLinkage() ||
2342adbaa39dSJoseph Huber       GlobalValue::isInterposableLinkage(F.getLinkage()))
2343adbaa39dSJoseph Huber     return false;
2344adbaa39dSJoseph Huber   return true;
2345adbaa39dSJoseph Huber }
2346adbaa39dSJoseph Huber 
internalizeFunction(Function & F,bool Force)234703d7e61cSJoseph Huber Function *Attributor::internalizeFunction(Function &F, bool Force) {
234803d7e61cSJoseph Huber   if (!AllowDeepWrapper && !Force)
234903d7e61cSJoseph Huber     return nullptr;
2350adbaa39dSJoseph Huber   if (!isInternalizable(F))
235103d7e61cSJoseph Huber     return nullptr;
235287a85f3dSLuofan Chen 
2353adbaa39dSJoseph Huber   SmallPtrSet<Function *, 2> FnSet = {&F};
2354adbaa39dSJoseph Huber   DenseMap<Function *, Function *> InternalizedFns;
2355adbaa39dSJoseph Huber   internalizeFunctions(FnSet, InternalizedFns);
235687a85f3dSLuofan Chen 
2357adbaa39dSJoseph Huber   return InternalizedFns[&F];
2358adbaa39dSJoseph Huber }
2359adbaa39dSJoseph Huber 
internalizeFunctions(SmallPtrSetImpl<Function * > & FnSet,DenseMap<Function *,Function * > & FnMap)2360adbaa39dSJoseph Huber bool Attributor::internalizeFunctions(SmallPtrSetImpl<Function *> &FnSet,
2361adbaa39dSJoseph Huber                                       DenseMap<Function *, Function *> &FnMap) {
2362adbaa39dSJoseph Huber   for (Function *F : FnSet)
2363adbaa39dSJoseph Huber     if (!Attributor::isInternalizable(*F))
2364adbaa39dSJoseph Huber       return false;
2365adbaa39dSJoseph Huber 
2366adbaa39dSJoseph Huber   FnMap.clear();
2367adbaa39dSJoseph Huber   // Generate the internalized version of each function.
2368adbaa39dSJoseph Huber   for (Function *F : FnSet) {
2369adbaa39dSJoseph Huber     Module &M = *F->getParent();
2370adbaa39dSJoseph Huber     FunctionType *FnTy = F->getFunctionType();
2371adbaa39dSJoseph Huber 
2372adbaa39dSJoseph Huber     // Create a copy of the current function
2373adbaa39dSJoseph Huber     Function *Copied =
2374adbaa39dSJoseph Huber         Function::Create(FnTy, F->getLinkage(), F->getAddressSpace(),
2375adbaa39dSJoseph Huber                          F->getName() + ".internalized");
237687a85f3dSLuofan Chen     ValueToValueMapTy VMap;
237787a85f3dSLuofan Chen     auto *NewFArgIt = Copied->arg_begin();
2378adbaa39dSJoseph Huber     for (auto &Arg : F->args()) {
237987a85f3dSLuofan Chen       auto ArgName = Arg.getName();
238087a85f3dSLuofan Chen       NewFArgIt->setName(ArgName);
238187a85f3dSLuofan Chen       VMap[&Arg] = &(*NewFArgIt++);
238287a85f3dSLuofan Chen     }
238387a85f3dSLuofan Chen     SmallVector<ReturnInst *, 8> Returns;
238487a85f3dSLuofan Chen 
238587a85f3dSLuofan Chen     // Copy the body of the original function to the new one
2386adbaa39dSJoseph Huber     CloneFunctionInto(Copied, F, VMap,
2387adbaa39dSJoseph Huber                       CloneFunctionChangeType::LocalChangesOnly, Returns);
238887a85f3dSLuofan Chen 
2389adbaa39dSJoseph Huber     // Set the linakage and visibility late as CloneFunctionInto has some
2390adbaa39dSJoseph Huber     // implicit requirements.
2391711bf7dcSJohannes Doerfert     Copied->setVisibility(GlobalValue::DefaultVisibility);
2392711bf7dcSJohannes Doerfert     Copied->setLinkage(GlobalValue::PrivateLinkage);
2393711bf7dcSJohannes Doerfert 
239487a85f3dSLuofan Chen     // Copy metadata
239587a85f3dSLuofan Chen     SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
2396adbaa39dSJoseph Huber     F->getAllMetadata(MDs);
239787a85f3dSLuofan Chen     for (auto MDIt : MDs)
239803d7e61cSJoseph Huber       if (!Copied->hasMetadata())
239987a85f3dSLuofan Chen         Copied->addMetadata(MDIt.first, *MDIt.second);
240087a85f3dSLuofan Chen 
2401adbaa39dSJoseph Huber     M.getFunctionList().insert(F->getIterator(), Copied);
240287a85f3dSLuofan Chen     Copied->setDSOLocal(true);
2403adbaa39dSJoseph Huber     FnMap[F] = Copied;
2404adbaa39dSJoseph Huber   }
240587a85f3dSLuofan Chen 
2406adbaa39dSJoseph Huber   // Replace all uses of the old function with the new internalized function
2407adbaa39dSJoseph Huber   // unless the caller is a function that was just internalized.
2408adbaa39dSJoseph Huber   for (Function *F : FnSet) {
2409adbaa39dSJoseph Huber     auto &InternalizedFn = FnMap[F];
2410adbaa39dSJoseph Huber     auto IsNotInternalized = [&](Use &U) -> bool {
2411adbaa39dSJoseph Huber       if (auto *CB = dyn_cast<CallBase>(U.getUser()))
2412adbaa39dSJoseph Huber         return !FnMap.lookup(CB->getCaller());
2413adbaa39dSJoseph Huber       return false;
2414adbaa39dSJoseph Huber     };
2415adbaa39dSJoseph Huber     F->replaceUsesWithIf(InternalizedFn, IsNotInternalized);
2416adbaa39dSJoseph Huber   }
2417adbaa39dSJoseph Huber 
2418adbaa39dSJoseph Huber   return true;
241987a85f3dSLuofan Chen }
242087a85f3dSLuofan Chen 
isValidFunctionSignatureRewrite(Argument & Arg,ArrayRef<Type * > ReplacementTypes)242189c2e733SJohannes Doerfert bool Attributor::isValidFunctionSignatureRewrite(
242289c2e733SJohannes Doerfert     Argument &Arg, ArrayRef<Type *> ReplacementTypes) {
242375133634SJohannes Doerfert 
24243be3b401SJohannes Doerfert   if (!Configuration.RewriteSignatures)
242503d7e61cSJoseph Huber     return false;
242603d7e61cSJoseph Huber 
24274e7d7caeSJohannes Doerfert   Function *Fn = Arg.getParent();
24284e7d7caeSJohannes Doerfert   auto CallSiteCanBeChanged = [Fn](AbstractCallSite ACS) {
24298d94d3c3SJohannes Doerfert     // Forbid the call site to cast the function return type. If we need to
24308d94d3c3SJohannes Doerfert     // rewrite these functions we need to re-create a cast for the new call site
24318d94d3c3SJohannes Doerfert     // (if the old had uses).
24328d94d3c3SJohannes Doerfert     if (!ACS.getCalledFunction() ||
24338d94d3c3SJohannes Doerfert         ACS.getInstruction()->getType() !=
24348d94d3c3SJohannes Doerfert             ACS.getCalledFunction()->getReturnType())
24358d94d3c3SJohannes Doerfert       return false;
24364e7d7caeSJohannes Doerfert     if (ACS.getCalledOperand()->getType() != Fn->getType())
24374e7d7caeSJohannes Doerfert       return false;
243875133634SJohannes Doerfert     // Forbid must-tail calls for now.
2439798b262cSCraig Topper     return !ACS.isCallbackCall() && !ACS.getInstruction()->isMustTailCall();
244075133634SJohannes Doerfert   };
244175133634SJohannes Doerfert 
244275133634SJohannes Doerfert   // Avoid var-arg functions for now.
244375133634SJohannes Doerfert   if (Fn->isVarArg()) {
244475133634SJohannes Doerfert     LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
244575133634SJohannes Doerfert     return false;
244675133634SJohannes Doerfert   }
244775133634SJohannes Doerfert 
244875133634SJohannes Doerfert   // Avoid functions with complicated argument passing semantics.
244975133634SJohannes Doerfert   AttributeList FnAttributeList = Fn->getAttributes();
245075133634SJohannes Doerfert   if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
245175133634SJohannes Doerfert       FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
24528a887556SArthur Eubanks       FnAttributeList.hasAttrSomewhere(Attribute::InAlloca) ||
24538a887556SArthur Eubanks       FnAttributeList.hasAttrSomewhere(Attribute::Preallocated)) {
245475133634SJohannes Doerfert     LLVM_DEBUG(
245575133634SJohannes Doerfert         dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
245675133634SJohannes Doerfert     return false;
245775133634SJohannes Doerfert   }
245875133634SJohannes Doerfert 
245975133634SJohannes Doerfert   // Avoid callbacks for now.
24606ed1ef06SJohannes Doerfert   bool UsedAssumedInformation = false;
2461368f7ee7SJohannes Doerfert   if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,
24626ed1ef06SJohannes Doerfert                             UsedAssumedInformation)) {
246375133634SJohannes Doerfert     LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
246475133634SJohannes Doerfert     return false;
246575133634SJohannes Doerfert   }
246675133634SJohannes Doerfert 
246775133634SJohannes Doerfert   auto InstPred = [](Instruction &I) {
246875133634SJohannes Doerfert     if (auto *CI = dyn_cast<CallInst>(&I))
246975133634SJohannes Doerfert       return !CI->isMustTailCall();
247075133634SJohannes Doerfert     return true;
247175133634SJohannes Doerfert   };
247275133634SJohannes Doerfert 
247375133634SJohannes Doerfert   // Forbid must-tail calls for now.
247475133634SJohannes Doerfert   // TODO:
247575133634SJohannes Doerfert   auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
247623f41f16SJohannes Doerfert   if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,
2477792aac98SJohannes Doerfert                                    nullptr, {Instruction::Call},
2478792aac98SJohannes Doerfert                                    UsedAssumedInformation)) {
247975133634SJohannes Doerfert     LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
248075133634SJohannes Doerfert     return false;
248175133634SJohannes Doerfert   }
248275133634SJohannes Doerfert 
248389c2e733SJohannes Doerfert   return true;
248489c2e733SJohannes Doerfert }
248589c2e733SJohannes Doerfert 
registerFunctionSignatureRewrite(Argument & Arg,ArrayRef<Type * > ReplacementTypes,ArgumentReplacementInfo::CalleeRepairCBTy && CalleeRepairCB,ArgumentReplacementInfo::ACSRepairCBTy && ACSRepairCB)248689c2e733SJohannes Doerfert bool Attributor::registerFunctionSignatureRewrite(
248789c2e733SJohannes Doerfert     Argument &Arg, ArrayRef<Type *> ReplacementTypes,
248889c2e733SJohannes Doerfert     ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,
248989c2e733SJohannes Doerfert     ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {
249089c2e733SJohannes Doerfert   LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
249189c2e733SJohannes Doerfert                     << Arg.getParent()->getName() << " with "
249289c2e733SJohannes Doerfert                     << ReplacementTypes.size() << " replacements\n");
249389c2e733SJohannes Doerfert   assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&
249489c2e733SJohannes Doerfert          "Cannot register an invalid rewrite");
249589c2e733SJohannes Doerfert 
249689c2e733SJohannes Doerfert   Function *Fn = Arg.getParent();
24973c89256dSDavid Blaikie   SmallVectorImpl<std::unique_ptr<ArgumentReplacementInfo>> &ARIs =
24983c89256dSDavid Blaikie       ArgumentReplacementMap[Fn];
249989c2e733SJohannes Doerfert   if (ARIs.empty())
250075133634SJohannes Doerfert     ARIs.resize(Fn->arg_size());
250175133634SJohannes Doerfert 
250275133634SJohannes Doerfert   // If we have a replacement already with less than or equal new arguments,
250375133634SJohannes Doerfert   // ignore this request.
25043c89256dSDavid Blaikie   std::unique_ptr<ArgumentReplacementInfo> &ARI = ARIs[Arg.getArgNo()];
250575133634SJohannes Doerfert   if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
250675133634SJohannes Doerfert     LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
250775133634SJohannes Doerfert     return false;
250875133634SJohannes Doerfert   }
250975133634SJohannes Doerfert 
251075133634SJohannes Doerfert   // If we have a replacement already but we like the new one better, delete
251175133634SJohannes Doerfert   // the old.
25123c89256dSDavid Blaikie   ARI.reset();
251375133634SJohannes Doerfert 
251489c2e733SJohannes Doerfert   LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
251589c2e733SJohannes Doerfert                     << Arg.getParent()->getName() << " with "
251689c2e733SJohannes Doerfert                     << ReplacementTypes.size() << " replacements\n");
251789c2e733SJohannes Doerfert 
251875133634SJohannes Doerfert   // Remember the replacement.
25193c89256dSDavid Blaikie   ARI.reset(new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
252075133634SJohannes Doerfert                                         std::move(CalleeRepairCB),
25213c89256dSDavid Blaikie                                         std::move(ACSRepairCB)));
252275133634SJohannes Doerfert 
252375133634SJohannes Doerfert   return true;
252475133634SJohannes Doerfert }
252575133634SJohannes Doerfert 
shouldSeedAttribute(AbstractAttribute & AA)25264dbe82eeSkuter bool Attributor::shouldSeedAttribute(AbstractAttribute &AA) {
252765fcc0eeSkuterd   bool Result = true;
252865fcc0eeSkuterd #ifndef NDEBUG
252965fcc0eeSkuterd   if (SeedAllowList.size() != 0)
253036b8a4f9SKazu Hirata     Result = llvm::is_contained(SeedAllowList, AA.getName());
253165fcc0eeSkuterd   Function *Fn = AA.getAnchorScope();
253265fcc0eeSkuterd   if (FunctionSeedAllowList.size() != 0 && Fn)
253336b8a4f9SKazu Hirata     Result &= llvm::is_contained(FunctionSeedAllowList, Fn->getName());
253465fcc0eeSkuterd #endif
253565fcc0eeSkuterd   return Result;
25364dbe82eeSkuter }
25374dbe82eeSkuter 
rewriteFunctionSignatures(SmallSetVector<Function *,8> & ModifiedFns)2538b0c77c36SJohannes Doerfert ChangeStatus Attributor::rewriteFunctionSignatures(
25397211dbd0SJohannes Doerfert     SmallSetVector<Function *, 8> &ModifiedFns) {
254075133634SJohannes Doerfert   ChangeStatus Changed = ChangeStatus::UNCHANGED;
254175133634SJohannes Doerfert 
254275133634SJohannes Doerfert   for (auto &It : ArgumentReplacementMap) {
254375133634SJohannes Doerfert     Function *OldFn = It.getFirst();
254475133634SJohannes Doerfert 
254575133634SJohannes Doerfert     // Deleted functions do not require rewrites.
25468d8ce85bSsstefan1     if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn))
254775133634SJohannes Doerfert       continue;
254875133634SJohannes Doerfert 
2549a9ee8b49SJohannes Doerfert     const SmallVectorImpl<std::unique_ptr<ArgumentReplacementInfo>> &ARIs =
2550a9ee8b49SJohannes Doerfert         It.getSecond();
255175133634SJohannes Doerfert     assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
255275133634SJohannes Doerfert 
255375133634SJohannes Doerfert     SmallVector<Type *, 16> NewArgumentTypes;
255475133634SJohannes Doerfert     SmallVector<AttributeSet, 16> NewArgumentAttributes;
255575133634SJohannes Doerfert 
255675133634SJohannes Doerfert     // Collect replacement argument types and copy over existing attributes.
255775133634SJohannes Doerfert     AttributeList OldFnAttributeList = OldFn->getAttributes();
255875133634SJohannes Doerfert     for (Argument &Arg : OldFn->args()) {
2559a9ee8b49SJohannes Doerfert       if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
2560a9ee8b49SJohannes Doerfert               ARIs[Arg.getArgNo()]) {
256175133634SJohannes Doerfert         NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
256275133634SJohannes Doerfert                                 ARI->ReplacementTypes.end());
256375133634SJohannes Doerfert         NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
256475133634SJohannes Doerfert                                      AttributeSet());
256575133634SJohannes Doerfert       } else {
256675133634SJohannes Doerfert         NewArgumentTypes.push_back(Arg.getType());
256775133634SJohannes Doerfert         NewArgumentAttributes.push_back(
256880ea2bb5SArthur Eubanks             OldFnAttributeList.getParamAttrs(Arg.getArgNo()));
256975133634SJohannes Doerfert       }
257075133634SJohannes Doerfert     }
257175133634SJohannes Doerfert 
25727c044542SPhoebe Wang     uint64_t LargestVectorWidth = 0;
25737c044542SPhoebe Wang     for (auto *I : NewArgumentTypes)
25747c044542SPhoebe Wang       if (auto *VT = dyn_cast<llvm::VectorType>(I))
25757c044542SPhoebe Wang         LargestVectorWidth = std::max(
25767c044542SPhoebe Wang             LargestVectorWidth, VT->getPrimitiveSizeInBits().getKnownMinSize());
25777c044542SPhoebe Wang 
257875133634SJohannes Doerfert     FunctionType *OldFnTy = OldFn->getFunctionType();
257975133634SJohannes Doerfert     Type *RetTy = OldFnTy->getReturnType();
258075133634SJohannes Doerfert 
258175133634SJohannes Doerfert     // Construct the new function type using the new arguments types.
258275133634SJohannes Doerfert     FunctionType *NewFnTy =
258375133634SJohannes Doerfert         FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
258475133634SJohannes Doerfert 
258575133634SJohannes Doerfert     LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
258675133634SJohannes Doerfert                       << "' from " << *OldFn->getFunctionType() << " to "
258775133634SJohannes Doerfert                       << *NewFnTy << "\n");
258875133634SJohannes Doerfert 
258975133634SJohannes Doerfert     // Create the new function body and insert it into the module.
259075133634SJohannes Doerfert     Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
259175133634SJohannes Doerfert                                        OldFn->getAddressSpace(), "");
25921ba2929bSJohannes Doerfert     Functions.insert(NewFn);
259375133634SJohannes Doerfert     OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
259475133634SJohannes Doerfert     NewFn->takeName(OldFn);
259575133634SJohannes Doerfert     NewFn->copyAttributesFrom(OldFn);
259675133634SJohannes Doerfert 
259775133634SJohannes Doerfert     // Patch the pointer to LLVM function in debug info descriptor.
259875133634SJohannes Doerfert     NewFn->setSubprogram(OldFn->getSubprogram());
259975133634SJohannes Doerfert     OldFn->setSubprogram(nullptr);
260075133634SJohannes Doerfert 
260175133634SJohannes Doerfert     // Recompute the parameter attributes list based on the new arguments for
260275133634SJohannes Doerfert     // the function.
260375133634SJohannes Doerfert     LLVMContext &Ctx = OldFn->getContext();
260475133634SJohannes Doerfert     NewFn->setAttributes(AttributeList::get(
260580ea2bb5SArthur Eubanks         Ctx, OldFnAttributeList.getFnAttrs(), OldFnAttributeList.getRetAttrs(),
260680ea2bb5SArthur Eubanks         NewArgumentAttributes));
26077c044542SPhoebe Wang     AttributeFuncs::updateMinLegalVectorWidthAttr(*NewFn, LargestVectorWidth);
260875133634SJohannes Doerfert 
260975133634SJohannes Doerfert     // Since we have now created the new function, splice the body of the old
261075133634SJohannes Doerfert     // function right into the new function, leaving the old rotting hulk of the
261175133634SJohannes Doerfert     // function empty.
261275133634SJohannes Doerfert     NewFn->getBasicBlockList().splice(NewFn->begin(),
261375133634SJohannes Doerfert                                       OldFn->getBasicBlockList());
261475133634SJohannes Doerfert 
261532f5ee83SSergey Dmitriev     // Fixup block addresses to reference new function.
261632f5ee83SSergey Dmitriev     SmallVector<BlockAddress *, 8u> BlockAddresses;
261732f5ee83SSergey Dmitriev     for (User *U : OldFn->users())
261832f5ee83SSergey Dmitriev       if (auto *BA = dyn_cast<BlockAddress>(U))
261932f5ee83SSergey Dmitriev         BlockAddresses.push_back(BA);
262032f5ee83SSergey Dmitriev     for (auto *BA : BlockAddresses)
262132f5ee83SSergey Dmitriev       BA->replaceAllUsesWith(BlockAddress::get(NewFn, BA->getBasicBlock()));
262232f5ee83SSergey Dmitriev 
2623d2d2fb19SJohannes Doerfert     // Set of all "call-like" instructions that invoke the old function mapped
2624d2d2fb19SJohannes Doerfert     // to their new replacements.
2625d2d2fb19SJohannes Doerfert     SmallVector<std::pair<CallBase *, CallBase *>, 8> CallSitePairs;
262675133634SJohannes Doerfert 
262775133634SJohannes Doerfert     // Callback to create a new "call-like" instruction for a given one.
262875133634SJohannes Doerfert     auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
262975133634SJohannes Doerfert       CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
263075133634SJohannes Doerfert       const AttributeList &OldCallAttributeList = OldCB->getAttributes();
263175133634SJohannes Doerfert 
263275133634SJohannes Doerfert       // Collect the new argument operands for the replacement call site.
263375133634SJohannes Doerfert       SmallVector<Value *, 16> NewArgOperands;
263475133634SJohannes Doerfert       SmallVector<AttributeSet, 16> NewArgOperandAttributes;
263575133634SJohannes Doerfert       for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
263675133634SJohannes Doerfert         unsigned NewFirstArgNum = NewArgOperands.size();
26374f82af81SIlya Biryukov         (void)NewFirstArgNum; // only used inside assert.
2638a9ee8b49SJohannes Doerfert         if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
2639a9ee8b49SJohannes Doerfert                 ARIs[OldArgNum]) {
264075133634SJohannes Doerfert           if (ARI->ACSRepairCB)
264175133634SJohannes Doerfert             ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
264275133634SJohannes Doerfert           assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
264375133634SJohannes Doerfert                      NewArgOperands.size() &&
264475133634SJohannes Doerfert                  "ACS repair callback did not provide as many operand as new "
264575133634SJohannes Doerfert                  "types were registered!");
264675133634SJohannes Doerfert           // TODO: Exose the attribute set to the ACS repair callback
264775133634SJohannes Doerfert           NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
264875133634SJohannes Doerfert                                          AttributeSet());
264975133634SJohannes Doerfert         } else {
265075133634SJohannes Doerfert           NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
265175133634SJohannes Doerfert           NewArgOperandAttributes.push_back(
265280ea2bb5SArthur Eubanks               OldCallAttributeList.getParamAttrs(OldArgNum));
265375133634SJohannes Doerfert         }
265475133634SJohannes Doerfert       }
265575133634SJohannes Doerfert 
265675133634SJohannes Doerfert       assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
265775133634SJohannes Doerfert              "Mismatch # argument operands vs. # argument operand attributes!");
265875133634SJohannes Doerfert       assert(NewArgOperands.size() == NewFn->arg_size() &&
265975133634SJohannes Doerfert              "Mismatch # argument operands vs. # function arguments!");
266075133634SJohannes Doerfert 
266175133634SJohannes Doerfert       SmallVector<OperandBundleDef, 4> OperandBundleDefs;
266275133634SJohannes Doerfert       OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
266375133634SJohannes Doerfert 
266475133634SJohannes Doerfert       // Create a new call or invoke instruction to replace the old one.
266575133634SJohannes Doerfert       CallBase *NewCB;
266675133634SJohannes Doerfert       if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
266775133634SJohannes Doerfert         NewCB =
266875133634SJohannes Doerfert             InvokeInst::Create(NewFn, II->getNormalDest(), II->getUnwindDest(),
266975133634SJohannes Doerfert                                NewArgOperands, OperandBundleDefs, "", OldCB);
267075133634SJohannes Doerfert       } else {
267175133634SJohannes Doerfert         auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
267275133634SJohannes Doerfert                                        "", OldCB);
267375133634SJohannes Doerfert         NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
267475133634SJohannes Doerfert         NewCB = NewCI;
267575133634SJohannes Doerfert       }
267675133634SJohannes Doerfert 
267775133634SJohannes Doerfert       // Copy over various properties and the new attributes.
2678417bcb88SYevgeny Rouban       NewCB->copyMetadata(*OldCB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
267975133634SJohannes Doerfert       NewCB->setCallingConv(OldCB->getCallingConv());
268075133634SJohannes Doerfert       NewCB->takeName(OldCB);
268175133634SJohannes Doerfert       NewCB->setAttributes(AttributeList::get(
268280ea2bb5SArthur Eubanks           Ctx, OldCallAttributeList.getFnAttrs(),
268380ea2bb5SArthur Eubanks           OldCallAttributeList.getRetAttrs(), NewArgOperandAttributes));
268475133634SJohannes Doerfert 
26857c044542SPhoebe Wang       AttributeFuncs::updateMinLegalVectorWidthAttr(*NewCB->getCaller(),
26867c044542SPhoebe Wang                                                     LargestVectorWidth);
26877c044542SPhoebe Wang 
2688d2d2fb19SJohannes Doerfert       CallSitePairs.push_back({OldCB, NewCB});
268975133634SJohannes Doerfert       return true;
269075133634SJohannes Doerfert     };
269175133634SJohannes Doerfert 
269275133634SJohannes Doerfert     // Use the CallSiteReplacementCreator to create replacement call sites.
26936ed1ef06SJohannes Doerfert     bool UsedAssumedInformation = false;
2694368f7ee7SJohannes Doerfert     bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,
26956ed1ef06SJohannes Doerfert                                         true, nullptr, UsedAssumedInformation);
26964f82af81SIlya Biryukov     (void)Success;
269775133634SJohannes Doerfert     assert(Success && "Assumed call site replacement to succeed!");
269875133634SJohannes Doerfert 
269975133634SJohannes Doerfert     // Rewire the arguments.
2700ff70c25dSJohannes Doerfert     Argument *OldFnArgIt = OldFn->arg_begin();
2701ff70c25dSJohannes Doerfert     Argument *NewFnArgIt = NewFn->arg_begin();
270275133634SJohannes Doerfert     for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
270375133634SJohannes Doerfert          ++OldArgNum, ++OldFnArgIt) {
27043c89256dSDavid Blaikie       if (const std::unique_ptr<ArgumentReplacementInfo> &ARI =
27053c89256dSDavid Blaikie               ARIs[OldArgNum]) {
270675133634SJohannes Doerfert         if (ARI->CalleeRepairCB)
270775133634SJohannes Doerfert           ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
2708f3ad8cf0SJohannes Doerfert         if (ARI->ReplacementTypes.empty())
2709f3ad8cf0SJohannes Doerfert           OldFnArgIt->replaceAllUsesWith(
2710f3ad8cf0SJohannes Doerfert               PoisonValue::get(OldFnArgIt->getType()));
271175133634SJohannes Doerfert         NewFnArgIt += ARI->ReplacementTypes.size();
271275133634SJohannes Doerfert       } else {
271375133634SJohannes Doerfert         NewFnArgIt->takeName(&*OldFnArgIt);
271475133634SJohannes Doerfert         OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
271575133634SJohannes Doerfert         ++NewFnArgIt;
271675133634SJohannes Doerfert       }
271775133634SJohannes Doerfert     }
271875133634SJohannes Doerfert 
271975133634SJohannes Doerfert     // Eliminate the instructions *after* we visited all of them.
2720d2d2fb19SJohannes Doerfert     for (auto &CallSitePair : CallSitePairs) {
2721d2d2fb19SJohannes Doerfert       CallBase &OldCB = *CallSitePair.first;
2722d2d2fb19SJohannes Doerfert       CallBase &NewCB = *CallSitePair.second;
27238d94d3c3SJohannes Doerfert       assert(OldCB.getType() == NewCB.getType() &&
27248d94d3c3SJohannes Doerfert              "Cannot handle call sites with different types!");
2725b0c77c36SJohannes Doerfert       ModifiedFns.insert(OldCB.getFunction());
27263be3b401SJohannes Doerfert       Configuration.CGUpdater.replaceCallSite(OldCB, NewCB);
2727d2d2fb19SJohannes Doerfert       OldCB.replaceAllUsesWith(&NewCB);
2728d2d2fb19SJohannes Doerfert       OldCB.eraseFromParent();
2729d2d2fb19SJohannes Doerfert     }
273075133634SJohannes Doerfert 
2731b0c77c36SJohannes Doerfert     // Replace the function in the call graph (if any).
27323be3b401SJohannes Doerfert     Configuration.CGUpdater.replaceFunctionWith(*OldFn, *NewFn);
2733b0c77c36SJohannes Doerfert 
2734b0c77c36SJohannes Doerfert     // If the old function was modified and needed to be reanalyzed, the new one
2735b0c77c36SJohannes Doerfert     // does now.
27367211dbd0SJohannes Doerfert     if (ModifiedFns.remove(OldFn))
2737b0c77c36SJohannes Doerfert       ModifiedFns.insert(NewFn);
2738d2d2fb19SJohannes Doerfert 
273975133634SJohannes Doerfert     Changed = ChangeStatus::CHANGED;
274075133634SJohannes Doerfert   }
274175133634SJohannes Doerfert 
274275133634SJohannes Doerfert   return Changed;
274375133634SJohannes Doerfert }
274475133634SJohannes Doerfert 
initializeInformationCache(const Function & CF,FunctionInfo & FI)2745898bbc25SJohannes Doerfert void InformationCache::initializeInformationCache(const Function &CF,
2746898bbc25SJohannes Doerfert                                                   FunctionInfo &FI) {
2747898bbc25SJohannes Doerfert   // As we do not modify the function here we can remove the const
2748898bbc25SJohannes Doerfert   // withouth breaking implicit assumptions. At the end of the day, we could
2749898bbc25SJohannes Doerfert   // initialize the cache eagerly which would look the same to the users.
2750898bbc25SJohannes Doerfert   Function &F = const_cast<Function &>(CF);
27513ab9e8b8SJohannes Doerfert 
27523ab9e8b8SJohannes Doerfert   // Walk all instructions to find interesting instructions that might be
27533ab9e8b8SJohannes Doerfert   // queried by abstract attributes during their initialization or update.
27543ab9e8b8SJohannes Doerfert   // This has to happen before we create attributes.
27553ab9e8b8SJohannes Doerfert 
2756c42aa1beSJohannes Doerfert   DenseMap<const Value *, Optional<short>> AssumeUsesMap;
2757c42aa1beSJohannes Doerfert 
2758c42aa1beSJohannes Doerfert   // Add \p V to the assume uses map which track the number of uses outside of
2759c42aa1beSJohannes Doerfert   // "visited" assumes. If no outside uses are left the value is added to the
2760c42aa1beSJohannes Doerfert   // assume only use vector.
2761c42aa1beSJohannes Doerfert   auto AddToAssumeUsesMap = [&](const Value &V) -> void {
2762c42aa1beSJohannes Doerfert     SmallVector<const Instruction *> Worklist;
2763c42aa1beSJohannes Doerfert     if (auto *I = dyn_cast<Instruction>(&V))
2764c42aa1beSJohannes Doerfert       Worklist.push_back(I);
2765c42aa1beSJohannes Doerfert     while (!Worklist.empty()) {
2766c42aa1beSJohannes Doerfert       const Instruction *I = Worklist.pop_back_val();
2767c42aa1beSJohannes Doerfert       Optional<short> &NumUses = AssumeUsesMap[I];
2768a7938c74SKazu Hirata       if (!NumUses)
2769c42aa1beSJohannes Doerfert         NumUses = I->getNumUses();
2770611ffcf4SKazu Hirata       NumUses = NumUses.value() - /* this assume */ 1;
2771611ffcf4SKazu Hirata       if (NumUses.value() != 0)
2772c42aa1beSJohannes Doerfert         continue;
2773c42aa1beSJohannes Doerfert       AssumeOnlyValues.insert(I);
2774c42aa1beSJohannes Doerfert       for (const Value *Op : I->operands())
2775c42aa1beSJohannes Doerfert         if (auto *OpI = dyn_cast<Instruction>(Op))
2776c42aa1beSJohannes Doerfert           Worklist.push_back(OpI);
2777c42aa1beSJohannes Doerfert     }
2778c42aa1beSJohannes Doerfert   };
2779c42aa1beSJohannes Doerfert 
27803ab9e8b8SJohannes Doerfert   for (Instruction &I : instructions(&F)) {
27813ab9e8b8SJohannes Doerfert     bool IsInterestingOpcode = false;
27823ab9e8b8SJohannes Doerfert 
27833ab9e8b8SJohannes Doerfert     // To allow easy access to all instructions in a function with a given
27843ab9e8b8SJohannes Doerfert     // opcode we store them in the InfoCache. As not all opcodes are interesting
27853ab9e8b8SJohannes Doerfert     // to concrete attributes we only cache the ones that are as identified in
27863ab9e8b8SJohannes Doerfert     // the following switch.
27873ab9e8b8SJohannes Doerfert     // Note: There are no concrete attributes now so this is initially empty.
27883ab9e8b8SJohannes Doerfert     switch (I.getOpcode()) {
27893ab9e8b8SJohannes Doerfert     default:
27905f6d93c7SCraig Topper       assert(!isa<CallBase>(&I) &&
27915f6d93c7SCraig Topper              "New call base instruction type needs to be known in the "
27923ab9e8b8SJohannes Doerfert              "Attributor.");
27933ab9e8b8SJohannes Doerfert       break;
27945699d08bSJohannes Doerfert     case Instruction::Call:
2795b1c788d0SJohannes Doerfert       // Calls are interesting on their own, additionally:
2796b1c788d0SJohannes Doerfert       // For `llvm.assume` calls we also fill the KnowledgeMap as we find them.
2797b1c788d0SJohannes Doerfert       // For `must-tail` calls we remember the caller and callee.
27989ef6aa02SPhilip Reames       if (auto *Assume = dyn_cast<AssumeInst>(&I)) {
2799898bbc25SJohannes Doerfert         fillMapFromAssume(*Assume, KnowledgeMap);
2800c42aa1beSJohannes Doerfert         AddToAssumeUsesMap(*Assume->getArgOperand(0));
2801b1c788d0SJohannes Doerfert       } else if (cast<CallInst>(I).isMustTailCall()) {
2802898bbc25SJohannes Doerfert         FI.ContainsMustTailCall = true;
2803898bbc25SJohannes Doerfert         if (const Function *Callee = cast<CallInst>(I).getCalledFunction())
2804898bbc25SJohannes Doerfert           getFunctionInfo(*Callee).CalledViaMustTail = true;
28055699d08bSJohannes Doerfert       }
28065699d08bSJohannes Doerfert       LLVM_FALLTHROUGH;
28073ab9e8b8SJohannes Doerfert     case Instruction::CallBr:
28083ab9e8b8SJohannes Doerfert     case Instruction::Invoke:
28093ab9e8b8SJohannes Doerfert     case Instruction::CleanupRet:
28103ab9e8b8SJohannes Doerfert     case Instruction::CatchSwitch:
28115732f56bSJohannes Doerfert     case Instruction::AtomicRMW:
28125732f56bSJohannes Doerfert     case Instruction::AtomicCmpXchg:
2813ef4febd8SHideto Ueno     case Instruction::Br:
28143ab9e8b8SJohannes Doerfert     case Instruction::Resume:
28153ab9e8b8SJohannes Doerfert     case Instruction::Ret:
2816b1c788d0SJohannes Doerfert     case Instruction::Load:
2817b1c788d0SJohannes Doerfert       // The alignment of a pointer is interesting for loads.
2818b1c788d0SJohannes Doerfert     case Instruction::Store:
2819b1c788d0SJohannes Doerfert       // The alignment of a pointer is interesting for stores.
282096709823SKuter Dinel     case Instruction::Alloca:
282196709823SKuter Dinel     case Instruction::AddrSpaceCast:
28223ab9e8b8SJohannes Doerfert       IsInterestingOpcode = true;
28233ab9e8b8SJohannes Doerfert     }
2824177c065eSJohannes Doerfert     if (IsInterestingOpcode) {
2825177c065eSJohannes Doerfert       auto *&Insts = FI.OpcodeInstMap[I.getOpcode()];
2826177c065eSJohannes Doerfert       if (!Insts)
2827177c065eSJohannes Doerfert         Insts = new (Allocator) InstructionVectorTy();
2828177c065eSJohannes Doerfert       Insts->push_back(&I);
2829177c065eSJohannes Doerfert     }
28303ab9e8b8SJohannes Doerfert     if (I.mayReadOrWriteMemory())
2831898bbc25SJohannes Doerfert       FI.RWInsts.push_back(&I);
28323ab9e8b8SJohannes Doerfert   }
2833a198adb4SJohannes Doerfert 
2834a198adb4SJohannes Doerfert   if (F.hasFnAttribute(Attribute::AlwaysInline) &&
2835a198adb4SJohannes Doerfert       isInlineViable(F).isSuccess())
2836898bbc25SJohannes Doerfert     InlineableFunctions.insert(&F);
28373ab9e8b8SJohannes Doerfert }
28383ab9e8b8SJohannes Doerfert 
getAAResultsForFunction(const Function & F)28392ce38b3fSdfukalov AAResults *InformationCache::getAAResultsForFunction(const Function &F) {
28402ce38b3fSdfukalov   return AG.getAnalysis<AAManager>(F);
28412ce38b3fSdfukalov }
28422ce38b3fSdfukalov 
~FunctionInfo()2843177c065eSJohannes Doerfert InformationCache::FunctionInfo::~FunctionInfo() {
2844177c065eSJohannes Doerfert   // The instruction vectors are allocated using a BumpPtrAllocator, we need to
2845177c065eSJohannes Doerfert   // manually destroy them.
2846177c065eSJohannes Doerfert   for (auto &It : OpcodeInstMap)
2847177c065eSJohannes Doerfert     It.getSecond()->~InstructionVectorTy();
2848177c065eSJohannes Doerfert }
2849177c065eSJohannes Doerfert 
recordDependence(const AbstractAttribute & FromAA,const AbstractAttribute & ToAA,DepClassTy DepClass)285012173e60SJohannes Doerfert void Attributor::recordDependence(const AbstractAttribute &FromAA,
2851680f6380SJohannes Doerfert                                   const AbstractAttribute &ToAA,
2852680f6380SJohannes Doerfert                                   DepClassTy DepClass) {
2853e592dad8SJohannes Doerfert   if (DepClass == DepClassTy::NONE)
2854e592dad8SJohannes Doerfert     return;
285595e0d28bSJohannes Doerfert   // If we are outside of an update, thus before the actual fixpoint iteration
285695e0d28bSJohannes Doerfert   // started (= when we create AAs), we do not track dependences because we will
285795e0d28bSJohannes Doerfert   // put all AAs into the initial worklist anyway.
285895e0d28bSJohannes Doerfert   if (DependenceStack.empty())
285995e0d28bSJohannes Doerfert     return;
28602dad729fSJohannes Doerfert   if (FromAA.getState().isAtFixpoint())
28612dad729fSJohannes Doerfert     return;
286295e0d28bSJohannes Doerfert   DependenceStack.back()->push_back({&FromAA, &ToAA, DepClass});
286395e0d28bSJohannes Doerfert }
28642dad729fSJohannes Doerfert 
rememberDependences()286595e0d28bSJohannes Doerfert void Attributor::rememberDependences() {
286695e0d28bSJohannes Doerfert   assert(!DependenceStack.empty() && "No dependences to remember!");
286795e0d28bSJohannes Doerfert 
286895e0d28bSJohannes Doerfert   for (DepInfo &DI : *DependenceStack.back()) {
2869e592dad8SJohannes Doerfert     assert((DI.DepClass == DepClassTy::REQUIRED ||
2870e592dad8SJohannes Doerfert             DI.DepClass == DepClassTy::OPTIONAL) &&
2871e592dad8SJohannes Doerfert            "Expected required or optional dependence (1 bit)!");
28723a8740bdSJohannes Doerfert     auto &DepAAs = const_cast<AbstractAttribute &>(*DI.FromAA).Deps;
28733a8740bdSJohannes Doerfert     DepAAs.push_back(AbstractAttribute::DepTy(
28743a8740bdSJohannes Doerfert         const_cast<AbstractAttribute *>(DI.ToAA), unsigned(DI.DepClass)));
287595e0d28bSJohannes Doerfert   }
287612173e60SJohannes Doerfert }
287712173e60SJohannes Doerfert 
identifyDefaultAbstractAttributes(Function & F)28783bb5cbc2SHideto Ueno void Attributor::identifyDefaultAbstractAttributes(Function &F) {
28792f622063SJohannes Doerfert   if (!VisitedFunctions.insert(&F).second)
28802f622063SJohannes Doerfert     return;
2881c36e2ebfSJohannes Doerfert   if (F.isDeclaration())
2882c36e2ebfSJohannes Doerfert     return;
2883aade782aSJohannes Doerfert 
2884b1c788d0SJohannes Doerfert   // In non-module runs we need to look at the call sites of a function to
2885b1c788d0SJohannes Doerfert   // determine if it is part of a must-tail call edge. This will influence what
2886b1c788d0SJohannes Doerfert   // attributes we can derive.
2887898bbc25SJohannes Doerfert   InformationCache::FunctionInfo &FI = InfoCache.getFunctionInfo(F);
2888898bbc25SJohannes Doerfert   if (!isModulePass() && !FI.CalledViaMustTail) {
2889b1c788d0SJohannes Doerfert     for (const Use &U : F.uses())
28905f6d93c7SCraig Topper       if (const auto *CB = dyn_cast<CallBase>(U.getUser()))
28915f6d93c7SCraig Topper         if (CB->isCallee(&U) && CB->isMustTailCall())
2892898bbc25SJohannes Doerfert           FI.CalledViaMustTail = true;
2893898bbc25SJohannes Doerfert   }
2894b1c788d0SJohannes Doerfert 
2895710ebb03SJohannes Doerfert   IRPosition FPos = IRPosition::function(F);
2896710ebb03SJohannes Doerfert 
2897305b961fSJohannes Doerfert   // Check for dead BasicBlocks in every function.
289821fe0a31SJohannes Doerfert   // We need dead instruction detection because we do not want to deal with
289921fe0a31SJohannes Doerfert   // broken IR in which SSA rules do not apply.
290097fd582bSJohannes Doerfert   getOrCreateAAFor<AAIsDead>(FPos);
2901305b961fSJohannes Doerfert 
2902305b961fSJohannes Doerfert   // Every function might be "will-return".
290397fd582bSJohannes Doerfert   getOrCreateAAFor<AAWillReturn>(FPos);
2904305b961fSJohannes Doerfert 
290558f324a4SJohannes Doerfert   // Every function might contain instructions that cause "undefined behavior".
290658f324a4SJohannes Doerfert   getOrCreateAAFor<AAUndefinedBehavior>(FPos);
290758f324a4SJohannes Doerfert 
29085360589bSStefan Stipanovic   // Every function can be nounwind.
290997fd582bSJohannes Doerfert   getOrCreateAAFor<AANoUnwind>(FPos);
29105360589bSStefan Stipanovic 
291106263672SStefan Stipanovic   // Every function might be marked "nosync"
291297fd582bSJohannes Doerfert   getOrCreateAAFor<AANoSync>(FPos);
291306263672SStefan Stipanovic 
291465bbaf9eSHideto Ueno   // Every function might be "no-free".
291597fd582bSJohannes Doerfert   getOrCreateAAFor<AANoFree>(FPos);
291665bbaf9eSHideto Ueno 
2917e83f3039SJohannes Doerfert   // Every function might be "no-return".
291897fd582bSJohannes Doerfert   getOrCreateAAFor<AANoReturn>(FPos);
2919e83f3039SJohannes Doerfert 
292063f6066bSHideto Ueno   // Every function might be "no-recurse".
292163f6066bSHideto Ueno   getOrCreateAAFor<AANoRecurse>(FPos);
292263f6066bSHideto Ueno 
29231097fab1SJohannes Doerfert   // Every function might be "readnone/readonly/writeonly/...".
29241097fab1SJohannes Doerfert   getOrCreateAAFor<AAMemoryBehavior>(FPos);
29251097fab1SJohannes Doerfert 
2926282f5d7aSJohannes Doerfert   // Every function can be "readnone/argmemonly/inaccessiblememonly/...".
2927282f5d7aSJohannes Doerfert   getOrCreateAAFor<AAMemoryLocation>(FPos);
2928282f5d7aSJohannes Doerfert 
2929b8a825b4SJoseph Huber   // Every function can track active assumptions.
2930b8a825b4SJoseph Huber   getOrCreateAAFor<AAAssumptionInfo>(FPos);
2931b8a825b4SJoseph Huber 
2932431141c5SStefan Stipanovic   // Every function might be applicable for Heap-To-Stack conversion.
2933431141c5SStefan Stipanovic   if (EnableHeapToStack)
2934431141c5SStefan Stipanovic     getOrCreateAAFor<AAHeapToStack>(FPos);
2935431141c5SStefan Stipanovic 
2936accd3e87SJohannes Doerfert   // Return attributes are only appropriate if the return type is non void.
2937accd3e87SJohannes Doerfert   Type *ReturnType = F.getReturnType();
2938accd3e87SJohannes Doerfert   if (!ReturnType->isVoidTy()) {
2939accd3e87SJohannes Doerfert     // Argument attribute "returned" --- Create only one per function even
2940accd3e87SJohannes Doerfert     // though it is an argument attribute.
294197fd582bSJohannes Doerfert     getOrCreateAAFor<AAReturnedValues>(FPos);
294254869ec9SHideto Ueno 
2943710ebb03SJohannes Doerfert     IRPosition RetPos = IRPosition::returned(F);
2944710ebb03SJohannes Doerfert 
2945cd4aab4aSJohannes Doerfert     // Every returned value might be dead.
2946cd4aab4aSJohannes Doerfert     getOrCreateAAFor<AAIsDead>(RetPos);
2947cd4aab4aSJohannes Doerfert 
2948f2b9dc47SHideto Ueno     // Every function might be simplified.
294994841c71SJohannes Doerfert     bool UsedAssumedInformation = false;
2950bf789b19SJohannes Doerfert     getAssumedSimplified(RetPos, nullptr, UsedAssumedInformation,
2951bf789b19SJohannes Doerfert                          AA::Intraprocedural);
2952f2b9dc47SHideto Ueno 
29537a15dfd0SShinji Okumura     // Every returned value might be marked noundef.
29547a15dfd0SShinji Okumura     getOrCreateAAFor<AANoUndef>(RetPos);
29557a15dfd0SShinji Okumura 
2956f2b9dc47SHideto Ueno     if (ReturnType->isPointerTy()) {
2957f2b9dc47SHideto Ueno 
2958e7bea9b7SHideto Ueno       // Every function with pointer return type might be marked align.
295997fd582bSJohannes Doerfert       getOrCreateAAFor<AAAlign>(RetPos);
2960e7bea9b7SHideto Ueno 
296154869ec9SHideto Ueno       // Every function with pointer return type might be marked nonnull.
296297fd582bSJohannes Doerfert       getOrCreateAAFor<AANonNull>(RetPos);
296369ebb020SStefan Stipanovic 
296469ebb020SStefan Stipanovic       // Every function with pointer return type might be marked noalias.
296597fd582bSJohannes Doerfert       getOrCreateAAFor<AANoAlias>(RetPos);
296619c07afeSHideto Ueno 
296719c07afeSHideto Ueno       // Every function with pointer return type might be marked
296819c07afeSHideto Ueno       // dereferenceable.
296997fd582bSJohannes Doerfert       getOrCreateAAFor<AADereferenceable>(RetPos);
297069ebb020SStefan Stipanovic     }
297154869ec9SHideto Ueno   }
297254869ec9SHideto Ueno 
297354869ec9SHideto Ueno   for (Argument &Arg : F.args()) {
2974710ebb03SJohannes Doerfert     IRPosition ArgPos = IRPosition::argument(Arg);
2975f2b9dc47SHideto Ueno 
2976666dc6f1SJohannes Doerfert     // Every argument might be simplified. We have to go through the Attributor
2977666dc6f1SJohannes Doerfert     // interface though as outside AAs can register custom simplification
2978666dc6f1SJohannes Doerfert     // callbacks.
29793f5d53a5SHaojian Wu     bool UsedAssumedInformation = false;
2980bf789b19SJohannes Doerfert     getAssumedSimplified(ArgPos, /* AA */ nullptr, UsedAssumedInformation,
2981bf789b19SJohannes Doerfert                          AA::Intraprocedural);
2982f2b9dc47SHideto Ueno 
29831e99fc9dSJohannes Doerfert     // Every argument might be dead.
29841e99fc9dSJohannes Doerfert     getOrCreateAAFor<AAIsDead>(ArgPos);
29851e99fc9dSJohannes Doerfert 
29867a15dfd0SShinji Okumura     // Every argument might be marked noundef.
29877a15dfd0SShinji Okumura     getOrCreateAAFor<AANoUndef>(ArgPos);
29887a15dfd0SShinji Okumura 
2989f2b9dc47SHideto Ueno     if (Arg.getType()->isPointerTy()) {
299019c07afeSHideto Ueno       // Every argument with pointer type might be marked nonnull.
299197fd582bSJohannes Doerfert       getOrCreateAAFor<AANonNull>(ArgPos);
299219c07afeSHideto Ueno 
2993cbab334eSHideto Ueno       // Every argument with pointer type might be marked noalias.
299497fd582bSJohannes Doerfert       getOrCreateAAFor<AANoAlias>(ArgPos);
2995cbab334eSHideto Ueno 
299619c07afeSHideto Ueno       // Every argument with pointer type might be marked dereferenceable.
299797fd582bSJohannes Doerfert       getOrCreateAAFor<AADereferenceable>(ArgPos);
2998e7bea9b7SHideto Ueno 
2999e7bea9b7SHideto Ueno       // Every argument with pointer type might be marked align.
300097fd582bSJohannes Doerfert       getOrCreateAAFor<AAAlign>(ArgPos);
30017516a5e0SJohannes Doerfert 
30027516a5e0SJohannes Doerfert       // Every argument with pointer type might be marked nocapture.
300397fd582bSJohannes Doerfert       getOrCreateAAFor<AANoCapture>(ArgPos);
30041097fab1SJohannes Doerfert 
30051097fab1SJohannes Doerfert       // Every argument with pointer type might be marked
30061097fab1SJohannes Doerfert       // "readnone/readonly/writeonly/..."
30071097fab1SJohannes Doerfert       getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
3008f35740d6SStefan Stipanovic 
3009f35740d6SStefan Stipanovic       // Every argument with pointer type might be marked nofree.
3010f35740d6SStefan Stipanovic       getOrCreateAAFor<AANoFree>(ArgPos);
301189c2e733SJohannes Doerfert 
301289c2e733SJohannes Doerfert       // Every argument with pointer type might be privatizable (or promotable)
301389c2e733SJohannes Doerfert       getOrCreateAAFor<AAPrivatizablePtr>(ArgPos);
301419c07afeSHideto Ueno     }
3015accd3e87SJohannes Doerfert   }
3016accd3e87SJohannes Doerfert 
30173ab9e8b8SJohannes Doerfert   auto CallSitePred = [&](Instruction &I) -> bool {
301887f1e939SJohannes Doerfert     auto &CB = cast<CallBase>(I);
3019a1db0e52SJohannes Doerfert     IRPosition CBInstPos = IRPosition::inst(CB);
3020b8a825b4SJoseph Huber     IRPosition CBFnPos = IRPosition::callsite_function(CB);
302186509e8cSJohannes Doerfert 
302286509e8cSJohannes Doerfert     // Call sites might be dead if they do not have side effects and no live
302386509e8cSJohannes Doerfert     // users. The return value might be dead if there are no live users.
3024a1db0e52SJohannes Doerfert     getOrCreateAAFor<AAIsDead>(CBInstPos);
302586509e8cSJohannes Doerfert 
302687f1e939SJohannes Doerfert     Function *Callee = CB.getCalledFunction();
3027c4d3188aSJohannes Doerfert     // TODO: Even if the callee is not known now we might be able to simplify
3028c4d3188aSJohannes Doerfert     //       the call/callee.
3029c4d3188aSJohannes Doerfert     if (!Callee)
3030c4d3188aSJohannes Doerfert       return true;
3031c4d3188aSJohannes Doerfert 
3032b8a825b4SJoseph Huber     // Every call site can track active assumptions.
3033b8a825b4SJoseph Huber     getOrCreateAAFor<AAAssumptionInfo>(CBFnPos);
3034b8a825b4SJoseph Huber 
3035c4d3188aSJohannes Doerfert     // Skip declarations except if annotations on their call sites were
3036c36e2ebfSJohannes Doerfert     // explicitly requested.
3037139c9ef4SJohannes Doerfert     if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
3038139c9ef4SJohannes Doerfert         !Callee->hasMetadata(LLVMContext::MD_callback))
3039c36e2ebfSJohannes Doerfert       return true;
3040c36e2ebfSJohannes Doerfert 
304187f1e939SJohannes Doerfert     if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
3042188f9a34SHideto Ueno 
304387f1e939SJohannes Doerfert       IRPosition CBRetPos = IRPosition::callsite_returned(CB);
304494841c71SJohannes Doerfert       bool UsedAssumedInformation = false;
3045bf789b19SJohannes Doerfert       getAssumedSimplified(CBRetPos, nullptr, UsedAssumedInformation,
3046bf789b19SJohannes Doerfert                            AA::Intraprocedural);
3047188f9a34SHideto Ueno     }
3048cd4aab4aSJohannes Doerfert 
30494f0225f6SKazu Hirata     for (int I = 0, E = CB.arg_size(); I < E; ++I) {
3050f2b9dc47SHideto Ueno 
305187f1e939SJohannes Doerfert       IRPosition CBArgPos = IRPosition::callsite_argument(CB, I);
3052f2b9dc47SHideto Ueno 
3053cd4aab4aSJohannes Doerfert       // Every call site argument might be dead.
30545f6d93c7SCraig Topper       getOrCreateAAFor<AAIsDead>(CBArgPos);
3055cd4aab4aSJohannes Doerfert 
3056666dc6f1SJohannes Doerfert       // Call site argument might be simplified. We have to go through the
3057666dc6f1SJohannes Doerfert       // Attributor interface though as outside AAs can register custom
3058666dc6f1SJohannes Doerfert       // simplification callbacks.
30593f5d53a5SHaojian Wu       bool UsedAssumedInformation = false;
3060bf789b19SJohannes Doerfert       getAssumedSimplified(CBArgPos, /* AA */ nullptr, UsedAssumedInformation,
3061bf789b19SJohannes Doerfert                            AA::Intraprocedural);
3062f2b9dc47SHideto Ueno 
30637a15dfd0SShinji Okumura       // Every call site argument might be marked "noundef".
30647a15dfd0SShinji Okumura       getOrCreateAAFor<AANoUndef>(CBArgPos);
30657a15dfd0SShinji Okumura 
306687f1e939SJohannes Doerfert       if (!CB.getArgOperand(I)->getType()->isPointerTy())
306754869ec9SHideto Ueno         continue;
306854869ec9SHideto Ueno 
306954869ec9SHideto Ueno       // Call site argument attribute "non-null".
30705f6d93c7SCraig Topper       getOrCreateAAFor<AANonNull>(CBArgPos);
307119c07afeSHideto Ueno 
30722f97b8b8SJohannes Doerfert       // Call site argument attribute "nocapture".
30732f97b8b8SJohannes Doerfert       getOrCreateAAFor<AANoCapture>(CBArgPos);
30742f97b8b8SJohannes Doerfert 
3075cbab334eSHideto Ueno       // Call site argument attribute "no-alias".
30765f6d93c7SCraig Topper       getOrCreateAAFor<AANoAlias>(CBArgPos);
3077cbab334eSHideto Ueno 
307819c07afeSHideto Ueno       // Call site argument attribute "dereferenceable".
30795f6d93c7SCraig Topper       getOrCreateAAFor<AADereferenceable>(CBArgPos);
3080e7bea9b7SHideto Ueno 
3081e7bea9b7SHideto Ueno       // Call site argument attribute "align".
30825f6d93c7SCraig Topper       getOrCreateAAFor<AAAlign>(CBArgPos);
3083f35740d6SStefan Stipanovic 
308428880198SJohannes Doerfert       // Call site argument attribute
308528880198SJohannes Doerfert       // "readnone/readonly/writeonly/..."
30865f6d93c7SCraig Topper       getOrCreateAAFor<AAMemoryBehavior>(CBArgPos);
308728880198SJohannes Doerfert 
3088f35740d6SStefan Stipanovic       // Call site argument attribute "nofree".
30895f6d93c7SCraig Topper       getOrCreateAAFor<AANoFree>(CBArgPos);
309054869ec9SHideto Ueno     }
30913ab9e8b8SJohannes Doerfert     return true;
30923ab9e8b8SJohannes Doerfert   };
30933ab9e8b8SJohannes Doerfert 
30943ab9e8b8SJohannes Doerfert   auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
309523f41f16SJohannes Doerfert   bool Success;
3096792aac98SJohannes Doerfert   bool UsedAssumedInformation = false;
30973ab9e8b8SJohannes Doerfert   Success = checkForAllInstructionsImpl(
309823f41f16SJohannes Doerfert       nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,
30993ab9e8b8SJohannes Doerfert       {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
3100792aac98SJohannes Doerfert        (unsigned)Instruction::Call},
3101792aac98SJohannes Doerfert       UsedAssumedInformation);
31023ab9e8b8SJohannes Doerfert   (void)Success;
310323f41f16SJohannes Doerfert   assert(Success && "Expected the check call to be successful!");
31043ab9e8b8SJohannes Doerfert 
31053ab9e8b8SJohannes Doerfert   auto LoadStorePred = [&](Instruction &I) -> bool {
3106c2281f15SJohannes Doerfert     if (isa<LoadInst>(I)) {
31073ab9e8b8SJohannes Doerfert       getOrCreateAAFor<AAAlign>(
31083ab9e8b8SJohannes Doerfert           IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
3109c2281f15SJohannes Doerfert       if (SimplifyAllLoads)
311094841c71SJohannes Doerfert         getAssumedSimplified(IRPosition::value(I), nullptr,
3111bf789b19SJohannes Doerfert                              UsedAssumedInformation, AA::Intraprocedural);
311294841c71SJohannes Doerfert     } else {
311394841c71SJohannes Doerfert       auto &SI = cast<StoreInst>(I);
311494841c71SJohannes Doerfert       getOrCreateAAFor<AAIsDead>(IRPosition::inst(I));
311594841c71SJohannes Doerfert       getAssumedSimplified(IRPosition::value(*SI.getValueOperand()), nullptr,
3116bf789b19SJohannes Doerfert                            UsedAssumedInformation, AA::Intraprocedural);
311794841c71SJohannes Doerfert       getOrCreateAAFor<AAAlign>(IRPosition::value(*SI.getPointerOperand()));
311894841c71SJohannes Doerfert     }
31193ab9e8b8SJohannes Doerfert     return true;
31203ab9e8b8SJohannes Doerfert   };
31213ab9e8b8SJohannes Doerfert   Success = checkForAllInstructionsImpl(
312223f41f16SJohannes Doerfert       nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,
3123792aac98SJohannes Doerfert       {(unsigned)Instruction::Load, (unsigned)Instruction::Store},
3124792aac98SJohannes Doerfert       UsedAssumedInformation);
31253ab9e8b8SJohannes Doerfert   (void)Success;
312623f41f16SJohannes Doerfert   assert(Success && "Expected the check call to be successful!");
3127aade782aSJohannes Doerfert }
3128aade782aSJohannes Doerfert 
3129aade782aSJohannes Doerfert /// Helpers to ease debugging through output streams and print calls.
3130aade782aSJohannes Doerfert ///
3131aade782aSJohannes Doerfert ///{
operator <<(raw_ostream & OS,ChangeStatus S)3132aade782aSJohannes Doerfert raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
3133aade782aSJohannes Doerfert   return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
3134aade782aSJohannes Doerfert }
3135aade782aSJohannes Doerfert 
operator <<(raw_ostream & OS,IRPosition::Kind AP)3136fb69f768SJohannes Doerfert raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
3137aade782aSJohannes Doerfert   switch (AP) {
3138710ebb03SJohannes Doerfert   case IRPosition::IRP_INVALID:
3139710ebb03SJohannes Doerfert     return OS << "inv";
3140710ebb03SJohannes Doerfert   case IRPosition::IRP_FLOAT:
3141710ebb03SJohannes Doerfert     return OS << "flt";
3142710ebb03SJohannes Doerfert   case IRPosition::IRP_RETURNED:
3143710ebb03SJohannes Doerfert     return OS << "fn_ret";
3144710ebb03SJohannes Doerfert   case IRPosition::IRP_CALL_SITE_RETURNED:
3145710ebb03SJohannes Doerfert     return OS << "cs_ret";
3146710ebb03SJohannes Doerfert   case IRPosition::IRP_FUNCTION:
3147710ebb03SJohannes Doerfert     return OS << "fn";
3148710ebb03SJohannes Doerfert   case IRPosition::IRP_CALL_SITE:
3149710ebb03SJohannes Doerfert     return OS << "cs";
3150fb69f768SJohannes Doerfert   case IRPosition::IRP_ARGUMENT:
3151aade782aSJohannes Doerfert     return OS << "arg";
3152fb69f768SJohannes Doerfert   case IRPosition::IRP_CALL_SITE_ARGUMENT:
3153aade782aSJohannes Doerfert     return OS << "cs_arg";
3154aade782aSJohannes Doerfert   }
3155aade782aSJohannes Doerfert   llvm_unreachable("Unknown attribute position!");
3156aade782aSJohannes Doerfert }
3157aade782aSJohannes Doerfert 
operator <<(raw_ostream & OS,const IRPosition & Pos)3158fb69f768SJohannes Doerfert raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
3159710ebb03SJohannes Doerfert   const Value &AV = Pos.getAssociatedValue();
3160d75c9e61Skuterd   OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
3161d75c9e61Skuterd      << Pos.getAnchorValue().getName() << "@" << Pos.getCallSiteArgNo() << "]";
3162d75c9e61Skuterd 
3163d75c9e61Skuterd   if (Pos.hasCallBaseContext())
3164d75c9e61Skuterd     OS << "[cb_context:" << *Pos.getCallBaseContext() << "]";
3165d75c9e61Skuterd   return OS << "}";
3166fb69f768SJohannes Doerfert }
3167fb69f768SJohannes Doerfert 
operator <<(raw_ostream & OS,const IntegerRangeState & S)3168188f9a34SHideto Ueno raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerRangeState &S) {
3169188f9a34SHideto Ueno   OS << "range-state(" << S.getBitWidth() << ")<";
3170188f9a34SHideto Ueno   S.getKnown().print(OS);
3171188f9a34SHideto Ueno   OS << " / ";
3172188f9a34SHideto Ueno   S.getAssumed().print(OS);
3173188f9a34SHideto Ueno   OS << ">";
3174188f9a34SHideto Ueno 
3175188f9a34SHideto Ueno   return OS << static_cast<const AbstractState &>(S);
3176188f9a34SHideto Ueno }
3177188f9a34SHideto Ueno 
operator <<(raw_ostream & OS,const AbstractState & S)3178aade782aSJohannes Doerfert raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
3179aade782aSJohannes Doerfert   return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
3180aade782aSJohannes Doerfert }
3181aade782aSJohannes Doerfert 
operator <<(raw_ostream & OS,const AbstractAttribute & AA)3182aade782aSJohannes Doerfert raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
3183aade782aSJohannes Doerfert   AA.print(OS);
3184aade782aSJohannes Doerfert   return OS;
3185aade782aSJohannes Doerfert }
3186aade782aSJohannes Doerfert 
operator <<(raw_ostream & OS,const PotentialConstantIntValuesState & S)3187c575ba28SShinji Okumura raw_ostream &llvm::operator<<(raw_ostream &OS,
3188c575ba28SShinji Okumura                               const PotentialConstantIntValuesState &S) {
3189c575ba28SShinji Okumura   OS << "set-state(< {";
3190c575ba28SShinji Okumura   if (!S.isValidState())
3191c575ba28SShinji Okumura     OS << "full-set";
31926c25eca6SShinji Okumura   else {
3193982053e8SJohannes Doerfert     for (auto &It : S.getAssumedSet())
3194982053e8SJohannes Doerfert       OS << It << ", ";
31956c25eca6SShinji Okumura     if (S.undefIsContained())
31966c25eca6SShinji Okumura       OS << "undef ";
31976c25eca6SShinji Okumura   }
3198c575ba28SShinji Okumura   OS << "} >)";
3199c575ba28SShinji Okumura 
3200c575ba28SShinji Okumura   return OS;
3201c575ba28SShinji Okumura }
3202c575ba28SShinji Okumura 
operator <<(raw_ostream & OS,const PotentialLLVMValuesState & S)3203bf789b19SJohannes Doerfert raw_ostream &llvm::operator<<(raw_ostream &OS,
3204bf789b19SJohannes Doerfert                               const PotentialLLVMValuesState &S) {
3205bf789b19SJohannes Doerfert   OS << "set-state(< {";
3206bf789b19SJohannes Doerfert   if (!S.isValidState())
3207bf789b19SJohannes Doerfert     OS << "full-set";
3208bf789b19SJohannes Doerfert   else {
3209bf789b19SJohannes Doerfert     for (auto &It : S.getAssumedSet()) {
3210bf789b19SJohannes Doerfert       if (auto *F = dyn_cast<Function>(It.first.getValue()))
3211bf789b19SJohannes Doerfert         OS << "@" << F->getName() << "[" << int(It.second) << "], ";
3212bf789b19SJohannes Doerfert       else
3213bf789b19SJohannes Doerfert         OS << *It.first.getValue() << "[" << int(It.second) << "], ";
3214bf789b19SJohannes Doerfert     }
3215bf789b19SJohannes Doerfert     if (S.undefIsContained())
3216bf789b19SJohannes Doerfert       OS << "undef ";
3217bf789b19SJohannes Doerfert   }
3218bf789b19SJohannes Doerfert   OS << "} >)";
3219bf789b19SJohannes Doerfert 
3220bf789b19SJohannes Doerfert   return OS;
3221bf789b19SJohannes Doerfert }
3222bf789b19SJohannes Doerfert 
print(raw_ostream & OS) const3223aade782aSJohannes Doerfert void AbstractAttribute::print(raw_ostream &OS) const {
32245ee07dc5SLuofan Chen   OS << "[";
32255ee07dc5SLuofan Chen   OS << getName();
32265ee07dc5SLuofan Chen   OS << "] for CtxI ";
32275ee07dc5SLuofan Chen 
32285ee07dc5SLuofan Chen   if (auto *I = getCtxI()) {
32295ee07dc5SLuofan Chen     OS << "'";
32305ee07dc5SLuofan Chen     I->print(OS);
32315ee07dc5SLuofan Chen     OS << "'";
32325ee07dc5SLuofan Chen   } else
32335ee07dc5SLuofan Chen     OS << "<<null inst>>";
32345ee07dc5SLuofan Chen 
32355ee07dc5SLuofan Chen   OS << " at position " << getIRPosition() << " with state " << getAsStr()
32365ee07dc5SLuofan Chen      << '\n';
32375ee07dc5SLuofan Chen }
32385ee07dc5SLuofan Chen 
printWithDeps(raw_ostream & OS) const32395ee07dc5SLuofan Chen void AbstractAttribute::printWithDeps(raw_ostream &OS) const {
32405ee07dc5SLuofan Chen   print(OS);
32415ee07dc5SLuofan Chen 
32425ee07dc5SLuofan Chen   for (const auto &DepAA : Deps) {
32435ee07dc5SLuofan Chen     auto *AA = DepAA.getPointer();
32445ee07dc5SLuofan Chen     OS << "  updates ";
32455ee07dc5SLuofan Chen     AA->print(OS);
32465ee07dc5SLuofan Chen   }
32475ee07dc5SLuofan Chen 
32485ee07dc5SLuofan Chen   OS << '\n';
3249aade782aSJohannes Doerfert }
3250c2281f15SJohannes Doerfert 
operator <<(raw_ostream & OS,const AAPointerInfo::Access & Acc)3251c7781a09SJohannes Doerfert raw_ostream &llvm::operator<<(raw_ostream &OS,
3252c7781a09SJohannes Doerfert                               const AAPointerInfo::Access &Acc) {
3253c2281f15SJohannes Doerfert   OS << " [" << Acc.getKind() << "] " << *Acc.getRemoteInst();
3254c2281f15SJohannes Doerfert   if (Acc.getLocalInst() != Acc.getRemoteInst())
3255c55e1882SJohannes Doerfert     OS << " via " << *Acc.getLocalInst();
3256e0e687a6SKazu Hirata   if (Acc.getContent()) {
32574308fdf8SJohannes Doerfert     if (*Acc.getContent())
32584308fdf8SJohannes Doerfert       OS << " [" << **Acc.getContent() << "]";
32594308fdf8SJohannes Doerfert     else
32604308fdf8SJohannes Doerfert       OS << " [ <unknown> ]";
32614308fdf8SJohannes Doerfert   }
3262c2281f15SJohannes Doerfert   return OS;
3263c2281f15SJohannes Doerfert }
3264aade782aSJohannes Doerfert ///}
3265aade782aSJohannes Doerfert 
3266aade782aSJohannes Doerfert /// ----------------------------------------------------------------------------
3267aade782aSJohannes Doerfert ///                       Pass (Manager) Boilerplate
3268aade782aSJohannes Doerfert /// ----------------------------------------------------------------------------
3269aade782aSJohannes Doerfert 
runAttributorOnFunctions(InformationCache & InfoCache,SetVector<Function * > & Functions,AnalysisGetter & AG,CallGraphUpdater & CGUpdater,bool DeleteFns,bool IsModulePass)3270b0c77c36SJohannes Doerfert static bool runAttributorOnFunctions(InformationCache &InfoCache,
3271b0c77c36SJohannes Doerfert                                      SetVector<Function *> &Functions,
3272b0c77c36SJohannes Doerfert                                      AnalysisGetter &AG,
3273b077d82bSWilliam S. Moses                                      CallGraphUpdater &CGUpdater,
32743be3b401SJohannes Doerfert                                      bool DeleteFns, bool IsModulePass) {
3275b43b59fcSTarindu Jayatilaka   if (Functions.empty())
3276aade782aSJohannes Doerfert     return false;
3277aade782aSJohannes Doerfert 
32782bc51d39SJohannes Doerfert   LLVM_DEBUG({
32792bc51d39SJohannes Doerfert     dbgs() << "[Attributor] Run on module with " << Functions.size()
32802bc51d39SJohannes Doerfert            << " functions:\n";
32812bc51d39SJohannes Doerfert     for (Function *Fn : Functions)
32822bc51d39SJohannes Doerfert       dbgs() << "  - " << Fn->getName() << "\n";
32832bc51d39SJohannes Doerfert   });
3284aade782aSJohannes Doerfert 
3285aade782aSJohannes Doerfert   // Create an Attributor and initially empty information cache that is filled
3286aade782aSJohannes Doerfert   // while we identify default attribute opportunities.
32873be3b401SJohannes Doerfert   AttributorConfig AC(CGUpdater);
32883be3b401SJohannes Doerfert   AC.IsModulePass = IsModulePass;
32893be3b401SJohannes Doerfert   AC.DeleteFns = DeleteFns;
32903be3b401SJohannes Doerfert   Attributor A(Functions, InfoCache, AC);
3291aade782aSJohannes Doerfert 
3292eec6d876SLuofan Chen   // Create shallow wrappers for all functions that are not IPO amendable
3293eec6d876SLuofan Chen   if (AllowShallowWrappers)
3294eec6d876SLuofan Chen     for (Function *F : Functions)
3295eec6d876SLuofan Chen       if (!A.isFunctionIPOAmendable(*F))
3296ce16be25Ssstefan1         Attributor::createShallowWrapper(*F);
3297eec6d876SLuofan Chen 
329887a85f3dSLuofan Chen   // Internalize non-exact functions
329987a85f3dSLuofan Chen   // TODO: for now we eagerly internalize functions without calculating the
330087a85f3dSLuofan Chen   //       cost, we need a cost interface to determine whether internalizing
330187a85f3dSLuofan Chen   //       a function is "benefitial"
3302266949b2SLuofan Chen   if (AllowDeepWrapper) {
3303266949b2SLuofan Chen     unsigned FunSize = Functions.size();
3304266949b2SLuofan Chen     for (unsigned u = 0; u < FunSize; u++) {
3305b7448a34SLuofan Chen       Function *F = Functions[u];
330687a85f3dSLuofan Chen       if (!F->isDeclaration() && !F->isDefinitionExact() && F->getNumUses() &&
330787a85f3dSLuofan Chen           !GlobalValue::isInterposableLinkage(F->getLinkage())) {
330803d7e61cSJoseph Huber         Function *NewF = Attributor::internalizeFunction(*F);
330903d7e61cSJoseph Huber         assert(NewF && "Could not internalize function.");
331087a85f3dSLuofan Chen         Functions.insert(NewF);
331187a85f3dSLuofan Chen 
331287a85f3dSLuofan Chen         // Update call graph
3313012819f3SJohannes Doerfert         CGUpdater.replaceFunctionWith(*F, *NewF);
331487a85f3dSLuofan Chen         for (const Use &U : NewF->uses())
331587a85f3dSLuofan Chen           if (CallBase *CB = dyn_cast<CallBase>(U.getUser())) {
331687a85f3dSLuofan Chen             auto *CallerF = CB->getCaller();
331787a85f3dSLuofan Chen             CGUpdater.reanalyzeFunction(*CallerF);
331887a85f3dSLuofan Chen           }
331987a85f3dSLuofan Chen       }
332087a85f3dSLuofan Chen     }
3321266949b2SLuofan Chen   }
332287a85f3dSLuofan Chen 
3323b0c77c36SJohannes Doerfert   for (Function *F : Functions) {
3324b0c77c36SJohannes Doerfert     if (F->hasExactDefinition())
3325b0412e43SJohannes Doerfert       NumFnWithExactDefinition++;
3326b0412e43SJohannes Doerfert     else
3327aade782aSJohannes Doerfert       NumFnWithoutExactDefinition++;
3328aade782aSJohannes Doerfert 
33292f622063SJohannes Doerfert     // We look at internal functions only on-demand but if any use is not a
33305ee07dc5SLuofan Chen     // direct call or outside the current set of analyzed functions, we have
33315ee07dc5SLuofan Chen     // to do it eagerly.
3332b0c77c36SJohannes Doerfert     if (F->hasLocalLinkage()) {
3333b0c77c36SJohannes Doerfert       if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
33345f6d93c7SCraig Topper             const auto *CB = dyn_cast<CallBase>(U.getUser());
33355f6d93c7SCraig Topper             return CB && CB->isCallee(&U) &&
33365f6d93c7SCraig Topper                    Functions.count(const_cast<Function *>(CB->getCaller()));
33372f622063SJohannes Doerfert           }))
33382f622063SJohannes Doerfert         continue;
33392f622063SJohannes Doerfert     }
33402f622063SJohannes Doerfert 
3341aade782aSJohannes Doerfert     // Populate the Attributor with abstract attribute opportunities in the
3342aade782aSJohannes Doerfert     // function and the information cache with IR information.
3343b0c77c36SJohannes Doerfert     A.identifyDefaultAbstractAttributes(*F);
3344aade782aSJohannes Doerfert   }
3345aade782aSJohannes Doerfert 
334677a9e61cSJohannes Doerfert   ChangeStatus Changed = A.run();
33475ee07dc5SLuofan Chen 
334877a9e61cSJohannes Doerfert   LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
334977a9e61cSJohannes Doerfert                     << " functions, result: " << Changed << ".\n");
335077a9e61cSJohannes Doerfert   return Changed == ChangeStatus::CHANGED;
3351aade782aSJohannes Doerfert }
3352aade782aSJohannes Doerfert 
viewGraph()33535ee07dc5SLuofan Chen void AADepGraph::viewGraph() { llvm::ViewGraph(this, "Dependency Graph"); }
33545ee07dc5SLuofan Chen 
dumpGraph()33555ee07dc5SLuofan Chen void AADepGraph::dumpGraph() {
33565ee07dc5SLuofan Chen   static std::atomic<int> CallTimes;
33575ee07dc5SLuofan Chen   std::string Prefix;
33585ee07dc5SLuofan Chen 
33595ee07dc5SLuofan Chen   if (!DepGraphDotFileNamePrefix.empty())
33605ee07dc5SLuofan Chen     Prefix = DepGraphDotFileNamePrefix;
33615ee07dc5SLuofan Chen   else
33625ee07dc5SLuofan Chen     Prefix = "dep_graph";
33635ee07dc5SLuofan Chen   std::string Filename =
33645ee07dc5SLuofan Chen       Prefix + "_" + std::to_string(CallTimes.load()) + ".dot";
33655ee07dc5SLuofan Chen 
33665ee07dc5SLuofan Chen   outs() << "Dependency graph dump to " << Filename << ".\n";
33675ee07dc5SLuofan Chen 
33685ee07dc5SLuofan Chen   std::error_code EC;
33695ee07dc5SLuofan Chen 
337082b3e28eSAbhina Sreeskantharajan   raw_fd_ostream File(Filename, EC, sys::fs::OF_TextWithCRLF);
33715ee07dc5SLuofan Chen   if (!EC)
33725ee07dc5SLuofan Chen     llvm::WriteGraph(File, this);
33735ee07dc5SLuofan Chen 
33745ee07dc5SLuofan Chen   CallTimes++;
33755ee07dc5SLuofan Chen }
33765ee07dc5SLuofan Chen 
print()33775ee07dc5SLuofan Chen void AADepGraph::print() {
33785ee07dc5SLuofan Chen   for (auto DepAA : SyntheticRoot.Deps)
33795ee07dc5SLuofan Chen     cast<AbstractAttribute>(DepAA.getPointer())->printWithDeps(outs());
33805ee07dc5SLuofan Chen }
33815ee07dc5SLuofan Chen 
run(Module & M,ModuleAnalysisManager & AM)3382aade782aSJohannes Doerfert PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
3383b0c77c36SJohannes Doerfert   FunctionAnalysisManager &FAM =
3384b0c77c36SJohannes Doerfert       AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
3385b0c77c36SJohannes Doerfert   AnalysisGetter AG(FAM);
3386b0c77c36SJohannes Doerfert 
3387b0c77c36SJohannes Doerfert   SetVector<Function *> Functions;
3388b0c77c36SJohannes Doerfert   for (Function &F : M)
3389b0c77c36SJohannes Doerfert     Functions.insert(&F);
3390b0c77c36SJohannes Doerfert 
3391b0c77c36SJohannes Doerfert   CallGraphUpdater CGUpdater;
339287aa3629SJohannes Doerfert   BumpPtrAllocator Allocator;
339387aa3629SJohannes Doerfert   InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);
3394b077d82bSWilliam S. Moses   if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater,
33953be3b401SJohannes Doerfert                                /* DeleteFns */ true, /* IsModulePass */ true)) {
3396b0c77c36SJohannes Doerfert     // FIXME: Think about passes we will preserve and add them here.
3397b0c77c36SJohannes Doerfert     return PreservedAnalyses::none();
3398b0c77c36SJohannes Doerfert   }
3399b0c77c36SJohannes Doerfert   return PreservedAnalyses::all();
3400b0c77c36SJohannes Doerfert }
3401b0c77c36SJohannes Doerfert 
run(LazyCallGraph::SCC & C,CGSCCAnalysisManager & AM,LazyCallGraph & CG,CGSCCUpdateResult & UR)3402b0c77c36SJohannes Doerfert PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C,
3403b0c77c36SJohannes Doerfert                                            CGSCCAnalysisManager &AM,
3404b0c77c36SJohannes Doerfert                                            LazyCallGraph &CG,
3405b0c77c36SJohannes Doerfert                                            CGSCCUpdateResult &UR) {
3406b0c77c36SJohannes Doerfert   FunctionAnalysisManager &FAM =
3407b0c77c36SJohannes Doerfert       AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
3408b0c77c36SJohannes Doerfert   AnalysisGetter AG(FAM);
3409b0c77c36SJohannes Doerfert 
3410b0c77c36SJohannes Doerfert   SetVector<Function *> Functions;
3411b0c77c36SJohannes Doerfert   for (LazyCallGraph::Node &N : C)
3412b0c77c36SJohannes Doerfert     Functions.insert(&N.getFunction());
3413b0c77c36SJohannes Doerfert 
3414b0c77c36SJohannes Doerfert   if (Functions.empty())
3415b0c77c36SJohannes Doerfert     return PreservedAnalyses::all();
3416b0c77c36SJohannes Doerfert 
3417b0c77c36SJohannes Doerfert   Module &M = *Functions.back()->getParent();
3418b0c77c36SJohannes Doerfert   CallGraphUpdater CGUpdater;
3419b0c77c36SJohannes Doerfert   CGUpdater.initialize(CG, C, AM, UR);
342087aa3629SJohannes Doerfert   BumpPtrAllocator Allocator;
342187aa3629SJohannes Doerfert   InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);
3422b077d82bSWilliam S. Moses   if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater,
34233be3b401SJohannes Doerfert                                /* DeleteFns */ false,
34243be3b401SJohannes Doerfert                                /* IsModulePass */ false)) {
3425aade782aSJohannes Doerfert     // FIXME: Think about passes we will preserve and add them here.
34261d99c3d7SJohannes Doerfert     PreservedAnalyses PA;
34271d99c3d7SJohannes Doerfert     PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
34281d99c3d7SJohannes Doerfert     return PA;
3429aade782aSJohannes Doerfert   }
3430aade782aSJohannes Doerfert   return PreservedAnalyses::all();
3431aade782aSJohannes Doerfert }
3432aade782aSJohannes Doerfert 
34335ee07dc5SLuofan Chen namespace llvm {
34345ee07dc5SLuofan Chen 
34355ee07dc5SLuofan Chen template <> struct GraphTraits<AADepGraphNode *> {
34365ee07dc5SLuofan Chen   using NodeRef = AADepGraphNode *;
34375ee07dc5SLuofan Chen   using DepTy = PointerIntPair<AADepGraphNode *, 1>;
34385ee07dc5SLuofan Chen   using EdgeRef = PointerIntPair<AADepGraphNode *, 1>;
34395ee07dc5SLuofan Chen 
getEntryNodellvm::GraphTraits34405ee07dc5SLuofan Chen   static NodeRef getEntryNode(AADepGraphNode *DGN) { return DGN; }
DepGetValllvm::GraphTraits34415ee07dc5SLuofan Chen   static NodeRef DepGetVal(DepTy &DT) { return DT.getPointer(); }
34425ee07dc5SLuofan Chen 
34435ee07dc5SLuofan Chen   using ChildIteratorType =
34445ee07dc5SLuofan Chen       mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
34455ee07dc5SLuofan Chen   using ChildEdgeIteratorType = TinyPtrVector<DepTy>::iterator;
34465ee07dc5SLuofan Chen 
child_beginllvm::GraphTraits34475ee07dc5SLuofan Chen   static ChildIteratorType child_begin(NodeRef N) { return N->child_begin(); }
34485ee07dc5SLuofan Chen 
child_endllvm::GraphTraits34495ee07dc5SLuofan Chen   static ChildIteratorType child_end(NodeRef N) { return N->child_end(); }
34505ee07dc5SLuofan Chen };
34515ee07dc5SLuofan Chen 
34525ee07dc5SLuofan Chen template <>
34535ee07dc5SLuofan Chen struct GraphTraits<AADepGraph *> : public GraphTraits<AADepGraphNode *> {
getEntryNodellvm::GraphTraits34545ee07dc5SLuofan Chen   static NodeRef getEntryNode(AADepGraph *DG) { return DG->GetEntryNode(); }
34555ee07dc5SLuofan Chen 
34565ee07dc5SLuofan Chen   using nodes_iterator =
34575ee07dc5SLuofan Chen       mapped_iterator<TinyPtrVector<DepTy>::iterator, decltype(&DepGetVal)>;
34585ee07dc5SLuofan Chen 
nodes_beginllvm::GraphTraits34595ee07dc5SLuofan Chen   static nodes_iterator nodes_begin(AADepGraph *DG) { return DG->begin(); }
34605ee07dc5SLuofan Chen 
nodes_endllvm::GraphTraits34615ee07dc5SLuofan Chen   static nodes_iterator nodes_end(AADepGraph *DG) { return DG->end(); }
34625ee07dc5SLuofan Chen };
34635ee07dc5SLuofan Chen 
34645ee07dc5SLuofan Chen template <> struct DOTGraphTraits<AADepGraph *> : public DefaultDOTGraphTraits {
DOTGraphTraitsllvm::DOTGraphTraits34655ee07dc5SLuofan Chen   DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
34665ee07dc5SLuofan Chen 
getNodeLabelllvm::DOTGraphTraits34675ee07dc5SLuofan Chen   static std::string getNodeLabel(const AADepGraphNode *Node,
34685ee07dc5SLuofan Chen                                   const AADepGraph *DG) {
346912fc9ca3SKazu Hirata     std::string AAString;
34705ee07dc5SLuofan Chen     raw_string_ostream O(AAString);
34715ee07dc5SLuofan Chen     Node->print(O);
34725ee07dc5SLuofan Chen     return AAString;
34735ee07dc5SLuofan Chen   }
34745ee07dc5SLuofan Chen };
34755ee07dc5SLuofan Chen 
34765ee07dc5SLuofan Chen } // end namespace llvm
34775ee07dc5SLuofan Chen 
3478aade782aSJohannes Doerfert namespace {
3479aade782aSJohannes Doerfert 
3480aade782aSJohannes Doerfert struct AttributorLegacyPass : public ModulePass {
3481aade782aSJohannes Doerfert   static char ID;
3482aade782aSJohannes Doerfert 
AttributorLegacyPass__anon708136851511::AttributorLegacyPass3483aade782aSJohannes Doerfert   AttributorLegacyPass() : ModulePass(ID) {
3484aade782aSJohannes Doerfert     initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
3485aade782aSJohannes Doerfert   }
3486aade782aSJohannes Doerfert 
runOnModule__anon708136851511::AttributorLegacyPass3487aade782aSJohannes Doerfert   bool runOnModule(Module &M) override {
3488aade782aSJohannes Doerfert     if (skipModule(M))
3489aade782aSJohannes Doerfert       return false;
3490431141c5SStefan Stipanovic 
34913bb5cbc2SHideto Ueno     AnalysisGetter AG;
3492b0c77c36SJohannes Doerfert     SetVector<Function *> Functions;
3493b0c77c36SJohannes Doerfert     for (Function &F : M)
3494b0c77c36SJohannes Doerfert       Functions.insert(&F);
3495b0c77c36SJohannes Doerfert 
3496b0c77c36SJohannes Doerfert     CallGraphUpdater CGUpdater;
349787aa3629SJohannes Doerfert     BumpPtrAllocator Allocator;
349887aa3629SJohannes Doerfert     InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr);
3499b077d82bSWilliam S. Moses     return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater,
35003be3b401SJohannes Doerfert                                     /* DeleteFns*/ true,
35013be3b401SJohannes Doerfert                                     /* IsModulePass */ true);
3502aade782aSJohannes Doerfert   }
3503aade782aSJohannes Doerfert 
getAnalysisUsage__anon708136851511::AttributorLegacyPass3504aade782aSJohannes Doerfert   void getAnalysisUsage(AnalysisUsage &AU) const override {
3505aade782aSJohannes Doerfert     // FIXME: Think about passes we will preserve and add them here.
3506431141c5SStefan Stipanovic     AU.addRequired<TargetLibraryInfoWrapperPass>();
3507aade782aSJohannes Doerfert   }
3508aade782aSJohannes Doerfert };
3509aade782aSJohannes Doerfert 
3510b0c77c36SJohannes Doerfert struct AttributorCGSCCLegacyPass : public CallGraphSCCPass {
3511b0c77c36SJohannes Doerfert   static char ID;
3512b0c77c36SJohannes Doerfert 
AttributorCGSCCLegacyPass__anon708136851511::AttributorCGSCCLegacyPass3513b0c77c36SJohannes Doerfert   AttributorCGSCCLegacyPass() : CallGraphSCCPass(ID) {
3514b0c77c36SJohannes Doerfert     initializeAttributorCGSCCLegacyPassPass(*PassRegistry::getPassRegistry());
3515b0c77c36SJohannes Doerfert   }
3516b0c77c36SJohannes Doerfert 
runOnSCC__anon708136851511::AttributorCGSCCLegacyPass3517b0c77c36SJohannes Doerfert   bool runOnSCC(CallGraphSCC &SCC) override {
3518b0c77c36SJohannes Doerfert     if (skipSCC(SCC))
3519b0c77c36SJohannes Doerfert       return false;
3520b0c77c36SJohannes Doerfert 
3521b0c77c36SJohannes Doerfert     SetVector<Function *> Functions;
3522b0c77c36SJohannes Doerfert     for (CallGraphNode *CGN : SCC)
3523b0c77c36SJohannes Doerfert       if (Function *Fn = CGN->getFunction())
3524b0c77c36SJohannes Doerfert         if (!Fn->isDeclaration())
3525b0c77c36SJohannes Doerfert           Functions.insert(Fn);
3526b0c77c36SJohannes Doerfert 
3527b0c77c36SJohannes Doerfert     if (Functions.empty())
3528b0c77c36SJohannes Doerfert       return false;
3529b0c77c36SJohannes Doerfert 
3530b0c77c36SJohannes Doerfert     AnalysisGetter AG;
3531b0c77c36SJohannes Doerfert     CallGraph &CG = const_cast<CallGraph &>(SCC.getCallGraph());
3532d13daa40SJohannes Doerfert     CallGraphUpdater CGUpdater;
3533b0c77c36SJohannes Doerfert     CGUpdater.initialize(CG, SCC);
3534b0c77c36SJohannes Doerfert     Module &M = *Functions.back()->getParent();
353587aa3629SJohannes Doerfert     BumpPtrAllocator Allocator;
353687aa3629SJohannes Doerfert     InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions);
3537b077d82bSWilliam S. Moses     return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater,
35383be3b401SJohannes Doerfert                                     /* DeleteFns */ false,
35393be3b401SJohannes Doerfert                                     /* IsModulePass */ false);
3540b0c77c36SJohannes Doerfert   }
3541b0c77c36SJohannes Doerfert 
getAnalysisUsage__anon708136851511::AttributorCGSCCLegacyPass3542b0c77c36SJohannes Doerfert   void getAnalysisUsage(AnalysisUsage &AU) const override {
3543b0c77c36SJohannes Doerfert     // FIXME: Think about passes we will preserve and add them here.
3544b0c77c36SJohannes Doerfert     AU.addRequired<TargetLibraryInfoWrapperPass>();
3545b0c77c36SJohannes Doerfert     CallGraphSCCPass::getAnalysisUsage(AU);
3546b0c77c36SJohannes Doerfert   }
3547b0c77c36SJohannes Doerfert };
3548b0c77c36SJohannes Doerfert 
3549aade782aSJohannes Doerfert } // end anonymous namespace
3550aade782aSJohannes Doerfert 
createAttributorLegacyPass()3551aade782aSJohannes Doerfert Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
createAttributorCGSCCLegacyPass()3552b0c77c36SJohannes Doerfert Pass *llvm::createAttributorCGSCCLegacyPass() {
3553b0c77c36SJohannes Doerfert   return new AttributorCGSCCLegacyPass();
3554b0c77c36SJohannes Doerfert }
3555aade782aSJohannes Doerfert 
3556aade782aSJohannes Doerfert char AttributorLegacyPass::ID = 0;
3557b0c77c36SJohannes Doerfert char AttributorCGSCCLegacyPass::ID = 0;
355824020625SJohannes Doerfert 
3559aade782aSJohannes Doerfert INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
3560aade782aSJohannes Doerfert                       "Deduce and propagate attributes", false, false)
3561431141c5SStefan Stipanovic INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
3562aade782aSJohannes Doerfert INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
3563aade782aSJohannes Doerfert                     "Deduce and propagate attributes", false, false)
3564b0c77c36SJohannes Doerfert INITIALIZE_PASS_BEGIN(AttributorCGSCCLegacyPass, "attributor-cgscc",
3565b0c77c36SJohannes Doerfert                       "Deduce and propagate attributes (CGSCC pass)", false,
3566b0c77c36SJohannes Doerfert                       false)
3567b0c77c36SJohannes Doerfert INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
3568b0c77c36SJohannes Doerfert INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
3569b0c77c36SJohannes Doerfert INITIALIZE_PASS_END(AttributorCGSCCLegacyPass, "attributor-cgscc",
3570b0c77c36SJohannes Doerfert                     "Deduce and propagate attributes (CGSCC pass)", false,
3571b0c77c36SJohannes Doerfert                     false)
3572