blob: ddd2ff076e114644cf1f9144f61fd74131c33cc0 [file] [log] [blame]
Johannes Doerfertaade7822019-06-05 03:02:24 +00001//===- Attributor.cpp - Module-wide attribute deduction -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements an inter procedural pass that deduces and/or propagating
10// attributes. This is done in an abstract interpretation style fixpoint
11// iteration. See the Attributor.h file comment and the class descriptions in
12// that file for more information.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Transforms/IPO/Attributor.h"
17
Hideto Ueno11d37102019-07-17 15:15:43 +000018#include "llvm/ADT/DepthFirstIterator.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000019#include "llvm/ADT/STLExtras.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000020#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/Statistic.h"
Stefan Stipanovic69ebb022019-07-22 19:36:27 +000023#include "llvm/Analysis/CaptureTracking.h"
Johannes Doerfert924d2132019-08-05 21:34:45 +000024#include "llvm/Analysis/EHPersonalities.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000025#include "llvm/Analysis/GlobalsModRef.h"
Hideto Ueno19c07af2019-07-23 08:16:17 +000026#include "llvm/Analysis/Loads.h"
Stefan Stipanovic431141c2019-09-15 21:47:41 +000027#include "llvm/Analysis/MemoryBuiltins.h"
Hideto Ueno54869ec2019-07-15 06:49:04 +000028#include "llvm/Analysis/ValueTracking.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000029#include "llvm/IR/Argument.h"
30#include "llvm/IR/Attributes.h"
Hideto Ueno11d37102019-07-17 15:15:43 +000031#include "llvm/IR/CFG.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000032#include "llvm/IR/InstIterator.h"
Stefan Stipanovic06263672019-07-11 21:37:40 +000033#include "llvm/IR/IntrinsicInst.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000034#include "llvm/Support/CommandLine.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/raw_ostream.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000037#include "llvm/Transforms/Utils/BasicBlockUtils.h"
38#include "llvm/Transforms/Utils/Local.h"
39
Johannes Doerfertaade7822019-06-05 03:02:24 +000040#include <cassert>
41
42using namespace llvm;
43
44#define DEBUG_TYPE "attributor"
45
46STATISTIC(NumFnWithExactDefinition,
47 "Number of function with exact definitions");
48STATISTIC(NumFnWithoutExactDefinition,
49 "Number of function without exact definitions");
50STATISTIC(NumAttributesTimedOut,
51 "Number of abstract attributes timed out before fixpoint");
52STATISTIC(NumAttributesValidFixpoint,
53 "Number of abstract attributes in a valid fixpoint state");
54STATISTIC(NumAttributesManifested,
55 "Number of abstract attributes manifested in IR");
56
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000057// Some helper macros to deal with statistics tracking.
58//
59// Usage:
60// For simple IR attribute tracking overload trackStatistics in the abstract
Johannes Doerfert17b578b2019-08-14 21:46:25 +000061// attribute and choose the right STATS_DECLTRACK_********* macro,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000062// e.g.,:
63// void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +000064// STATS_DECLTRACK_ARG_ATTR(returned)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000065// }
66// If there is a single "increment" side one can use the macro
Johannes Doerfert17b578b2019-08-14 21:46:25 +000067// STATS_DECLTRACK with a custom message. If there are multiple increment
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000068// sides, STATS_DECL and STATS_TRACK can also be used separatly.
69//
70#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
71 ("Number of " #TYPE " marked '" #NAME "'")
72#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
Johannes Doerferta7a3b3a2019-09-04 19:01:08 +000073#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
74#define STATS_DECL(NAME, TYPE, MSG) \
75 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000076#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
Johannes Doerfert17b578b2019-08-14 21:46:25 +000077#define STATS_DECLTRACK(NAME, TYPE, MSG) \
Johannes Doerfert169af992019-08-20 06:09:56 +000078 { \
79 STATS_DECL(NAME, TYPE, MSG) \
80 STATS_TRACK(NAME, TYPE) \
81 }
Johannes Doerfert17b578b2019-08-14 21:46:25 +000082#define STATS_DECLTRACK_ARG_ATTR(NAME) \
83 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
84#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
85 STATS_DECLTRACK(NAME, CSArguments, \
86 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
87#define STATS_DECLTRACK_FN_ATTR(NAME) \
88 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
89#define STATS_DECLTRACK_CS_ATTR(NAME) \
90 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
91#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
92 STATS_DECLTRACK(NAME, FunctionReturn, \
Johannes Doerfert2db85282019-08-21 20:56:56 +000093 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
Johannes Doerfert17b578b2019-08-14 21:46:25 +000094#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
95 STATS_DECLTRACK(NAME, CSReturn, \
96 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
97#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
98 STATS_DECLTRACK(NAME, Floating, \
99 ("Number of floating values known to be '" #NAME "'"))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000100
Johannes Doerfertaade7822019-06-05 03:02:24 +0000101// TODO: Determine a good default value.
102//
103// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
104// (when run with the first 5 abstract attributes). The results also indicate
105// that we never reach 32 iterations but always find a fixpoint sooner.
106//
107// This will become more evolved once we perform two interleaved fixpoint
108// iterations: bottom-up and top-down.
109static cl::opt<unsigned>
110 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
111 cl::desc("Maximal number of fixpoint iterations."),
112 cl::init(32));
Johannes Doerfertb504eb82019-08-26 18:55:47 +0000113static cl::opt<bool> VerifyMaxFixpointIterations(
114 "attributor-max-iterations-verify", cl::Hidden,
115 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
116 cl::init(false));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000117
118static cl::opt<bool> DisableAttributor(
119 "attributor-disable", cl::Hidden,
120 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +0000121 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000122
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500123static cl::opt<bool> AnnotateDeclarationCallSites(
124 "attributor-annotate-decl-cs", cl::Hidden,
125 cl::desc("Annoate call sites of function declarations."), cl::init(false));
126
Johannes Doerfert7516a5e2019-09-03 20:37:24 +0000127static cl::opt<bool> ManifestInternal(
128 "attributor-manifest-internal", cl::Hidden,
129 cl::desc("Manifest Attributor internal string attributes."),
130 cl::init(false));
131
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000132static cl::opt<unsigned> DepRecInterval(
133 "attributor-dependence-recompute-interval", cl::Hidden,
134 cl::desc("Number of iterations until dependences are recomputed."),
135 cl::init(4));
136
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000137static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
138 cl::init(true), cl::Hidden);
139
Johannes Doerfert1c2afae2019-10-10 05:34:21 +0000140static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
141 cl::Hidden);
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000142
Johannes Doerfertaade7822019-06-05 03:02:24 +0000143/// Logic operators for the change status enum class.
144///
145///{
146ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
147 return l == ChangeStatus::CHANGED ? l : r;
148}
149ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
150 return l == ChangeStatus::UNCHANGED ? l : r;
151}
152///}
153
Johannes Doerfertdef99282019-08-14 21:29:37 +0000154/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000155/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000156/// with the "returned" attribute. Once we cannot look through the value any
157/// further, the callback \p VisitValueCB is invoked and passed the current
158/// value, the \p State, and a flag to indicate if we stripped anything. To
159/// limit how much effort is invested, we will never visit more values than
160/// specified by \p MaxValues.
161template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000162static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000163 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000164 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000165 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000166
Johannes Doerfertdef99282019-08-14 21:29:37 +0000167 const AAIsDead *LivenessAA = nullptr;
168 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000169 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000170 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
171 /* TrackDependence */ false);
172 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000173
174 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000175 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000176 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000177 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000178
179 int Iteration = 0;
180 do {
181 Value *V = Worklist.pop_back_val();
182
183 // Check if we should process the current value. To prevent endless
184 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000185 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000186 continue;
187
188 // Make sure we limit the compile time for complex expressions.
189 if (Iteration++ >= MaxValues)
190 return false;
191
192 // Explicitly look through calls with a "returned" attribute if we do
193 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000194 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000195 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000196 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000197 } else {
198 CallSite CS(V);
199 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000200 for (Argument &Arg : CS.getCalledFunction()->args())
201 if (Arg.hasReturnedAttr()) {
202 NewV = CS.getArgOperand(Arg.getArgNo());
203 break;
204 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000205 }
206 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000207 if (NewV && NewV != V) {
208 Worklist.push_back(NewV);
209 continue;
210 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000211
212 // Look through select instructions, visit both potential values.
213 if (auto *SI = dyn_cast<SelectInst>(V)) {
214 Worklist.push_back(SI->getTrueValue());
215 Worklist.push_back(SI->getFalseValue());
216 continue;
217 }
218
Johannes Doerfertdef99282019-08-14 21:29:37 +0000219 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000220 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000221 assert(LivenessAA &&
222 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000223 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
224 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000225 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000226 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000227 continue;
228 }
229 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000230 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000231 continue;
232 }
233
234 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000235 if (!VisitValueCB(*V, State, Iteration > 1))
236 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000237 } while (!Worklist.empty());
238
Johannes Doerfert19b00432019-08-26 17:48:05 +0000239 // If we actually used liveness information so we have to record a dependence.
240 if (AnyDead)
241 A.recordDependence(*LivenessAA, QueryingAA);
242
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000243 // All values have been visited.
244 return true;
245}
246
Johannes Doerfertaade7822019-06-05 03:02:24 +0000247/// Return true if \p New is equal or worse than \p Old.
248static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
249 if (!Old.isIntAttribute())
250 return true;
251
252 return Old.getValueAsInt() >= New.getValueAsInt();
253}
254
255/// Return true if the information provided by \p Attr was added to the
256/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000257/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000258static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000259 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000260
261 if (Attr.isEnumAttribute()) {
262 Attribute::AttrKind Kind = Attr.getKindAsEnum();
263 if (Attrs.hasAttribute(AttrIdx, Kind))
264 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
265 return false;
266 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
267 return true;
268 }
269 if (Attr.isStringAttribute()) {
270 StringRef Kind = Attr.getKindAsString();
271 if (Attrs.hasAttribute(AttrIdx, Kind))
272 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
273 return false;
274 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
275 return true;
276 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000277 if (Attr.isIntAttribute()) {
278 Attribute::AttrKind Kind = Attr.getKindAsEnum();
279 if (Attrs.hasAttribute(AttrIdx, Kind))
280 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
281 return false;
282 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
283 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
284 return true;
285 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000286
287 llvm_unreachable("Expected enum or string attribute!");
288}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000289static const Value *getPointerOperand(const Instruction *I) {
290 if (auto *LI = dyn_cast<LoadInst>(I))
291 if (!LI->isVolatile())
292 return LI->getPointerOperand();
293
294 if (auto *SI = dyn_cast<StoreInst>(I))
295 if (!SI->isVolatile())
296 return SI->getPointerOperand();
297
298 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I))
299 if (!CXI->isVolatile())
300 return CXI->getPointerOperand();
301
302 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I))
303 if (!RMWI->isVolatile())
304 return RMWI->getPointerOperand();
305
306 return nullptr;
307}
308static const Value *getBasePointerOfAccessPointerOperand(const Instruction *I,
309 int64_t &BytesOffset,
310 const DataLayout &DL) {
311 const Value *Ptr = getPointerOperand(I);
312 if (!Ptr)
313 return nullptr;
314
315 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
316 /*AllowNonInbounds*/ false);
317}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000318
Johannes Doerfertece81902019-08-12 22:05:53 +0000319ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000320 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
321 if (getState().isAtFixpoint())
322 return HasChanged;
323
324 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
325
Johannes Doerfertece81902019-08-12 22:05:53 +0000326 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000327
328 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
329 << "\n");
330
331 return HasChanged;
332}
333
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000334ChangeStatus
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500335IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000336 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000337 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000338 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000339
Johannes Doerfertaade7822019-06-05 03:02:24 +0000340 // In the following some generic code that will manifest attributes in
341 // DeducedAttrs if they improve the current IR. Due to the different
342 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000343
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000344 AttributeList Attrs;
345 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000346 case IRPosition::IRP_INVALID:
347 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000348 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000349 case IRPosition::IRP_ARGUMENT:
350 case IRPosition::IRP_FUNCTION:
351 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000352 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000353 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000354 case IRPosition::IRP_CALL_SITE:
355 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000356 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000357 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000358 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000359 }
360
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000361 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000362 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000363 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000364 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000365 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000366
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000367 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000368 }
369
370 if (HasChanged == ChangeStatus::UNCHANGED)
371 return HasChanged;
372
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000373 switch (PK) {
374 case IRPosition::IRP_ARGUMENT:
375 case IRPosition::IRP_FUNCTION:
376 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000377 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000378 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000379 case IRPosition::IRP_CALL_SITE:
380 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000381 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000382 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000383 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000384 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000385 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000386 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000387 }
388
389 return HasChanged;
390}
391
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000392const IRPosition IRPosition::EmptyKey(255);
393const IRPosition IRPosition::TombstoneKey(256);
394
395SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
396 IRPositions.emplace_back(IRP);
397
398 ImmutableCallSite ICS(&IRP.getAnchorValue());
399 switch (IRP.getPositionKind()) {
400 case IRPosition::IRP_INVALID:
401 case IRPosition::IRP_FLOAT:
402 case IRPosition::IRP_FUNCTION:
403 return;
404 case IRPosition::IRP_ARGUMENT:
405 case IRPosition::IRP_RETURNED:
406 IRPositions.emplace_back(
407 IRPosition::function(*IRP.getAssociatedFunction()));
408 return;
409 case IRPosition::IRP_CALL_SITE:
410 assert(ICS && "Expected call site!");
411 // TODO: We need to look at the operand bundles similar to the redirection
412 // in CallBase.
413 if (!ICS.hasOperandBundles())
414 if (const Function *Callee = ICS.getCalledFunction())
415 IRPositions.emplace_back(IRPosition::function(*Callee));
416 return;
417 case IRPosition::IRP_CALL_SITE_RETURNED:
418 assert(ICS && "Expected call site!");
419 // TODO: We need to look at the operand bundles similar to the redirection
420 // in CallBase.
421 if (!ICS.hasOperandBundles()) {
422 if (const Function *Callee = ICS.getCalledFunction()) {
423 IRPositions.emplace_back(IRPosition::returned(*Callee));
424 IRPositions.emplace_back(IRPosition::function(*Callee));
425 }
426 }
427 IRPositions.emplace_back(
428 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
429 return;
430 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
431 int ArgNo = IRP.getArgNo();
432 assert(ICS && ArgNo >= 0 && "Expected call site!");
433 // TODO: We need to look at the operand bundles similar to the redirection
434 // in CallBase.
435 if (!ICS.hasOperandBundles()) {
436 const Function *Callee = ICS.getCalledFunction();
437 if (Callee && Callee->arg_size() > unsigned(ArgNo))
438 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
439 if (Callee)
440 IRPositions.emplace_back(IRPosition::function(*Callee));
441 }
442 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
443 return;
444 }
445 }
446}
447
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000448bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
449 bool IgnoreSubsumingPositions) const {
450 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000451 for (Attribute::AttrKind AK : AKs)
452 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
453 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000454 // The first position returned by the SubsumingPositionIterator is
455 // always the position itself. If we ignore subsuming positions we
456 // are done after the first iteration.
457 if (IgnoreSubsumingPositions)
458 break;
459 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000460 return false;
461}
462
463void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
464 SmallVectorImpl<Attribute> &Attrs) const {
465 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this))
466 for (Attribute::AttrKind AK : AKs) {
467 const Attribute &Attr = EquivIRP.getAttr(AK);
468 if (Attr.getKindAsEnum() == AK)
469 Attrs.push_back(Attr);
470 }
471}
472
473void IRPosition::verify() {
474 switch (KindOrArgNo) {
475 default:
476 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
477 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
478 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000479 if (isa<Argument>(AnchorVal)) {
480 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000481 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000482 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
483 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000484 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000485 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000486 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000487 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
488 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000489 "Associated value mismatch!");
490 }
491 break;
492 case IRP_INVALID:
493 assert(!AnchorVal && "Expected no value for an invalid position!");
494 break;
495 case IRP_FLOAT:
496 assert((!isa<CallBase>(&getAssociatedValue()) &&
497 !isa<Argument>(&getAssociatedValue())) &&
498 "Expected specialized kind for call base and argument values!");
499 break;
500 case IRP_RETURNED:
501 assert(isa<Function>(AnchorVal) &&
502 "Expected function for a 'returned' position!");
503 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
504 break;
505 case IRP_CALL_SITE_RETURNED:
506 assert((isa<CallBase>(AnchorVal)) &&
507 "Expected call base for 'call site returned' position!");
508 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
509 break;
510 case IRP_CALL_SITE:
511 assert((isa<CallBase>(AnchorVal)) &&
512 "Expected call base for 'call site function' position!");
513 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
514 break;
515 case IRP_FUNCTION:
516 assert(isa<Function>(AnchorVal) &&
517 "Expected function for a 'function' position!");
518 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
519 break;
520 }
521}
522
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000523namespace {
Johannes Doerfert1a746452019-10-20 22:28:49 -0500524/// Helper function to clamp a state \p S of type \p StateType with the
Johannes Doerfert234eda52019-08-16 19:51:23 +0000525/// information in \p R and indicate/return if \p S did change (as-in update is
526/// required to be run again).
Johannes Doerfert234eda52019-08-16 19:51:23 +0000527template <typename StateType>
Johannes Doerfert1a746452019-10-20 22:28:49 -0500528ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000529 auto Assumed = S.getAssumed();
530 S ^= R;
531 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
532 : ChangeStatus::CHANGED;
533}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000534
Johannes Doerfert234eda52019-08-16 19:51:23 +0000535/// Clamp the information known for all returned values of a function
536/// (identified by \p QueryingAA) into \p S.
537template <typename AAType, typename StateType = typename AAType::StateType>
538static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
539 StateType &S) {
540 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
541 << static_cast<const AbstractAttribute &>(QueryingAA)
542 << " into " << S << "\n");
543
544 assert((QueryingAA.getIRPosition().getPositionKind() ==
545 IRPosition::IRP_RETURNED ||
546 QueryingAA.getIRPosition().getPositionKind() ==
547 IRPosition::IRP_CALL_SITE_RETURNED) &&
548 "Can only clamp returned value states for a function returned or call "
549 "site returned position!");
550
551 // Use an optional state as there might not be any return values and we want
552 // to join (IntegerState::operator&) the state of all there are.
553 Optional<StateType> T;
554
555 // Callback for each possibly returned value.
556 auto CheckReturnValue = [&](Value &RV) -> bool {
557 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000558 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
559 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
560 << " @ " << RVPos << "\n");
561 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000562 if (T.hasValue())
563 *T &= AAS;
564 else
565 T = AAS;
566 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
567 << "\n");
568 return T->isValidState();
569 };
570
571 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
572 S.indicatePessimisticFixpoint();
573 else if (T.hasValue())
574 S ^= *T;
575}
576
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000577/// Helper class to compose two generic deduction
578template <typename AAType, typename Base, typename StateType,
579 template <typename...> class F, template <typename...> class G>
580struct AAComposeTwoGenericDeduction
581 : public F<AAType, G<AAType, Base, StateType>, StateType> {
582 AAComposeTwoGenericDeduction(const IRPosition &IRP)
583 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
584
585 /// See AbstractAttribute::updateImpl(...).
586 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000587 ChangeStatus ChangedF = F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
588 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
589 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000590 }
591};
592
Johannes Doerfert234eda52019-08-16 19:51:23 +0000593/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000594template <typename AAType, typename Base,
595 typename StateType = typename AAType::StateType>
596struct AAReturnedFromReturnedValues : public Base {
597 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000598
599 /// See AbstractAttribute::updateImpl(...).
600 ChangeStatus updateImpl(Attributor &A) override {
601 StateType S;
602 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000603 // TODO: If we know we visited all returned values, thus no are assumed
604 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000605 return clampStateAndIndicateChange<StateType>(this->getState(), S);
606 }
607};
608
609/// Clamp the information known at all call sites for a given argument
610/// (identified by \p QueryingAA) into \p S.
611template <typename AAType, typename StateType = typename AAType::StateType>
612static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
613 StateType &S) {
614 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
615 << static_cast<const AbstractAttribute &>(QueryingAA)
616 << " into " << S << "\n");
617
618 assert(QueryingAA.getIRPosition().getPositionKind() ==
619 IRPosition::IRP_ARGUMENT &&
620 "Can only clamp call site argument states for an argument position!");
621
622 // Use an optional state as there might not be any return values and we want
623 // to join (IntegerState::operator&) the state of all there are.
624 Optional<StateType> T;
625
626 // The argument number which is also the call site argument number.
627 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
628
Johannes Doerfert661db042019-10-07 23:14:58 +0000629 auto CallSiteCheck = [&](AbstractCallSite ACS) {
630 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
631 // Check if a coresponding argument was found or if it is on not associated
632 // (which can happen for callback calls).
633 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
634 return false;
635
636 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
637 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
638 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000639 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000640 if (T.hasValue())
641 *T &= AAS;
642 else
643 T = AAS;
644 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
645 << "\n");
646 return T->isValidState();
647 };
648
649 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true))
650 S.indicatePessimisticFixpoint();
651 else if (T.hasValue())
652 S ^= *T;
653}
654
655/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000656template <typename AAType, typename Base,
657 typename StateType = typename AAType::StateType>
658struct AAArgumentFromCallSiteArguments : public Base {
659 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000660
661 /// See AbstractAttribute::updateImpl(...).
662 ChangeStatus updateImpl(Attributor &A) override {
663 StateType S;
664 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000665 // TODO: If we know we visited all incoming values, thus no are assumed
666 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000667 return clampStateAndIndicateChange<StateType>(this->getState(), S);
668 }
669};
670
671/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000672template <typename AAType, typename Base,
673 typename StateType = typename AAType::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000674struct AACallSiteReturnedFromReturned : public Base {
675 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000676
677 /// See AbstractAttribute::updateImpl(...).
678 ChangeStatus updateImpl(Attributor &A) override {
679 assert(this->getIRPosition().getPositionKind() ==
680 IRPosition::IRP_CALL_SITE_RETURNED &&
681 "Can only wrap function returned positions for call site returned "
682 "positions!");
683 auto &S = this->getState();
684
685 const Function *AssociatedFunction =
686 this->getIRPosition().getAssociatedFunction();
687 if (!AssociatedFunction)
688 return S.indicatePessimisticFixpoint();
689
690 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000691 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000692 return clampStateAndIndicateChange(
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000693 S, static_cast<const typename AAType::StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000694 }
695};
696
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000697/// Helper class for generic deduction using must-be-executed-context
698/// Base class is required to have `followUse` method.
699
700/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000701/// U - Underlying use.
702/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000703/// `followUse` returns true if the value should be tracked transitively.
704
705template <typename AAType, typename Base,
706 typename StateType = typename AAType::StateType>
707struct AAFromMustBeExecutedContext : public Base {
708 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
709
710 void initialize(Attributor &A) override {
711 Base::initialize(A);
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500712 const IRPosition &IRP = this->getIRPosition();
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000713 Instruction *CtxI = IRP.getCtxI();
714
715 if (!CtxI)
716 return;
717
718 for (const Use &U : IRP.getAssociatedValue().uses())
719 Uses.insert(&U);
720 }
721
722 /// See AbstractAttribute::updateImpl(...).
723 ChangeStatus updateImpl(Attributor &A) override {
724 auto BeforeState = this->getState();
725 auto &S = this->getState();
726 Instruction *CtxI = this->getIRPosition().getCtxI();
727 if (!CtxI)
728 return ChangeStatus::UNCHANGED;
729
730 MustBeExecutedContextExplorer &Explorer =
731 A.getInfoCache().getMustBeExecutedContextExplorer();
732
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500733 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500734 for (unsigned u = 0 ; u < Uses.size(); ++u) {
735 const Use *U = Uses[u];
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000736 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500737 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000738 if (Found && Base::followUse(A, U, UserI))
739 for (const Use &Us : UserI->uses())
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500740 Uses.insert(&Us);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000741 }
742 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000743
744 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
745 }
746
747private:
748 /// Container for (transitive) uses of the associated value.
749 SetVector<const Use *> Uses;
750};
751
752template <typename AAType, typename Base,
753 typename StateType = typename AAType::StateType>
754using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
755 AAComposeTwoGenericDeduction<AAType, Base, StateType,
756 AAFromMustBeExecutedContext,
757 AAArgumentFromCallSiteArguments>;
758
759template <typename AAType, typename Base,
760 typename StateType = typename AAType::StateType>
761using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
762 AAComposeTwoGenericDeduction<AAType, Base, StateType,
763 AAFromMustBeExecutedContext,
764 AACallSiteReturnedFromReturned>;
765
Stefan Stipanovic53605892019-06-27 11:27:54 +0000766/// -----------------------NoUnwind Function Attribute--------------------------
767
Johannes Doerfert344d0382019-08-07 22:34:26 +0000768struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000769 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000770
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000771 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000772 return getAssumed() ? "nounwind" : "may-unwind";
773 }
774
775 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000776 ChangeStatus updateImpl(Attributor &A) override {
777 auto Opcodes = {
778 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
779 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
780 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
781
782 auto CheckForNoUnwind = [&](Instruction &I) {
783 if (!I.mayThrow())
784 return true;
785
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000786 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
787 const auto &NoUnwindAA =
788 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
789 return NoUnwindAA.isAssumedNoUnwind();
790 }
791 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000792 };
793
794 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
795 return indicatePessimisticFixpoint();
796
797 return ChangeStatus::UNCHANGED;
798 }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000799};
800
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000801struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000802 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000803
804 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000805 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000806};
807
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000808/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000809struct AANoUnwindCallSite final : AANoUnwindImpl {
810 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
811
812 /// See AbstractAttribute::initialize(...).
813 void initialize(Attributor &A) override {
814 AANoUnwindImpl::initialize(A);
815 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000816 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000817 indicatePessimisticFixpoint();
818 }
819
820 /// See AbstractAttribute::updateImpl(...).
821 ChangeStatus updateImpl(Attributor &A) override {
822 // TODO: Once we have call site specific value information we can provide
823 // call site specific liveness information and then it makes
824 // sense to specialize attributes for call sites arguments instead of
825 // redirecting requests to the callee argument.
826 Function *F = getAssociatedFunction();
827 const IRPosition &FnPos = IRPosition::function(*F);
828 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
829 return clampStateAndIndicateChange(
830 getState(),
831 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
832 }
833
834 /// See AbstractAttribute::trackStatistics()
835 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
836};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000837
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000838/// --------------------- Function Return Values -------------------------------
839
840/// "Attribute" that collects all potential returned values and the return
841/// instructions that they arise from.
842///
843/// If there is a unique returned value R, the manifest method will:
844/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +0000845class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000846
847 /// Mapping of values potentially returned by the associated function to the
848 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +0000849 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000850
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000851 /// Mapping to remember the number of returned values for a call site such
852 /// that we can avoid updates if nothing changed.
853 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
854
855 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +0000856 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000857
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000858 /// State flags
859 ///
860 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000861 bool IsFixed = false;
862 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000863 ///}
864
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000865public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000866 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000867
868 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +0000869 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000870 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000871 IsFixed = false;
872 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000873 ReturnedValues.clear();
874
Johannes Doerfertdef99282019-08-14 21:29:37 +0000875 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000876 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000877 indicatePessimisticFixpoint();
878 return;
879 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000880
881 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000882 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000883
884 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000885 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000886 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000887 auto &ReturnInstSet = ReturnedValues[&Arg];
888 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
889 ReturnInstSet.insert(cast<ReturnInst>(RI));
890
891 indicateOptimisticFixpoint();
892 return;
893 }
894 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000895
896 if (!F->hasExactDefinition())
897 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000898 }
899
900 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000901 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000902
903 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000904 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000905
906 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000907 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000908
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000909 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +0000910 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000911
Johannes Doerfertdef99282019-08-14 21:29:37 +0000912 llvm::iterator_range<iterator> returned_values() override {
913 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
914 }
915
916 llvm::iterator_range<const_iterator> returned_values() const override {
917 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
918 }
919
Johannes Doerfert695089e2019-08-23 15:23:49 +0000920 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000921 return UnresolvedCalls;
922 }
923
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000924 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000925 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000926 return isValidState() ? ReturnedValues.size() : -1;
927 }
928
929 /// Return an assumed unique return value if a single candidate is found. If
930 /// there cannot be one, return a nullptr. If it is not clear yet, return the
931 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000932 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000933
Johannes Doerfert14a04932019-08-07 22:27:24 +0000934 /// See AbstractState::checkForAllReturnedValues(...).
935 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +0000936 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +0000937 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000938
939 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000940 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000941
942 /// See AbstractState::isAtFixpoint().
943 bool isAtFixpoint() const override { return IsFixed; }
944
945 /// See AbstractState::isValidState().
946 bool isValidState() const override { return IsValidState; }
947
948 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000949 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000950 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000951 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000952 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000953
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000954 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000955 IsFixed = true;
956 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000957 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000958 }
959};
960
961ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
962 ChangeStatus Changed = ChangeStatus::UNCHANGED;
963
964 // Bookkeeping.
965 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000966 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
967 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000968
969 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000970 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000971
972 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
973 return Changed;
974
975 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000976 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
977 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000978
Johannes Doerfert23400e612019-08-23 17:41:37 +0000979 // Callback to replace the uses of CB with the constant C.
980 auto ReplaceCallSiteUsersWith = [](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +0000981 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +0000982 return ChangeStatus::UNCHANGED;
983 CB.replaceAllUsesWith(&C);
984 return ChangeStatus::CHANGED;
985 };
986
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000987 // If the assumed unique return value is an argument, annotate it.
988 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500989 // TODO: This should be handled differently!
990 this->AnchorVal = UniqueRVArg;
991 this->KindOrArgNo = UniqueRVArg->getArgNo();
Johannes Doerfert23400e612019-08-23 17:41:37 +0000992 Changed = IRAttribute::manifest(A);
993 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
994 // We can replace the returned value with the unique returned constant.
995 Value &AnchorValue = getAnchorValue();
996 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
997 for (const Use &U : F->uses())
998 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +0000999 if (CB->isCallee(&U)) {
1000 Constant *RVCCast =
1001 ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
1002 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1003 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001004 } else {
1005 assert(isa<CallBase>(AnchorValue) &&
1006 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001007 Constant *RVCCast =
1008 ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
1009 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001010 }
1011 if (Changed == ChangeStatus::CHANGED)
1012 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1013 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001014 }
1015
1016 return Changed;
1017}
1018
1019const std::string AAReturnedValuesImpl::getAsStr() const {
1020 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001021 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001022 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001023}
1024
Johannes Doerfert14a04932019-08-07 22:27:24 +00001025Optional<Value *>
1026AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1027 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001028 // undef values that can also be present, it is assumed to be the actual
1029 // return value and forwarded to the caller of this method. If there are
1030 // multiple, a nullptr is returned indicating there cannot be a unique
1031 // returned value.
1032 Optional<Value *> UniqueRV;
1033
Johannes Doerfert14a04932019-08-07 22:27:24 +00001034 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001035 // If we found a second returned value and neither the current nor the saved
1036 // one is an undef, there is no unique returned value. Undefs are special
1037 // since we can pretend they have any value.
1038 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1039 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1040 UniqueRV = nullptr;
1041 return false;
1042 }
1043
1044 // Do not overwrite a value with an undef.
1045 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1046 UniqueRV = &RV;
1047
1048 return true;
1049 };
1050
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001051 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001052 UniqueRV = nullptr;
1053
1054 return UniqueRV;
1055}
1056
Johannes Doerfert14a04932019-08-07 22:27:24 +00001057bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001058 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001059 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001060 if (!isValidState())
1061 return false;
1062
1063 // Check all returned values but ignore call sites as long as we have not
1064 // encountered an overdefined one during an update.
1065 for (auto &It : ReturnedValues) {
1066 Value *RV = It.first;
1067
Johannes Doerfertdef99282019-08-14 21:29:37 +00001068 CallBase *CB = dyn_cast<CallBase>(RV);
1069 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001070 continue;
1071
Johannes Doerfert695089e2019-08-23 15:23:49 +00001072 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001073 return false;
1074 }
1075
1076 return true;
1077}
1078
Johannes Doerfertece81902019-08-12 22:05:53 +00001079ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001080 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1081 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001082
Johannes Doerfertdef99282019-08-14 21:29:37 +00001083 // State used in the value traversals starting in returned values.
1084 struct RVState {
1085 // The map in which we collect return values -> return instrs.
1086 decltype(ReturnedValues) &RetValsMap;
1087 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001088 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001089 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001090 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001091 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001092
Johannes Doerfertdef99282019-08-14 21:29:37 +00001093 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001094 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001095 auto Size = RVS.RetValsMap[&Val].size();
1096 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1097 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1098 RVS.Changed |= Inserted;
1099 LLVM_DEBUG({
1100 if (Inserted)
1101 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1102 << " => " << RVS.RetInsts.size() << "\n";
1103 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001104 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001105 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001106
Johannes Doerfertdef99282019-08-14 21:29:37 +00001107 // Helper method to invoke the generic value traversal.
1108 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1109 IRPosition RetValPos = IRPosition::value(RV);
1110 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1111 RVS, VisitValueCB);
1112 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001113
Johannes Doerfertdef99282019-08-14 21:29:37 +00001114 // Callback for all "return intructions" live in the associated function.
1115 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1116 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001117 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001118 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001119 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1120 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001121
Johannes Doerfertdef99282019-08-14 21:29:37 +00001122 // Start by discovering returned values from all live returned instructions in
1123 // the associated function.
1124 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1125 return indicatePessimisticFixpoint();
1126
1127 // Once returned values "directly" present in the code are handled we try to
1128 // resolve returned calls.
1129 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001130 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001131 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1132 << " by #" << It.second.size() << " RIs\n");
1133 CallBase *CB = dyn_cast<CallBase>(It.first);
1134 if (!CB || UnresolvedCalls.count(CB))
1135 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001136
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001137 if (!CB->getCalledFunction()) {
1138 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1139 << "\n");
1140 UnresolvedCalls.insert(CB);
1141 continue;
1142 }
1143
1144 // TODO: use the function scope once we have call site AAReturnedValues.
1145 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1146 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001147 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
1148 << static_cast<const AbstractAttribute &>(RetValAA)
1149 << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001150
1151 // Skip dead ends, thus if we do not know anything about the returned
1152 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001153 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001154 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1155 << "\n");
1156 UnresolvedCalls.insert(CB);
1157 continue;
1158 }
1159
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001160 // Do not try to learn partial information. If the callee has unresolved
1161 // return values we will treat the call as unresolved/opaque.
1162 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1163 if (!RetValAAUnresolvedCalls.empty()) {
1164 UnresolvedCalls.insert(CB);
1165 continue;
1166 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001167
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001168 // Now check if we can track transitively returned values. If possible, thus
1169 // if all return value can be represented in the current scope, do so.
1170 bool Unresolved = false;
1171 for (auto &RetValAAIt : RetValAA.returned_values()) {
1172 Value *RetVal = RetValAAIt.first;
1173 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1174 isa<Constant>(RetVal))
1175 continue;
1176 // Anything that did not fit in the above categories cannot be resolved,
1177 // mark the call as unresolved.
1178 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1179 "cannot be translated: "
1180 << *RetVal << "\n");
1181 UnresolvedCalls.insert(CB);
1182 Unresolved = true;
1183 break;
1184 }
1185
1186 if (Unresolved)
1187 continue;
1188
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001189 // Now track transitively returned values.
1190 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1191 if (NumRetAA == RetValAA.getNumReturnValues()) {
1192 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1193 "changed since it was seen last\n");
1194 continue;
1195 }
1196 NumRetAA = RetValAA.getNumReturnValues();
1197
Johannes Doerfertdef99282019-08-14 21:29:37 +00001198 for (auto &RetValAAIt : RetValAA.returned_values()) {
1199 Value *RetVal = RetValAAIt.first;
1200 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1201 // Arguments are mapped to call site operands and we begin the traversal
1202 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001203 bool Unused = false;
1204 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001205 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1206 continue;
1207 } else if (isa<CallBase>(RetVal)) {
1208 // Call sites are resolved by the callee attribute over time, no need to
1209 // do anything for us.
1210 continue;
1211 } else if (isa<Constant>(RetVal)) {
1212 // Constants are valid everywhere, we can simply take them.
1213 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1214 continue;
1215 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001216 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001217 }
1218
Johannes Doerfertdef99282019-08-14 21:29:37 +00001219 // To avoid modifications to the ReturnedValues map while we iterate over it
1220 // we kept record of potential new entries in a copy map, NewRVsMap.
1221 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001222 assert(!It.second.empty() && "Entry does not add anything.");
1223 auto &ReturnInsts = ReturnedValues[It.first];
1224 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001225 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001226 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1227 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001228 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001229 }
1230 }
1231
Johannes Doerfertdef99282019-08-14 21:29:37 +00001232 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1233 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001234}
1235
Johannes Doerfertdef99282019-08-14 21:29:37 +00001236struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1237 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1238
1239 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001240 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001241};
1242
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001243/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001244struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1245 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1246
1247 /// See AbstractAttribute::initialize(...).
1248 void initialize(Attributor &A) override {
1249 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001250 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001251 // sense to specialize attributes for call sites instead of
1252 // redirecting requests to the callee.
1253 llvm_unreachable("Abstract attributes for returned values are not "
1254 "supported for call sites yet!");
1255 }
1256
1257 /// See AbstractAttribute::updateImpl(...).
1258 ChangeStatus updateImpl(Attributor &A) override {
1259 return indicatePessimisticFixpoint();
1260 }
1261
1262 /// See AbstractAttribute::trackStatistics()
1263 void trackStatistics() const override {}
1264};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001265
Stefan Stipanovic06263672019-07-11 21:37:40 +00001266/// ------------------------ NoSync Function Attribute -------------------------
1267
Johannes Doerfert344d0382019-08-07 22:34:26 +00001268struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001269 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001270
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001271 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001272 return getAssumed() ? "nosync" : "may-sync";
1273 }
1274
1275 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001276 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001277
Stefan Stipanovic06263672019-07-11 21:37:40 +00001278 /// Helper function used to determine whether an instruction is non-relaxed
1279 /// atomic. In other words, if an atomic instruction does not have unordered
1280 /// or monotonic ordering
1281 static bool isNonRelaxedAtomic(Instruction *I);
1282
1283 /// Helper function used to determine whether an instruction is volatile.
1284 static bool isVolatile(Instruction *I);
1285
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001286 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1287 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001288 static bool isNoSyncIntrinsic(Instruction *I);
1289};
1290
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001291bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001292 if (!I->isAtomic())
1293 return false;
1294
1295 AtomicOrdering Ordering;
1296 switch (I->getOpcode()) {
1297 case Instruction::AtomicRMW:
1298 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1299 break;
1300 case Instruction::Store:
1301 Ordering = cast<StoreInst>(I)->getOrdering();
1302 break;
1303 case Instruction::Load:
1304 Ordering = cast<LoadInst>(I)->getOrdering();
1305 break;
1306 case Instruction::Fence: {
1307 auto *FI = cast<FenceInst>(I);
1308 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1309 return false;
1310 Ordering = FI->getOrdering();
1311 break;
1312 }
1313 case Instruction::AtomicCmpXchg: {
1314 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1315 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1316 // Only if both are relaxed, than it can be treated as relaxed.
1317 // Otherwise it is non-relaxed.
1318 if (Success != AtomicOrdering::Unordered &&
1319 Success != AtomicOrdering::Monotonic)
1320 return true;
1321 if (Failure != AtomicOrdering::Unordered &&
1322 Failure != AtomicOrdering::Monotonic)
1323 return true;
1324 return false;
1325 }
1326 default:
1327 llvm_unreachable(
1328 "New atomic operations need to be known in the attributor.");
1329 }
1330
1331 // Relaxed.
1332 if (Ordering == AtomicOrdering::Unordered ||
1333 Ordering == AtomicOrdering::Monotonic)
1334 return false;
1335 return true;
1336}
1337
1338/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1339/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001340bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001341 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1342 switch (II->getIntrinsicID()) {
1343 /// Element wise atomic memory intrinsics are can only be unordered,
1344 /// therefore nosync.
1345 case Intrinsic::memset_element_unordered_atomic:
1346 case Intrinsic::memmove_element_unordered_atomic:
1347 case Intrinsic::memcpy_element_unordered_atomic:
1348 return true;
1349 case Intrinsic::memset:
1350 case Intrinsic::memmove:
1351 case Intrinsic::memcpy:
1352 if (!cast<MemIntrinsic>(II)->isVolatile())
1353 return true;
1354 return false;
1355 default:
1356 return false;
1357 }
1358 }
1359 return false;
1360}
1361
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001362bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001363 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1364 "Calls should not be checked here");
1365
1366 switch (I->getOpcode()) {
1367 case Instruction::AtomicRMW:
1368 return cast<AtomicRMWInst>(I)->isVolatile();
1369 case Instruction::Store:
1370 return cast<StoreInst>(I)->isVolatile();
1371 case Instruction::Load:
1372 return cast<LoadInst>(I)->isVolatile();
1373 case Instruction::AtomicCmpXchg:
1374 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1375 default:
1376 return false;
1377 }
1378}
1379
Johannes Doerfertece81902019-08-12 22:05:53 +00001380ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001381
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001382 auto CheckRWInstForNoSync = [&](Instruction &I) {
1383 /// We are looking for volatile instructions or Non-Relaxed atomics.
1384 /// FIXME: We should ipmrove the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001385
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001386 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1387 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001388
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001389 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1390 if (ICS.hasFnAttr(Attribute::NoSync))
1391 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001392
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001393 const auto &NoSyncAA =
1394 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1395 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001396 return true;
1397 return false;
1398 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001399
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001400 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1401 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001402
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001403 return false;
1404 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001405
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001406 auto CheckForNoSync = [&](Instruction &I) {
1407 // At this point we handled all read/write effects and they are all
1408 // nosync, so they can be skipped.
1409 if (I.mayReadOrWriteMemory())
1410 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001411
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001412 // non-convergent and readnone imply nosync.
1413 return !ImmutableCallSite(&I).isConvergent();
1414 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001415
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001416 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1417 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001418 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001419
Stefan Stipanovic06263672019-07-11 21:37:40 +00001420 return ChangeStatus::UNCHANGED;
1421}
1422
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001423struct AANoSyncFunction final : public AANoSyncImpl {
1424 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1425
1426 /// See AbstractAttribute::trackStatistics()
1427 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1428};
1429
1430/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001431struct AANoSyncCallSite final : AANoSyncImpl {
1432 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1433
1434 /// See AbstractAttribute::initialize(...).
1435 void initialize(Attributor &A) override {
1436 AANoSyncImpl::initialize(A);
1437 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001438 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001439 indicatePessimisticFixpoint();
1440 }
1441
1442 /// See AbstractAttribute::updateImpl(...).
1443 ChangeStatus updateImpl(Attributor &A) override {
1444 // TODO: Once we have call site specific value information we can provide
1445 // call site specific liveness information and then it makes
1446 // sense to specialize attributes for call sites arguments instead of
1447 // redirecting requests to the callee argument.
1448 Function *F = getAssociatedFunction();
1449 const IRPosition &FnPos = IRPosition::function(*F);
1450 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1451 return clampStateAndIndicateChange(
1452 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1453 }
1454
1455 /// See AbstractAttribute::trackStatistics()
1456 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1457};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001458
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001459/// ------------------------ No-Free Attributes ----------------------------
1460
Johannes Doerfert344d0382019-08-07 22:34:26 +00001461struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001462 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001463
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001464 /// See AbstractAttribute::updateImpl(...).
1465 ChangeStatus updateImpl(Attributor &A) override {
1466 auto CheckForNoFree = [&](Instruction &I) {
1467 ImmutableCallSite ICS(&I);
1468 if (ICS.hasFnAttr(Attribute::NoFree))
1469 return true;
1470
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001471 const auto &NoFreeAA =
1472 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1473 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001474 };
1475
1476 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1477 return indicatePessimisticFixpoint();
1478 return ChangeStatus::UNCHANGED;
1479 }
1480
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001481 /// See AbstractAttribute::getAsStr().
1482 const std::string getAsStr() const override {
1483 return getAssumed() ? "nofree" : "may-free";
1484 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001485};
1486
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001487struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001488 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001489
1490 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001491 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001492};
1493
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001494/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001495struct AANoFreeCallSite final : AANoFreeImpl {
1496 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1497
1498 /// See AbstractAttribute::initialize(...).
1499 void initialize(Attributor &A) override {
1500 AANoFreeImpl::initialize(A);
1501 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001502 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001503 indicatePessimisticFixpoint();
1504 }
1505
1506 /// See AbstractAttribute::updateImpl(...).
1507 ChangeStatus updateImpl(Attributor &A) override {
1508 // TODO: Once we have call site specific value information we can provide
1509 // call site specific liveness information and then it makes
1510 // sense to specialize attributes for call sites arguments instead of
1511 // redirecting requests to the callee argument.
1512 Function *F = getAssociatedFunction();
1513 const IRPosition &FnPos = IRPosition::function(*F);
1514 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1515 return clampStateAndIndicateChange(
1516 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1517 }
1518
1519 /// See AbstractAttribute::trackStatistics()
1520 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1521};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001522
Hideto Ueno54869ec2019-07-15 06:49:04 +00001523/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001524static int64_t getKnownNonNullAndDerefBytesForUse(
1525 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1526 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001527 TrackUse = false;
1528
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001529 const Value *UseV = U->get();
1530 if (!UseV->getType()->isPointerTy())
1531 return 0;
1532
1533 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001534 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001535 bool NullPointerIsDefined =
1536 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001537 const DataLayout &DL = A.getInfoCache().getDL();
1538 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1539 if (ICS.isBundleOperand(U))
1540 return 0;
1541
1542 if (ICS.isCallee(U)) {
1543 IsNonNull |= !NullPointerIsDefined;
1544 return 0;
1545 }
1546
1547 unsigned ArgNo = ICS.getArgumentNo(U);
1548 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
1549 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP);
1550 IsNonNull |= DerefAA.isKnownNonNull();
1551 return DerefAA.getKnownDereferenceableBytes();
1552 }
1553
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001554 // We need to follow common pointer manipulation uses to the accesses they
1555 // feed into. We can try to be smart to avoid looking through things we do not
1556 // like for now, e.g., non-inbounds GEPs.
1557 if (isa<CastInst>(I)) {
1558 TrackUse = true;
1559 return 0;
1560 }
1561 if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
1562 if (GEP->hasAllZeroIndices() ||
1563 (GEP->isInBounds() && GEP->hasAllConstantIndices())) {
1564 TrackUse = true;
1565 return 0;
1566 }
1567
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001568 int64_t Offset;
1569 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001570 if (Base == &AssociatedValue && getPointerOperand(I) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001571 int64_t DerefBytes =
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001572 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType()) + Offset;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001573
1574 IsNonNull |= !NullPointerIsDefined;
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001575 return std::max(int64_t(0), DerefBytes);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001576 }
1577 }
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001578 if (const Value *Base =
1579 GetPointerBaseWithConstantOffset(UseV, Offset, DL,
1580 /*AllowNonInbounds*/ false)) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001581 if (Base == &AssociatedValue) {
1582 auto &DerefAA =
1583 A.getAAFor<AADereferenceable>(QueryingAA, IRPosition::value(*Base));
1584 IsNonNull |= (!NullPointerIsDefined && DerefAA.isKnownNonNull());
1585 IsNonNull |= (!NullPointerIsDefined && (Offset != 0));
1586 int64_t DerefBytes = DerefAA.getKnownDereferenceableBytes();
1587 return std::max(int64_t(0), DerefBytes - std::max(int64_t(0), Offset));
1588 }
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001589 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001590
1591 return 0;
1592}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001593
Johannes Doerfert344d0382019-08-07 22:34:26 +00001594struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001595 AANonNullImpl(const IRPosition &IRP)
1596 : AANonNull(IRP),
1597 NullIsDefined(NullPointerIsDefined(
1598 getAnchorScope(),
1599 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001600
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001601 /// See AbstractAttribute::initialize(...).
1602 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001603 if (!NullIsDefined &&
1604 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001605 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001606 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1607 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001608 else
1609 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001610 }
1611
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001612 /// See AAFromMustBeExecutedContext
1613 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1614 bool IsNonNull = false;
1615 bool TrackUse = false;
1616 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1617 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001618 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001619 return TrackUse;
1620 }
1621
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001622 /// See AbstractAttribute::getAsStr().
1623 const std::string getAsStr() const override {
1624 return getAssumed() ? "nonnull" : "may-null";
1625 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001626
1627 /// Flag to determine if the underlying value can be null and still allow
1628 /// valid accesses.
1629 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001630};
1631
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001632/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001633struct AANonNullFloating
1634 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1635 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1636 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001637
Hideto Ueno54869ec2019-07-15 06:49:04 +00001638 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001639 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001640 ChangeStatus Change = Base::updateImpl(A);
1641 if (isKnownNonNull())
1642 return Change;
1643
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001644 if (!NullIsDefined) {
1645 const auto &DerefAA = A.getAAFor<AADereferenceable>(*this, getIRPosition());
1646 if (DerefAA.getAssumedDereferenceableBytes())
1647 return Change;
1648 }
1649
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001650 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001651
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001652 DominatorTree *DT = nullptr;
1653 InformationCache &InfoCache = A.getInfoCache();
1654 if (const Function *Fn = getAnchorScope())
1655 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
1656
Johannes Doerfert1a746452019-10-20 22:28:49 -05001657 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001658 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001659 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1660 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001661 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001662 T.indicatePessimisticFixpoint();
1663 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001664 // Use abstract attribute information.
1665 const AANonNull::StateType &NS =
1666 static_cast<const AANonNull::StateType &>(AA.getState());
1667 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001668 }
1669 return T.isValidState();
1670 };
1671
1672 StateType T;
1673 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
1674 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001675 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001676
1677 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001678 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001679
1680 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001681 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001682};
1683
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001684/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001685struct AANonNullReturned final
1686 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001687 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001688 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001689
1690 /// See AbstractAttribute::trackStatistics()
1691 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
1692};
1693
Hideto Ueno54869ec2019-07-15 06:49:04 +00001694/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001695struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001696 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1697 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001698 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001699 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1700 AANonNullImpl>(
1701 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001702
1703 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001704 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001705};
1706
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001707struct AANonNullCallSiteArgument final : AANonNullFloating {
1708 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001709
1710 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00001711 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001712};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001713
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001714/// NonNull attribute for a call site return position.
1715struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001716 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1717 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001718 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001719 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1720 AANonNullImpl>(
1721 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001722
1723 /// See AbstractAttribute::trackStatistics()
1724 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
1725};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001726
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001727/// ------------------------ No-Recurse Attributes ----------------------------
1728
1729struct AANoRecurseImpl : public AANoRecurse {
1730 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
1731
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001732 /// See AbstractAttribute::getAsStr()
1733 const std::string getAsStr() const override {
1734 return getAssumed() ? "norecurse" : "may-recurse";
1735 }
1736};
1737
1738struct AANoRecurseFunction final : AANoRecurseImpl {
1739 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1740
Hideto Ueno63f60662019-09-21 15:13:19 +00001741 /// See AbstractAttribute::initialize(...).
1742 void initialize(Attributor &A) override {
1743 AANoRecurseImpl::initialize(A);
1744 if (const Function *F = getAnchorScope())
1745 if (A.getInfoCache().getSccSize(*F) == 1)
1746 return;
1747 indicatePessimisticFixpoint();
1748 }
1749
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001750 /// See AbstractAttribute::updateImpl(...).
1751 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00001752
1753 auto CheckForNoRecurse = [&](Instruction &I) {
1754 ImmutableCallSite ICS(&I);
1755 if (ICS.hasFnAttr(Attribute::NoRecurse))
1756 return true;
1757
1758 const auto &NoRecurseAA =
1759 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
1760 if (!NoRecurseAA.isAssumedNoRecurse())
1761 return false;
1762
1763 // Recursion to the same function
1764 if (ICS.getCalledFunction() == getAnchorScope())
1765 return false;
1766
1767 return true;
1768 };
1769
1770 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
1771 return indicatePessimisticFixpoint();
1772 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001773 }
1774
1775 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
1776};
1777
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001778/// NoRecurse attribute deduction for a call sites.
1779struct AANoRecurseCallSite final : AANoRecurseImpl {
1780 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1781
1782 /// See AbstractAttribute::initialize(...).
1783 void initialize(Attributor &A) override {
1784 AANoRecurseImpl::initialize(A);
1785 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001786 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001787 indicatePessimisticFixpoint();
1788 }
1789
1790 /// See AbstractAttribute::updateImpl(...).
1791 ChangeStatus updateImpl(Attributor &A) override {
1792 // TODO: Once we have call site specific value information we can provide
1793 // call site specific liveness information and then it makes
1794 // sense to specialize attributes for call sites arguments instead of
1795 // redirecting requests to the callee argument.
1796 Function *F = getAssociatedFunction();
1797 const IRPosition &FnPos = IRPosition::function(*F);
1798 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
1799 return clampStateAndIndicateChange(
1800 getState(),
1801 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
1802 }
1803
1804 /// See AbstractAttribute::trackStatistics()
1805 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
1806};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001807
Hideto Ueno11d37102019-07-17 15:15:43 +00001808/// ------------------------ Will-Return Attributes ----------------------------
1809
Hideto Ueno11d37102019-07-17 15:15:43 +00001810// Helper function that checks whether a function has any cycle.
1811// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001812static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00001813 SmallPtrSet<BasicBlock *, 32> Visited;
1814
1815 // Traverse BB by dfs and check whether successor is already visited.
1816 for (BasicBlock *BB : depth_first(&F)) {
1817 Visited.insert(BB);
1818 for (auto *SuccBB : successors(BB)) {
1819 if (Visited.count(SuccBB))
1820 return true;
1821 }
1822 }
1823 return false;
1824}
1825
1826// Helper function that checks the function have a loop which might become an
1827// endless loop
1828// FIXME: Any cycle is regarded as endless loop for now.
1829// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001830static bool containsPossiblyEndlessLoop(Function *F) {
1831 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00001832}
1833
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001834struct AAWillReturnImpl : public AAWillReturn {
1835 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00001836
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001837 /// See AbstractAttribute::initialize(...).
1838 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001839 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00001840
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001841 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001842 if (containsPossiblyEndlessLoop(F))
1843 indicatePessimisticFixpoint();
1844 }
Hideto Ueno11d37102019-07-17 15:15:43 +00001845
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001846 /// See AbstractAttribute::updateImpl(...).
1847 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001848 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001849 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
1850 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
1851 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001852 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001853 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001854 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001855 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
1856 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001857 };
1858
1859 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
1860 return indicatePessimisticFixpoint();
1861
1862 return ChangeStatus::UNCHANGED;
1863 }
1864
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001865 /// See AbstractAttribute::getAsStr()
1866 const std::string getAsStr() const override {
1867 return getAssumed() ? "willreturn" : "may-noreturn";
1868 }
1869};
1870
1871struct AAWillReturnFunction final : AAWillReturnImpl {
1872 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1873
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001874 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001875 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001876};
Hideto Ueno11d37102019-07-17 15:15:43 +00001877
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001878/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001879struct AAWillReturnCallSite final : AAWillReturnImpl {
1880 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1881
1882 /// See AbstractAttribute::initialize(...).
1883 void initialize(Attributor &A) override {
1884 AAWillReturnImpl::initialize(A);
1885 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001886 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001887 indicatePessimisticFixpoint();
1888 }
1889
1890 /// See AbstractAttribute::updateImpl(...).
1891 ChangeStatus updateImpl(Attributor &A) override {
1892 // TODO: Once we have call site specific value information we can provide
1893 // call site specific liveness information and then it makes
1894 // sense to specialize attributes for call sites arguments instead of
1895 // redirecting requests to the callee argument.
1896 Function *F = getAssociatedFunction();
1897 const IRPosition &FnPos = IRPosition::function(*F);
1898 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
1899 return clampStateAndIndicateChange(
1900 getState(),
1901 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
1902 }
1903
1904 /// See AbstractAttribute::trackStatistics()
1905 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
1906};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001907
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001908/// ------------------------ NoAlias Argument Attribute ------------------------
1909
Johannes Doerfert344d0382019-08-07 22:34:26 +00001910struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001911 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001912
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001913 const std::string getAsStr() const override {
1914 return getAssumed() ? "noalias" : "may-alias";
1915 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001916};
1917
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001918/// NoAlias attribute for a floating value.
1919struct AANoAliasFloating final : AANoAliasImpl {
1920 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1921
Hideto Uenocbab3342019-08-29 05:52:00 +00001922 /// See AbstractAttribute::initialize(...).
1923 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001924 AANoAliasImpl::initialize(A);
Johannes Doerfert72adda12019-10-10 05:33:21 +00001925 Value &Val = getAssociatedValue();
1926 if (isa<AllocaInst>(Val))
1927 indicateOptimisticFixpoint();
1928 if (isa<ConstantPointerNull>(Val) &&
1929 Val.getType()->getPointerAddressSpace() == 0)
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001930 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001931 }
1932
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001933 /// See AbstractAttribute::updateImpl(...).
1934 ChangeStatus updateImpl(Attributor &A) override {
1935 // TODO: Implement this.
1936 return indicatePessimisticFixpoint();
1937 }
1938
1939 /// See AbstractAttribute::trackStatistics()
1940 void trackStatistics() const override {
1941 STATS_DECLTRACK_FLOATING_ATTR(noalias)
1942 }
1943};
1944
1945/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00001946struct AANoAliasArgument final
1947 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
1948 AANoAliasArgument(const IRPosition &IRP)
1949 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001950
1951 /// See AbstractAttribute::trackStatistics()
1952 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
1953};
1954
1955struct AANoAliasCallSiteArgument final : AANoAliasImpl {
1956 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1957
Hideto Uenocbab3342019-08-29 05:52:00 +00001958 /// See AbstractAttribute::initialize(...).
1959 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00001960 // See callsite argument attribute and callee argument attribute.
1961 ImmutableCallSite ICS(&getAnchorValue());
1962 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
1963 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001964 }
1965
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001966 /// See AbstractAttribute::updateImpl(...).
1967 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001968 // We can deduce "noalias" if the following conditions hold.
1969 // (i) Associated value is assumed to be noalias in the definition.
1970 // (ii) Associated value is assumed to be no-capture in all the uses
1971 // possibly executed before this callsite.
1972 // (iii) There is no other pointer argument which could alias with the
1973 // value.
1974
1975 const Value &V = getAssociatedValue();
1976 const IRPosition IRP = IRPosition::value(V);
1977
1978 // (i) Check whether noalias holds in the definition.
1979
1980 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
1981
1982 if (!NoAliasAA.isAssumedNoAlias())
1983 return indicatePessimisticFixpoint();
1984
1985 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
1986 << " is assumed NoAlias in the definition\n");
1987
1988 // (ii) Check whether the value is captured in the scope using AANoCapture.
1989 // FIXME: This is conservative though, it is better to look at CFG and
1990 // check only uses possibly executed before this callsite.
1991
1992 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert72adda12019-10-10 05:33:21 +00001993 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
1994 LLVM_DEBUG(
1995 dbgs() << "[Attributor][AANoAliasCSArg] " << V
1996 << " cannot be noalias as it is potentially captured\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001997 return indicatePessimisticFixpoint();
Johannes Doerfert72adda12019-10-10 05:33:21 +00001998 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001999
2000 // (iii) Check there is no other pointer argument which could alias with the
2001 // value.
2002 ImmutableCallSite ICS(&getAnchorValue());
2003 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
2004 if (getArgNo() == (int)i)
2005 continue;
2006 const Value *ArgOp = ICS.getArgOperand(i);
2007 if (!ArgOp->getType()->isPointerTy())
2008 continue;
2009
Hideto Ueno30d86f12019-09-17 06:53:27 +00002010 if (const Function *F = getAnchorScope()) {
2011 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
Johannes Doerfert72adda12019-10-10 05:33:21 +00002012 bool IsAliasing = AAR->isNoAlias(&getAssociatedValue(), ArgOp);
Hideto Ueno30d86f12019-09-17 06:53:27 +00002013 LLVM_DEBUG(dbgs()
2014 << "[Attributor][NoAliasCSArg] Check alias between "
2015 "callsite arguments "
2016 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
Johannes Doerfert72adda12019-10-10 05:33:21 +00002017 << getAssociatedValue() << " " << *ArgOp << " => "
2018 << (IsAliasing ? "" : "no-") << "alias \n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002019
Johannes Doerfert72adda12019-10-10 05:33:21 +00002020 if (IsAliasing)
Hideto Ueno30d86f12019-09-17 06:53:27 +00002021 continue;
2022 }
2023 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002024 return indicatePessimisticFixpoint();
2025 }
2026
2027 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002028 }
2029
2030 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002031 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002032};
2033
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002034/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002035struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002036 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002037
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002038 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002039 virtual ChangeStatus updateImpl(Attributor &A) override {
2040
2041 auto CheckReturnValue = [&](Value &RV) -> bool {
2042 if (Constant *C = dyn_cast<Constant>(&RV))
2043 if (C->isNullValue() || isa<UndefValue>(C))
2044 return true;
2045
2046 /// For now, we can only deduce noalias if we have call sites.
2047 /// FIXME: add more support.
2048 ImmutableCallSite ICS(&RV);
2049 if (!ICS)
2050 return false;
2051
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002052 const IRPosition &RVPos = IRPosition::value(RV);
2053 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002054 if (!NoAliasAA.isAssumedNoAlias())
2055 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002056
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002057 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2058 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002059 };
2060
2061 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2062 return indicatePessimisticFixpoint();
2063
2064 return ChangeStatus::UNCHANGED;
2065 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002066
2067 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002068 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002069};
2070
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002071/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002072struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2073 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2074
2075 /// See AbstractAttribute::initialize(...).
2076 void initialize(Attributor &A) override {
2077 AANoAliasImpl::initialize(A);
2078 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002079 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002080 indicatePessimisticFixpoint();
2081 }
2082
2083 /// See AbstractAttribute::updateImpl(...).
2084 ChangeStatus updateImpl(Attributor &A) override {
2085 // TODO: Once we have call site specific value information we can provide
2086 // call site specific liveness information and then it makes
2087 // sense to specialize attributes for call sites arguments instead of
2088 // redirecting requests to the callee argument.
2089 Function *F = getAssociatedFunction();
2090 const IRPosition &FnPos = IRPosition::returned(*F);
2091 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2092 return clampStateAndIndicateChange(
2093 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2094 }
2095
2096 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002097 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002098};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002099
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002100/// -------------------AAIsDead Function Attribute-----------------------
2101
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002102struct AAIsDeadValueImpl : public AAIsDead {
2103 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002104
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002105 /// See AAIsDead::isAssumedDead().
2106 bool isAssumedDead() const override { return getAssumed(); }
2107
2108 /// See AAIsDead::isAssumedDead(BasicBlock *).
2109 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2110
2111 /// See AAIsDead::isKnownDead(BasicBlock *).
2112 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2113
2114 /// See AAIsDead::isAssumedDead(Instruction *I).
2115 bool isAssumedDead(const Instruction *I) const override {
2116 return I == getCtxI() && isAssumedDead();
2117 }
2118
2119 /// See AAIsDead::isKnownDead(Instruction *I).
2120 bool isKnownDead(const Instruction *I) const override {
2121 return I == getCtxI() && getKnown();
2122 }
2123
2124 /// See AbstractAttribute::getAsStr().
2125 const std::string getAsStr() const override {
2126 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2127 }
2128};
2129
2130struct AAIsDeadFloating : public AAIsDeadValueImpl {
2131 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2132
2133 /// See AbstractAttribute::initialize(...).
2134 void initialize(Attributor &A) override {
2135 if (Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()))
2136 if (!wouldInstructionBeTriviallyDead(I))
2137 indicatePessimisticFixpoint();
2138 if (isa<UndefValue>(getAssociatedValue()))
2139 indicatePessimisticFixpoint();
2140 }
2141
2142 /// See AbstractAttribute::updateImpl(...).
2143 ChangeStatus updateImpl(Attributor &A) override {
2144 auto UsePred = [&](const Use &U, bool &Follow) {
2145 Instruction *UserI = cast<Instruction>(U.getUser());
2146 if (CallSite CS = CallSite(UserI)) {
2147 if (!CS.isArgOperand(&U))
2148 return false;
2149 const IRPosition &CSArgPos =
2150 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
2151 const auto &CSArgIsDead = A.getAAFor<AAIsDead>(*this, CSArgPos);
2152 return CSArgIsDead.isAssumedDead();
2153 }
2154 if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
2155 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
2156 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, RetPos);
2157 return RetIsDeadAA.isAssumedDead();
2158 }
2159 Follow = true;
2160 return wouldInstructionBeTriviallyDead(UserI);
2161 };
2162
2163 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
2164 return indicatePessimisticFixpoint();
2165 return ChangeStatus::UNCHANGED;
2166 }
2167
2168 /// See AbstractAttribute::manifest(...).
2169 ChangeStatus manifest(Attributor &A) override {
2170 Value &V = getAssociatedValue();
2171 if (auto *I = dyn_cast<Instruction>(&V))
2172 if (wouldInstructionBeTriviallyDead(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002173 A.deleteAfterManifest(*I);
2174 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002175 }
2176
2177 if (V.use_empty())
2178 return ChangeStatus::UNCHANGED;
2179
2180 UndefValue &UV = *UndefValue::get(V.getType());
2181 bool AnyChange = false;
2182 for (Use &U : V.uses())
2183 AnyChange |= A.changeUseAfterManifest(U, UV);
2184 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2185 }
2186
2187 /// See AbstractAttribute::trackStatistics()
2188 void trackStatistics() const override {
2189 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2190 }
2191};
2192
2193struct AAIsDeadArgument : public AAIsDeadFloating {
2194 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2195
2196 /// See AbstractAttribute::initialize(...).
2197 void initialize(Attributor &A) override {
2198 if (!getAssociatedFunction()->hasExactDefinition())
2199 indicatePessimisticFixpoint();
2200 }
2201
2202 /// See AbstractAttribute::trackStatistics()
2203 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
2204};
2205
2206struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
2207 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2208
2209 /// See AbstractAttribute::initialize(...).
2210 void initialize(Attributor &A) override {
2211 if (isa<UndefValue>(getAssociatedValue()))
2212 indicatePessimisticFixpoint();
2213 }
2214
2215 /// See AbstractAttribute::updateImpl(...).
2216 ChangeStatus updateImpl(Attributor &A) override {
2217 // TODO: Once we have call site specific value information we can provide
2218 // call site specific liveness information and then it makes
2219 // sense to specialize attributes for call sites arguments instead of
2220 // redirecting requests to the callee argument.
2221 Argument *Arg = getAssociatedArgument();
2222 if (!Arg)
2223 return indicatePessimisticFixpoint();
2224 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2225 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
2226 return clampStateAndIndicateChange(
2227 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
2228 }
2229
2230 /// See AbstractAttribute::manifest(...).
2231 ChangeStatus manifest(Attributor &A) override {
2232 CallBase &CB = cast<CallBase>(getAnchorValue());
2233 Use &U = CB.getArgOperandUse(getArgNo());
2234 assert(!isa<UndefValue>(U.get()) &&
2235 "Expected undef values to be filtered out!");
2236 UndefValue &UV = *UndefValue::get(U->getType());
2237 if (A.changeUseAfterManifest(U, UV))
2238 return ChangeStatus::CHANGED;
2239 return ChangeStatus::UNCHANGED;
2240 }
2241
2242 /// See AbstractAttribute::trackStatistics()
2243 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
2244};
2245
2246struct AAIsDeadReturned : public AAIsDeadValueImpl {
2247 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2248
2249 /// See AbstractAttribute::updateImpl(...).
2250 ChangeStatus updateImpl(Attributor &A) override {
2251
2252 auto PredForCallSite = [&](AbstractCallSite ACS) {
2253 if (ACS.isCallbackCall())
2254 return false;
2255 const IRPosition &CSRetPos =
2256 IRPosition::callsite_returned(ACS.getCallSite());
2257 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, CSRetPos);
2258 return RetIsDeadAA.isAssumedDead();
2259 };
2260
2261 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
2262 return indicatePessimisticFixpoint();
2263
2264 return ChangeStatus::UNCHANGED;
2265 }
2266
2267 /// See AbstractAttribute::manifest(...).
2268 ChangeStatus manifest(Attributor &A) override {
2269 // TODO: Rewrite the signature to return void?
2270 bool AnyChange = false;
2271 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
2272 auto RetInstPred = [&](Instruction &I) {
2273 ReturnInst &RI = cast<ReturnInst>(I);
2274 if (!isa<UndefValue>(RI.getReturnValue()))
2275 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
2276 return true;
2277 };
2278 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
2279 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2280 }
2281
2282 /// See AbstractAttribute::trackStatistics()
2283 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
2284};
2285
2286struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
2287 AAIsDeadCallSiteReturned(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2288
2289 /// See AbstractAttribute::initialize(...).
2290 void initialize(Attributor &A) override {}
2291
2292 /// See AbstractAttribute::trackStatistics()
2293 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(IsDead) }
2294};
2295
2296struct AAIsDeadFunction : public AAIsDead {
2297 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
2298
2299 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002300 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002301 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002302 if (F && !F->isDeclaration()) {
2303 ToBeExploredFrom.insert(&F->getEntryBlock().front());
2304 assumeLive(A, F->getEntryBlock());
2305 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002306 }
2307
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002308 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002309 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002310 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002311 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
2312 std::to_string(ToBeExploredFrom.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002313 }
2314
2315 /// See AbstractAttribute::manifest(...).
2316 ChangeStatus manifest(Attributor &A) override {
2317 assert(getState().isValidState() &&
2318 "Attempted to manifest an invalid state!");
2319
2320 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002321 Function &F = *getAssociatedFunction();
2322
2323 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002324 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002325 return ChangeStatus::CHANGED;
2326 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00002327
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002328 // Flag to determine if we can change an invoke to a call assuming the
2329 // callee is nounwind. This is not possible if the personality of the
2330 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002331 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002332
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002333 for (const Instruction *ExploreEndI : ToBeExploredFrom) {
2334 auto *CB = dyn_cast<CallBase>(ExploreEndI);
2335 if (!CB)
2336 continue;
2337 const auto &NoReturnAA =
2338 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
2339 if (!NoReturnAA.isAssumedNoReturn())
2340 continue;
2341 Instruction *I = const_cast<Instruction *>(ExploreEndI);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002342 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002343 Instruction *SplitPos = I->getNextNode();
Johannes Doerfertd4108052019-08-21 20:56:41 +00002344 // TODO: mark stuff before unreachable instructions as dead.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002345
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002346 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002347 // If we keep the invoke the split position is at the beginning of the
2348 // normal desitination block (it invokes a noreturn function after all).
2349 BasicBlock *NormalDestBB = II->getNormalDest();
2350 SplitPos = &NormalDestBB->front();
2351
Johannes Doerfert4361da22019-08-04 18:38:53 +00002352 /// Invoke is replaced with a call and unreachable is placed after it if
2353 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
2354 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002355 if (Invoke2CallAllowed) {
Michael Liaoa99086d2019-08-20 21:02:31 +00002356 if (II->getCalledFunction()) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002357 const IRPosition &IPos = IRPosition::callsite_function(*II);
2358 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2359 if (AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert924d2132019-08-05 21:34:45 +00002360 LLVM_DEBUG(dbgs()
2361 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002362 // We do not need an invoke (II) but instead want a call followed
2363 // by an unreachable. However, we do not remove II as other
2364 // abstract attributes might have it cached as part of their
2365 // results. Given that we modify the CFG anyway, we simply keep II
2366 // around but in a new dead block. To avoid II being live through
2367 // a different edge we have to ensure the block we place it in is
2368 // only reached from the current block of II and then not reached
2369 // at all when we insert the unreachable.
2370 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
2371 CallInst *CI = createCallMatchingInvoke(II);
2372 CI->insertBefore(II);
2373 CI->takeName(II);
2374 II->replaceAllUsesWith(CI);
2375 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002376 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002377 }
2378 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002379
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002380 if (SplitPos == &NormalDestBB->front()) {
2381 // If this is an invoke of a noreturn function the edge to the normal
2382 // destination block is dead but not necessarily the block itself.
2383 // TODO: We need to move to an edge based system during deduction and
2384 // also manifest.
2385 assert(!NormalDestBB->isLandingPad() &&
2386 "Expected the normal destination not to be a landingpad!");
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002387 if (NormalDestBB->getUniquePredecessor() == BB) {
2388 assumeLive(A, *NormalDestBB);
2389 } else {
2390 BasicBlock *SplitBB =
2391 SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2392 // The split block is live even if it contains only an unreachable
2393 // instruction at the end.
2394 assumeLive(A, *SplitBB);
2395 SplitPos = SplitBB->getTerminator();
2396 HasChanged = ChangeStatus::CHANGED;
2397 }
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002398 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002399 }
2400
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002401 if (isa_and_nonnull<UnreachableInst>(SplitPos))
2402 continue;
2403
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002404 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002405 SplitBlock(BB, SplitPos);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002406 changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
2407 HasChanged = ChangeStatus::CHANGED;
2408 }
2409
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002410 for (BasicBlock &BB : F)
2411 if (!AssumedLiveBlocks.count(&BB))
2412 A.deleteAfterManifest(BB);
2413
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002414 return HasChanged;
2415 }
2416
2417 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002418 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002419
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002420 /// See AbstractAttribute::trackStatistics()
2421 void trackStatistics() const override {}
2422
2423 /// Returns true if the function is assumed dead.
2424 bool isAssumedDead() const override { return false; }
2425
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002426 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002427 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002428 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002429 "BB must be in the same anchor scope function.");
2430
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002431 if (!getAssumed())
2432 return false;
2433 return !AssumedLiveBlocks.count(BB);
2434 }
2435
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002436 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002437 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002438 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002439 }
2440
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002441 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002442 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002443 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002444 "Instruction must be in the same anchor scope function.");
2445
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002446 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002447 return false;
2448
2449 // If it is not in AssumedLiveBlocks then it for sure dead.
2450 // Otherwise, it can still be after noreturn call in a live block.
2451 if (!AssumedLiveBlocks.count(I->getParent()))
2452 return true;
2453
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002454 // If it is not after a liveness barrier it is live.
2455 const Instruction *PrevI = I->getPrevNode();
2456 while (PrevI) {
2457 if (ToBeExploredFrom.count(PrevI))
2458 return true;
2459 PrevI = PrevI->getPrevNode();
2460 }
2461 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002462 }
2463
2464 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002465 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002466 return getKnown() && isAssumedDead(I);
2467 }
2468
Johannes Doerfert924d2132019-08-05 21:34:45 +00002469 /// Determine if \p F might catch asynchronous exceptions.
2470 static bool mayCatchAsynchronousExceptions(const Function &F) {
2471 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2472 }
2473
Johannes Doerfert2f622062019-09-04 16:35:20 +00002474 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2475 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002476 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002477 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002478 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002479
2480 // We assume that all of BB is (probably) live now and if there are calls to
2481 // internal functions we will assume that those are now live as well. This
2482 // is a performance optimization for blocks with calls to a lot of internal
2483 // functions. It can however cause dead functions to be treated as live.
2484 for (const Instruction &I : BB)
2485 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
2486 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00002487 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00002488 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002489 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002490 }
2491
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002492 /// Collection of instructions that need to be explored again, e.g., we
2493 /// did assume they do not transfer control to (one of their) successors.
2494 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002495
2496 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002497 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002498};
2499
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002500static bool
2501identifyAliveSuccessors(Attributor &A, const CallBase &CB,
2502 AbstractAttribute &AA,
2503 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2504 const IRPosition &IPos = IRPosition::callsite_function(CB);
2505
2506 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
2507 if (NoReturnAA.isAssumedNoReturn())
2508 return true;
2509 if (CB.isTerminator())
2510 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
2511 else
2512 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002513 return false;
2514}
2515
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002516static bool
2517identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
2518 AbstractAttribute &AA,
2519 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2520 bool UsedAssumedInformation =
2521 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00002522
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002523 // First, determine if we can change an invoke to a call assuming the
2524 // callee is nounwind. This is not possible if the personality of the
2525 // function allows to catch asynchronous exceptions.
2526 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
2527 AliveSuccessors.push_back(&II.getUnwindDest()->front());
2528 } else {
2529 const IRPosition &IPos = IRPosition::callsite_function(II);
2530 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
2531 if (!AANoUnw.isAssumedNoUnwind()) {
2532 AliveSuccessors.push_back(&II.getUnwindDest()->front());
2533 UsedAssumedInformation = true;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002534 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002535 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002536 return UsedAssumedInformation;
2537}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002538
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002539static Optional<ConstantInt *> getAssumedConstant(Attributor &A, const Value &V,
2540 AbstractAttribute &AA) {
2541 const auto &ValueSimplifyAA =
2542 A.getAAFor<AAValueSimplify>(AA, IRPosition::value(V));
2543 Optional<Value *> SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(A);
2544 if (!SimplifiedV.hasValue())
2545 return llvm::None;
2546 if (isa_and_nonnull<UndefValue>(SimplifiedV.getValue()))
2547 return llvm::None;
2548 return dyn_cast_or_null<ConstantInt>(SimplifiedV.getValue());
2549}
2550
2551static bool
2552identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
2553 AbstractAttribute &AA,
2554 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2555 bool UsedAssumedInformation = false;
2556 if (BI.getNumSuccessors() == 1) {
2557 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
2558 } else {
2559 Optional<ConstantInt *> CI = getAssumedConstant(A, *BI.getCondition(), AA);
2560 if (!CI.hasValue()) {
2561 // No value yet, assume both edges are dead.
2562 } else if (CI.getValue()) {
2563 const BasicBlock *SuccBB =
2564 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
2565 AliveSuccessors.push_back(&SuccBB->front());
2566 UsedAssumedInformation = true;
2567 } else {
2568 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
2569 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
2570 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002571 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002572 return UsedAssumedInformation;
2573}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002574
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002575static bool
2576identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
2577 AbstractAttribute &AA,
2578 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2579 bool UsedAssumedInformation = false;
2580 Optional<ConstantInt *> CI = getAssumedConstant(A, *SI.getCondition(), AA);
2581 if (!CI.hasValue()) {
2582 // No value yet, assume all edges are dead.
2583 } else if (CI.getValue()) {
2584 for (auto &CaseIt : SI.cases()) {
2585 if (CaseIt.getCaseValue() == CI.getValue()) {
2586 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
2587 UsedAssumedInformation = true;
2588 break;
2589 }
2590 }
2591 } else {
2592 for (const BasicBlock *SuccBB : successors(SI.getParent()))
2593 AliveSuccessors.push_back(&SuccBB->front());
2594 }
2595 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002596}
2597
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002598ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002599 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002600
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002601 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
2602 << getAssociatedFunction()->size() << "] BBs and "
2603 << ToBeExploredFrom.size() << " exploration points\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002604
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002605 // Copy and clear the list of instructions we need to explore from. It is
2606 // refilled with instructions the next update has to look at.
2607 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
2608 ToBeExploredFrom.end());
2609 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002610
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002611 SmallVector<const Instruction *, 8> AliveSuccessors;
2612 while (!Worklist.empty()) {
2613 const Instruction *I = Worklist.pop_back_val();
2614 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002615
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002616 AliveSuccessors.clear();
2617
2618 bool UsedAssumedInformation = false;
2619 switch (I->getOpcode()) {
2620 // TODO: look for (assumed) UB to backwards propagate "deadness".
2621 default:
2622 if (I->isTerminator()) {
2623 for (const BasicBlock *SuccBB : successors(I->getParent()))
2624 AliveSuccessors.push_back(&SuccBB->front());
2625 } else {
2626 AliveSuccessors.push_back(I->getNextNode());
2627 }
2628 break;
2629 case Instruction::Call:
2630 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
2631 *this, AliveSuccessors);
2632 break;
2633 case Instruction::Invoke:
2634 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
2635 *this, AliveSuccessors);
2636 break;
2637 case Instruction::Br:
2638 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
2639 *this, AliveSuccessors);
2640 break;
2641 case Instruction::Switch:
2642 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
2643 *this, AliveSuccessors);
2644 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00002645 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002646
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002647 if (UsedAssumedInformation)
2648 NewToBeExploredFrom.insert(I);
2649 else
2650 Change = ChangeStatus::CHANGED;
2651
2652 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
2653 << AliveSuccessors.size() << " UsedAssumedInformation: "
2654 << UsedAssumedInformation << "\n");
2655
2656 for (const Instruction *AliveSuccessor : AliveSuccessors) {
2657 if (!I->isTerminator()) {
2658 assert(AliveSuccessors.size() == 1 &&
2659 "Non-terminator expected to have a single successor!");
2660 Worklist.push_back(AliveSuccessor);
2661 } else {
2662 if (assumeLive(A, *AliveSuccessor->getParent()))
2663 Worklist.push_back(AliveSuccessor);
2664 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002665 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002666 }
2667
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002668 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002669
Johannes Doerfertd6207812019-08-07 22:32:38 +00002670 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002671 // Instead, indicating a pessimistic fixpoint will cause the state to be
2672 // "invalid" and all queries to be answered conservatively.
2673 if (ToBeExploredFrom.empty() &&
2674 getAssociatedFunction()->size() == AssumedLiveBlocks.size())
2675 return indicatePessimisticFixpoint();
2676 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002677}
2678
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002679/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002680struct AAIsDeadCallSite final : AAIsDeadFunction {
2681 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002682
2683 /// See AbstractAttribute::initialize(...).
2684 void initialize(Attributor &A) override {
2685 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002686 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002687 // sense to specialize attributes for call sites instead of
2688 // redirecting requests to the callee.
2689 llvm_unreachable("Abstract attributes for liveness are not "
2690 "supported for call sites yet!");
2691 }
2692
2693 /// See AbstractAttribute::updateImpl(...).
2694 ChangeStatus updateImpl(Attributor &A) override {
2695 return indicatePessimisticFixpoint();
2696 }
2697
2698 /// See AbstractAttribute::trackStatistics()
2699 void trackStatistics() const override {}
2700};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002701
Hideto Ueno19c07af2019-07-23 08:16:17 +00002702/// -------------------- Dereferenceable Argument Attribute --------------------
2703
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002704template <>
2705ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
2706 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05002707 ChangeStatus CS0 =
2708 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
2709 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002710 return CS0 | CS1;
2711}
2712
Hideto Ueno70576ca2019-08-22 14:18:29 +00002713struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002714 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00002715 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00002716
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002717 void initialize(Attributor &A) override {
2718 SmallVector<Attribute, 4> Attrs;
2719 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
2720 Attrs);
2721 for (const Attribute &Attr : Attrs)
2722 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
2723
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002724 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002725
2726 const IRPosition &IRP = this->getIRPosition();
2727 bool IsFnInterface = IRP.isFnInterfaceKind();
2728 const Function *FnScope = IRP.getAnchorScope();
2729 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
2730 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002731 }
2732
Hideto Ueno19c07af2019-07-23 08:16:17 +00002733 /// See AbstractAttribute::getState()
2734 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00002735 StateType &getState() override { return *this; }
2736 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002737 /// }
2738
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002739 /// See AAFromMustBeExecutedContext
2740 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
2741 bool IsNonNull = false;
2742 bool TrackUse = false;
2743 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
2744 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
2745 takeKnownDerefBytesMaximum(DerefBytes);
2746 return TrackUse;
2747 }
2748
Johannes Doerferteccdf082019-08-05 23:35:12 +00002749 void getDeducedAttributes(LLVMContext &Ctx,
2750 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002751 // TODO: Add *_globally support
2752 if (isAssumedNonNull())
2753 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
2754 Ctx, getAssumedDereferenceableBytes()));
2755 else
2756 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
2757 Ctx, getAssumedDereferenceableBytes()));
2758 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002759
2760 /// See AbstractAttribute::getAsStr().
2761 const std::string getAsStr() const override {
2762 if (!getAssumedDereferenceableBytes())
2763 return "unknown-dereferenceable";
2764 return std::string("dereferenceable") +
2765 (isAssumedNonNull() ? "" : "_or_null") +
2766 (isAssumedGlobal() ? "_globally" : "") + "<" +
2767 std::to_string(getKnownDereferenceableBytes()) + "-" +
2768 std::to_string(getAssumedDereferenceableBytes()) + ">";
2769 }
2770};
2771
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002772/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002773struct AADereferenceableFloating
2774 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
2775 using Base =
2776 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
2777 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00002778
2779 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002780 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002781 ChangeStatus Change = Base::updateImpl(A);
2782
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002783 const DataLayout &DL = A.getDataLayout();
2784
2785 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
2786 unsigned IdxWidth =
2787 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
2788 APInt Offset(IdxWidth, 0);
2789 const Value *Base =
2790 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
2791
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002792 const auto &AA =
2793 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002794 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002795 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002796 // Use IR information if we did not strip anything.
2797 // TODO: track globally.
2798 bool CanBeNull;
2799 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
2800 T.GlobalState.indicatePessimisticFixpoint();
2801 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002802 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002803 DerefBytes = DS.DerefBytesState.getAssumed();
2804 T.GlobalState &= DS.GlobalState;
2805 }
2806
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002807 // For now we do not try to "increase" dereferenceability due to negative
2808 // indices as we first have to come up with code to deal with loops and
2809 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00002810 int64_t OffsetSExt = Offset.getSExtValue();
2811 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00002812 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002813
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002814 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00002815 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002816
Johannes Doerfert785fad32019-08-23 17:29:23 +00002817 if (this == &AA) {
2818 if (!Stripped) {
2819 // If nothing was stripped IR information is all we got.
2820 T.takeKnownDerefBytesMaximum(
2821 std::max(int64_t(0), DerefBytes - OffsetSExt));
2822 T.indicatePessimisticFixpoint();
2823 } else if (OffsetSExt > 0) {
2824 // If something was stripped but there is circular reasoning we look
2825 // for the offset. If it is positive we basically decrease the
2826 // dereferenceable bytes in a circluar loop now, which will simply
2827 // drive them down to the known value in a very slow way which we
2828 // can accelerate.
2829 T.indicatePessimisticFixpoint();
2830 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002831 }
2832
2833 return T.isValidState();
2834 };
2835
2836 DerefState T;
2837 if (!genericValueTraversal<AADereferenceable, DerefState>(
2838 A, getIRPosition(), *this, T, VisitValueCB))
2839 return indicatePessimisticFixpoint();
2840
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002841 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002842 }
2843
2844 /// See AbstractAttribute::trackStatistics()
2845 void trackStatistics() const override {
2846 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
2847 }
2848};
2849
2850/// Dereferenceable attribute for a return value.
2851struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002852 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2853 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002854 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002855 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2856 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002857
2858 /// See AbstractAttribute::trackStatistics()
2859 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002860 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002861 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002862};
2863
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002864/// Dereferenceable attribute for an argument
2865struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002866 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2867 AADereferenceable, AADereferenceableImpl, DerefState> {
2868 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2869 AADereferenceable, AADereferenceableImpl, DerefState>;
2870 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002871
2872 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002873 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00002874 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
2875 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002876};
2877
Hideto Ueno19c07af2019-07-23 08:16:17 +00002878/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002879struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002880 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002881 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002882
2883 /// See AbstractAttribute::trackStatistics()
2884 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002885 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002886 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002887};
2888
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002889/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002890struct AADereferenceableCallSiteReturned final
2891 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2892 AADereferenceable, AADereferenceableImpl> {
2893 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2894 AADereferenceable, AADereferenceableImpl>;
2895 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002896
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002897 /// See AbstractAttribute::trackStatistics()
2898 void trackStatistics() const override {
2899 STATS_DECLTRACK_CS_ATTR(dereferenceable);
2900 }
2901};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002902
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002903// ------------------------ Align Argument Attribute ------------------------
2904
Johannes Doerfert344d0382019-08-07 22:34:26 +00002905struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002906 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002907
Johannes Doerfert234eda52019-08-16 19:51:23 +00002908 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002909 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002910 SmallVector<Attribute, 4> Attrs;
2911 getAttrs({Attribute::Alignment}, Attrs);
2912 for (const Attribute &Attr : Attrs)
2913 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00002914
2915 if (getIRPosition().isFnInterfaceKind() &&
2916 (!getAssociatedFunction() ||
2917 !getAssociatedFunction()->hasExactDefinition()))
2918 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002919 }
2920
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002921 /// See AbstractAttribute::manifest(...).
2922 ChangeStatus manifest(Attributor &A) override {
2923 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2924
2925 // Check for users that allow alignment annotations.
2926 Value &AnchorVal = getIRPosition().getAnchorValue();
2927 for (const Use &U : AnchorVal.uses()) {
2928 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
2929 if (SI->getPointerOperand() == &AnchorVal)
2930 if (SI->getAlignment() < getAssumedAlign()) {
2931 STATS_DECLTRACK(AAAlign, Store,
2932 "Number of times alignemnt added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00002933 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002934 Changed = ChangeStatus::CHANGED;
2935 }
2936 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
2937 if (LI->getPointerOperand() == &AnchorVal)
2938 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00002939 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002940 STATS_DECLTRACK(AAAlign, Load,
2941 "Number of times alignemnt added to a load");
2942 Changed = ChangeStatus::CHANGED;
2943 }
2944 }
2945 }
2946
Johannes Doerfert81df4522019-08-30 15:22:28 +00002947 return AAAlign::manifest(A) | Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002948 }
2949
Johannes Doerfert81df4522019-08-30 15:22:28 +00002950 // TODO: Provide a helper to determine the implied ABI alignment and check in
2951 // the existing manifest method and a new one for AAAlignImpl that value
2952 // to avoid making the alignment explicit if it did not improve.
2953
2954 /// See AbstractAttribute::getDeducedAttributes
2955 virtual void
2956 getDeducedAttributes(LLVMContext &Ctx,
2957 SmallVectorImpl<Attribute> &Attrs) const override {
2958 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00002959 Attrs.emplace_back(
2960 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00002961 }
2962
2963 /// See AbstractAttribute::getAsStr().
2964 const std::string getAsStr() const override {
2965 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
2966 "-" + std::to_string(getAssumedAlign()) + ">")
2967 : "unknown-align";
2968 }
2969};
2970
2971/// Align attribute for a floating value.
2972struct AAAlignFloating : AAAlignImpl {
2973 AAAlignFloating(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2974
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002975 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00002976 ChangeStatus updateImpl(Attributor &A) override {
2977 const DataLayout &DL = A.getDataLayout();
2978
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002979 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
2980 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002981 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
2982 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002983 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00002984 const MaybeAlign PA = V.getPointerAlignment(DL);
2985 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00002986 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002987 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002988 // Use abstract attribute information.
2989 const AAAlign::StateType &DS =
2990 static_cast<const AAAlign::StateType &>(AA.getState());
2991 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00002992 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002993 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002994 };
2995
2996 StateType T;
2997 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
2998 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002999 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003000
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003001 // TODO: If we know we visited all incoming values, thus no are assumed
3002 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003003 return clampStateAndIndicateChange(getState(), T);
3004 }
3005
3006 /// See AbstractAttribute::trackStatistics()
3007 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3008};
3009
3010/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003011struct AAAlignReturned final
3012 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003013 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003014 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003015
3016 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003017 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003018};
3019
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003020/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003021struct AAAlignArgument final
3022 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003023 AAAlignArgument(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003024 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003025
3026 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003027 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003028};
3029
Johannes Doerfert234eda52019-08-16 19:51:23 +00003030struct AAAlignCallSiteArgument final : AAAlignFloating {
3031 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003032
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003033 /// See AbstractAttribute::manifest(...).
3034 ChangeStatus manifest(Attributor &A) override {
3035 return AAAlignImpl::manifest(A);
3036 }
3037
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003038 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003039 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003040};
3041
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003042/// Align attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003043struct AAAlignCallSiteReturned final : AAAlignImpl {
3044 AAAlignCallSiteReturned(const IRPosition &IRP) : AAAlignImpl(IRP) {}
3045
3046 /// See AbstractAttribute::initialize(...).
3047 void initialize(Attributor &A) override {
3048 AAAlignImpl::initialize(A);
3049 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003050 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003051 indicatePessimisticFixpoint();
3052 }
3053
3054 /// See AbstractAttribute::updateImpl(...).
3055 ChangeStatus updateImpl(Attributor &A) override {
3056 // TODO: Once we have call site specific value information we can provide
3057 // call site specific liveness information and then it makes
3058 // sense to specialize attributes for call sites arguments instead of
3059 // redirecting requests to the callee argument.
3060 Function *F = getAssociatedFunction();
3061 const IRPosition &FnPos = IRPosition::returned(*F);
3062 auto &FnAA = A.getAAFor<AAAlign>(*this, FnPos);
3063 return clampStateAndIndicateChange(
3064 getState(), static_cast<const AAAlign::StateType &>(FnAA.getState()));
3065 }
3066
3067 /// See AbstractAttribute::trackStatistics()
3068 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3069};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003070
Johannes Doerferte83f3032019-08-05 23:22:05 +00003071/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00003072struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003073 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00003074
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003075 /// See AbstractAttribute::initialize(...).
3076 void initialize(Attributor &A) override {
3077 AANoReturn::initialize(A);
3078 Function *F = getAssociatedFunction();
3079 if (!F || F->hasFnAttribute(Attribute::WillReturn))
3080 indicatePessimisticFixpoint();
3081 }
3082
Johannes Doerferte83f3032019-08-05 23:22:05 +00003083 /// See AbstractAttribute::getAsStr().
3084 const std::string getAsStr() const override {
3085 return getAssumed() ? "noreturn" : "may-return";
3086 }
3087
Johannes Doerferte83f3032019-08-05 23:22:05 +00003088 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00003089 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003090 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, getIRPosition());
3091 if (WillReturnAA.isKnownWillReturn())
3092 return indicatePessimisticFixpoint();
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003093 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003094 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003095 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00003096 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00003097 return ChangeStatus::UNCHANGED;
3098 }
3099};
3100
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003101struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003102 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003103
3104 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003105 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003106};
3107
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003108/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003109struct AANoReturnCallSite final : AANoReturnImpl {
3110 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
3111
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003112 /// See AbstractAttribute::updateImpl(...).
3113 ChangeStatus updateImpl(Attributor &A) override {
3114 // TODO: Once we have call site specific value information we can provide
3115 // call site specific liveness information and then it makes
3116 // sense to specialize attributes for call sites arguments instead of
3117 // redirecting requests to the callee argument.
3118 Function *F = getAssociatedFunction();
3119 const IRPosition &FnPos = IRPosition::function(*F);
3120 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
3121 return clampStateAndIndicateChange(
3122 getState(),
3123 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
3124 }
3125
3126 /// See AbstractAttribute::trackStatistics()
3127 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
3128};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003129
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003130/// ----------------------- Variable Capturing ---------------------------------
3131
3132/// A class to hold the state of for no-capture attributes.
3133struct AANoCaptureImpl : public AANoCapture {
3134 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
3135
3136 /// See AbstractAttribute::initialize(...).
3137 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003138 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
3139 indicateOptimisticFixpoint();
3140 return;
3141 }
3142 Function *AnchorScope = getAnchorScope();
3143 if (isFnInterfaceKind() &&
3144 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
3145 indicatePessimisticFixpoint();
3146 return;
3147 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003148
Johannes Doerfert72adda12019-10-10 05:33:21 +00003149 // You cannot "capture" null in the default address space.
3150 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
3151 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
3152 indicateOptimisticFixpoint();
3153 return;
3154 }
3155
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003156 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003157
3158 // Check what state the associated function can actually capture.
3159 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003160 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003161 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003162 indicatePessimisticFixpoint();
3163 }
3164
3165 /// See AbstractAttribute::updateImpl(...).
3166 ChangeStatus updateImpl(Attributor &A) override;
3167
3168 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
3169 virtual void
3170 getDeducedAttributes(LLVMContext &Ctx,
3171 SmallVectorImpl<Attribute> &Attrs) const override {
3172 if (!isAssumedNoCaptureMaybeReturned())
3173 return;
3174
Hideto Ueno37367642019-09-11 06:52:11 +00003175 if (getArgNo() >= 0) {
3176 if (isAssumedNoCapture())
3177 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
3178 else if (ManifestInternal)
3179 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
3180 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003181 }
3182
3183 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
3184 /// depending on the ability of the function associated with \p IRP to capture
3185 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00003186 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
3187 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05003188 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003189 // TODO: Once we have memory behavior attributes we should use them here.
3190
3191 // If we know we cannot communicate or write to memory, we do not care about
3192 // ptr2int anymore.
3193 if (F.onlyReadsMemory() && F.doesNotThrow() &&
3194 F.getReturnType()->isVoidTy()) {
3195 State.addKnownBits(NO_CAPTURE);
3196 return;
3197 }
3198
3199 // A function cannot capture state in memory if it only reads memory, it can
3200 // however return/throw state and the state might be influenced by the
3201 // pointer value, e.g., loading from a returned pointer might reveal a bit.
3202 if (F.onlyReadsMemory())
3203 State.addKnownBits(NOT_CAPTURED_IN_MEM);
3204
3205 // A function cannot communicate state back if it does not through
3206 // exceptions and doesn not return values.
3207 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
3208 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00003209
3210 // Check existing "returned" attributes.
3211 int ArgNo = IRP.getArgNo();
3212 if (F.doesNotThrow() && ArgNo >= 0) {
3213 for (unsigned u = 0, e = F.arg_size(); u< e; ++u)
3214 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00003215 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00003216 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
3217 else if (F.onlyReadsMemory())
3218 State.addKnownBits(NO_CAPTURE);
3219 else
3220 State.addKnownBits(NOT_CAPTURED_IN_RET);
3221 break;
3222 }
3223 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003224 }
3225
3226 /// See AbstractState::getAsStr().
3227 const std::string getAsStr() const override {
3228 if (isKnownNoCapture())
3229 return "known not-captured";
3230 if (isAssumedNoCapture())
3231 return "assumed not-captured";
3232 if (isKnownNoCaptureMaybeReturned())
3233 return "known not-captured-maybe-returned";
3234 if (isAssumedNoCaptureMaybeReturned())
3235 return "assumed not-captured-maybe-returned";
3236 return "assumed-captured";
3237 }
3238};
3239
3240/// Attributor-aware capture tracker.
3241struct AACaptureUseTracker final : public CaptureTracker {
3242
3243 /// Create a capture tracker that can lookup in-flight abstract attributes
3244 /// through the Attributor \p A.
3245 ///
3246 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
3247 /// search is stopped. If a use leads to a return instruction,
3248 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
3249 /// If a use leads to a ptr2int which may capture the value,
3250 /// \p CapturedInInteger is set. If a use is found that is currently assumed
3251 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
3252 /// set. All values in \p PotentialCopies are later tracked as well. For every
3253 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
3254 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
3255 /// conservatively set to true.
3256 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05003257 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003258 SmallVectorImpl<const Value *> &PotentialCopies,
3259 unsigned &RemainingUsesToExplore)
3260 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
3261 PotentialCopies(PotentialCopies),
3262 RemainingUsesToExplore(RemainingUsesToExplore) {}
3263
3264 /// Determine if \p V maybe captured. *Also updates the state!*
3265 bool valueMayBeCaptured(const Value *V) {
3266 if (V->getType()->isPointerTy()) {
3267 PointerMayBeCaptured(V, this);
3268 } else {
3269 State.indicatePessimisticFixpoint();
3270 }
3271 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3272 }
3273
3274 /// See CaptureTracker::tooManyUses().
3275 void tooManyUses() override {
3276 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
3277 }
3278
3279 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
3280 if (CaptureTracker::isDereferenceableOrNull(O, DL))
3281 return true;
3282 const auto &DerefAA =
3283 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
3284 return DerefAA.getAssumedDereferenceableBytes();
3285 }
3286
3287 /// See CaptureTracker::captured(...).
3288 bool captured(const Use *U) override {
3289 Instruction *UInst = cast<Instruction>(U->getUser());
3290 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3291 << "\n");
3292
3293 // Because we may reuse the tracker multiple times we keep track of the
3294 // number of explored uses ourselves as well.
3295 if (RemainingUsesToExplore-- == 0) {
3296 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3297 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3298 /* Return */ true);
3299 }
3300
3301 // Deal with ptr2int by following uses.
3302 if (isa<PtrToIntInst>(UInst)) {
3303 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3304 return valueMayBeCaptured(UInst);
3305 }
3306
3307 // Explicitly catch return instructions.
3308 if (isa<ReturnInst>(UInst))
3309 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3310 /* Return */ true);
3311
3312 // For now we only use special logic for call sites. However, the tracker
3313 // itself knows about a lot of other non-capturing cases already.
3314 CallSite CS(UInst);
3315 if (!CS || !CS.isArgOperand(U))
3316 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3317 /* Return */ true);
3318
3319 unsigned ArgNo = CS.getArgumentNo(U);
3320 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3321 // If we have a abstract no-capture attribute for the argument we can use
3322 // it to justify a non-capture attribute here. This allows recursion!
3323 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3324 if (ArgNoCaptureAA.isAssumedNoCapture())
3325 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3326 /* Return */ false);
3327 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3328 addPotentialCopy(CS);
3329 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3330 /* Return */ false);
3331 }
3332
3333 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3334 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3335 /* Return */ true);
3336 }
3337
3338 /// Register \p CS as potential copy of the value we are checking.
3339 void addPotentialCopy(CallSite CS) {
3340 PotentialCopies.push_back(CS.getInstruction());
3341 }
3342
3343 /// See CaptureTracker::shouldExplore(...).
3344 bool shouldExplore(const Use *U) override {
3345 // Check liveness.
3346 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3347 }
3348
3349 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3350 /// \p CapturedInRet, then return the appropriate value for use in the
3351 /// CaptureTracker::captured() interface.
3352 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3353 bool CapturedInRet) {
3354 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
3355 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
3356 if (CapturedInMem)
3357 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
3358 if (CapturedInInt)
3359 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
3360 if (CapturedInRet)
3361 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
3362 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3363 }
3364
3365private:
3366 /// The attributor providing in-flight abstract attributes.
3367 Attributor &A;
3368
3369 /// The abstract attribute currently updated.
3370 AANoCapture &NoCaptureAA;
3371
3372 /// The abstract liveness state.
3373 const AAIsDead &IsDeadAA;
3374
3375 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05003376 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003377
3378 /// Set of potential copies of the tracked value.
3379 SmallVectorImpl<const Value *> &PotentialCopies;
3380
3381 /// Global counter to limit the number of explored uses.
3382 unsigned &RemainingUsesToExplore;
3383};
3384
3385ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
3386 const IRPosition &IRP = getIRPosition();
3387 const Value *V =
3388 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
3389 if (!V)
3390 return indicatePessimisticFixpoint();
3391
3392 const Function *F =
3393 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
3394 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00003395 const IRPosition &FnPos = IRPosition::function(*F);
3396 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, FnPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003397
3398 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003399
Johannes Doerfert3839b572019-10-21 00:48:42 +00003400 // Readonly means we cannot capture through memory.
3401 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3402 if (FnMemAA.isAssumedReadOnly()) {
3403 T.addKnownBits(NOT_CAPTURED_IN_MEM);
3404 if (FnMemAA.isKnownReadOnly())
3405 addKnownBits(NOT_CAPTURED_IN_MEM);
3406 }
3407
3408 // Make sure all returned values are different than the underlying value.
3409 // TODO: we could do this in a more sophisticated way inside
3410 // AAReturnedValues, e.g., track all values that escape through returns
3411 // directly somehow.
3412 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
3413 bool SeenConstant = false;
3414 for (auto &It : RVAA.returned_values()) {
3415 if (isa<Constant>(It.first)) {
3416 if (SeenConstant)
3417 return false;
3418 SeenConstant = true;
3419 } else if (!isa<Argument>(It.first) ||
3420 It.first == getAssociatedArgument())
3421 return false;
3422 }
3423 return true;
3424 };
3425
3426 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, FnPos);
3427 if (NoUnwindAA.isAssumedNoUnwind()) {
3428 bool IsVoidTy = F->getReturnType()->isVoidTy();
3429 const AAReturnedValues *RVAA =
3430 IsVoidTy ? nullptr : &A.getAAFor<AAReturnedValues>(*this, FnPos);
3431 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
3432 T.addKnownBits(NOT_CAPTURED_IN_RET);
3433 if (T.isKnown(NOT_CAPTURED_IN_MEM))
3434 return ChangeStatus::UNCHANGED;
3435 if (NoUnwindAA.isKnownNoUnwind() &&
3436 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
3437 addKnownBits(NOT_CAPTURED_IN_RET);
3438 if (isKnown(NOT_CAPTURED_IN_MEM))
3439 return indicateOptimisticFixpoint();
3440 }
3441 }
3442 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003443
3444 // Use the CaptureTracker interface and logic with the specialized tracker,
3445 // defined in AACaptureUseTracker, that can look at in-flight abstract
3446 // attributes and directly updates the assumed state.
3447 SmallVector<const Value *, 4> PotentialCopies;
3448 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
3449 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
3450 RemainingUsesToExplore);
3451
3452 // Check all potential copies of the associated value until we can assume
3453 // none will be captured or we have to assume at least one might be.
3454 unsigned Idx = 0;
3455 PotentialCopies.push_back(V);
3456 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
3457 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
3458
Johannes Doerfert1a746452019-10-20 22:28:49 -05003459 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003460 auto Assumed = S.getAssumed();
3461 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05003462 if (!isAssumedNoCaptureMaybeReturned())
3463 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003464 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3465 : ChangeStatus::CHANGED;
3466}
3467
3468/// NoCapture attribute for function arguments.
3469struct AANoCaptureArgument final : AANoCaptureImpl {
3470 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3471
3472 /// See AbstractAttribute::trackStatistics()
3473 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
3474};
3475
3476/// NoCapture attribute for call site arguments.
3477struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
3478 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3479
3480 /// See AbstractAttribute::updateImpl(...).
3481 ChangeStatus updateImpl(Attributor &A) override {
3482 // TODO: Once we have call site specific value information we can provide
3483 // call site specific liveness information and then it makes
3484 // sense to specialize attributes for call sites arguments instead of
3485 // redirecting requests to the callee argument.
3486 Argument *Arg = getAssociatedArgument();
3487 if (!Arg)
3488 return indicatePessimisticFixpoint();
3489 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3490 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
3491 return clampStateAndIndicateChange(
3492 getState(),
3493 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3494 }
3495
3496 /// See AbstractAttribute::trackStatistics()
3497 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
3498};
3499
3500/// NoCapture attribute for floating values.
3501struct AANoCaptureFloating final : AANoCaptureImpl {
3502 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3503
3504 /// See AbstractAttribute::trackStatistics()
3505 void trackStatistics() const override {
3506 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
3507 }
3508};
3509
3510/// NoCapture attribute for function return value.
3511struct AANoCaptureReturned final : AANoCaptureImpl {
3512 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
3513 llvm_unreachable("NoCapture is not applicable to function returns!");
3514 }
3515
3516 /// See AbstractAttribute::initialize(...).
3517 void initialize(Attributor &A) override {
3518 llvm_unreachable("NoCapture is not applicable to function returns!");
3519 }
3520
3521 /// See AbstractAttribute::updateImpl(...).
3522 ChangeStatus updateImpl(Attributor &A) override {
3523 llvm_unreachable("NoCapture is not applicable to function returns!");
3524 }
3525
3526 /// See AbstractAttribute::trackStatistics()
3527 void trackStatistics() const override {}
3528};
3529
3530/// NoCapture attribute deduction for a call site return value.
3531struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
3532 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3533
3534 /// See AbstractAttribute::trackStatistics()
3535 void trackStatistics() const override {
3536 STATS_DECLTRACK_CSRET_ATTR(nocapture)
3537 }
3538};
3539
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003540/// ------------------ Value Simplify Attribute ----------------------------
3541struct AAValueSimplifyImpl : AAValueSimplify {
3542 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
3543
3544 /// See AbstractAttribute::getAsStr().
3545 const std::string getAsStr() const override {
3546 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
3547 : "not-simple";
3548 }
3549
3550 /// See AbstractAttribute::trackStatistics()
3551 void trackStatistics() const override {}
3552
3553 /// See AAValueSimplify::getAssumedSimplifiedValue()
3554 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
3555 if (!getAssumed())
3556 return const_cast<Value *>(&getAssociatedValue());
3557 return SimplifiedAssociatedValue;
3558 }
3559 void initialize(Attributor &A) override {}
3560
3561 /// Helper function for querying AAValueSimplify and updating candicate.
3562 /// \param QueryingValue Value trying to unify with SimplifiedValue
3563 /// \param AccumulatedSimplifiedValue Current simplification result.
3564 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
3565 Value &QueryingValue,
3566 Optional<Value *> &AccumulatedSimplifiedValue) {
3567 // FIXME: Add a typecast support.
3568
3569 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
3570 QueryingAA, IRPosition::value(QueryingValue));
3571
3572 Optional<Value *> QueryingValueSimplified =
3573 ValueSimpifyAA.getAssumedSimplifiedValue(A);
3574
3575 if (!QueryingValueSimplified.hasValue())
3576 return true;
3577
3578 if (!QueryingValueSimplified.getValue())
3579 return false;
3580
3581 Value &QueryingValueSimplifiedUnwrapped =
3582 *QueryingValueSimplified.getValue();
3583
3584 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
3585 return true;
3586
3587 if (AccumulatedSimplifiedValue.hasValue())
3588 return AccumulatedSimplifiedValue == QueryingValueSimplified;
3589
3590 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
3591 << " is assumed to be "
3592 << QueryingValueSimplifiedUnwrapped << "\n");
3593
3594 AccumulatedSimplifiedValue = QueryingValueSimplified;
3595 return true;
3596 }
3597
3598 /// See AbstractAttribute::manifest(...).
3599 ChangeStatus manifest(Attributor &A) override {
3600 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3601
3602 if (!SimplifiedAssociatedValue.hasValue() ||
3603 !SimplifiedAssociatedValue.getValue())
3604 return Changed;
3605
3606 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
3607 // We can replace the AssociatedValue with the constant.
3608 Value &V = getAssociatedValue();
3609 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
3610 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
3611 << "\n");
3612 V.replaceAllUsesWith(C);
3613 Changed = ChangeStatus::CHANGED;
3614 }
3615 }
3616
3617 return Changed | AAValueSimplify::manifest(A);
3618 }
3619
3620protected:
3621 // An assumed simplified value. Initially, it is set to Optional::None, which
3622 // means that the value is not clear under current assumption. If in the
3623 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
3624 // returns orignal associated value.
3625 Optional<Value *> SimplifiedAssociatedValue;
3626};
3627
3628struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
3629 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3630
3631 /// See AbstractAttribute::updateImpl(...).
3632 ChangeStatus updateImpl(Attributor &A) override {
3633 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3634
Johannes Doerfert661db042019-10-07 23:14:58 +00003635 auto PredForCallSite = [&](AbstractCallSite ACS) {
3636 // Check if we have an associated argument or not (which can happen for
3637 // callback calls).
3638 if (Value *ArgOp = ACS.getCallArgOperand(getArgNo()))
3639 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
3640 return false;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003641 };
3642
3643 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
3644 return indicatePessimisticFixpoint();
3645
3646 // If a candicate was found in this update, return CHANGED.
3647 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3648 ? ChangeStatus::UNCHANGED
3649 : ChangeStatus ::CHANGED;
3650 }
3651
3652 /// See AbstractAttribute::trackStatistics()
3653 void trackStatistics() const override {
3654 STATS_DECLTRACK_ARG_ATTR(value_simplify)
3655 }
3656};
3657
3658struct AAValueSimplifyReturned : AAValueSimplifyImpl {
3659 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3660
3661 /// See AbstractAttribute::updateImpl(...).
3662 ChangeStatus updateImpl(Attributor &A) override {
3663 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3664
3665 auto PredForReturned = [&](Value &V) {
3666 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3667 };
3668
3669 if (!A.checkForAllReturnedValues(PredForReturned, *this))
3670 return indicatePessimisticFixpoint();
3671
3672 // If a candicate was found in this update, return CHANGED.
3673 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3674 ? ChangeStatus::UNCHANGED
3675 : ChangeStatus ::CHANGED;
3676 }
3677 /// See AbstractAttribute::trackStatistics()
3678 void trackStatistics() const override {
3679 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
3680 }
3681};
3682
3683struct AAValueSimplifyFloating : AAValueSimplifyImpl {
3684 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3685
3686 /// See AbstractAttribute::initialize(...).
3687 void initialize(Attributor &A) override {
3688 Value &V = getAnchorValue();
3689
3690 // TODO: add other stuffs
3691 if (isa<Constant>(V) || isa<UndefValue>(V))
3692 indicatePessimisticFixpoint();
3693 }
3694
3695 /// See AbstractAttribute::updateImpl(...).
3696 ChangeStatus updateImpl(Attributor &A) override {
3697 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3698
3699 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
3700 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
3701 if (!Stripped && this == &AA) {
3702 // TODO: Look the instruction and check recursively.
3703 LLVM_DEBUG(
3704 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
3705 << V << "\n");
3706 indicatePessimisticFixpoint();
3707 return false;
3708 }
3709 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3710 };
3711
3712 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
3713 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
3714 VisitValueCB))
3715 return indicatePessimisticFixpoint();
3716
3717 // If a candicate was found in this update, return CHANGED.
3718
3719 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3720 ? ChangeStatus::UNCHANGED
3721 : ChangeStatus ::CHANGED;
3722 }
3723
3724 /// See AbstractAttribute::trackStatistics()
3725 void trackStatistics() const override {
3726 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
3727 }
3728};
3729
3730struct AAValueSimplifyFunction : AAValueSimplifyImpl {
3731 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3732
3733 /// See AbstractAttribute::initialize(...).
3734 void initialize(Attributor &A) override {
3735 SimplifiedAssociatedValue = &getAnchorValue();
3736 indicateOptimisticFixpoint();
3737 }
3738 /// See AbstractAttribute::initialize(...).
3739 ChangeStatus updateImpl(Attributor &A) override {
3740 llvm_unreachable(
3741 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
3742 }
3743 /// See AbstractAttribute::trackStatistics()
3744 void trackStatistics() const override {
3745 STATS_DECLTRACK_FN_ATTR(value_simplify)
3746 }
3747};
3748
3749struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
3750 AAValueSimplifyCallSite(const IRPosition &IRP)
3751 : AAValueSimplifyFunction(IRP) {}
3752 /// See AbstractAttribute::trackStatistics()
3753 void trackStatistics() const override {
3754 STATS_DECLTRACK_CS_ATTR(value_simplify)
3755 }
3756};
3757
3758struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
3759 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
3760 : AAValueSimplifyReturned(IRP) {}
3761
3762 void trackStatistics() const override {
3763 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
3764 }
3765};
3766struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
3767 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
3768 : AAValueSimplifyFloating(IRP) {}
3769
3770 void trackStatistics() const override {
3771 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
3772 }
3773};
3774
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003775/// ----------------------- Heap-To-Stack Conversion ---------------------------
3776struct AAHeapToStackImpl : public AAHeapToStack {
3777 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
3778
3779 const std::string getAsStr() const override {
3780 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
3781 }
3782
3783 ChangeStatus manifest(Attributor &A) override {
3784 assert(getState().isValidState() &&
3785 "Attempted to manifest an invalid state!");
3786
3787 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
3788 Function *F = getAssociatedFunction();
3789 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3790
3791 for (Instruction *MallocCall : MallocCalls) {
3792 // This malloc cannot be replaced.
3793 if (BadMallocCalls.count(MallocCall))
3794 continue;
3795
3796 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
3797 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
3798 A.deleteAfterManifest(*FreeCall);
3799 HasChanged = ChangeStatus::CHANGED;
3800 }
3801
3802 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
3803 << "\n");
3804
3805 Constant *Size;
3806 if (isCallocLikeFn(MallocCall, TLI)) {
3807 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
3808 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
3809 APInt TotalSize = SizeT->getValue() * Num->getValue();
3810 Size =
3811 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
3812 } else {
3813 Size = cast<ConstantInt>(MallocCall->getOperand(0));
3814 }
3815
3816 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
3817 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
3818 Size, "", MallocCall->getNextNode());
3819
3820 if (AI->getType() != MallocCall->getType())
3821 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
3822 AI->getNextNode());
3823
3824 MallocCall->replaceAllUsesWith(AI);
3825
3826 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
3827 auto *NBB = II->getNormalDest();
3828 BranchInst::Create(NBB, MallocCall->getParent());
3829 A.deleteAfterManifest(*MallocCall);
3830 } else {
3831 A.deleteAfterManifest(*MallocCall);
3832 }
3833
3834 if (isCallocLikeFn(MallocCall, TLI)) {
3835 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
3836 AI->getNextNode());
3837 Value *Ops[] = {
3838 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
3839 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
3840
3841 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
3842 Module *M = F->getParent();
3843 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
3844 CallInst::Create(Fn, Ops, "", BI->getNextNode());
3845 }
3846 HasChanged = ChangeStatus::CHANGED;
3847 }
3848
3849 return HasChanged;
3850 }
3851
3852 /// Collection of all malloc calls in a function.
3853 SmallSetVector<Instruction *, 4> MallocCalls;
3854
3855 /// Collection of malloc calls that cannot be converted.
3856 DenseSet<const Instruction *> BadMallocCalls;
3857
3858 /// A map for each malloc call to the set of associated free calls.
3859 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
3860
3861 ChangeStatus updateImpl(Attributor &A) override;
3862};
3863
3864ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
3865 const Function *F = getAssociatedFunction();
3866 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3867
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003868 MustBeExecutedContextExplorer &Explorer =
3869 A.getInfoCache().getMustBeExecutedContextExplorer();
3870
3871 auto FreeCheck = [&](Instruction &I) {
3872 const auto &Frees = FreesForMalloc.lookup(&I);
3873 if (Frees.size() != 1)
3874 return false;
3875 Instruction *UniqueFree = *Frees.begin();
3876 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
3877 };
3878
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003879 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003880 bool ValidUsesOnly = true;
3881 bool MustUse = true;
3882
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003883 SmallPtrSet<const Use *, 8> Visited;
3884 SmallVector<const Use *, 8> Worklist;
3885
3886 for (Use &U : I.uses())
3887 Worklist.push_back(&U);
3888
3889 while (!Worklist.empty()) {
3890 const Use *U = Worklist.pop_back_val();
3891 if (!Visited.insert(U).second)
3892 continue;
3893
3894 auto *UserI = U->getUser();
3895
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003896 if (isa<LoadInst>(UserI))
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003897 continue;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003898 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
3899 if (SI->getValueOperand() == U->get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003900 LLVM_DEBUG(dbgs()
3901 << "[H2S] escaping store to memory: " << *UserI << "\n");
3902 ValidUsesOnly = false;
3903 } else {
3904 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003905 }
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003906 continue;
3907 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003908
3909 // NOTE: Right now, if a function that has malloc pointer as an argument
3910 // frees memory, we assume that the malloc pointer is freed.
3911
3912 // TODO: Add nofree callsite argument attribute to indicate that pointer
3913 // argument is not freed.
3914 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3915 if (!CB->isArgOperand(U))
3916 continue;
3917
3918 if (CB->isLifetimeStartOrEnd())
3919 continue;
3920
3921 // Record malloc.
3922 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003923 if (MustUse) {
3924 FreesForMalloc[&I].insert(
3925 cast<Instruction>(const_cast<User *>(UserI)));
3926 } else {
3927 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
3928 << *UserI << "\n");
3929 ValidUsesOnly = false;
3930 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003931 continue;
3932 }
3933
3934 // If a function does not free memory we are fine
3935 const auto &NoFreeAA =
3936 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(*CB));
3937
3938 unsigned ArgNo = U - CB->arg_begin();
3939 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
3940 *this, IRPosition::callsite_argument(*CB, ArgNo));
3941
3942 if (!NoCaptureAA.isAssumedNoCapture() || !NoFreeAA.isAssumedNoFree()) {
3943 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003944 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003945 }
3946 continue;
3947 }
3948
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003949 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
3950 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
3951 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003952 for (Use &U : UserI->uses())
3953 Worklist.push_back(&U);
3954 continue;
3955 }
3956
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003957 // Unknown user for which we can not track uses further (in a way that
3958 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003959 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003960 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003961 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003962 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003963 };
3964
3965 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003966 if (BadMallocCalls.count(&I))
3967 return true;
3968
3969 bool IsMalloc = isMallocLikeFn(&I, TLI);
3970 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
3971 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003972 BadMallocCalls.insert(&I);
3973 return true;
3974 }
3975
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003976 if (IsMalloc) {
3977 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
3978 if (Size->getValue().sle(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003979 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003980 MallocCalls.insert(&I);
3981 return true;
3982 }
3983 } else if (IsCalloc) {
3984 bool Overflow = false;
3985 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
3986 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
3987 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
3988 .sle(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003989 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003990 MallocCalls.insert(&I);
3991 return true;
3992 }
3993 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003994
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003995 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003996 return true;
3997 };
3998
3999 size_t NumBadMallocs = BadMallocCalls.size();
4000
4001 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
4002
4003 if (NumBadMallocs != BadMallocCalls.size())
4004 return ChangeStatus::CHANGED;
4005
4006 return ChangeStatus::UNCHANGED;
4007}
4008
4009struct AAHeapToStackFunction final : public AAHeapToStackImpl {
4010 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
4011
4012 /// See AbstractAttribute::trackStatistics()
4013 void trackStatistics() const override {
4014 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004015 "Number of malloc calls converted to allocas");
4016 for (auto *C : MallocCalls)
4017 if (!BadMallocCalls.count(C))
4018 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004019 }
4020};
4021
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004022/// -------------------- Memory Behavior Attributes ----------------------------
4023/// Includes read-none, read-only, and write-only.
4024/// ----------------------------------------------------------------------------
4025struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
4026 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
4027
4028 /// See AbstractAttribute::initialize(...).
4029 void initialize(Attributor &A) override {
4030 intersectAssumedBits(BEST_STATE);
4031 getKnownStateFromValue(getIRPosition(), getState());
4032 IRAttribute::initialize(A);
4033 }
4034
4035 /// Return the memory behavior information encoded in the IR for \p IRP.
4036 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert1a746452019-10-20 22:28:49 -05004037 BitIntegerState &State) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004038 SmallVector<Attribute, 2> Attrs;
4039 IRP.getAttrs(AttrKinds, Attrs);
4040 for (const Attribute &Attr : Attrs) {
4041 switch (Attr.getKindAsEnum()) {
4042 case Attribute::ReadNone:
4043 State.addKnownBits(NO_ACCESSES);
4044 break;
4045 case Attribute::ReadOnly:
4046 State.addKnownBits(NO_WRITES);
4047 break;
4048 case Attribute::WriteOnly:
4049 State.addKnownBits(NO_READS);
4050 break;
4051 default:
4052 llvm_unreachable("Unexpcted attribute!");
4053 }
4054 }
4055
4056 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
4057 if (!I->mayReadFromMemory())
4058 State.addKnownBits(NO_READS);
4059 if (!I->mayWriteToMemory())
4060 State.addKnownBits(NO_WRITES);
4061 }
4062 }
4063
4064 /// See AbstractAttribute::getDeducedAttributes(...).
4065 void getDeducedAttributes(LLVMContext &Ctx,
4066 SmallVectorImpl<Attribute> &Attrs) const override {
4067 assert(Attrs.size() == 0);
4068 if (isAssumedReadNone())
4069 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
4070 else if (isAssumedReadOnly())
4071 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
4072 else if (isAssumedWriteOnly())
4073 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
4074 assert(Attrs.size() <= 1);
4075 }
4076
4077 /// See AbstractAttribute::manifest(...).
4078 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05004079 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004080
4081 // Check if we would improve the existing attributes first.
4082 SmallVector<Attribute, 4> DeducedAttrs;
4083 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
4084 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
4085 return IRP.hasAttr(Attr.getKindAsEnum(),
4086 /* IgnoreSubsumingPositions */ true);
4087 }))
4088 return ChangeStatus::UNCHANGED;
4089
4090 // Clear existing attributes.
4091 IRP.removeAttrs(AttrKinds);
4092
4093 // Use the generic manifest method.
4094 return IRAttribute::manifest(A);
4095 }
4096
4097 /// See AbstractState::getAsStr().
4098 const std::string getAsStr() const override {
4099 if (isAssumedReadNone())
4100 return "readnone";
4101 if (isAssumedReadOnly())
4102 return "readonly";
4103 if (isAssumedWriteOnly())
4104 return "writeonly";
4105 return "may-read/write";
4106 }
4107
4108 /// The set of IR attributes AAMemoryBehavior deals with.
4109 static const Attribute::AttrKind AttrKinds[3];
4110};
4111
4112const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
4113 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
4114
4115/// Memory behavior attribute for a floating value.
4116struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
4117 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4118
4119 /// See AbstractAttribute::initialize(...).
4120 void initialize(Attributor &A) override {
4121 AAMemoryBehaviorImpl::initialize(A);
4122 // Initialize the use vector with all direct uses of the associated value.
4123 for (const Use &U : getAssociatedValue().uses())
4124 Uses.insert(&U);
4125 }
4126
4127 /// See AbstractAttribute::updateImpl(...).
4128 ChangeStatus updateImpl(Attributor &A) override;
4129
4130 /// See AbstractAttribute::trackStatistics()
4131 void trackStatistics() const override {
4132 if (isAssumedReadNone())
4133 STATS_DECLTRACK_FLOATING_ATTR(readnone)
4134 else if (isAssumedReadOnly())
4135 STATS_DECLTRACK_FLOATING_ATTR(readonly)
4136 else if (isAssumedWriteOnly())
4137 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
4138 }
4139
4140private:
4141 /// Return true if users of \p UserI might access the underlying
4142 /// variable/location described by \p U and should therefore be analyzed.
4143 bool followUsersOfUseIn(Attributor &A, const Use *U,
4144 const Instruction *UserI);
4145
4146 /// Update the state according to the effect of use \p U in \p UserI.
4147 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
4148
4149protected:
4150 /// Container for (transitive) uses of the associated argument.
4151 SetVector<const Use *> Uses;
4152};
4153
4154/// Memory behavior attribute for function argument.
4155struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
4156 AAMemoryBehaviorArgument(const IRPosition &IRP)
4157 : AAMemoryBehaviorFloating(IRP) {}
4158
4159 /// See AbstractAttribute::initialize(...).
4160 void initialize(Attributor &A) override {
4161 AAMemoryBehaviorFloating::initialize(A);
4162
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004163 // Initialize the use vector with all direct uses of the associated value.
4164 Argument *Arg = getAssociatedArgument();
4165 if (!Arg || !Arg->getParent()->hasExactDefinition())
4166 indicatePessimisticFixpoint();
4167 }
4168
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004169 ChangeStatus manifest(Attributor &A) override {
4170 // TODO: From readattrs.ll: "inalloca parameters are always
4171 // considered written"
4172 if (hasAttr({Attribute::InAlloca})) {
4173 removeKnownBits(NO_WRITES);
4174 removeAssumedBits(NO_WRITES);
4175 }
4176 return AAMemoryBehaviorFloating::manifest(A);
4177 }
4178
4179
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004180 /// See AbstractAttribute::trackStatistics()
4181 void trackStatistics() const override {
4182 if (isAssumedReadNone())
4183 STATS_DECLTRACK_ARG_ATTR(readnone)
4184 else if (isAssumedReadOnly())
4185 STATS_DECLTRACK_ARG_ATTR(readonly)
4186 else if (isAssumedWriteOnly())
4187 STATS_DECLTRACK_ARG_ATTR(writeonly)
4188 }
4189};
4190
4191struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
4192 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
4193 : AAMemoryBehaviorArgument(IRP) {}
4194
4195 /// See AbstractAttribute::updateImpl(...).
4196 ChangeStatus updateImpl(Attributor &A) override {
4197 // TODO: Once we have call site specific value information we can provide
4198 // call site specific liveness liveness information and then it makes
4199 // sense to specialize attributes for call sites arguments instead of
4200 // redirecting requests to the callee argument.
4201 Argument *Arg = getAssociatedArgument();
4202 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4203 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4204 return clampStateAndIndicateChange(
4205 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05004206 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004207 }
4208
4209 /// See AbstractAttribute::trackStatistics()
4210 void trackStatistics() const override {
4211 if (isAssumedReadNone())
4212 STATS_DECLTRACK_CSARG_ATTR(readnone)
4213 else if (isAssumedReadOnly())
4214 STATS_DECLTRACK_CSARG_ATTR(readonly)
4215 else if (isAssumedWriteOnly())
4216 STATS_DECLTRACK_CSARG_ATTR(writeonly)
4217 }
4218};
4219
4220/// Memory behavior attribute for a call site return position.
4221struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
4222 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
4223 : AAMemoryBehaviorFloating(IRP) {}
4224
4225 /// See AbstractAttribute::manifest(...).
4226 ChangeStatus manifest(Attributor &A) override {
4227 // We do not annotate returned values.
4228 return ChangeStatus::UNCHANGED;
4229 }
4230
4231 /// See AbstractAttribute::trackStatistics()
4232 void trackStatistics() const override {}
4233};
4234
4235/// An AA to represent the memory behavior function attributes.
4236struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
4237 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4238
4239 /// See AbstractAttribute::updateImpl(Attributor &A).
4240 virtual ChangeStatus updateImpl(Attributor &A) override;
4241
4242 /// See AbstractAttribute::manifest(...).
4243 ChangeStatus manifest(Attributor &A) override {
4244 Function &F = cast<Function>(getAnchorValue());
4245 if (isAssumedReadNone()) {
4246 F.removeFnAttr(Attribute::ArgMemOnly);
4247 F.removeFnAttr(Attribute::InaccessibleMemOnly);
4248 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
4249 }
4250 return AAMemoryBehaviorImpl::manifest(A);
4251 }
4252
4253 /// See AbstractAttribute::trackStatistics()
4254 void trackStatistics() const override {
4255 if (isAssumedReadNone())
4256 STATS_DECLTRACK_FN_ATTR(readnone)
4257 else if (isAssumedReadOnly())
4258 STATS_DECLTRACK_FN_ATTR(readonly)
4259 else if (isAssumedWriteOnly())
4260 STATS_DECLTRACK_FN_ATTR(writeonly)
4261 }
4262};
4263
4264/// AAMemoryBehavior attribute for call sites.
4265struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
4266 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4267
4268 /// See AbstractAttribute::initialize(...).
4269 void initialize(Attributor &A) override {
4270 AAMemoryBehaviorImpl::initialize(A);
4271 Function *F = getAssociatedFunction();
4272 if (!F || !F->hasExactDefinition())
4273 indicatePessimisticFixpoint();
4274 }
4275
4276 /// See AbstractAttribute::updateImpl(...).
4277 ChangeStatus updateImpl(Attributor &A) override {
4278 // TODO: Once we have call site specific value information we can provide
4279 // call site specific liveness liveness information and then it makes
4280 // sense to specialize attributes for call sites arguments instead of
4281 // redirecting requests to the callee argument.
4282 Function *F = getAssociatedFunction();
4283 const IRPosition &FnPos = IRPosition::function(*F);
4284 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4285 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05004286 getState(),
4287 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004288 }
4289
4290 /// See AbstractAttribute::trackStatistics()
4291 void trackStatistics() const override {
4292 if (isAssumedReadNone())
4293 STATS_DECLTRACK_CS_ATTR(readnone)
4294 else if (isAssumedReadOnly())
4295 STATS_DECLTRACK_CS_ATTR(readonly)
4296 else if (isAssumedWriteOnly())
4297 STATS_DECLTRACK_CS_ATTR(writeonly)
4298 }
4299};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00004300} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004301
4302ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
4303
4304 // The current assumed state used to determine a change.
4305 auto AssumedState = getAssumed();
4306
4307 auto CheckRWInst = [&](Instruction &I) {
4308 // If the instruction has an own memory behavior state, use it to restrict
4309 // the local state. No further analysis is required as the other memory
4310 // state is as optimistic as it gets.
4311 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
4312 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
4313 *this, IRPosition::callsite_function(ICS));
4314 intersectAssumedBits(MemBehaviorAA.getAssumed());
4315 return !isAtFixpoint();
4316 }
4317
4318 // Remove access kind modifiers if necessary.
4319 if (I.mayReadFromMemory())
4320 removeAssumedBits(NO_READS);
4321 if (I.mayWriteToMemory())
4322 removeAssumedBits(NO_WRITES);
4323 return !isAtFixpoint();
4324 };
4325
4326 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
4327 return indicatePessimisticFixpoint();
4328
4329 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4330 : ChangeStatus::UNCHANGED;
4331}
4332
4333ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
4334
4335 const IRPosition &IRP = getIRPosition();
4336 const IRPosition &FnPos = IRPosition::function_scope(IRP);
4337 AAMemoryBehavior::StateType &S = getState();
4338
4339 // First, check the function scope. We take the known information and we avoid
4340 // work if the assumed information implies the current assumed information for
4341 // this attribute.
4342 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4343 S.addKnownBits(FnMemAA.getKnown());
4344 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
4345 return ChangeStatus::UNCHANGED;
4346
4347 // Make sure the value is not captured (except through "return"), if
4348 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004349 // check the potential aliases introduced by the capture. However, no need
4350 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004351 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004352 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
4353 S.intersectAssumedBits(FnMemAA.getAssumed());
4354 return ChangeStatus::CHANGED;
4355 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004356
4357 // The current assumed state used to determine a change.
4358 auto AssumedState = S.getAssumed();
4359
4360 // Liveness information to exclude dead users.
4361 // TODO: Take the FnPos once we have call site specific liveness information.
4362 const auto &LivenessAA = A.getAAFor<AAIsDead>(
4363 *this, IRPosition::function(*IRP.getAssociatedFunction()));
4364
4365 // Visit and expand uses until all are analyzed or a fixpoint is reached.
4366 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
4367 const Use *U = Uses[i];
4368 Instruction *UserI = cast<Instruction>(U->getUser());
4369 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
4370 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
4371 << "]\n");
4372 if (LivenessAA.isAssumedDead(UserI))
4373 continue;
4374
4375 // Check if the users of UserI should also be visited.
4376 if (followUsersOfUseIn(A, U, UserI))
4377 for (const Use &UserIUse : UserI->uses())
4378 Uses.insert(&UserIUse);
4379
4380 // If UserI might touch memory we analyze the use in detail.
4381 if (UserI->mayReadOrWriteMemory())
4382 analyzeUseIn(A, U, UserI);
4383 }
4384
4385 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4386 : ChangeStatus::UNCHANGED;
4387}
4388
4389bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
4390 const Instruction *UserI) {
4391 // The loaded value is unrelated to the pointer argument, no need to
4392 // follow the users of the load.
4393 if (isa<LoadInst>(UserI))
4394 return false;
4395
4396 // By default we follow all uses assuming UserI might leak information on U,
4397 // we have special handling for call sites operands though.
4398 ImmutableCallSite ICS(UserI);
4399 if (!ICS || !ICS.isArgOperand(U))
4400 return true;
4401
4402 // If the use is a call argument known not to be captured, the users of
4403 // the call do not need to be visited because they have to be unrelated to
4404 // the input. Note that this check is not trivial even though we disallow
4405 // general capturing of the underlying argument. The reason is that the
4406 // call might the argument "through return", which we allow and for which we
4407 // need to check call users.
4408 unsigned ArgNo = ICS.getArgumentNo(U);
4409 const auto &ArgNoCaptureAA =
4410 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
4411 return !ArgNoCaptureAA.isAssumedNoCapture();
4412}
4413
4414void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
4415 const Instruction *UserI) {
4416 assert(UserI->mayReadOrWriteMemory());
4417
4418 switch (UserI->getOpcode()) {
4419 default:
4420 // TODO: Handle all atomics and other side-effect operations we know of.
4421 break;
4422 case Instruction::Load:
4423 // Loads cause the NO_READS property to disappear.
4424 removeAssumedBits(NO_READS);
4425 return;
4426
4427 case Instruction::Store:
4428 // Stores cause the NO_WRITES property to disappear if the use is the
4429 // pointer operand. Note that we do assume that capturing was taken care of
4430 // somewhere else.
4431 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
4432 removeAssumedBits(NO_WRITES);
4433 return;
4434
4435 case Instruction::Call:
4436 case Instruction::CallBr:
4437 case Instruction::Invoke: {
4438 // For call sites we look at the argument memory behavior attribute (this
4439 // could be recursive!) in order to restrict our own state.
4440 ImmutableCallSite ICS(UserI);
4441
4442 // Give up on operand bundles.
4443 if (ICS.isBundleOperand(U)) {
4444 indicatePessimisticFixpoint();
4445 return;
4446 }
4447
4448 // Calling a function does read the function pointer, maybe write it if the
4449 // function is self-modifying.
4450 if (ICS.isCallee(U)) {
4451 removeAssumedBits(NO_READS);
4452 break;
4453 }
4454
4455 // Adjust the possible access behavior based on the information on the
4456 // argument.
4457 unsigned ArgNo = ICS.getArgumentNo(U);
4458 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
4459 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4460 // "assumed" has at most the same bits as the MemBehaviorAA assumed
4461 // and at least "known".
4462 intersectAssumedBits(MemBehaviorAA.getAssumed());
4463 return;
4464 }
4465 };
4466
4467 // Generally, look at the "may-properties" and adjust the assumed state if we
4468 // did not trigger special handling before.
4469 if (UserI->mayReadFromMemory())
4470 removeAssumedBits(NO_READS);
4471 if (UserI->mayWriteToMemory())
4472 removeAssumedBits(NO_WRITES);
4473}
4474
Johannes Doerfertaade7822019-06-05 03:02:24 +00004475/// ----------------------------------------------------------------------------
4476/// Attributor
4477/// ----------------------------------------------------------------------------
4478
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004479bool Attributor::isAssumedDead(const AbstractAttribute &AA,
4480 const AAIsDead *LivenessAA) {
4481 const Instruction *CtxI = AA.getIRPosition().getCtxI();
4482 if (!CtxI)
4483 return false;
4484
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004485 // TODO: Find a good way to utilize fine and coarse grained liveness
4486 // information.
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004487 if (!LivenessAA)
4488 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00004489 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
4490 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00004491
4492 // Don't check liveness for AAIsDead.
4493 if (&AA == LivenessAA)
4494 return false;
4495
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004496 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004497 return false;
4498
Johannes Doerfert19b00432019-08-26 17:48:05 +00004499 // We actually used liveness information so we have to record a dependence.
4500 recordDependence(*LivenessAA, AA);
4501
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004502 return true;
4503}
4504
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004505bool Attributor::checkForAllUses(
4506 const function_ref<bool(const Use &, bool &)> &Pred,
4507 const AbstractAttribute &QueryingAA, const Value &V) {
4508 const IRPosition &IRP = QueryingAA.getIRPosition();
4509 SmallVector<const Use *, 16> Worklist;
4510 SmallPtrSet<const Use *, 16> Visited;
4511
4512 for (const Use &U : V.uses())
4513 Worklist.push_back(&U);
4514
4515 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
4516 << " initial uses to check\n");
4517
4518 if (Worklist.empty())
4519 return true;
4520
4521 bool AnyDead = false;
4522 const Function *ScopeFn = IRP.getAnchorScope();
4523 const auto *LivenessAA =
4524 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
4525 /* TrackDependence */ false)
4526 : nullptr;
4527
4528 while (!Worklist.empty()) {
4529 const Use *U = Worklist.pop_back_val();
4530 if (!Visited.insert(U).second)
4531 continue;
4532 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << "\n");
4533 if (Instruction *UserI = dyn_cast<Instruction>(U->getUser()))
4534 if (LivenessAA && LivenessAA->isAssumedDead(UserI)) {
4535 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
4536 << static_cast<const AbstractAttribute &>(*LivenessAA)
4537 << "\n");
4538 AnyDead = true;
4539 continue;
4540 }
4541
4542 bool Follow = false;
4543 if (!Pred(*U, Follow))
4544 return false;
4545 if (!Follow)
4546 continue;
4547 for (const Use &UU : U->getUser()->uses())
4548 Worklist.push_back(&UU);
4549 }
4550
4551 if (AnyDead)
4552 recordDependence(*LivenessAA, QueryingAA);
4553
4554 return true;
4555}
4556
Johannes Doerfert661db042019-10-07 23:14:58 +00004557bool Attributor::checkForAllCallSites(
4558 const function_ref<bool(AbstractCallSite)> &Pred,
4559 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004560 // We can try to determine information from
4561 // the call sites. However, this is only possible all call sites are known,
4562 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004563 const IRPosition &IRP = QueryingAA.getIRPosition();
4564 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00004565 if (!AssociatedFunction) {
4566 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
4567 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004568 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00004569 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004570
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004571 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
4572 &QueryingAA);
4573}
4574
4575bool Attributor::checkForAllCallSites(
4576 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
4577 bool RequireAllCallSites, const AbstractAttribute *QueryingAA) {
4578 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004579 LLVM_DEBUG(
4580 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004581 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00004582 << " has no internal linkage, hence not all call sites are known\n");
4583 return false;
4584 }
4585
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004586 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00004587 AbstractCallSite ACS(&U);
4588 if (!ACS) {
4589 LLVM_DEBUG(dbgs() << "[Attributor] Function "
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004590 << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00004591 << " has non call site use " << *U.get() << " in "
4592 << *U.getUser() << "\n");
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004593 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00004594 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004595
Johannes Doerfert661db042019-10-07 23:14:58 +00004596 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004597 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004598
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004599 const auto *LivenessAA =
4600 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Johannes Doerfert661db042019-10-07 23:14:58 +00004601 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004602
4603 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004604 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00004605 // We actually used liveness information so we have to record a
4606 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004607 if (QueryingAA)
4608 recordDependence(*LivenessAA, *QueryingAA);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004609 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004610 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004611
Johannes Doerfert661db042019-10-07 23:14:58 +00004612 const Use *EffectiveUse =
4613 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
4614 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004615 if (!RequireAllCallSites)
4616 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00004617 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004618 << " is an invalid use of "
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004619 << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004620 return false;
4621 }
4622
Johannes Doerfert661db042019-10-07 23:14:58 +00004623 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00004624 continue;
4625
Johannes Doerfert5304b722019-08-14 22:04:28 +00004626 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00004627 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004628 return false;
4629 }
4630
4631 return true;
4632}
4633
Johannes Doerfert14a04932019-08-07 22:27:24 +00004634bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004635 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00004636 &Pred,
4637 const AbstractAttribute &QueryingAA) {
4638
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004639 const IRPosition &IRP = QueryingAA.getIRPosition();
4640 // Since we need to provide return instructions we have to have an exact
4641 // definition.
4642 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004643 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004644 return false;
4645
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004646 // If this is a call site query we use the call site specific return values
4647 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004648 // TODO: use the function scope once we have call site AAReturnedValues.
4649 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004650 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004651 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004652 return false;
4653
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004654 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00004655}
4656
4657bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004658 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00004659 const AbstractAttribute &QueryingAA) {
4660
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004661 const IRPosition &IRP = QueryingAA.getIRPosition();
4662 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004663 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004664 return false;
4665
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004666 // TODO: use the function scope once we have call site AAReturnedValues.
4667 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004668 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004669 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004670 return false;
4671
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004672 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004673 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00004674 return Pred(RV);
4675 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00004676}
4677
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004678static bool
4679checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
4680 const function_ref<bool(Instruction &)> &Pred,
4681 const AAIsDead *LivenessAA, bool &AnyDead,
4682 const ArrayRef<unsigned> &Opcodes) {
4683 for (unsigned Opcode : Opcodes) {
4684 for (Instruction *I : OpcodeInstMap[Opcode]) {
4685 // Skip dead instructions.
4686 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
4687 AnyDead = true;
4688 continue;
4689 }
4690
4691 if (!Pred(*I))
4692 return false;
4693 }
4694 }
4695 return true;
4696}
4697
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004698bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004699 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004700 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004701
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004702 const IRPosition &IRP = QueryingAA.getIRPosition();
4703 // Since we need to provide instructions we have to have an exact definition.
4704 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004705 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004706 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004707
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004708 // TODO: use the function scope once we have call site AAReturnedValues.
4709 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004710 const auto &LivenessAA =
4711 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
4712 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004713
4714 auto &OpcodeInstMap =
4715 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004716 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
4717 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004718 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004719
Johannes Doerfert19b00432019-08-26 17:48:05 +00004720 // If we actually used liveness information so we have to record a dependence.
4721 if (AnyDead)
4722 recordDependence(LivenessAA, QueryingAA);
4723
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004724 return true;
4725}
4726
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004727bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004728 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004729 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004730
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004731 const Function *AssociatedFunction =
4732 QueryingAA.getIRPosition().getAssociatedFunction();
4733 if (!AssociatedFunction)
4734 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004735
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004736 // TODO: use the function scope once we have call site AAReturnedValues.
4737 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
4738 const auto &LivenessAA =
4739 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004740 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004741
4742 for (Instruction *I :
4743 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004744 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00004745 if (LivenessAA.isAssumedDead(I)) {
4746 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004747 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004748 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004749
4750 if (!Pred(*I))
4751 return false;
4752 }
4753
Johannes Doerfert19b00432019-08-26 17:48:05 +00004754 // If we actually used liveness information so we have to record a dependence.
4755 if (AnyDead)
4756 recordDependence(LivenessAA, QueryingAA);
4757
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004758 return true;
4759}
4760
Johannes Doerfert2f622062019-09-04 16:35:20 +00004761ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004762 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
4763 << AllAbstractAttributes.size()
4764 << " abstract attributes.\n");
4765
Stefan Stipanovic53605892019-06-27 11:27:54 +00004766 // Now that all abstract attributes are collected and initialized we start
4767 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00004768
4769 unsigned IterationCounter = 1;
4770
4771 SmallVector<AbstractAttribute *, 64> ChangedAAs;
4772 SetVector<AbstractAttribute *> Worklist;
4773 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
4774
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004775 bool RecomputeDependences = false;
4776
Johannes Doerfertaade7822019-06-05 03:02:24 +00004777 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004778 // Remember the size to determine new attributes.
4779 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004780 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
4781 << ", Worklist size: " << Worklist.size() << "\n");
4782
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004783 // If dependences (=QueryMap) are recomputed we have to look at all abstract
4784 // attributes again, regardless of what changed in the last iteration.
4785 if (RecomputeDependences) {
4786 LLVM_DEBUG(
4787 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
4788 QueryMap.clear();
4789 ChangedAAs.clear();
4790 Worklist.insert(AllAbstractAttributes.begin(),
4791 AllAbstractAttributes.end());
4792 }
4793
Johannes Doerfertaade7822019-06-05 03:02:24 +00004794 // Add all abstract attributes that are potentially dependent on one that
4795 // changed to the work list.
4796 for (AbstractAttribute *ChangedAA : ChangedAAs) {
4797 auto &QuerriedAAs = QueryMap[ChangedAA];
4798 Worklist.insert(QuerriedAAs.begin(), QuerriedAAs.end());
4799 }
4800
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004801 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
4802 << ", Worklist+Dependent size: " << Worklist.size()
4803 << "\n");
4804
Johannes Doerfertaade7822019-06-05 03:02:24 +00004805 // Reset the changed set.
4806 ChangedAAs.clear();
4807
4808 // Update all abstract attribute in the work list and record the ones that
4809 // changed.
4810 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert2dad7292019-10-13 21:10:31 -05004811 if (!AA->getState().isAtFixpoint() && !isAssumedDead(*AA, nullptr)) {
4812 QueriedNonFixAA = false;
4813 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004814 ChangedAAs.push_back(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05004815 } else if (!QueriedNonFixAA) {
4816 // If the attribute did not query any non-fix information, the state
4817 // will not change and we can indicate that right away.
4818 AA->getState().indicateOptimisticFixpoint();
4819 }
4820 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00004821
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004822 // Check if we recompute the dependences in the next iteration.
4823 RecomputeDependences = (DepRecomputeInterval > 0 &&
4824 IterationCounter % DepRecomputeInterval == 0);
4825
Johannes Doerfert9543f142019-08-23 15:24:57 +00004826 // Add attributes to the changed set if they have been created in the last
4827 // iteration.
4828 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
4829 AllAbstractAttributes.end());
4830
Johannes Doerfertaade7822019-06-05 03:02:24 +00004831 // Reset the work list and repopulate with the changed abstract attributes.
4832 // Note that dependent ones are added above.
4833 Worklist.clear();
4834 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
4835
Johannes Doerfertbf112132019-08-29 01:29:44 +00004836 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
4837 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004838
Johannes Doerfertaade7822019-06-05 03:02:24 +00004839 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
4840 << IterationCounter << "/" << MaxFixpointIterations
4841 << " iterations\n");
4842
Johannes Doerfertbf112132019-08-29 01:29:44 +00004843 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004844
Johannes Doerfertaade7822019-06-05 03:02:24 +00004845 // Reset abstract arguments not settled in a sound fixpoint by now. This
4846 // happens when we stopped the fixpoint iteration early. Note that only the
4847 // ones marked as "changed" *and* the ones transitively depending on them
4848 // need to be reverted to a pessimistic state. Others might not be in a
4849 // fixpoint state but we can use the optimistic results for them anyway.
4850 SmallPtrSet<AbstractAttribute *, 32> Visited;
4851 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
4852 AbstractAttribute *ChangedAA = ChangedAAs[u];
4853 if (!Visited.insert(ChangedAA).second)
4854 continue;
4855
4856 AbstractState &State = ChangedAA->getState();
4857 if (!State.isAtFixpoint()) {
4858 State.indicatePessimisticFixpoint();
4859
4860 NumAttributesTimedOut++;
4861 }
4862
4863 auto &QuerriedAAs = QueryMap[ChangedAA];
4864 ChangedAAs.append(QuerriedAAs.begin(), QuerriedAAs.end());
4865 }
4866
4867 LLVM_DEBUG({
4868 if (!Visited.empty())
4869 dbgs() << "\n[Attributor] Finalized " << Visited.size()
4870 << " abstract attributes.\n";
4871 });
4872
4873 unsigned NumManifested = 0;
4874 unsigned NumAtFixpoint = 0;
4875 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
4876 for (AbstractAttribute *AA : AllAbstractAttributes) {
4877 AbstractState &State = AA->getState();
4878
4879 // If there is not already a fixpoint reached, we can now take the
4880 // optimistic state. This is correct because we enforced a pessimistic one
4881 // on abstract attributes that were transitively dependent on a changed one
4882 // already above.
4883 if (!State.isAtFixpoint())
4884 State.indicateOptimisticFixpoint();
4885
4886 // If the state is invalid, we do not try to manifest it.
4887 if (!State.isValidState())
4888 continue;
4889
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004890 // Skip dead code.
4891 if (isAssumedDead(*AA, nullptr))
4892 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004893 // Manifest the state and record if we changed the IR.
4894 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00004895 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
4896 AA->trackStatistics();
4897
Johannes Doerfertaade7822019-06-05 03:02:24 +00004898 ManifestChange = ManifestChange | LocalChange;
4899
4900 NumAtFixpoint++;
4901 NumManifested += (LocalChange == ChangeStatus::CHANGED);
4902 }
4903
4904 (void)NumManifested;
4905 (void)NumAtFixpoint;
4906 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
4907 << " arguments while " << NumAtFixpoint
4908 << " were in a valid fixpoint state\n");
4909
Johannes Doerfertaade7822019-06-05 03:02:24 +00004910 NumAttributesManifested += NumManifested;
4911 NumAttributesValidFixpoint += NumAtFixpoint;
4912
Fangrui Songf1826172019-08-20 07:21:43 +00004913 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004914 assert(
4915 NumFinalAAs == AllAbstractAttributes.size() &&
4916 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00004917
4918 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00004919 {
4920 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
4921 << ToBeDeletedFunctions.size() << " functions and "
4922 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004923 << ToBeDeletedInsts.size() << " instructions and "
4924 << ToBeChangedUses.size() << " uses\n");
4925
4926 SmallVector<Instruction *, 32> DeadInsts;
4927 SmallVector<Instruction *, 32> TerminatorsToFold;
4928 SmallVector<Instruction *, 32> UnreachablesToInsert;
4929
4930 for (auto &It : ToBeChangedUses) {
4931 Use *U = It.first;
4932 Value *NewV = It.second;
4933 Value *OldV = U->get();
4934 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
4935 << " instead of " << *OldV << "\n");
4936 U->set(NewV);
4937 if (Instruction *I = dyn_cast<Instruction>(OldV))
4938 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) && isInstructionTriviallyDead(I)) {
4939 DeadInsts.push_back(I);
4940 }
4941 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
4942 Instruction *UserI = cast<Instruction>(U->getUser());
4943 if (isa<UndefValue>(NewV)) {
4944 UnreachablesToInsert.push_back(UserI);
4945 } else {
4946 TerminatorsToFold.push_back(UserI);
4947 }
4948 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00004949 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004950 for (Instruction *I : UnreachablesToInsert)
4951 changeToUnreachable(I, /* UseLLVMTrap */ false);
4952 for (Instruction *I : TerminatorsToFold)
4953 ConstantFoldTerminator(I->getParent());
4954
4955 for (Instruction *I : ToBeDeletedInsts) {
4956 I->replaceAllUsesWith(UndefValue::get(I->getType()));
4957 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
4958 DeadInsts.push_back(I);
4959 else
4960 I->eraseFromParent();
4961 }
4962
4963 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00004964
Johannes Doerfert2f622062019-09-04 16:35:20 +00004965 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
4966 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
4967 ToBeDeletedBBs.reserve(NumDeadBlocks);
4968 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
Johannes Doerfert5e442a52019-10-30 17:34:59 -05004969 // Actually we do not delete the blocks but squash them into a single
4970 // unreachable but untangling branches that jump here is something we need
4971 // to do in a more generic way.
4972 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
4973 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4974 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00004975 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00004976
Johannes Doerfert2f622062019-09-04 16:35:20 +00004977 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
4978 for (Function *Fn : ToBeDeletedFunctions) {
4979 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
4980 Fn->eraseFromParent();
4981 STATS_TRACK(AAIsDead, Function);
4982 }
4983
4984 // Identify dead internal functions and delete them. This happens outside
4985 // the other fixpoint analysis as we might treat potentially dead functions
4986 // as live to lower the number of iterations. If they happen to be dead, the
4987 // below fixpoint loop will identify and eliminate them.
4988 SmallVector<Function *, 8> InternalFns;
4989 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00004990 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00004991 InternalFns.push_back(&F);
4992
4993 bool FoundDeadFn = true;
4994 while (FoundDeadFn) {
4995 FoundDeadFn = false;
4996 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
4997 Function *F = InternalFns[u];
4998 if (!F)
4999 continue;
5000
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005001 if (!checkForAllCallSites([](AbstractCallSite ACS) { return false; },
5002 *F, true, nullptr))
Johannes Doerfert2f622062019-09-04 16:35:20 +00005003 continue;
5004
5005 STATS_TRACK(AAIsDead, Function);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005006 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00005007 F->replaceAllUsesWith(UndefValue::get(F->getType()));
5008 F->eraseFromParent();
5009 InternalFns[u] = nullptr;
5010 FoundDeadFn = true;
5011 }
5012 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00005013 }
5014
Johannes Doerfertbf112132019-08-29 01:29:44 +00005015 if (VerifyMaxFixpointIterations &&
5016 IterationCounter != MaxFixpointIterations) {
5017 errs() << "\n[Attributor] Fixpoint iteration done after: "
5018 << IterationCounter << "/" << MaxFixpointIterations
5019 << " iterations\n";
5020 llvm_unreachable("The fixpoint was not reached with exactly the number of "
5021 "specified iterations!");
5022 }
5023
Johannes Doerfertaade7822019-06-05 03:02:24 +00005024 return ManifestChange;
5025}
5026
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005027void Attributor::initializeInformationCache(Function &F) {
5028
5029 // Walk all instructions to find interesting instructions that might be
5030 // queried by abstract attributes during their initialization or update.
5031 // This has to happen before we create attributes.
5032 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
5033 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
5034
5035 for (Instruction &I : instructions(&F)) {
5036 bool IsInterestingOpcode = false;
5037
5038 // To allow easy access to all instructions in a function with a given
5039 // opcode we store them in the InfoCache. As not all opcodes are interesting
5040 // to concrete attributes we only cache the ones that are as identified in
5041 // the following switch.
5042 // Note: There are no concrete attributes now so this is initially empty.
5043 switch (I.getOpcode()) {
5044 default:
5045 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
5046 "New call site/base instruction type needs to be known int the "
5047 "Attributor.");
5048 break;
5049 case Instruction::Load:
5050 // The alignment of a pointer is interesting for loads.
5051 case Instruction::Store:
5052 // The alignment of a pointer is interesting for stores.
5053 case Instruction::Call:
5054 case Instruction::CallBr:
5055 case Instruction::Invoke:
5056 case Instruction::CleanupRet:
5057 case Instruction::CatchSwitch:
5058 case Instruction::Resume:
5059 case Instruction::Ret:
5060 IsInterestingOpcode = true;
5061 }
5062 if (IsInterestingOpcode)
5063 InstOpcodeMap[I.getOpcode()].push_back(&I);
5064 if (I.mayReadOrWriteMemory())
5065 ReadOrWriteInsts.push_back(&I);
5066 }
5067}
5068
Johannes Doerfert12173e62019-10-13 20:25:25 -05005069void Attributor::recordDependence(const AbstractAttribute &FromAA,
5070 const AbstractAttribute &ToAA) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005071 if (FromAA.getState().isAtFixpoint())
5072 return;
5073
5074 QueryMap[&FromAA].insert(const_cast<AbstractAttribute *>(&ToAA));
5075 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05005076}
5077
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005078void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00005079 if (!VisitedFunctions.insert(&F).second)
5080 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05005081 if (F.isDeclaration())
5082 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005083
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005084 IRPosition FPos = IRPosition::function(F);
5085
Johannes Doerfert305b9612019-08-04 18:40:01 +00005086 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00005087 // We need dead instruction detection because we do not want to deal with
5088 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005089 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00005090
5091 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005092 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00005093
Stefan Stipanovic53605892019-06-27 11:27:54 +00005094 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005095 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00005096
Stefan Stipanovic06263672019-07-11 21:37:40 +00005097 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005098 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00005099
Hideto Ueno65bbaf92019-07-12 17:38:51 +00005100 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005101 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00005102
Johannes Doerferte83f3032019-08-05 23:22:05 +00005103 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005104 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00005105
Hideto Ueno63f60662019-09-21 15:13:19 +00005106 // Every function might be "no-recurse".
5107 getOrCreateAAFor<AANoRecurse>(FPos);
5108
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005109 // Every function might be "readnone/readonly/writeonly/...".
5110 getOrCreateAAFor<AAMemoryBehavior>(FPos);
5111
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005112 // Every function might be applicable for Heap-To-Stack conversion.
5113 if (EnableHeapToStack)
5114 getOrCreateAAFor<AAHeapToStack>(FPos);
5115
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00005116 // Return attributes are only appropriate if the return type is non void.
5117 Type *ReturnType = F.getReturnType();
5118 if (!ReturnType->isVoidTy()) {
5119 // Argument attribute "returned" --- Create only one per function even
5120 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005121 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00005122
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005123 IRPosition RetPos = IRPosition::returned(F);
5124
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005125 // Every returned value might be dead.
5126 getOrCreateAAFor<AAIsDead>(RetPos);
5127
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005128 // Every function might be simplified.
5129 getOrCreateAAFor<AAValueSimplify>(RetPos);
5130
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005131 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005132
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005133 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005134 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005135
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005136 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005137 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005138
5139 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005140 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005141
5142 // Every function with pointer return type might be marked
5143 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005144 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005145 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00005146 }
5147
Hideto Ueno54869ec2019-07-15 06:49:04 +00005148 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005149 IRPosition ArgPos = IRPosition::argument(Arg);
5150
5151 // Every argument might be simplified.
5152 getOrCreateAAFor<AAValueSimplify>(ArgPos);
5153
Hideto Ueno19c07af2019-07-23 08:16:17 +00005154 if (Arg.getType()->isPointerTy()) {
5155 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005156 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005157
Hideto Uenocbab3342019-08-29 05:52:00 +00005158 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005159 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00005160
Hideto Ueno19c07af2019-07-23 08:16:17 +00005161 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005162 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005163
5164 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005165 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005166
5167 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005168 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005169
5170 // Every argument with pointer type might be marked
5171 // "readnone/readonly/writeonly/..."
5172 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005173 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00005174 }
5175
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005176 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005177 CallSite CS(&I);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005178 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05005179 // Skip declerations except if annotations on their call sites were
5180 // explicitly requested.
5181 if (!AnnotateDeclarationCallSites && Callee->isDeclaration())
5182 return true;
5183
5184 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005185 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
5186
5187 // Call site return values might be dead.
5188 getOrCreateAAFor<AAIsDead>(CSRetPos);
5189 }
5190
5191 for (int i = 0, e = Callee->arg_size(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005192
5193 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
5194
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005195 // Every call site argument might be dead.
5196 getOrCreateAAFor<AAIsDead>(CSArgPos);
5197
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005198 // Call site argument might be simplified.
5199 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
5200
Hideto Ueno54869ec2019-07-15 06:49:04 +00005201 if (!CS.getArgument(i)->getType()->isPointerTy())
5202 continue;
5203
5204 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005205 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005206
Hideto Uenocbab3342019-08-29 05:52:00 +00005207 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005208 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00005209
Hideto Ueno19c07af2019-07-23 08:16:17 +00005210 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005211 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005212
5213 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005214 getOrCreateAAFor<AAAlign>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00005215 }
5216 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005217 return true;
5218 };
5219
5220 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
5221 bool Success, AnyDead = false;
5222 Success = checkForAllInstructionsImpl(
5223 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
5224 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
5225 (unsigned)Instruction::Call});
5226 (void)Success;
5227 assert(Success && !AnyDead && "Expected the check call to be successful!");
5228
5229 auto LoadStorePred = [&](Instruction &I) -> bool {
5230 if (isa<LoadInst>(I))
5231 getOrCreateAAFor<AAAlign>(
5232 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
5233 else
5234 getOrCreateAAFor<AAAlign>(
5235 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
5236 return true;
5237 };
5238 Success = checkForAllInstructionsImpl(
5239 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
5240 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
5241 (void)Success;
5242 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00005243}
5244
5245/// Helpers to ease debugging through output streams and print calls.
5246///
5247///{
5248raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
5249 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
5250}
5251
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005252raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005253 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005254 case IRPosition::IRP_INVALID:
5255 return OS << "inv";
5256 case IRPosition::IRP_FLOAT:
5257 return OS << "flt";
5258 case IRPosition::IRP_RETURNED:
5259 return OS << "fn_ret";
5260 case IRPosition::IRP_CALL_SITE_RETURNED:
5261 return OS << "cs_ret";
5262 case IRPosition::IRP_FUNCTION:
5263 return OS << "fn";
5264 case IRPosition::IRP_CALL_SITE:
5265 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005266 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00005267 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005268 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00005269 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00005270 }
5271 llvm_unreachable("Unknown attribute position!");
5272}
5273
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005274raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005275 const Value &AV = Pos.getAssociatedValue();
5276 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005277 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
5278}
5279
Johannes Doerfert1a746452019-10-20 22:28:49 -05005280template <typename base_ty, base_ty BestState, base_ty WorstState>
5281raw_ostream &llvm::
5282operator<<(raw_ostream &OS,
5283 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00005284 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
5285 << static_cast<const AbstractState &>(S);
5286}
5287
Johannes Doerfertaade7822019-06-05 03:02:24 +00005288raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
5289 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
5290}
5291
5292raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
5293 AA.print(OS);
5294 return OS;
5295}
5296
5297void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005298 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
5299 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00005300}
5301///}
5302
5303/// ----------------------------------------------------------------------------
5304/// Pass (Manager) Boilerplate
5305/// ----------------------------------------------------------------------------
5306
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005307static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005308 if (DisableAttributor)
5309 return false;
5310
5311 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
5312 << " functions.\n");
5313
5314 // Create an Attributor and initially empty information cache that is filled
5315 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00005316 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005317 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005318
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005319 for (Function &F : M)
5320 A.initializeInformationCache(F);
5321
Johannes Doerfertaade7822019-06-05 03:02:24 +00005322 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005323 if (F.hasExactDefinition())
5324 NumFnWithExactDefinition++;
5325 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00005326 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005327
Johannes Doerfert2f622062019-09-04 16:35:20 +00005328 // We look at internal functions only on-demand but if any use is not a
5329 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00005330 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00005331 if (llvm::all_of(F.uses(), [](const Use &U) {
5332 return ImmutableCallSite(U.getUser()) &&
5333 ImmutableCallSite(U.getUser()).isCallee(&U);
5334 }))
5335 continue;
5336 }
5337
Johannes Doerfertaade7822019-06-05 03:02:24 +00005338 // Populate the Attributor with abstract attribute opportunities in the
5339 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005340 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005341 }
5342
Johannes Doerfert2f622062019-09-04 16:35:20 +00005343 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005344}
5345
5346PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00005347 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005348 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005349 // FIXME: Think about passes we will preserve and add them here.
5350 return PreservedAnalyses::none();
5351 }
5352 return PreservedAnalyses::all();
5353}
5354
5355namespace {
5356
5357struct AttributorLegacyPass : public ModulePass {
5358 static char ID;
5359
5360 AttributorLegacyPass() : ModulePass(ID) {
5361 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
5362 }
5363
5364 bool runOnModule(Module &M) override {
5365 if (skipModule(M))
5366 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005367
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005368 AnalysisGetter AG;
5369 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005370 }
5371
5372 void getAnalysisUsage(AnalysisUsage &AU) const override {
5373 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005374 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005375 }
5376};
5377
5378} // end anonymous namespace
5379
5380Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
5381
5382char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005383
5384const char AAReturnedValues::ID = 0;
5385const char AANoUnwind::ID = 0;
5386const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00005387const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005388const char AANonNull::ID = 0;
5389const char AANoRecurse::ID = 0;
5390const char AAWillReturn::ID = 0;
5391const char AANoAlias::ID = 0;
5392const char AANoReturn::ID = 0;
5393const char AAIsDead::ID = 0;
5394const char AADereferenceable::ID = 0;
5395const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005396const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005397const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005398const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005399const char AAMemoryBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005400
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005401// Macro magic to create the static generator function for attributes that
5402// follow the naming scheme.
5403
5404#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
5405 case IRPosition::PK: \
5406 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
5407
5408#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
5409 case IRPosition::PK: \
5410 AA = new CLASS##SUFFIX(IRP); \
5411 break;
5412
5413#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5414 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5415 CLASS *AA = nullptr; \
5416 switch (IRP.getPositionKind()) { \
5417 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5418 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5419 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5420 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5421 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5422 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5423 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5424 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5425 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005426 return *AA; \
5427 }
5428
5429#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5430 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5431 CLASS *AA = nullptr; \
5432 switch (IRP.getPositionKind()) { \
5433 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5434 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
5435 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5436 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5437 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5438 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5439 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5440 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5441 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005442 return *AA; \
5443 }
5444
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005445#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5446 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5447 CLASS *AA = nullptr; \
5448 switch (IRP.getPositionKind()) { \
5449 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5450 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5451 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5452 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5453 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5454 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5455 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5456 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5457 } \
5458 return *AA; \
5459 }
5460
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005461#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5462 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5463 CLASS *AA = nullptr; \
5464 switch (IRP.getPositionKind()) { \
5465 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5466 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5467 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5468 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5469 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5470 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5471 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5472 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5473 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005474 return *AA; \
5475 }
5476
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005477#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5478 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5479 CLASS *AA = nullptr; \
5480 switch (IRP.getPositionKind()) { \
5481 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5482 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5483 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5484 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5485 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5486 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5487 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5488 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5489 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005490 return *AA; \
5491 }
5492
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005493CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
5494CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
5495CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
5496CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
5497CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
5498CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005499CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
5500
5501CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
5502CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
5503CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
5504CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005505CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005506
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005507CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005508CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005509
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005510CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
5511
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005512CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
5513
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005514#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005515#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005516#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005517#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005518#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005519#undef SWITCH_PK_CREATE
5520#undef SWITCH_PK_INV
5521
Johannes Doerfertaade7822019-06-05 03:02:24 +00005522INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
5523 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005524INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00005525INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
5526 "Deduce and propagate attributes", false, false)