blob: ee7166e381aea81a14ed252f88b26b562cbff46a [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) {
Johannes Doerferted47a9c2019-11-01 13:57:49 -05002579 Optional<ConstantInt *> CI = getAssumedConstant(A, *SI.getCondition(), AA);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002580 if (!CI.hasValue()) {
2581 // No value yet, assume all edges are dead.
2582 } else if (CI.getValue()) {
2583 for (auto &CaseIt : SI.cases()) {
2584 if (CaseIt.getCaseValue() == CI.getValue()) {
2585 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerferted47a9c2019-11-01 13:57:49 -05002586 return true;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002587 }
2588 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05002589 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
2590 return true;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002591 } else {
2592 for (const BasicBlock *SuccBB : successors(SI.getParent()))
2593 AliveSuccessors.push_back(&SuccBB->front());
2594 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05002595 return false;
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();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05003079 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003080 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 Doerfertd0f64002019-08-06 00:32:43 +00003090 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003091 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003092 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00003093 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00003094 return ChangeStatus::UNCHANGED;
3095 }
3096};
3097
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003098struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003099 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003100
3101 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003102 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003103};
3104
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003105/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003106struct AANoReturnCallSite final : AANoReturnImpl {
3107 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
3108
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003109 /// See AbstractAttribute::updateImpl(...).
3110 ChangeStatus updateImpl(Attributor &A) override {
3111 // TODO: Once we have call site specific value information we can provide
3112 // call site specific liveness information and then it makes
3113 // sense to specialize attributes for call sites arguments instead of
3114 // redirecting requests to the callee argument.
3115 Function *F = getAssociatedFunction();
3116 const IRPosition &FnPos = IRPosition::function(*F);
3117 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
3118 return clampStateAndIndicateChange(
3119 getState(),
3120 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
3121 }
3122
3123 /// See AbstractAttribute::trackStatistics()
3124 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
3125};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003126
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003127/// ----------------------- Variable Capturing ---------------------------------
3128
3129/// A class to hold the state of for no-capture attributes.
3130struct AANoCaptureImpl : public AANoCapture {
3131 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
3132
3133 /// See AbstractAttribute::initialize(...).
3134 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003135 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
3136 indicateOptimisticFixpoint();
3137 return;
3138 }
3139 Function *AnchorScope = getAnchorScope();
3140 if (isFnInterfaceKind() &&
3141 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
3142 indicatePessimisticFixpoint();
3143 return;
3144 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003145
Johannes Doerfert72adda12019-10-10 05:33:21 +00003146 // You cannot "capture" null in the default address space.
3147 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
3148 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
3149 indicateOptimisticFixpoint();
3150 return;
3151 }
3152
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003153 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003154
3155 // Check what state the associated function can actually capture.
3156 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003157 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003158 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003159 indicatePessimisticFixpoint();
3160 }
3161
3162 /// See AbstractAttribute::updateImpl(...).
3163 ChangeStatus updateImpl(Attributor &A) override;
3164
3165 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
3166 virtual void
3167 getDeducedAttributes(LLVMContext &Ctx,
3168 SmallVectorImpl<Attribute> &Attrs) const override {
3169 if (!isAssumedNoCaptureMaybeReturned())
3170 return;
3171
Hideto Ueno37367642019-09-11 06:52:11 +00003172 if (getArgNo() >= 0) {
3173 if (isAssumedNoCapture())
3174 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
3175 else if (ManifestInternal)
3176 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
3177 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003178 }
3179
3180 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
3181 /// depending on the ability of the function associated with \p IRP to capture
3182 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00003183 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
3184 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05003185 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003186 // TODO: Once we have memory behavior attributes we should use them here.
3187
3188 // If we know we cannot communicate or write to memory, we do not care about
3189 // ptr2int anymore.
3190 if (F.onlyReadsMemory() && F.doesNotThrow() &&
3191 F.getReturnType()->isVoidTy()) {
3192 State.addKnownBits(NO_CAPTURE);
3193 return;
3194 }
3195
3196 // A function cannot capture state in memory if it only reads memory, it can
3197 // however return/throw state and the state might be influenced by the
3198 // pointer value, e.g., loading from a returned pointer might reveal a bit.
3199 if (F.onlyReadsMemory())
3200 State.addKnownBits(NOT_CAPTURED_IN_MEM);
3201
3202 // A function cannot communicate state back if it does not through
3203 // exceptions and doesn not return values.
3204 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
3205 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00003206
3207 // Check existing "returned" attributes.
3208 int ArgNo = IRP.getArgNo();
3209 if (F.doesNotThrow() && ArgNo >= 0) {
3210 for (unsigned u = 0, e = F.arg_size(); u< e; ++u)
3211 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00003212 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00003213 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
3214 else if (F.onlyReadsMemory())
3215 State.addKnownBits(NO_CAPTURE);
3216 else
3217 State.addKnownBits(NOT_CAPTURED_IN_RET);
3218 break;
3219 }
3220 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003221 }
3222
3223 /// See AbstractState::getAsStr().
3224 const std::string getAsStr() const override {
3225 if (isKnownNoCapture())
3226 return "known not-captured";
3227 if (isAssumedNoCapture())
3228 return "assumed not-captured";
3229 if (isKnownNoCaptureMaybeReturned())
3230 return "known not-captured-maybe-returned";
3231 if (isAssumedNoCaptureMaybeReturned())
3232 return "assumed not-captured-maybe-returned";
3233 return "assumed-captured";
3234 }
3235};
3236
3237/// Attributor-aware capture tracker.
3238struct AACaptureUseTracker final : public CaptureTracker {
3239
3240 /// Create a capture tracker that can lookup in-flight abstract attributes
3241 /// through the Attributor \p A.
3242 ///
3243 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
3244 /// search is stopped. If a use leads to a return instruction,
3245 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
3246 /// If a use leads to a ptr2int which may capture the value,
3247 /// \p CapturedInInteger is set. If a use is found that is currently assumed
3248 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
3249 /// set. All values in \p PotentialCopies are later tracked as well. For every
3250 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
3251 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
3252 /// conservatively set to true.
3253 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05003254 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003255 SmallVectorImpl<const Value *> &PotentialCopies,
3256 unsigned &RemainingUsesToExplore)
3257 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
3258 PotentialCopies(PotentialCopies),
3259 RemainingUsesToExplore(RemainingUsesToExplore) {}
3260
3261 /// Determine if \p V maybe captured. *Also updates the state!*
3262 bool valueMayBeCaptured(const Value *V) {
3263 if (V->getType()->isPointerTy()) {
3264 PointerMayBeCaptured(V, this);
3265 } else {
3266 State.indicatePessimisticFixpoint();
3267 }
3268 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3269 }
3270
3271 /// See CaptureTracker::tooManyUses().
3272 void tooManyUses() override {
3273 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
3274 }
3275
3276 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
3277 if (CaptureTracker::isDereferenceableOrNull(O, DL))
3278 return true;
3279 const auto &DerefAA =
3280 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
3281 return DerefAA.getAssumedDereferenceableBytes();
3282 }
3283
3284 /// See CaptureTracker::captured(...).
3285 bool captured(const Use *U) override {
3286 Instruction *UInst = cast<Instruction>(U->getUser());
3287 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3288 << "\n");
3289
3290 // Because we may reuse the tracker multiple times we keep track of the
3291 // number of explored uses ourselves as well.
3292 if (RemainingUsesToExplore-- == 0) {
3293 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3294 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3295 /* Return */ true);
3296 }
3297
3298 // Deal with ptr2int by following uses.
3299 if (isa<PtrToIntInst>(UInst)) {
3300 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3301 return valueMayBeCaptured(UInst);
3302 }
3303
3304 // Explicitly catch return instructions.
3305 if (isa<ReturnInst>(UInst))
3306 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3307 /* Return */ true);
3308
3309 // For now we only use special logic for call sites. However, the tracker
3310 // itself knows about a lot of other non-capturing cases already.
3311 CallSite CS(UInst);
3312 if (!CS || !CS.isArgOperand(U))
3313 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3314 /* Return */ true);
3315
3316 unsigned ArgNo = CS.getArgumentNo(U);
3317 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3318 // If we have a abstract no-capture attribute for the argument we can use
3319 // it to justify a non-capture attribute here. This allows recursion!
3320 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3321 if (ArgNoCaptureAA.isAssumedNoCapture())
3322 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3323 /* Return */ false);
3324 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3325 addPotentialCopy(CS);
3326 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3327 /* Return */ false);
3328 }
3329
3330 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3331 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3332 /* Return */ true);
3333 }
3334
3335 /// Register \p CS as potential copy of the value we are checking.
3336 void addPotentialCopy(CallSite CS) {
3337 PotentialCopies.push_back(CS.getInstruction());
3338 }
3339
3340 /// See CaptureTracker::shouldExplore(...).
3341 bool shouldExplore(const Use *U) override {
3342 // Check liveness.
3343 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3344 }
3345
3346 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3347 /// \p CapturedInRet, then return the appropriate value for use in the
3348 /// CaptureTracker::captured() interface.
3349 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3350 bool CapturedInRet) {
3351 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
3352 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
3353 if (CapturedInMem)
3354 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
3355 if (CapturedInInt)
3356 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
3357 if (CapturedInRet)
3358 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
3359 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3360 }
3361
3362private:
3363 /// The attributor providing in-flight abstract attributes.
3364 Attributor &A;
3365
3366 /// The abstract attribute currently updated.
3367 AANoCapture &NoCaptureAA;
3368
3369 /// The abstract liveness state.
3370 const AAIsDead &IsDeadAA;
3371
3372 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05003373 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003374
3375 /// Set of potential copies of the tracked value.
3376 SmallVectorImpl<const Value *> &PotentialCopies;
3377
3378 /// Global counter to limit the number of explored uses.
3379 unsigned &RemainingUsesToExplore;
3380};
3381
3382ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
3383 const IRPosition &IRP = getIRPosition();
3384 const Value *V =
3385 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
3386 if (!V)
3387 return indicatePessimisticFixpoint();
3388
3389 const Function *F =
3390 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
3391 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00003392 const IRPosition &FnPos = IRPosition::function(*F);
3393 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, FnPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003394
3395 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003396
Johannes Doerfert3839b572019-10-21 00:48:42 +00003397 // Readonly means we cannot capture through memory.
3398 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3399 if (FnMemAA.isAssumedReadOnly()) {
3400 T.addKnownBits(NOT_CAPTURED_IN_MEM);
3401 if (FnMemAA.isKnownReadOnly())
3402 addKnownBits(NOT_CAPTURED_IN_MEM);
3403 }
3404
3405 // Make sure all returned values are different than the underlying value.
3406 // TODO: we could do this in a more sophisticated way inside
3407 // AAReturnedValues, e.g., track all values that escape through returns
3408 // directly somehow.
3409 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
3410 bool SeenConstant = false;
3411 for (auto &It : RVAA.returned_values()) {
3412 if (isa<Constant>(It.first)) {
3413 if (SeenConstant)
3414 return false;
3415 SeenConstant = true;
3416 } else if (!isa<Argument>(It.first) ||
3417 It.first == getAssociatedArgument())
3418 return false;
3419 }
3420 return true;
3421 };
3422
3423 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, FnPos);
3424 if (NoUnwindAA.isAssumedNoUnwind()) {
3425 bool IsVoidTy = F->getReturnType()->isVoidTy();
3426 const AAReturnedValues *RVAA =
3427 IsVoidTy ? nullptr : &A.getAAFor<AAReturnedValues>(*this, FnPos);
3428 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
3429 T.addKnownBits(NOT_CAPTURED_IN_RET);
3430 if (T.isKnown(NOT_CAPTURED_IN_MEM))
3431 return ChangeStatus::UNCHANGED;
3432 if (NoUnwindAA.isKnownNoUnwind() &&
3433 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
3434 addKnownBits(NOT_CAPTURED_IN_RET);
3435 if (isKnown(NOT_CAPTURED_IN_MEM))
3436 return indicateOptimisticFixpoint();
3437 }
3438 }
3439 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003440
3441 // Use the CaptureTracker interface and logic with the specialized tracker,
3442 // defined in AACaptureUseTracker, that can look at in-flight abstract
3443 // attributes and directly updates the assumed state.
3444 SmallVector<const Value *, 4> PotentialCopies;
3445 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
3446 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
3447 RemainingUsesToExplore);
3448
3449 // Check all potential copies of the associated value until we can assume
3450 // none will be captured or we have to assume at least one might be.
3451 unsigned Idx = 0;
3452 PotentialCopies.push_back(V);
3453 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
3454 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
3455
Johannes Doerfert1a746452019-10-20 22:28:49 -05003456 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003457 auto Assumed = S.getAssumed();
3458 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05003459 if (!isAssumedNoCaptureMaybeReturned())
3460 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003461 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3462 : ChangeStatus::CHANGED;
3463}
3464
3465/// NoCapture attribute for function arguments.
3466struct AANoCaptureArgument final : AANoCaptureImpl {
3467 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3468
3469 /// See AbstractAttribute::trackStatistics()
3470 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
3471};
3472
3473/// NoCapture attribute for call site arguments.
3474struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
3475 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3476
3477 /// See AbstractAttribute::updateImpl(...).
3478 ChangeStatus updateImpl(Attributor &A) override {
3479 // TODO: Once we have call site specific value information we can provide
3480 // call site specific liveness information and then it makes
3481 // sense to specialize attributes for call sites arguments instead of
3482 // redirecting requests to the callee argument.
3483 Argument *Arg = getAssociatedArgument();
3484 if (!Arg)
3485 return indicatePessimisticFixpoint();
3486 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3487 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
3488 return clampStateAndIndicateChange(
3489 getState(),
3490 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3491 }
3492
3493 /// See AbstractAttribute::trackStatistics()
3494 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
3495};
3496
3497/// NoCapture attribute for floating values.
3498struct AANoCaptureFloating final : AANoCaptureImpl {
3499 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3500
3501 /// See AbstractAttribute::trackStatistics()
3502 void trackStatistics() const override {
3503 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
3504 }
3505};
3506
3507/// NoCapture attribute for function return value.
3508struct AANoCaptureReturned final : AANoCaptureImpl {
3509 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
3510 llvm_unreachable("NoCapture is not applicable to function returns!");
3511 }
3512
3513 /// See AbstractAttribute::initialize(...).
3514 void initialize(Attributor &A) override {
3515 llvm_unreachable("NoCapture is not applicable to function returns!");
3516 }
3517
3518 /// See AbstractAttribute::updateImpl(...).
3519 ChangeStatus updateImpl(Attributor &A) override {
3520 llvm_unreachable("NoCapture is not applicable to function returns!");
3521 }
3522
3523 /// See AbstractAttribute::trackStatistics()
3524 void trackStatistics() const override {}
3525};
3526
3527/// NoCapture attribute deduction for a call site return value.
3528struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
3529 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3530
3531 /// See AbstractAttribute::trackStatistics()
3532 void trackStatistics() const override {
3533 STATS_DECLTRACK_CSRET_ATTR(nocapture)
3534 }
3535};
3536
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003537/// ------------------ Value Simplify Attribute ----------------------------
3538struct AAValueSimplifyImpl : AAValueSimplify {
3539 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
3540
3541 /// See AbstractAttribute::getAsStr().
3542 const std::string getAsStr() const override {
3543 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
3544 : "not-simple";
3545 }
3546
3547 /// See AbstractAttribute::trackStatistics()
3548 void trackStatistics() const override {}
3549
3550 /// See AAValueSimplify::getAssumedSimplifiedValue()
3551 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
3552 if (!getAssumed())
3553 return const_cast<Value *>(&getAssociatedValue());
3554 return SimplifiedAssociatedValue;
3555 }
3556 void initialize(Attributor &A) override {}
3557
3558 /// Helper function for querying AAValueSimplify and updating candicate.
3559 /// \param QueryingValue Value trying to unify with SimplifiedValue
3560 /// \param AccumulatedSimplifiedValue Current simplification result.
3561 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
3562 Value &QueryingValue,
3563 Optional<Value *> &AccumulatedSimplifiedValue) {
3564 // FIXME: Add a typecast support.
3565
3566 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
3567 QueryingAA, IRPosition::value(QueryingValue));
3568
3569 Optional<Value *> QueryingValueSimplified =
3570 ValueSimpifyAA.getAssumedSimplifiedValue(A);
3571
3572 if (!QueryingValueSimplified.hasValue())
3573 return true;
3574
3575 if (!QueryingValueSimplified.getValue())
3576 return false;
3577
3578 Value &QueryingValueSimplifiedUnwrapped =
3579 *QueryingValueSimplified.getValue();
3580
3581 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
3582 return true;
3583
3584 if (AccumulatedSimplifiedValue.hasValue())
3585 return AccumulatedSimplifiedValue == QueryingValueSimplified;
3586
3587 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
3588 << " is assumed to be "
3589 << QueryingValueSimplifiedUnwrapped << "\n");
3590
3591 AccumulatedSimplifiedValue = QueryingValueSimplified;
3592 return true;
3593 }
3594
3595 /// See AbstractAttribute::manifest(...).
3596 ChangeStatus manifest(Attributor &A) override {
3597 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3598
3599 if (!SimplifiedAssociatedValue.hasValue() ||
3600 !SimplifiedAssociatedValue.getValue())
3601 return Changed;
3602
3603 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
3604 // We can replace the AssociatedValue with the constant.
3605 Value &V = getAssociatedValue();
3606 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
3607 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
3608 << "\n");
3609 V.replaceAllUsesWith(C);
3610 Changed = ChangeStatus::CHANGED;
3611 }
3612 }
3613
3614 return Changed | AAValueSimplify::manifest(A);
3615 }
3616
3617protected:
3618 // An assumed simplified value. Initially, it is set to Optional::None, which
3619 // means that the value is not clear under current assumption. If in the
3620 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
3621 // returns orignal associated value.
3622 Optional<Value *> SimplifiedAssociatedValue;
3623};
3624
3625struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
3626 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3627
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05003628 void initialize(Attributor &A) override {
3629 AAValueSimplifyImpl::initialize(A);
3630 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
3631 indicatePessimisticFixpoint();
3632 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
3633 /* IgnoreSubsumingPositions */ true))
3634 indicatePessimisticFixpoint();
3635 }
3636
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003637 /// See AbstractAttribute::updateImpl(...).
3638 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05003639 // Byval is only replacable if it is readonly otherwise we would write into
3640 // the replaced value and not the copy that byval creates implicitly.
3641 Argument *Arg = getAssociatedArgument();
3642 if (Arg->hasByValAttr()) {
3643 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
3644 if (!MemAA.isAssumedReadOnly())
3645 return indicatePessimisticFixpoint();
3646 }
3647
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003648 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3649
Johannes Doerfert661db042019-10-07 23:14:58 +00003650 auto PredForCallSite = [&](AbstractCallSite ACS) {
3651 // Check if we have an associated argument or not (which can happen for
3652 // callback calls).
Johannes Doerferte360ee62019-11-01 18:45:25 -05003653 Value *ArgOp = ACS.getCallArgOperand(getArgNo());
3654 if (!ArgOp)
3655 return false;
3656 // We can only propagate thread independent values through callbacks.
3657 // This is different to direct/indirect call sites because for them we
3658 // know the thread executing the caller and callee is the same. For
3659 // callbacks this is not guaranteed, thus a thread dependent value could
3660 // be different for the caller and callee, making it invalid to propagate.
3661 if (ACS.isCallbackCall())
3662 if (auto *C =dyn_cast<Constant>(ArgOp))
3663 if (C->isThreadDependent())
3664 return false;
3665 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003666 };
3667
3668 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
3669 return indicatePessimisticFixpoint();
3670
3671 // If a candicate was found in this update, return CHANGED.
3672 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3673 ? ChangeStatus::UNCHANGED
3674 : ChangeStatus ::CHANGED;
3675 }
3676
3677 /// See AbstractAttribute::trackStatistics()
3678 void trackStatistics() const override {
3679 STATS_DECLTRACK_ARG_ATTR(value_simplify)
3680 }
3681};
3682
3683struct AAValueSimplifyReturned : AAValueSimplifyImpl {
3684 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3685
3686 /// See AbstractAttribute::updateImpl(...).
3687 ChangeStatus updateImpl(Attributor &A) override {
3688 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3689
3690 auto PredForReturned = [&](Value &V) {
3691 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3692 };
3693
3694 if (!A.checkForAllReturnedValues(PredForReturned, *this))
3695 return indicatePessimisticFixpoint();
3696
3697 // If a candicate was found in this update, return CHANGED.
3698 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3699 ? ChangeStatus::UNCHANGED
3700 : ChangeStatus ::CHANGED;
3701 }
3702 /// See AbstractAttribute::trackStatistics()
3703 void trackStatistics() const override {
3704 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
3705 }
3706};
3707
3708struct AAValueSimplifyFloating : AAValueSimplifyImpl {
3709 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3710
3711 /// See AbstractAttribute::initialize(...).
3712 void initialize(Attributor &A) override {
3713 Value &V = getAnchorValue();
3714
3715 // TODO: add other stuffs
3716 if (isa<Constant>(V) || isa<UndefValue>(V))
3717 indicatePessimisticFixpoint();
3718 }
3719
3720 /// See AbstractAttribute::updateImpl(...).
3721 ChangeStatus updateImpl(Attributor &A) override {
3722 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3723
3724 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
3725 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
3726 if (!Stripped && this == &AA) {
3727 // TODO: Look the instruction and check recursively.
3728 LLVM_DEBUG(
3729 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
3730 << V << "\n");
3731 indicatePessimisticFixpoint();
3732 return false;
3733 }
3734 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3735 };
3736
3737 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
3738 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
3739 VisitValueCB))
3740 return indicatePessimisticFixpoint();
3741
3742 // If a candicate was found in this update, return CHANGED.
3743
3744 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3745 ? ChangeStatus::UNCHANGED
3746 : ChangeStatus ::CHANGED;
3747 }
3748
3749 /// See AbstractAttribute::trackStatistics()
3750 void trackStatistics() const override {
3751 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
3752 }
3753};
3754
3755struct AAValueSimplifyFunction : AAValueSimplifyImpl {
3756 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3757
3758 /// See AbstractAttribute::initialize(...).
3759 void initialize(Attributor &A) override {
3760 SimplifiedAssociatedValue = &getAnchorValue();
3761 indicateOptimisticFixpoint();
3762 }
3763 /// See AbstractAttribute::initialize(...).
3764 ChangeStatus updateImpl(Attributor &A) override {
3765 llvm_unreachable(
3766 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
3767 }
3768 /// See AbstractAttribute::trackStatistics()
3769 void trackStatistics() const override {
3770 STATS_DECLTRACK_FN_ATTR(value_simplify)
3771 }
3772};
3773
3774struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
3775 AAValueSimplifyCallSite(const IRPosition &IRP)
3776 : AAValueSimplifyFunction(IRP) {}
3777 /// See AbstractAttribute::trackStatistics()
3778 void trackStatistics() const override {
3779 STATS_DECLTRACK_CS_ATTR(value_simplify)
3780 }
3781};
3782
3783struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
3784 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
3785 : AAValueSimplifyReturned(IRP) {}
3786
3787 void trackStatistics() const override {
3788 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
3789 }
3790};
3791struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
3792 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
3793 : AAValueSimplifyFloating(IRP) {}
3794
3795 void trackStatistics() const override {
3796 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
3797 }
3798};
3799
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003800/// ----------------------- Heap-To-Stack Conversion ---------------------------
3801struct AAHeapToStackImpl : public AAHeapToStack {
3802 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
3803
3804 const std::string getAsStr() const override {
3805 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
3806 }
3807
3808 ChangeStatus manifest(Attributor &A) override {
3809 assert(getState().isValidState() &&
3810 "Attempted to manifest an invalid state!");
3811
3812 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
3813 Function *F = getAssociatedFunction();
3814 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3815
3816 for (Instruction *MallocCall : MallocCalls) {
3817 // This malloc cannot be replaced.
3818 if (BadMallocCalls.count(MallocCall))
3819 continue;
3820
3821 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
3822 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
3823 A.deleteAfterManifest(*FreeCall);
3824 HasChanged = ChangeStatus::CHANGED;
3825 }
3826
3827 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
3828 << "\n");
3829
3830 Constant *Size;
3831 if (isCallocLikeFn(MallocCall, TLI)) {
3832 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
3833 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
3834 APInt TotalSize = SizeT->getValue() * Num->getValue();
3835 Size =
3836 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
3837 } else {
3838 Size = cast<ConstantInt>(MallocCall->getOperand(0));
3839 }
3840
3841 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
3842 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
3843 Size, "", MallocCall->getNextNode());
3844
3845 if (AI->getType() != MallocCall->getType())
3846 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
3847 AI->getNextNode());
3848
3849 MallocCall->replaceAllUsesWith(AI);
3850
3851 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
3852 auto *NBB = II->getNormalDest();
3853 BranchInst::Create(NBB, MallocCall->getParent());
3854 A.deleteAfterManifest(*MallocCall);
3855 } else {
3856 A.deleteAfterManifest(*MallocCall);
3857 }
3858
3859 if (isCallocLikeFn(MallocCall, TLI)) {
3860 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
3861 AI->getNextNode());
3862 Value *Ops[] = {
3863 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
3864 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
3865
3866 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
3867 Module *M = F->getParent();
3868 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
3869 CallInst::Create(Fn, Ops, "", BI->getNextNode());
3870 }
3871 HasChanged = ChangeStatus::CHANGED;
3872 }
3873
3874 return HasChanged;
3875 }
3876
3877 /// Collection of all malloc calls in a function.
3878 SmallSetVector<Instruction *, 4> MallocCalls;
3879
3880 /// Collection of malloc calls that cannot be converted.
3881 DenseSet<const Instruction *> BadMallocCalls;
3882
3883 /// A map for each malloc call to the set of associated free calls.
3884 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
3885
3886 ChangeStatus updateImpl(Attributor &A) override;
3887};
3888
3889ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
3890 const Function *F = getAssociatedFunction();
3891 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3892
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003893 MustBeExecutedContextExplorer &Explorer =
3894 A.getInfoCache().getMustBeExecutedContextExplorer();
3895
3896 auto FreeCheck = [&](Instruction &I) {
3897 const auto &Frees = FreesForMalloc.lookup(&I);
3898 if (Frees.size() != 1)
3899 return false;
3900 Instruction *UniqueFree = *Frees.begin();
3901 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
3902 };
3903
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003904 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003905 bool ValidUsesOnly = true;
3906 bool MustUse = true;
3907
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003908 SmallPtrSet<const Use *, 8> Visited;
3909 SmallVector<const Use *, 8> Worklist;
3910
3911 for (Use &U : I.uses())
3912 Worklist.push_back(&U);
3913
3914 while (!Worklist.empty()) {
3915 const Use *U = Worklist.pop_back_val();
3916 if (!Visited.insert(U).second)
3917 continue;
3918
3919 auto *UserI = U->getUser();
3920
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003921 if (isa<LoadInst>(UserI))
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003922 continue;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003923 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
3924 if (SI->getValueOperand() == U->get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003925 LLVM_DEBUG(dbgs()
3926 << "[H2S] escaping store to memory: " << *UserI << "\n");
3927 ValidUsesOnly = false;
3928 } else {
3929 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003930 }
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003931 continue;
3932 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003933
3934 // NOTE: Right now, if a function that has malloc pointer as an argument
3935 // frees memory, we assume that the malloc pointer is freed.
3936
3937 // TODO: Add nofree callsite argument attribute to indicate that pointer
3938 // argument is not freed.
3939 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3940 if (!CB->isArgOperand(U))
3941 continue;
3942
3943 if (CB->isLifetimeStartOrEnd())
3944 continue;
3945
3946 // Record malloc.
3947 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003948 if (MustUse) {
3949 FreesForMalloc[&I].insert(
3950 cast<Instruction>(const_cast<User *>(UserI)));
3951 } else {
3952 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
3953 << *UserI << "\n");
3954 ValidUsesOnly = false;
3955 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003956 continue;
3957 }
3958
3959 // If a function does not free memory we are fine
3960 const auto &NoFreeAA =
3961 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(*CB));
3962
3963 unsigned ArgNo = U - CB->arg_begin();
3964 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
3965 *this, IRPosition::callsite_argument(*CB, ArgNo));
3966
3967 if (!NoCaptureAA.isAssumedNoCapture() || !NoFreeAA.isAssumedNoFree()) {
3968 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003969 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003970 }
3971 continue;
3972 }
3973
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003974 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
3975 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
3976 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003977 for (Use &U : UserI->uses())
3978 Worklist.push_back(&U);
3979 continue;
3980 }
3981
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003982 // Unknown user for which we can not track uses further (in a way that
3983 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003984 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003985 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003986 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003987 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003988 };
3989
3990 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003991 if (BadMallocCalls.count(&I))
3992 return true;
3993
3994 bool IsMalloc = isMallocLikeFn(&I, TLI);
3995 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
3996 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003997 BadMallocCalls.insert(&I);
3998 return true;
3999 }
4000
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004001 if (IsMalloc) {
4002 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
4003 if (Size->getValue().sle(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004004 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004005 MallocCalls.insert(&I);
4006 return true;
4007 }
4008 } else if (IsCalloc) {
4009 bool Overflow = false;
4010 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
4011 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
4012 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
4013 .sle(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004014 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004015 MallocCalls.insert(&I);
4016 return true;
4017 }
4018 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004019
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004020 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004021 return true;
4022 };
4023
4024 size_t NumBadMallocs = BadMallocCalls.size();
4025
4026 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
4027
4028 if (NumBadMallocs != BadMallocCalls.size())
4029 return ChangeStatus::CHANGED;
4030
4031 return ChangeStatus::UNCHANGED;
4032}
4033
4034struct AAHeapToStackFunction final : public AAHeapToStackImpl {
4035 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
4036
4037 /// See AbstractAttribute::trackStatistics()
4038 void trackStatistics() const override {
4039 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004040 "Number of malloc calls converted to allocas");
4041 for (auto *C : MallocCalls)
4042 if (!BadMallocCalls.count(C))
4043 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004044 }
4045};
4046
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004047/// -------------------- Memory Behavior Attributes ----------------------------
4048/// Includes read-none, read-only, and write-only.
4049/// ----------------------------------------------------------------------------
4050struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
4051 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
4052
4053 /// See AbstractAttribute::initialize(...).
4054 void initialize(Attributor &A) override {
4055 intersectAssumedBits(BEST_STATE);
4056 getKnownStateFromValue(getIRPosition(), getState());
4057 IRAttribute::initialize(A);
4058 }
4059
4060 /// Return the memory behavior information encoded in the IR for \p IRP.
4061 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert1a746452019-10-20 22:28:49 -05004062 BitIntegerState &State) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004063 SmallVector<Attribute, 2> Attrs;
4064 IRP.getAttrs(AttrKinds, Attrs);
4065 for (const Attribute &Attr : Attrs) {
4066 switch (Attr.getKindAsEnum()) {
4067 case Attribute::ReadNone:
4068 State.addKnownBits(NO_ACCESSES);
4069 break;
4070 case Attribute::ReadOnly:
4071 State.addKnownBits(NO_WRITES);
4072 break;
4073 case Attribute::WriteOnly:
4074 State.addKnownBits(NO_READS);
4075 break;
4076 default:
4077 llvm_unreachable("Unexpcted attribute!");
4078 }
4079 }
4080
4081 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
4082 if (!I->mayReadFromMemory())
4083 State.addKnownBits(NO_READS);
4084 if (!I->mayWriteToMemory())
4085 State.addKnownBits(NO_WRITES);
4086 }
4087 }
4088
4089 /// See AbstractAttribute::getDeducedAttributes(...).
4090 void getDeducedAttributes(LLVMContext &Ctx,
4091 SmallVectorImpl<Attribute> &Attrs) const override {
4092 assert(Attrs.size() == 0);
4093 if (isAssumedReadNone())
4094 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
4095 else if (isAssumedReadOnly())
4096 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
4097 else if (isAssumedWriteOnly())
4098 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
4099 assert(Attrs.size() <= 1);
4100 }
4101
4102 /// See AbstractAttribute::manifest(...).
4103 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05004104 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004105
4106 // Check if we would improve the existing attributes first.
4107 SmallVector<Attribute, 4> DeducedAttrs;
4108 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
4109 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
4110 return IRP.hasAttr(Attr.getKindAsEnum(),
4111 /* IgnoreSubsumingPositions */ true);
4112 }))
4113 return ChangeStatus::UNCHANGED;
4114
4115 // Clear existing attributes.
4116 IRP.removeAttrs(AttrKinds);
4117
4118 // Use the generic manifest method.
4119 return IRAttribute::manifest(A);
4120 }
4121
4122 /// See AbstractState::getAsStr().
4123 const std::string getAsStr() const override {
4124 if (isAssumedReadNone())
4125 return "readnone";
4126 if (isAssumedReadOnly())
4127 return "readonly";
4128 if (isAssumedWriteOnly())
4129 return "writeonly";
4130 return "may-read/write";
4131 }
4132
4133 /// The set of IR attributes AAMemoryBehavior deals with.
4134 static const Attribute::AttrKind AttrKinds[3];
4135};
4136
4137const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
4138 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
4139
4140/// Memory behavior attribute for a floating value.
4141struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
4142 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4143
4144 /// See AbstractAttribute::initialize(...).
4145 void initialize(Attributor &A) override {
4146 AAMemoryBehaviorImpl::initialize(A);
4147 // Initialize the use vector with all direct uses of the associated value.
4148 for (const Use &U : getAssociatedValue().uses())
4149 Uses.insert(&U);
4150 }
4151
4152 /// See AbstractAttribute::updateImpl(...).
4153 ChangeStatus updateImpl(Attributor &A) override;
4154
4155 /// See AbstractAttribute::trackStatistics()
4156 void trackStatistics() const override {
4157 if (isAssumedReadNone())
4158 STATS_DECLTRACK_FLOATING_ATTR(readnone)
4159 else if (isAssumedReadOnly())
4160 STATS_DECLTRACK_FLOATING_ATTR(readonly)
4161 else if (isAssumedWriteOnly())
4162 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
4163 }
4164
4165private:
4166 /// Return true if users of \p UserI might access the underlying
4167 /// variable/location described by \p U and should therefore be analyzed.
4168 bool followUsersOfUseIn(Attributor &A, const Use *U,
4169 const Instruction *UserI);
4170
4171 /// Update the state according to the effect of use \p U in \p UserI.
4172 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
4173
4174protected:
4175 /// Container for (transitive) uses of the associated argument.
4176 SetVector<const Use *> Uses;
4177};
4178
4179/// Memory behavior attribute for function argument.
4180struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
4181 AAMemoryBehaviorArgument(const IRPosition &IRP)
4182 : AAMemoryBehaviorFloating(IRP) {}
4183
4184 /// See AbstractAttribute::initialize(...).
4185 void initialize(Attributor &A) override {
4186 AAMemoryBehaviorFloating::initialize(A);
4187
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004188 // Initialize the use vector with all direct uses of the associated value.
4189 Argument *Arg = getAssociatedArgument();
4190 if (!Arg || !Arg->getParent()->hasExactDefinition())
4191 indicatePessimisticFixpoint();
4192 }
4193
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004194 ChangeStatus manifest(Attributor &A) override {
4195 // TODO: From readattrs.ll: "inalloca parameters are always
4196 // considered written"
4197 if (hasAttr({Attribute::InAlloca})) {
4198 removeKnownBits(NO_WRITES);
4199 removeAssumedBits(NO_WRITES);
4200 }
4201 return AAMemoryBehaviorFloating::manifest(A);
4202 }
4203
4204
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004205 /// See AbstractAttribute::trackStatistics()
4206 void trackStatistics() const override {
4207 if (isAssumedReadNone())
4208 STATS_DECLTRACK_ARG_ATTR(readnone)
4209 else if (isAssumedReadOnly())
4210 STATS_DECLTRACK_ARG_ATTR(readonly)
4211 else if (isAssumedWriteOnly())
4212 STATS_DECLTRACK_ARG_ATTR(writeonly)
4213 }
4214};
4215
4216struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
4217 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
4218 : AAMemoryBehaviorArgument(IRP) {}
4219
4220 /// See AbstractAttribute::updateImpl(...).
4221 ChangeStatus updateImpl(Attributor &A) override {
4222 // TODO: Once we have call site specific value information we can provide
4223 // call site specific liveness liveness information and then it makes
4224 // sense to specialize attributes for call sites arguments instead of
4225 // redirecting requests to the callee argument.
4226 Argument *Arg = getAssociatedArgument();
4227 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4228 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4229 return clampStateAndIndicateChange(
4230 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05004231 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004232 }
4233
4234 /// See AbstractAttribute::trackStatistics()
4235 void trackStatistics() const override {
4236 if (isAssumedReadNone())
4237 STATS_DECLTRACK_CSARG_ATTR(readnone)
4238 else if (isAssumedReadOnly())
4239 STATS_DECLTRACK_CSARG_ATTR(readonly)
4240 else if (isAssumedWriteOnly())
4241 STATS_DECLTRACK_CSARG_ATTR(writeonly)
4242 }
4243};
4244
4245/// Memory behavior attribute for a call site return position.
4246struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
4247 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
4248 : AAMemoryBehaviorFloating(IRP) {}
4249
4250 /// See AbstractAttribute::manifest(...).
4251 ChangeStatus manifest(Attributor &A) override {
4252 // We do not annotate returned values.
4253 return ChangeStatus::UNCHANGED;
4254 }
4255
4256 /// See AbstractAttribute::trackStatistics()
4257 void trackStatistics() const override {}
4258};
4259
4260/// An AA to represent the memory behavior function attributes.
4261struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
4262 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4263
4264 /// See AbstractAttribute::updateImpl(Attributor &A).
4265 virtual ChangeStatus updateImpl(Attributor &A) override;
4266
4267 /// See AbstractAttribute::manifest(...).
4268 ChangeStatus manifest(Attributor &A) override {
4269 Function &F = cast<Function>(getAnchorValue());
4270 if (isAssumedReadNone()) {
4271 F.removeFnAttr(Attribute::ArgMemOnly);
4272 F.removeFnAttr(Attribute::InaccessibleMemOnly);
4273 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
4274 }
4275 return AAMemoryBehaviorImpl::manifest(A);
4276 }
4277
4278 /// See AbstractAttribute::trackStatistics()
4279 void trackStatistics() const override {
4280 if (isAssumedReadNone())
4281 STATS_DECLTRACK_FN_ATTR(readnone)
4282 else if (isAssumedReadOnly())
4283 STATS_DECLTRACK_FN_ATTR(readonly)
4284 else if (isAssumedWriteOnly())
4285 STATS_DECLTRACK_FN_ATTR(writeonly)
4286 }
4287};
4288
4289/// AAMemoryBehavior attribute for call sites.
4290struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
4291 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4292
4293 /// See AbstractAttribute::initialize(...).
4294 void initialize(Attributor &A) override {
4295 AAMemoryBehaviorImpl::initialize(A);
4296 Function *F = getAssociatedFunction();
4297 if (!F || !F->hasExactDefinition())
4298 indicatePessimisticFixpoint();
4299 }
4300
4301 /// See AbstractAttribute::updateImpl(...).
4302 ChangeStatus updateImpl(Attributor &A) override {
4303 // TODO: Once we have call site specific value information we can provide
4304 // call site specific liveness liveness information and then it makes
4305 // sense to specialize attributes for call sites arguments instead of
4306 // redirecting requests to the callee argument.
4307 Function *F = getAssociatedFunction();
4308 const IRPosition &FnPos = IRPosition::function(*F);
4309 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4310 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05004311 getState(),
4312 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004313 }
4314
4315 /// See AbstractAttribute::trackStatistics()
4316 void trackStatistics() const override {
4317 if (isAssumedReadNone())
4318 STATS_DECLTRACK_CS_ATTR(readnone)
4319 else if (isAssumedReadOnly())
4320 STATS_DECLTRACK_CS_ATTR(readonly)
4321 else if (isAssumedWriteOnly())
4322 STATS_DECLTRACK_CS_ATTR(writeonly)
4323 }
4324};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00004325} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004326
4327ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
4328
4329 // The current assumed state used to determine a change.
4330 auto AssumedState = getAssumed();
4331
4332 auto CheckRWInst = [&](Instruction &I) {
4333 // If the instruction has an own memory behavior state, use it to restrict
4334 // the local state. No further analysis is required as the other memory
4335 // state is as optimistic as it gets.
4336 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
4337 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
4338 *this, IRPosition::callsite_function(ICS));
4339 intersectAssumedBits(MemBehaviorAA.getAssumed());
4340 return !isAtFixpoint();
4341 }
4342
4343 // Remove access kind modifiers if necessary.
4344 if (I.mayReadFromMemory())
4345 removeAssumedBits(NO_READS);
4346 if (I.mayWriteToMemory())
4347 removeAssumedBits(NO_WRITES);
4348 return !isAtFixpoint();
4349 };
4350
4351 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
4352 return indicatePessimisticFixpoint();
4353
4354 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4355 : ChangeStatus::UNCHANGED;
4356}
4357
4358ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
4359
4360 const IRPosition &IRP = getIRPosition();
4361 const IRPosition &FnPos = IRPosition::function_scope(IRP);
4362 AAMemoryBehavior::StateType &S = getState();
4363
4364 // First, check the function scope. We take the known information and we avoid
4365 // work if the assumed information implies the current assumed information for
4366 // this attribute.
4367 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4368 S.addKnownBits(FnMemAA.getKnown());
4369 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
4370 return ChangeStatus::UNCHANGED;
4371
4372 // Make sure the value is not captured (except through "return"), if
4373 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004374 // check the potential aliases introduced by the capture. However, no need
4375 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004376 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004377 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
4378 S.intersectAssumedBits(FnMemAA.getAssumed());
4379 return ChangeStatus::CHANGED;
4380 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004381
4382 // The current assumed state used to determine a change.
4383 auto AssumedState = S.getAssumed();
4384
4385 // Liveness information to exclude dead users.
4386 // TODO: Take the FnPos once we have call site specific liveness information.
4387 const auto &LivenessAA = A.getAAFor<AAIsDead>(
4388 *this, IRPosition::function(*IRP.getAssociatedFunction()));
4389
4390 // Visit and expand uses until all are analyzed or a fixpoint is reached.
4391 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
4392 const Use *U = Uses[i];
4393 Instruction *UserI = cast<Instruction>(U->getUser());
4394 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
4395 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
4396 << "]\n");
4397 if (LivenessAA.isAssumedDead(UserI))
4398 continue;
4399
4400 // Check if the users of UserI should also be visited.
4401 if (followUsersOfUseIn(A, U, UserI))
4402 for (const Use &UserIUse : UserI->uses())
4403 Uses.insert(&UserIUse);
4404
4405 // If UserI might touch memory we analyze the use in detail.
4406 if (UserI->mayReadOrWriteMemory())
4407 analyzeUseIn(A, U, UserI);
4408 }
4409
4410 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4411 : ChangeStatus::UNCHANGED;
4412}
4413
4414bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
4415 const Instruction *UserI) {
4416 // The loaded value is unrelated to the pointer argument, no need to
4417 // follow the users of the load.
4418 if (isa<LoadInst>(UserI))
4419 return false;
4420
4421 // By default we follow all uses assuming UserI might leak information on U,
4422 // we have special handling for call sites operands though.
4423 ImmutableCallSite ICS(UserI);
4424 if (!ICS || !ICS.isArgOperand(U))
4425 return true;
4426
4427 // If the use is a call argument known not to be captured, the users of
4428 // the call do not need to be visited because they have to be unrelated to
4429 // the input. Note that this check is not trivial even though we disallow
4430 // general capturing of the underlying argument. The reason is that the
4431 // call might the argument "through return", which we allow and for which we
4432 // need to check call users.
4433 unsigned ArgNo = ICS.getArgumentNo(U);
4434 const auto &ArgNoCaptureAA =
4435 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
4436 return !ArgNoCaptureAA.isAssumedNoCapture();
4437}
4438
4439void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
4440 const Instruction *UserI) {
4441 assert(UserI->mayReadOrWriteMemory());
4442
4443 switch (UserI->getOpcode()) {
4444 default:
4445 // TODO: Handle all atomics and other side-effect operations we know of.
4446 break;
4447 case Instruction::Load:
4448 // Loads cause the NO_READS property to disappear.
4449 removeAssumedBits(NO_READS);
4450 return;
4451
4452 case Instruction::Store:
4453 // Stores cause the NO_WRITES property to disappear if the use is the
4454 // pointer operand. Note that we do assume that capturing was taken care of
4455 // somewhere else.
4456 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
4457 removeAssumedBits(NO_WRITES);
4458 return;
4459
4460 case Instruction::Call:
4461 case Instruction::CallBr:
4462 case Instruction::Invoke: {
4463 // For call sites we look at the argument memory behavior attribute (this
4464 // could be recursive!) in order to restrict our own state.
4465 ImmutableCallSite ICS(UserI);
4466
4467 // Give up on operand bundles.
4468 if (ICS.isBundleOperand(U)) {
4469 indicatePessimisticFixpoint();
4470 return;
4471 }
4472
4473 // Calling a function does read the function pointer, maybe write it if the
4474 // function is self-modifying.
4475 if (ICS.isCallee(U)) {
4476 removeAssumedBits(NO_READS);
4477 break;
4478 }
4479
4480 // Adjust the possible access behavior based on the information on the
4481 // argument.
4482 unsigned ArgNo = ICS.getArgumentNo(U);
4483 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
4484 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4485 // "assumed" has at most the same bits as the MemBehaviorAA assumed
4486 // and at least "known".
4487 intersectAssumedBits(MemBehaviorAA.getAssumed());
4488 return;
4489 }
4490 };
4491
4492 // Generally, look at the "may-properties" and adjust the assumed state if we
4493 // did not trigger special handling before.
4494 if (UserI->mayReadFromMemory())
4495 removeAssumedBits(NO_READS);
4496 if (UserI->mayWriteToMemory())
4497 removeAssumedBits(NO_WRITES);
4498}
4499
Johannes Doerfertaade7822019-06-05 03:02:24 +00004500/// ----------------------------------------------------------------------------
4501/// Attributor
4502/// ----------------------------------------------------------------------------
4503
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004504bool Attributor::isAssumedDead(const AbstractAttribute &AA,
4505 const AAIsDead *LivenessAA) {
4506 const Instruction *CtxI = AA.getIRPosition().getCtxI();
4507 if (!CtxI)
4508 return false;
4509
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004510 // TODO: Find a good way to utilize fine and coarse grained liveness
4511 // information.
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004512 if (!LivenessAA)
4513 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00004514 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
4515 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00004516
4517 // Don't check liveness for AAIsDead.
4518 if (&AA == LivenessAA)
4519 return false;
4520
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004521 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004522 return false;
4523
Johannes Doerfert19b00432019-08-26 17:48:05 +00004524 // We actually used liveness information so we have to record a dependence.
4525 recordDependence(*LivenessAA, AA);
4526
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004527 return true;
4528}
4529
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004530bool Attributor::checkForAllUses(
4531 const function_ref<bool(const Use &, bool &)> &Pred,
4532 const AbstractAttribute &QueryingAA, const Value &V) {
4533 const IRPosition &IRP = QueryingAA.getIRPosition();
4534 SmallVector<const Use *, 16> Worklist;
4535 SmallPtrSet<const Use *, 16> Visited;
4536
4537 for (const Use &U : V.uses())
4538 Worklist.push_back(&U);
4539
4540 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
4541 << " initial uses to check\n");
4542
4543 if (Worklist.empty())
4544 return true;
4545
4546 bool AnyDead = false;
4547 const Function *ScopeFn = IRP.getAnchorScope();
4548 const auto *LivenessAA =
4549 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
4550 /* TrackDependence */ false)
4551 : nullptr;
4552
4553 while (!Worklist.empty()) {
4554 const Use *U = Worklist.pop_back_val();
4555 if (!Visited.insert(U).second)
4556 continue;
4557 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << "\n");
4558 if (Instruction *UserI = dyn_cast<Instruction>(U->getUser()))
4559 if (LivenessAA && LivenessAA->isAssumedDead(UserI)) {
4560 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
4561 << static_cast<const AbstractAttribute &>(*LivenessAA)
4562 << "\n");
4563 AnyDead = true;
4564 continue;
4565 }
4566
4567 bool Follow = false;
4568 if (!Pred(*U, Follow))
4569 return false;
4570 if (!Follow)
4571 continue;
4572 for (const Use &UU : U->getUser()->uses())
4573 Worklist.push_back(&UU);
4574 }
4575
4576 if (AnyDead)
4577 recordDependence(*LivenessAA, QueryingAA);
4578
4579 return true;
4580}
4581
Johannes Doerfert661db042019-10-07 23:14:58 +00004582bool Attributor::checkForAllCallSites(
4583 const function_ref<bool(AbstractCallSite)> &Pred,
4584 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004585 // We can try to determine information from
4586 // the call sites. However, this is only possible all call sites are known,
4587 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004588 const IRPosition &IRP = QueryingAA.getIRPosition();
4589 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00004590 if (!AssociatedFunction) {
4591 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
4592 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004593 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00004594 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004595
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004596 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
4597 &QueryingAA);
4598}
4599
4600bool Attributor::checkForAllCallSites(
4601 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
4602 bool RequireAllCallSites, const AbstractAttribute *QueryingAA) {
4603 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004604 LLVM_DEBUG(
4605 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004606 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00004607 << " has no internal linkage, hence not all call sites are known\n");
4608 return false;
4609 }
4610
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004611 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00004612 AbstractCallSite ACS(&U);
4613 if (!ACS) {
4614 LLVM_DEBUG(dbgs() << "[Attributor] Function "
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004615 << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00004616 << " has non call site use " << *U.get() << " in "
4617 << *U.getUser() << "\n");
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004618 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00004619 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004620
Johannes Doerfert661db042019-10-07 23:14:58 +00004621 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004622 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004623
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004624 const auto *LivenessAA =
4625 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Johannes Doerfert661db042019-10-07 23:14:58 +00004626 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004627
4628 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004629 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00004630 // We actually used liveness information so we have to record a
4631 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004632 if (QueryingAA)
4633 recordDependence(*LivenessAA, *QueryingAA);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004634 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004635 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004636
Johannes Doerfert661db042019-10-07 23:14:58 +00004637 const Use *EffectiveUse =
4638 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
4639 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004640 if (!RequireAllCallSites)
4641 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00004642 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004643 << " is an invalid use of "
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004644 << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004645 return false;
4646 }
4647
Johannes Doerfert661db042019-10-07 23:14:58 +00004648 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00004649 continue;
4650
Johannes Doerfert5304b722019-08-14 22:04:28 +00004651 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00004652 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004653 return false;
4654 }
4655
4656 return true;
4657}
4658
Johannes Doerfert14a04932019-08-07 22:27:24 +00004659bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004660 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00004661 &Pred,
4662 const AbstractAttribute &QueryingAA) {
4663
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004664 const IRPosition &IRP = QueryingAA.getIRPosition();
4665 // Since we need to provide return instructions we have to have an exact
4666 // definition.
4667 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004668 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004669 return false;
4670
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004671 // If this is a call site query we use the call site specific return values
4672 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004673 // TODO: use the function scope once we have call site AAReturnedValues.
4674 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004675 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004676 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004677 return false;
4678
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004679 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00004680}
4681
4682bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004683 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00004684 const AbstractAttribute &QueryingAA) {
4685
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004686 const IRPosition &IRP = QueryingAA.getIRPosition();
4687 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004688 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004689 return false;
4690
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004691 // TODO: use the function scope once we have call site AAReturnedValues.
4692 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004693 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004694 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004695 return false;
4696
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004697 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004698 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00004699 return Pred(RV);
4700 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00004701}
4702
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004703static bool
4704checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
4705 const function_ref<bool(Instruction &)> &Pred,
4706 const AAIsDead *LivenessAA, bool &AnyDead,
4707 const ArrayRef<unsigned> &Opcodes) {
4708 for (unsigned Opcode : Opcodes) {
4709 for (Instruction *I : OpcodeInstMap[Opcode]) {
4710 // Skip dead instructions.
4711 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
4712 AnyDead = true;
4713 continue;
4714 }
4715
4716 if (!Pred(*I))
4717 return false;
4718 }
4719 }
4720 return true;
4721}
4722
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004723bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004724 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004725 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004726
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004727 const IRPosition &IRP = QueryingAA.getIRPosition();
4728 // Since we need to provide instructions we have to have an exact definition.
4729 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004730 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004731 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004732
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004733 // TODO: use the function scope once we have call site AAReturnedValues.
4734 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004735 const auto &LivenessAA =
4736 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
4737 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004738
4739 auto &OpcodeInstMap =
4740 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004741 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
4742 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004743 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004744
Johannes Doerfert19b00432019-08-26 17:48:05 +00004745 // If we actually used liveness information so we have to record a dependence.
4746 if (AnyDead)
4747 recordDependence(LivenessAA, QueryingAA);
4748
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004749 return true;
4750}
4751
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004752bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004753 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004754 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004755
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004756 const Function *AssociatedFunction =
4757 QueryingAA.getIRPosition().getAssociatedFunction();
4758 if (!AssociatedFunction)
4759 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004760
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004761 // TODO: use the function scope once we have call site AAReturnedValues.
4762 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
4763 const auto &LivenessAA =
4764 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004765 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004766
4767 for (Instruction *I :
4768 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004769 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00004770 if (LivenessAA.isAssumedDead(I)) {
4771 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004772 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004773 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004774
4775 if (!Pred(*I))
4776 return false;
4777 }
4778
Johannes Doerfert19b00432019-08-26 17:48:05 +00004779 // If we actually used liveness information so we have to record a dependence.
4780 if (AnyDead)
4781 recordDependence(LivenessAA, QueryingAA);
4782
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004783 return true;
4784}
4785
Johannes Doerfert2f622062019-09-04 16:35:20 +00004786ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004787 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
4788 << AllAbstractAttributes.size()
4789 << " abstract attributes.\n");
4790
Stefan Stipanovic53605892019-06-27 11:27:54 +00004791 // Now that all abstract attributes are collected and initialized we start
4792 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00004793
4794 unsigned IterationCounter = 1;
4795
4796 SmallVector<AbstractAttribute *, 64> ChangedAAs;
4797 SetVector<AbstractAttribute *> Worklist;
4798 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
4799
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004800 bool RecomputeDependences = false;
4801
Johannes Doerfertaade7822019-06-05 03:02:24 +00004802 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004803 // Remember the size to determine new attributes.
4804 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004805 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
4806 << ", Worklist size: " << Worklist.size() << "\n");
4807
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004808 // If dependences (=QueryMap) are recomputed we have to look at all abstract
4809 // attributes again, regardless of what changed in the last iteration.
4810 if (RecomputeDependences) {
4811 LLVM_DEBUG(
4812 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
4813 QueryMap.clear();
4814 ChangedAAs.clear();
4815 Worklist.insert(AllAbstractAttributes.begin(),
4816 AllAbstractAttributes.end());
4817 }
4818
Johannes Doerfertaade7822019-06-05 03:02:24 +00004819 // Add all abstract attributes that are potentially dependent on one that
4820 // changed to the work list.
4821 for (AbstractAttribute *ChangedAA : ChangedAAs) {
4822 auto &QuerriedAAs = QueryMap[ChangedAA];
4823 Worklist.insert(QuerriedAAs.begin(), QuerriedAAs.end());
4824 }
4825
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004826 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
4827 << ", Worklist+Dependent size: " << Worklist.size()
4828 << "\n");
4829
Johannes Doerfertaade7822019-06-05 03:02:24 +00004830 // Reset the changed set.
4831 ChangedAAs.clear();
4832
4833 // Update all abstract attribute in the work list and record the ones that
4834 // changed.
4835 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert2dad7292019-10-13 21:10:31 -05004836 if (!AA->getState().isAtFixpoint() && !isAssumedDead(*AA, nullptr)) {
4837 QueriedNonFixAA = false;
4838 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004839 ChangedAAs.push_back(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05004840 } else if (!QueriedNonFixAA) {
4841 // If the attribute did not query any non-fix information, the state
4842 // will not change and we can indicate that right away.
4843 AA->getState().indicateOptimisticFixpoint();
4844 }
4845 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00004846
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004847 // Check if we recompute the dependences in the next iteration.
4848 RecomputeDependences = (DepRecomputeInterval > 0 &&
4849 IterationCounter % DepRecomputeInterval == 0);
4850
Johannes Doerfert9543f142019-08-23 15:24:57 +00004851 // Add attributes to the changed set if they have been created in the last
4852 // iteration.
4853 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
4854 AllAbstractAttributes.end());
4855
Johannes Doerfertaade7822019-06-05 03:02:24 +00004856 // Reset the work list and repopulate with the changed abstract attributes.
4857 // Note that dependent ones are added above.
4858 Worklist.clear();
4859 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
4860
Johannes Doerfertbf112132019-08-29 01:29:44 +00004861 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
4862 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004863
Johannes Doerfertaade7822019-06-05 03:02:24 +00004864 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
4865 << IterationCounter << "/" << MaxFixpointIterations
4866 << " iterations\n");
4867
Johannes Doerfertbf112132019-08-29 01:29:44 +00004868 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004869
Johannes Doerfertaade7822019-06-05 03:02:24 +00004870 // Reset abstract arguments not settled in a sound fixpoint by now. This
4871 // happens when we stopped the fixpoint iteration early. Note that only the
4872 // ones marked as "changed" *and* the ones transitively depending on them
4873 // need to be reverted to a pessimistic state. Others might not be in a
4874 // fixpoint state but we can use the optimistic results for them anyway.
4875 SmallPtrSet<AbstractAttribute *, 32> Visited;
4876 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
4877 AbstractAttribute *ChangedAA = ChangedAAs[u];
4878 if (!Visited.insert(ChangedAA).second)
4879 continue;
4880
4881 AbstractState &State = ChangedAA->getState();
4882 if (!State.isAtFixpoint()) {
4883 State.indicatePessimisticFixpoint();
4884
4885 NumAttributesTimedOut++;
4886 }
4887
4888 auto &QuerriedAAs = QueryMap[ChangedAA];
4889 ChangedAAs.append(QuerriedAAs.begin(), QuerriedAAs.end());
4890 }
4891
4892 LLVM_DEBUG({
4893 if (!Visited.empty())
4894 dbgs() << "\n[Attributor] Finalized " << Visited.size()
4895 << " abstract attributes.\n";
4896 });
4897
4898 unsigned NumManifested = 0;
4899 unsigned NumAtFixpoint = 0;
4900 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
4901 for (AbstractAttribute *AA : AllAbstractAttributes) {
4902 AbstractState &State = AA->getState();
4903
4904 // If there is not already a fixpoint reached, we can now take the
4905 // optimistic state. This is correct because we enforced a pessimistic one
4906 // on abstract attributes that were transitively dependent on a changed one
4907 // already above.
4908 if (!State.isAtFixpoint())
4909 State.indicateOptimisticFixpoint();
4910
4911 // If the state is invalid, we do not try to manifest it.
4912 if (!State.isValidState())
4913 continue;
4914
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004915 // Skip dead code.
4916 if (isAssumedDead(*AA, nullptr))
4917 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004918 // Manifest the state and record if we changed the IR.
4919 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00004920 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
4921 AA->trackStatistics();
4922
Johannes Doerfertaade7822019-06-05 03:02:24 +00004923 ManifestChange = ManifestChange | LocalChange;
4924
4925 NumAtFixpoint++;
4926 NumManifested += (LocalChange == ChangeStatus::CHANGED);
4927 }
4928
4929 (void)NumManifested;
4930 (void)NumAtFixpoint;
4931 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
4932 << " arguments while " << NumAtFixpoint
4933 << " were in a valid fixpoint state\n");
4934
Johannes Doerfertaade7822019-06-05 03:02:24 +00004935 NumAttributesManifested += NumManifested;
4936 NumAttributesValidFixpoint += NumAtFixpoint;
4937
Fangrui Songf1826172019-08-20 07:21:43 +00004938 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004939 assert(
4940 NumFinalAAs == AllAbstractAttributes.size() &&
4941 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00004942
4943 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00004944 {
4945 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
4946 << ToBeDeletedFunctions.size() << " functions and "
4947 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004948 << ToBeDeletedInsts.size() << " instructions and "
4949 << ToBeChangedUses.size() << " uses\n");
4950
4951 SmallVector<Instruction *, 32> DeadInsts;
4952 SmallVector<Instruction *, 32> TerminatorsToFold;
4953 SmallVector<Instruction *, 32> UnreachablesToInsert;
4954
4955 for (auto &It : ToBeChangedUses) {
4956 Use *U = It.first;
4957 Value *NewV = It.second;
4958 Value *OldV = U->get();
4959 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
4960 << " instead of " << *OldV << "\n");
4961 U->set(NewV);
4962 if (Instruction *I = dyn_cast<Instruction>(OldV))
4963 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) && isInstructionTriviallyDead(I)) {
4964 DeadInsts.push_back(I);
4965 }
4966 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
4967 Instruction *UserI = cast<Instruction>(U->getUser());
4968 if (isa<UndefValue>(NewV)) {
4969 UnreachablesToInsert.push_back(UserI);
4970 } else {
4971 TerminatorsToFold.push_back(UserI);
4972 }
4973 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00004974 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004975 for (Instruction *I : UnreachablesToInsert)
4976 changeToUnreachable(I, /* UseLLVMTrap */ false);
4977 for (Instruction *I : TerminatorsToFold)
4978 ConstantFoldTerminator(I->getParent());
4979
4980 for (Instruction *I : ToBeDeletedInsts) {
4981 I->replaceAllUsesWith(UndefValue::get(I->getType()));
4982 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
4983 DeadInsts.push_back(I);
4984 else
4985 I->eraseFromParent();
4986 }
4987
4988 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00004989
Johannes Doerfert2f622062019-09-04 16:35:20 +00004990 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
4991 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
4992 ToBeDeletedBBs.reserve(NumDeadBlocks);
4993 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
Johannes Doerfert5e442a52019-10-30 17:34:59 -05004994 // Actually we do not delete the blocks but squash them into a single
4995 // unreachable but untangling branches that jump here is something we need
4996 // to do in a more generic way.
4997 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
4998 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4999 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00005000 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00005001
Johannes Doerfert2f622062019-09-04 16:35:20 +00005002 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
5003 for (Function *Fn : ToBeDeletedFunctions) {
5004 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
5005 Fn->eraseFromParent();
5006 STATS_TRACK(AAIsDead, Function);
5007 }
5008
5009 // Identify dead internal functions and delete them. This happens outside
5010 // the other fixpoint analysis as we might treat potentially dead functions
5011 // as live to lower the number of iterations. If they happen to be dead, the
5012 // below fixpoint loop will identify and eliminate them.
5013 SmallVector<Function *, 8> InternalFns;
5014 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00005015 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00005016 InternalFns.push_back(&F);
5017
5018 bool FoundDeadFn = true;
5019 while (FoundDeadFn) {
5020 FoundDeadFn = false;
5021 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
5022 Function *F = InternalFns[u];
5023 if (!F)
5024 continue;
5025
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005026 if (!checkForAllCallSites([](AbstractCallSite ACS) { return false; },
5027 *F, true, nullptr))
Johannes Doerfert2f622062019-09-04 16:35:20 +00005028 continue;
5029
5030 STATS_TRACK(AAIsDead, Function);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005031 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00005032 F->replaceAllUsesWith(UndefValue::get(F->getType()));
5033 F->eraseFromParent();
5034 InternalFns[u] = nullptr;
5035 FoundDeadFn = true;
5036 }
5037 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00005038 }
5039
Johannes Doerfertbf112132019-08-29 01:29:44 +00005040 if (VerifyMaxFixpointIterations &&
5041 IterationCounter != MaxFixpointIterations) {
5042 errs() << "\n[Attributor] Fixpoint iteration done after: "
5043 << IterationCounter << "/" << MaxFixpointIterations
5044 << " iterations\n";
5045 llvm_unreachable("The fixpoint was not reached with exactly the number of "
5046 "specified iterations!");
5047 }
5048
Johannes Doerfertaade7822019-06-05 03:02:24 +00005049 return ManifestChange;
5050}
5051
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005052void Attributor::initializeInformationCache(Function &F) {
5053
5054 // Walk all instructions to find interesting instructions that might be
5055 // queried by abstract attributes during their initialization or update.
5056 // This has to happen before we create attributes.
5057 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
5058 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
5059
5060 for (Instruction &I : instructions(&F)) {
5061 bool IsInterestingOpcode = false;
5062
5063 // To allow easy access to all instructions in a function with a given
5064 // opcode we store them in the InfoCache. As not all opcodes are interesting
5065 // to concrete attributes we only cache the ones that are as identified in
5066 // the following switch.
5067 // Note: There are no concrete attributes now so this is initially empty.
5068 switch (I.getOpcode()) {
5069 default:
5070 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
5071 "New call site/base instruction type needs to be known int the "
5072 "Attributor.");
5073 break;
5074 case Instruction::Load:
5075 // The alignment of a pointer is interesting for loads.
5076 case Instruction::Store:
5077 // The alignment of a pointer is interesting for stores.
5078 case Instruction::Call:
5079 case Instruction::CallBr:
5080 case Instruction::Invoke:
5081 case Instruction::CleanupRet:
5082 case Instruction::CatchSwitch:
5083 case Instruction::Resume:
5084 case Instruction::Ret:
5085 IsInterestingOpcode = true;
5086 }
5087 if (IsInterestingOpcode)
5088 InstOpcodeMap[I.getOpcode()].push_back(&I);
5089 if (I.mayReadOrWriteMemory())
5090 ReadOrWriteInsts.push_back(&I);
5091 }
5092}
5093
Johannes Doerfert12173e62019-10-13 20:25:25 -05005094void Attributor::recordDependence(const AbstractAttribute &FromAA,
5095 const AbstractAttribute &ToAA) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005096 if (FromAA.getState().isAtFixpoint())
5097 return;
5098
5099 QueryMap[&FromAA].insert(const_cast<AbstractAttribute *>(&ToAA));
5100 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05005101}
5102
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005103void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00005104 if (!VisitedFunctions.insert(&F).second)
5105 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05005106 if (F.isDeclaration())
5107 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005108
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005109 IRPosition FPos = IRPosition::function(F);
5110
Johannes Doerfert305b9612019-08-04 18:40:01 +00005111 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00005112 // We need dead instruction detection because we do not want to deal with
5113 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005114 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00005115
5116 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005117 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00005118
Stefan Stipanovic53605892019-06-27 11:27:54 +00005119 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005120 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00005121
Stefan Stipanovic06263672019-07-11 21:37:40 +00005122 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005123 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00005124
Hideto Ueno65bbaf92019-07-12 17:38:51 +00005125 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005126 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00005127
Johannes Doerferte83f3032019-08-05 23:22:05 +00005128 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005129 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00005130
Hideto Ueno63f60662019-09-21 15:13:19 +00005131 // Every function might be "no-recurse".
5132 getOrCreateAAFor<AANoRecurse>(FPos);
5133
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005134 // Every function might be "readnone/readonly/writeonly/...".
5135 getOrCreateAAFor<AAMemoryBehavior>(FPos);
5136
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005137 // Every function might be applicable for Heap-To-Stack conversion.
5138 if (EnableHeapToStack)
5139 getOrCreateAAFor<AAHeapToStack>(FPos);
5140
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00005141 // Return attributes are only appropriate if the return type is non void.
5142 Type *ReturnType = F.getReturnType();
5143 if (!ReturnType->isVoidTy()) {
5144 // Argument attribute "returned" --- Create only one per function even
5145 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005146 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00005147
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005148 IRPosition RetPos = IRPosition::returned(F);
5149
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005150 // Every returned value might be dead.
5151 getOrCreateAAFor<AAIsDead>(RetPos);
5152
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005153 // Every function might be simplified.
5154 getOrCreateAAFor<AAValueSimplify>(RetPos);
5155
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005156 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005157
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005158 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005159 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005160
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005161 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005162 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005163
5164 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005165 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005166
5167 // Every function with pointer return type might be marked
5168 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005169 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005170 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00005171 }
5172
Hideto Ueno54869ec2019-07-15 06:49:04 +00005173 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005174 IRPosition ArgPos = IRPosition::argument(Arg);
5175
5176 // Every argument might be simplified.
5177 getOrCreateAAFor<AAValueSimplify>(ArgPos);
5178
Hideto Ueno19c07af2019-07-23 08:16:17 +00005179 if (Arg.getType()->isPointerTy()) {
5180 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005181 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005182
Hideto Uenocbab3342019-08-29 05:52:00 +00005183 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005184 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00005185
Hideto Ueno19c07af2019-07-23 08:16:17 +00005186 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005187 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005188
5189 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005190 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005191
5192 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005193 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005194
5195 // Every argument with pointer type might be marked
5196 // "readnone/readonly/writeonly/..."
5197 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005198 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00005199 }
5200
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005201 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005202 CallSite CS(&I);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005203 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05005204 // Skip declerations except if annotations on their call sites were
5205 // explicitly requested.
5206 if (!AnnotateDeclarationCallSites && Callee->isDeclaration())
5207 return true;
5208
5209 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005210 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
5211
5212 // Call site return values might be dead.
5213 getOrCreateAAFor<AAIsDead>(CSRetPos);
5214 }
5215
5216 for (int i = 0, e = Callee->arg_size(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005217
5218 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
5219
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005220 // Every call site argument might be dead.
5221 getOrCreateAAFor<AAIsDead>(CSArgPos);
5222
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005223 // Call site argument might be simplified.
5224 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
5225
Hideto Ueno54869ec2019-07-15 06:49:04 +00005226 if (!CS.getArgument(i)->getType()->isPointerTy())
5227 continue;
5228
5229 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005230 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005231
Hideto Uenocbab3342019-08-29 05:52:00 +00005232 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005233 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00005234
Hideto Ueno19c07af2019-07-23 08:16:17 +00005235 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005236 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005237
5238 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005239 getOrCreateAAFor<AAAlign>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00005240 }
5241 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005242 return true;
5243 };
5244
5245 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
5246 bool Success, AnyDead = false;
5247 Success = checkForAllInstructionsImpl(
5248 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
5249 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
5250 (unsigned)Instruction::Call});
5251 (void)Success;
5252 assert(Success && !AnyDead && "Expected the check call to be successful!");
5253
5254 auto LoadStorePred = [&](Instruction &I) -> bool {
5255 if (isa<LoadInst>(I))
5256 getOrCreateAAFor<AAAlign>(
5257 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
5258 else
5259 getOrCreateAAFor<AAAlign>(
5260 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
5261 return true;
5262 };
5263 Success = checkForAllInstructionsImpl(
5264 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
5265 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
5266 (void)Success;
5267 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00005268}
5269
5270/// Helpers to ease debugging through output streams and print calls.
5271///
5272///{
5273raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
5274 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
5275}
5276
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005277raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005278 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005279 case IRPosition::IRP_INVALID:
5280 return OS << "inv";
5281 case IRPosition::IRP_FLOAT:
5282 return OS << "flt";
5283 case IRPosition::IRP_RETURNED:
5284 return OS << "fn_ret";
5285 case IRPosition::IRP_CALL_SITE_RETURNED:
5286 return OS << "cs_ret";
5287 case IRPosition::IRP_FUNCTION:
5288 return OS << "fn";
5289 case IRPosition::IRP_CALL_SITE:
5290 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005291 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00005292 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005293 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00005294 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00005295 }
5296 llvm_unreachable("Unknown attribute position!");
5297}
5298
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005299raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005300 const Value &AV = Pos.getAssociatedValue();
5301 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005302 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
5303}
5304
Johannes Doerfert1a746452019-10-20 22:28:49 -05005305template <typename base_ty, base_ty BestState, base_ty WorstState>
5306raw_ostream &llvm::
5307operator<<(raw_ostream &OS,
5308 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00005309 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
5310 << static_cast<const AbstractState &>(S);
5311}
5312
Johannes Doerfertaade7822019-06-05 03:02:24 +00005313raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
5314 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
5315}
5316
5317raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
5318 AA.print(OS);
5319 return OS;
5320}
5321
5322void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005323 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
5324 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00005325}
5326///}
5327
5328/// ----------------------------------------------------------------------------
5329/// Pass (Manager) Boilerplate
5330/// ----------------------------------------------------------------------------
5331
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005332static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005333 if (DisableAttributor)
5334 return false;
5335
5336 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
5337 << " functions.\n");
5338
5339 // Create an Attributor and initially empty information cache that is filled
5340 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00005341 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005342 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005343
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005344 for (Function &F : M)
5345 A.initializeInformationCache(F);
5346
Johannes Doerfertaade7822019-06-05 03:02:24 +00005347 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005348 if (F.hasExactDefinition())
5349 NumFnWithExactDefinition++;
5350 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00005351 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005352
Johannes Doerfert2f622062019-09-04 16:35:20 +00005353 // We look at internal functions only on-demand but if any use is not a
5354 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00005355 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00005356 if (llvm::all_of(F.uses(), [](const Use &U) {
5357 return ImmutableCallSite(U.getUser()) &&
5358 ImmutableCallSite(U.getUser()).isCallee(&U);
5359 }))
5360 continue;
5361 }
5362
Johannes Doerfertaade7822019-06-05 03:02:24 +00005363 // Populate the Attributor with abstract attribute opportunities in the
5364 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005365 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005366 }
5367
Johannes Doerfert2f622062019-09-04 16:35:20 +00005368 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005369}
5370
5371PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00005372 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005373 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005374 // FIXME: Think about passes we will preserve and add them here.
5375 return PreservedAnalyses::none();
5376 }
5377 return PreservedAnalyses::all();
5378}
5379
5380namespace {
5381
5382struct AttributorLegacyPass : public ModulePass {
5383 static char ID;
5384
5385 AttributorLegacyPass() : ModulePass(ID) {
5386 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
5387 }
5388
5389 bool runOnModule(Module &M) override {
5390 if (skipModule(M))
5391 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005392
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005393 AnalysisGetter AG;
5394 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005395 }
5396
5397 void getAnalysisUsage(AnalysisUsage &AU) const override {
5398 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005399 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005400 }
5401};
5402
5403} // end anonymous namespace
5404
5405Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
5406
5407char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005408
5409const char AAReturnedValues::ID = 0;
5410const char AANoUnwind::ID = 0;
5411const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00005412const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005413const char AANonNull::ID = 0;
5414const char AANoRecurse::ID = 0;
5415const char AAWillReturn::ID = 0;
5416const char AANoAlias::ID = 0;
5417const char AANoReturn::ID = 0;
5418const char AAIsDead::ID = 0;
5419const char AADereferenceable::ID = 0;
5420const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005421const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005422const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005423const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005424const char AAMemoryBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005425
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005426// Macro magic to create the static generator function for attributes that
5427// follow the naming scheme.
5428
5429#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
5430 case IRPosition::PK: \
5431 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
5432
5433#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
5434 case IRPosition::PK: \
5435 AA = new CLASS##SUFFIX(IRP); \
5436 break;
5437
5438#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5439 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5440 CLASS *AA = nullptr; \
5441 switch (IRP.getPositionKind()) { \
5442 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5443 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5444 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5445 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5446 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5447 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5448 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5449 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5450 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005451 return *AA; \
5452 }
5453
5454#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5455 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5456 CLASS *AA = nullptr; \
5457 switch (IRP.getPositionKind()) { \
5458 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5459 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
5460 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5461 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5462 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5463 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5464 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5465 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5466 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005467 return *AA; \
5468 }
5469
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005470#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5471 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5472 CLASS *AA = nullptr; \
5473 switch (IRP.getPositionKind()) { \
5474 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5475 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5476 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5477 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5478 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5479 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5480 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5481 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5482 } \
5483 return *AA; \
5484 }
5485
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005486#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5487 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5488 CLASS *AA = nullptr; \
5489 switch (IRP.getPositionKind()) { \
5490 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5491 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5492 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5493 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5494 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5495 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5496 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5497 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5498 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005499 return *AA; \
5500 }
5501
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005502#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5503 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5504 CLASS *AA = nullptr; \
5505 switch (IRP.getPositionKind()) { \
5506 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5507 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5508 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5509 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5510 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5511 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5512 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5513 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5514 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005515 return *AA; \
5516 }
5517
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005518CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
5519CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
5520CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
5521CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
5522CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
5523CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005524CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
5525
5526CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
5527CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
5528CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
5529CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005530CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005531
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005532CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005533CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005534
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005535CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
5536
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005537CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
5538
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005539#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005540#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005541#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005542#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005543#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005544#undef SWITCH_PK_CREATE
5545#undef SWITCH_PK_INV
5546
Johannes Doerfertaade7822019-06-05 03:02:24 +00005547INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
5548 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005549INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00005550INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
5551 "Deduce and propagate attributes", false, false)