blob: 95f47345d8fd06eba5839f4543643d2512b93bdc [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 Doerfert7516a5e2019-09-03 20:37:24 +0000123static cl::opt<bool> ManifestInternal(
124 "attributor-manifest-internal", cl::Hidden,
125 cl::desc("Manifest Attributor internal string attributes."),
126 cl::init(false));
127
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000128static cl::opt<unsigned> DepRecInterval(
129 "attributor-dependence-recompute-interval", cl::Hidden,
130 cl::desc("Number of iterations until dependences are recomputed."),
131 cl::init(4));
132
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000133static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
134 cl::init(true), cl::Hidden);
135
Johannes Doerfert1c2afae2019-10-10 05:34:21 +0000136static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
137 cl::Hidden);
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000138
Johannes Doerfertaade7822019-06-05 03:02:24 +0000139/// Logic operators for the change status enum class.
140///
141///{
142ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
143 return l == ChangeStatus::CHANGED ? l : r;
144}
145ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
146 return l == ChangeStatus::UNCHANGED ? l : r;
147}
148///}
149
Johannes Doerfertdef99282019-08-14 21:29:37 +0000150/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000151/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000152/// with the "returned" attribute. Once we cannot look through the value any
153/// further, the callback \p VisitValueCB is invoked and passed the current
154/// value, the \p State, and a flag to indicate if we stripped anything. To
155/// limit how much effort is invested, we will never visit more values than
156/// specified by \p MaxValues.
157template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000158static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000159 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000160 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000161 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000162
Johannes Doerfertdef99282019-08-14 21:29:37 +0000163 const AAIsDead *LivenessAA = nullptr;
164 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000165 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000166 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
167 /* TrackDependence */ false);
168 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000169
170 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000171 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000172 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000173 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000174
175 int Iteration = 0;
176 do {
177 Value *V = Worklist.pop_back_val();
178
179 // Check if we should process the current value. To prevent endless
180 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000181 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000182 continue;
183
184 // Make sure we limit the compile time for complex expressions.
185 if (Iteration++ >= MaxValues)
186 return false;
187
188 // Explicitly look through calls with a "returned" attribute if we do
189 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000190 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000191 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000192 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000193 } else {
194 CallSite CS(V);
195 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000196 for (Argument &Arg : CS.getCalledFunction()->args())
197 if (Arg.hasReturnedAttr()) {
198 NewV = CS.getArgOperand(Arg.getArgNo());
199 break;
200 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000201 }
202 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000203 if (NewV && NewV != V) {
204 Worklist.push_back(NewV);
205 continue;
206 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000207
208 // Look through select instructions, visit both potential values.
209 if (auto *SI = dyn_cast<SelectInst>(V)) {
210 Worklist.push_back(SI->getTrueValue());
211 Worklist.push_back(SI->getFalseValue());
212 continue;
213 }
214
Johannes Doerfertdef99282019-08-14 21:29:37 +0000215 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000216 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000217 assert(LivenessAA &&
218 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000219 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
220 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000221 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000222 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000223 continue;
224 }
225 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000226 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000227 continue;
228 }
229
230 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000231 if (!VisitValueCB(*V, State, Iteration > 1))
232 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000233 } while (!Worklist.empty());
234
Johannes Doerfert19b00432019-08-26 17:48:05 +0000235 // If we actually used liveness information so we have to record a dependence.
236 if (AnyDead)
237 A.recordDependence(*LivenessAA, QueryingAA);
238
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000239 // All values have been visited.
240 return true;
241}
242
Johannes Doerfertaade7822019-06-05 03:02:24 +0000243/// Return true if \p New is equal or worse than \p Old.
244static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
245 if (!Old.isIntAttribute())
246 return true;
247
248 return Old.getValueAsInt() >= New.getValueAsInt();
249}
250
251/// Return true if the information provided by \p Attr was added to the
252/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000253/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000254static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000255 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000256
257 if (Attr.isEnumAttribute()) {
258 Attribute::AttrKind Kind = Attr.getKindAsEnum();
259 if (Attrs.hasAttribute(AttrIdx, Kind))
260 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
261 return false;
262 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
263 return true;
264 }
265 if (Attr.isStringAttribute()) {
266 StringRef Kind = Attr.getKindAsString();
267 if (Attrs.hasAttribute(AttrIdx, Kind))
268 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
269 return false;
270 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
271 return true;
272 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000273 if (Attr.isIntAttribute()) {
274 Attribute::AttrKind Kind = Attr.getKindAsEnum();
275 if (Attrs.hasAttribute(AttrIdx, Kind))
276 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
277 return false;
278 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
279 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
280 return true;
281 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000282
283 llvm_unreachable("Expected enum or string attribute!");
284}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000285static const Value *getPointerOperand(const Instruction *I) {
286 if (auto *LI = dyn_cast<LoadInst>(I))
287 if (!LI->isVolatile())
288 return LI->getPointerOperand();
289
290 if (auto *SI = dyn_cast<StoreInst>(I))
291 if (!SI->isVolatile())
292 return SI->getPointerOperand();
293
294 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I))
295 if (!CXI->isVolatile())
296 return CXI->getPointerOperand();
297
298 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I))
299 if (!RMWI->isVolatile())
300 return RMWI->getPointerOperand();
301
302 return nullptr;
303}
304static const Value *getBasePointerOfAccessPointerOperand(const Instruction *I,
305 int64_t &BytesOffset,
306 const DataLayout &DL) {
307 const Value *Ptr = getPointerOperand(I);
308 if (!Ptr)
309 return nullptr;
310
311 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
312 /*AllowNonInbounds*/ false);
313}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000314
Johannes Doerfertece81902019-08-12 22:05:53 +0000315ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000316 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
317 if (getState().isAtFixpoint())
318 return HasChanged;
319
320 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
321
Johannes Doerfertece81902019-08-12 22:05:53 +0000322 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000323
324 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
325 << "\n");
326
327 return HasChanged;
328}
329
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000330ChangeStatus
331IRAttributeManifest::manifestAttrs(Attributor &A, IRPosition &IRP,
332 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000333 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000334 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000335
Johannes Doerfertaade7822019-06-05 03:02:24 +0000336 // In the following some generic code that will manifest attributes in
337 // DeducedAttrs if they improve the current IR. Due to the different
338 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000339
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000340 AttributeList Attrs;
341 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000342 case IRPosition::IRP_INVALID:
343 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000344 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000345 case IRPosition::IRP_ARGUMENT:
346 case IRPosition::IRP_FUNCTION:
347 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000348 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000349 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000350 case IRPosition::IRP_CALL_SITE:
351 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000352 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000353 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000354 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000355 }
356
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000357 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000358 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000359 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000360 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000361 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000362
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000363 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000364 }
365
366 if (HasChanged == ChangeStatus::UNCHANGED)
367 return HasChanged;
368
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000369 switch (PK) {
370 case IRPosition::IRP_ARGUMENT:
371 case IRPosition::IRP_FUNCTION:
372 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000373 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000374 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000375 case IRPosition::IRP_CALL_SITE:
376 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000377 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000378 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000379 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000380 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000381 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000382 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000383 }
384
385 return HasChanged;
386}
387
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000388const IRPosition IRPosition::EmptyKey(255);
389const IRPosition IRPosition::TombstoneKey(256);
390
391SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
392 IRPositions.emplace_back(IRP);
393
394 ImmutableCallSite ICS(&IRP.getAnchorValue());
395 switch (IRP.getPositionKind()) {
396 case IRPosition::IRP_INVALID:
397 case IRPosition::IRP_FLOAT:
398 case IRPosition::IRP_FUNCTION:
399 return;
400 case IRPosition::IRP_ARGUMENT:
401 case IRPosition::IRP_RETURNED:
402 IRPositions.emplace_back(
403 IRPosition::function(*IRP.getAssociatedFunction()));
404 return;
405 case IRPosition::IRP_CALL_SITE:
406 assert(ICS && "Expected call site!");
407 // TODO: We need to look at the operand bundles similar to the redirection
408 // in CallBase.
409 if (!ICS.hasOperandBundles())
410 if (const Function *Callee = ICS.getCalledFunction())
411 IRPositions.emplace_back(IRPosition::function(*Callee));
412 return;
413 case IRPosition::IRP_CALL_SITE_RETURNED:
414 assert(ICS && "Expected call site!");
415 // TODO: We need to look at the operand bundles similar to the redirection
416 // in CallBase.
417 if (!ICS.hasOperandBundles()) {
418 if (const Function *Callee = ICS.getCalledFunction()) {
419 IRPositions.emplace_back(IRPosition::returned(*Callee));
420 IRPositions.emplace_back(IRPosition::function(*Callee));
421 }
422 }
423 IRPositions.emplace_back(
424 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
425 return;
426 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
427 int ArgNo = IRP.getArgNo();
428 assert(ICS && ArgNo >= 0 && "Expected call site!");
429 // TODO: We need to look at the operand bundles similar to the redirection
430 // in CallBase.
431 if (!ICS.hasOperandBundles()) {
432 const Function *Callee = ICS.getCalledFunction();
433 if (Callee && Callee->arg_size() > unsigned(ArgNo))
434 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
435 if (Callee)
436 IRPositions.emplace_back(IRPosition::function(*Callee));
437 }
438 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
439 return;
440 }
441 }
442}
443
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000444bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
445 bool IgnoreSubsumingPositions) const {
446 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000447 for (Attribute::AttrKind AK : AKs)
448 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
449 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000450 // The first position returned by the SubsumingPositionIterator is
451 // always the position itself. If we ignore subsuming positions we
452 // are done after the first iteration.
453 if (IgnoreSubsumingPositions)
454 break;
455 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000456 return false;
457}
458
459void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
460 SmallVectorImpl<Attribute> &Attrs) const {
461 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this))
462 for (Attribute::AttrKind AK : AKs) {
463 const Attribute &Attr = EquivIRP.getAttr(AK);
464 if (Attr.getKindAsEnum() == AK)
465 Attrs.push_back(Attr);
466 }
467}
468
469void IRPosition::verify() {
470 switch (KindOrArgNo) {
471 default:
472 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
473 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
474 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000475 if (isa<Argument>(AnchorVal)) {
476 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000477 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000478 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
479 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000480 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000481 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000482 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000483 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
484 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000485 "Associated value mismatch!");
486 }
487 break;
488 case IRP_INVALID:
489 assert(!AnchorVal && "Expected no value for an invalid position!");
490 break;
491 case IRP_FLOAT:
492 assert((!isa<CallBase>(&getAssociatedValue()) &&
493 !isa<Argument>(&getAssociatedValue())) &&
494 "Expected specialized kind for call base and argument values!");
495 break;
496 case IRP_RETURNED:
497 assert(isa<Function>(AnchorVal) &&
498 "Expected function for a 'returned' position!");
499 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
500 break;
501 case IRP_CALL_SITE_RETURNED:
502 assert((isa<CallBase>(AnchorVal)) &&
503 "Expected call base for 'call site returned' position!");
504 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
505 break;
506 case IRP_CALL_SITE:
507 assert((isa<CallBase>(AnchorVal)) &&
508 "Expected call base for 'call site function' position!");
509 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
510 break;
511 case IRP_FUNCTION:
512 assert(isa<Function>(AnchorVal) &&
513 "Expected function for a 'function' position!");
514 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
515 break;
516 }
517}
518
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000519namespace {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000520/// Helper functions to clamp a state \p S of type \p StateType with the
521/// information in \p R and indicate/return if \p S did change (as-in update is
522/// required to be run again).
523///
524///{
525template <typename StateType>
526ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R);
527
528template <>
529ChangeStatus clampStateAndIndicateChange<IntegerState>(IntegerState &S,
530 const IntegerState &R) {
531 auto Assumed = S.getAssumed();
532 S ^= R;
533 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
534 : ChangeStatus::CHANGED;
535}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000536
537template <>
538ChangeStatus clampStateAndIndicateChange<BooleanState>(BooleanState &S,
539 const BooleanState &R) {
540 return clampStateAndIndicateChange<IntegerState>(S, R);
541}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000542///}
543
544/// Clamp the information known for all returned values of a function
545/// (identified by \p QueryingAA) into \p S.
546template <typename AAType, typename StateType = typename AAType::StateType>
547static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
548 StateType &S) {
549 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
550 << static_cast<const AbstractAttribute &>(QueryingAA)
551 << " into " << S << "\n");
552
553 assert((QueryingAA.getIRPosition().getPositionKind() ==
554 IRPosition::IRP_RETURNED ||
555 QueryingAA.getIRPosition().getPositionKind() ==
556 IRPosition::IRP_CALL_SITE_RETURNED) &&
557 "Can only clamp returned value states for a function returned or call "
558 "site returned position!");
559
560 // Use an optional state as there might not be any return values and we want
561 // to join (IntegerState::operator&) the state of all there are.
562 Optional<StateType> T;
563
564 // Callback for each possibly returned value.
565 auto CheckReturnValue = [&](Value &RV) -> bool {
566 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000567 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
568 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
569 << " @ " << RVPos << "\n");
570 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000571 if (T.hasValue())
572 *T &= AAS;
573 else
574 T = AAS;
575 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
576 << "\n");
577 return T->isValidState();
578 };
579
580 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
581 S.indicatePessimisticFixpoint();
582 else if (T.hasValue())
583 S ^= *T;
584}
585
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000586/// Helper class to compose two generic deduction
587template <typename AAType, typename Base, typename StateType,
588 template <typename...> class F, template <typename...> class G>
589struct AAComposeTwoGenericDeduction
590 : public F<AAType, G<AAType, Base, StateType>, StateType> {
591 AAComposeTwoGenericDeduction(const IRPosition &IRP)
592 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
593
594 /// See AbstractAttribute::updateImpl(...).
595 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000596 ChangeStatus ChangedF = F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
597 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
598 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000599 }
600};
601
Johannes Doerfert234eda52019-08-16 19:51:23 +0000602/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000603template <typename AAType, typename Base,
604 typename StateType = typename AAType::StateType>
605struct AAReturnedFromReturnedValues : public Base {
606 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000607
608 /// See AbstractAttribute::updateImpl(...).
609 ChangeStatus updateImpl(Attributor &A) override {
610 StateType S;
611 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000612 // TODO: If we know we visited all returned values, thus no are assumed
613 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000614 return clampStateAndIndicateChange<StateType>(this->getState(), S);
615 }
616};
617
618/// Clamp the information known at all call sites for a given argument
619/// (identified by \p QueryingAA) into \p S.
620template <typename AAType, typename StateType = typename AAType::StateType>
621static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
622 StateType &S) {
623 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
624 << static_cast<const AbstractAttribute &>(QueryingAA)
625 << " into " << S << "\n");
626
627 assert(QueryingAA.getIRPosition().getPositionKind() ==
628 IRPosition::IRP_ARGUMENT &&
629 "Can only clamp call site argument states for an argument position!");
630
631 // Use an optional state as there might not be any return values and we want
632 // to join (IntegerState::operator&) the state of all there are.
633 Optional<StateType> T;
634
635 // The argument number which is also the call site argument number.
636 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
637
Johannes Doerfert661db042019-10-07 23:14:58 +0000638 auto CallSiteCheck = [&](AbstractCallSite ACS) {
639 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
640 // Check if a coresponding argument was found or if it is on not associated
641 // (which can happen for callback calls).
642 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
643 return false;
644
645 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
646 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
647 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000648 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000649 if (T.hasValue())
650 *T &= AAS;
651 else
652 T = AAS;
653 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
654 << "\n");
655 return T->isValidState();
656 };
657
658 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true))
659 S.indicatePessimisticFixpoint();
660 else if (T.hasValue())
661 S ^= *T;
662}
663
664/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000665template <typename AAType, typename Base,
666 typename StateType = typename AAType::StateType>
667struct AAArgumentFromCallSiteArguments : public Base {
668 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000669
670 /// See AbstractAttribute::updateImpl(...).
671 ChangeStatus updateImpl(Attributor &A) override {
672 StateType S;
673 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000674 // TODO: If we know we visited all incoming values, thus no are assumed
675 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000676 return clampStateAndIndicateChange<StateType>(this->getState(), S);
677 }
678};
679
680/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000681template <typename AAType, typename Base,
682 typename StateType = typename AAType::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000683struct AACallSiteReturnedFromReturned : public Base {
684 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000685
686 /// See AbstractAttribute::updateImpl(...).
687 ChangeStatus updateImpl(Attributor &A) override {
688 assert(this->getIRPosition().getPositionKind() ==
689 IRPosition::IRP_CALL_SITE_RETURNED &&
690 "Can only wrap function returned positions for call site returned "
691 "positions!");
692 auto &S = this->getState();
693
694 const Function *AssociatedFunction =
695 this->getIRPosition().getAssociatedFunction();
696 if (!AssociatedFunction)
697 return S.indicatePessimisticFixpoint();
698
699 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000700 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000701 return clampStateAndIndicateChange(
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000702 S, static_cast<const typename AAType::StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000703 }
704};
705
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000706/// Helper class for generic deduction using must-be-executed-context
707/// Base class is required to have `followUse` method.
708
709/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000710/// U - Underlying use.
711/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000712/// `followUse` returns true if the value should be tracked transitively.
713
714template <typename AAType, typename Base,
715 typename StateType = typename AAType::StateType>
716struct AAFromMustBeExecutedContext : public Base {
717 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
718
719 void initialize(Attributor &A) override {
720 Base::initialize(A);
721 IRPosition &IRP = this->getIRPosition();
722 Instruction *CtxI = IRP.getCtxI();
723
724 if (!CtxI)
725 return;
726
727 for (const Use &U : IRP.getAssociatedValue().uses())
728 Uses.insert(&U);
729 }
730
731 /// See AbstractAttribute::updateImpl(...).
732 ChangeStatus updateImpl(Attributor &A) override {
733 auto BeforeState = this->getState();
734 auto &S = this->getState();
735 Instruction *CtxI = this->getIRPosition().getCtxI();
736 if (!CtxI)
737 return ChangeStatus::UNCHANGED;
738
739 MustBeExecutedContextExplorer &Explorer =
740 A.getInfoCache().getMustBeExecutedContextExplorer();
741
742 SetVector<const Use *> NextUses;
743
744 for (const Use *U : Uses) {
745 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
746 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
747 bool Found = EIt.count(UserI);
748 while (!Found && ++EIt != EEnd)
749 Found = EIt.getCurrentInst() == UserI;
750 if (Found && Base::followUse(A, U, UserI))
751 for (const Use &Us : UserI->uses())
752 NextUses.insert(&Us);
753 }
754 }
755 for (const Use *U : NextUses)
756 Uses.insert(U);
757
758 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
759 }
760
761private:
762 /// Container for (transitive) uses of the associated value.
763 SetVector<const Use *> Uses;
764};
765
766template <typename AAType, typename Base,
767 typename StateType = typename AAType::StateType>
768using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
769 AAComposeTwoGenericDeduction<AAType, Base, StateType,
770 AAFromMustBeExecutedContext,
771 AAArgumentFromCallSiteArguments>;
772
773template <typename AAType, typename Base,
774 typename StateType = typename AAType::StateType>
775using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
776 AAComposeTwoGenericDeduction<AAType, Base, StateType,
777 AAFromMustBeExecutedContext,
778 AACallSiteReturnedFromReturned>;
779
Stefan Stipanovic53605892019-06-27 11:27:54 +0000780/// -----------------------NoUnwind Function Attribute--------------------------
781
Johannes Doerfert344d0382019-08-07 22:34:26 +0000782struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000783 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000784
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000785 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000786 return getAssumed() ? "nounwind" : "may-unwind";
787 }
788
789 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000790 ChangeStatus updateImpl(Attributor &A) override {
791 auto Opcodes = {
792 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
793 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
794 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
795
796 auto CheckForNoUnwind = [&](Instruction &I) {
797 if (!I.mayThrow())
798 return true;
799
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000800 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
801 const auto &NoUnwindAA =
802 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
803 return NoUnwindAA.isAssumedNoUnwind();
804 }
805 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000806 };
807
808 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
809 return indicatePessimisticFixpoint();
810
811 return ChangeStatus::UNCHANGED;
812 }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000813};
814
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000815struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000816 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000817
818 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000819 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000820};
821
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000822/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000823struct AANoUnwindCallSite final : AANoUnwindImpl {
824 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
825
826 /// See AbstractAttribute::initialize(...).
827 void initialize(Attributor &A) override {
828 AANoUnwindImpl::initialize(A);
829 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000830 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000831 indicatePessimisticFixpoint();
832 }
833
834 /// See AbstractAttribute::updateImpl(...).
835 ChangeStatus updateImpl(Attributor &A) override {
836 // TODO: Once we have call site specific value information we can provide
837 // call site specific liveness information and then it makes
838 // sense to specialize attributes for call sites arguments instead of
839 // redirecting requests to the callee argument.
840 Function *F = getAssociatedFunction();
841 const IRPosition &FnPos = IRPosition::function(*F);
842 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
843 return clampStateAndIndicateChange(
844 getState(),
845 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
846 }
847
848 /// See AbstractAttribute::trackStatistics()
849 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
850};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000851
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000852/// --------------------- Function Return Values -------------------------------
853
854/// "Attribute" that collects all potential returned values and the return
855/// instructions that they arise from.
856///
857/// If there is a unique returned value R, the manifest method will:
858/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +0000859class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000860
861 /// Mapping of values potentially returned by the associated function to the
862 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +0000863 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000864
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000865 /// Mapping to remember the number of returned values for a call site such
866 /// that we can avoid updates if nothing changed.
867 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
868
869 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +0000870 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000871
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000872 /// State flags
873 ///
874 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000875 bool IsFixed = false;
876 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000877 ///}
878
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000879public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000880 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000881
882 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +0000883 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000884 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000885 IsFixed = false;
886 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000887 ReturnedValues.clear();
888
Johannes Doerfertdef99282019-08-14 21:29:37 +0000889 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000890 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000891 indicatePessimisticFixpoint();
892 return;
893 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000894
895 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000896 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000897
898 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000899 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000900 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000901 auto &ReturnInstSet = ReturnedValues[&Arg];
902 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
903 ReturnInstSet.insert(cast<ReturnInst>(RI));
904
905 indicateOptimisticFixpoint();
906 return;
907 }
908 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000909
910 if (!F->hasExactDefinition())
911 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000912 }
913
914 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000915 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000916
917 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000918 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000919
920 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000921 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000922
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000923 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +0000924 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000925
Johannes Doerfertdef99282019-08-14 21:29:37 +0000926 llvm::iterator_range<iterator> returned_values() override {
927 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
928 }
929
930 llvm::iterator_range<const_iterator> returned_values() const override {
931 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
932 }
933
Johannes Doerfert695089e2019-08-23 15:23:49 +0000934 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000935 return UnresolvedCalls;
936 }
937
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000938 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000939 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000940 return isValidState() ? ReturnedValues.size() : -1;
941 }
942
943 /// Return an assumed unique return value if a single candidate is found. If
944 /// there cannot be one, return a nullptr. If it is not clear yet, return the
945 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000946 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000947
Johannes Doerfert14a04932019-08-07 22:27:24 +0000948 /// See AbstractState::checkForAllReturnedValues(...).
949 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +0000950 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +0000951 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000952
953 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000954 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000955
956 /// See AbstractState::isAtFixpoint().
957 bool isAtFixpoint() const override { return IsFixed; }
958
959 /// See AbstractState::isValidState().
960 bool isValidState() const override { return IsValidState; }
961
962 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000963 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000964 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000965 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000966 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000967
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000968 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000969 IsFixed = true;
970 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000971 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000972 }
973};
974
975ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
976 ChangeStatus Changed = ChangeStatus::UNCHANGED;
977
978 // Bookkeeping.
979 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000980 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
981 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000982
983 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000984 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000985
986 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
987 return Changed;
988
989 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000990 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
991 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000992
Johannes Doerfert23400e612019-08-23 17:41:37 +0000993 // Callback to replace the uses of CB with the constant C.
994 auto ReplaceCallSiteUsersWith = [](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +0000995 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +0000996 return ChangeStatus::UNCHANGED;
997 CB.replaceAllUsesWith(&C);
998 return ChangeStatus::CHANGED;
999 };
1000
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001001 // If the assumed unique return value is an argument, annotate it.
1002 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001003 getIRPosition() = IRPosition::argument(*UniqueRVArg);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001004 Changed = IRAttribute::manifest(A);
1005 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
1006 // We can replace the returned value with the unique returned constant.
1007 Value &AnchorValue = getAnchorValue();
1008 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
1009 for (const Use &U : F->uses())
1010 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001011 if (CB->isCallee(&U)) {
1012 Constant *RVCCast =
1013 ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
1014 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1015 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001016 } else {
1017 assert(isa<CallBase>(AnchorValue) &&
1018 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001019 Constant *RVCCast =
1020 ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
1021 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001022 }
1023 if (Changed == ChangeStatus::CHANGED)
1024 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1025 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001026 }
1027
1028 return Changed;
1029}
1030
1031const std::string AAReturnedValuesImpl::getAsStr() const {
1032 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001033 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001034 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001035}
1036
Johannes Doerfert14a04932019-08-07 22:27:24 +00001037Optional<Value *>
1038AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1039 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001040 // undef values that can also be present, it is assumed to be the actual
1041 // return value and forwarded to the caller of this method. If there are
1042 // multiple, a nullptr is returned indicating there cannot be a unique
1043 // returned value.
1044 Optional<Value *> UniqueRV;
1045
Johannes Doerfert14a04932019-08-07 22:27:24 +00001046 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001047 // If we found a second returned value and neither the current nor the saved
1048 // one is an undef, there is no unique returned value. Undefs are special
1049 // since we can pretend they have any value.
1050 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1051 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1052 UniqueRV = nullptr;
1053 return false;
1054 }
1055
1056 // Do not overwrite a value with an undef.
1057 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1058 UniqueRV = &RV;
1059
1060 return true;
1061 };
1062
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001063 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001064 UniqueRV = nullptr;
1065
1066 return UniqueRV;
1067}
1068
Johannes Doerfert14a04932019-08-07 22:27:24 +00001069bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001070 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001071 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001072 if (!isValidState())
1073 return false;
1074
1075 // Check all returned values but ignore call sites as long as we have not
1076 // encountered an overdefined one during an update.
1077 for (auto &It : ReturnedValues) {
1078 Value *RV = It.first;
1079
Johannes Doerfertdef99282019-08-14 21:29:37 +00001080 CallBase *CB = dyn_cast<CallBase>(RV);
1081 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001082 continue;
1083
Johannes Doerfert695089e2019-08-23 15:23:49 +00001084 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001085 return false;
1086 }
1087
1088 return true;
1089}
1090
Johannes Doerfertece81902019-08-12 22:05:53 +00001091ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001092 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1093 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001094
Johannes Doerfertdef99282019-08-14 21:29:37 +00001095 // State used in the value traversals starting in returned values.
1096 struct RVState {
1097 // The map in which we collect return values -> return instrs.
1098 decltype(ReturnedValues) &RetValsMap;
1099 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001100 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001101 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001102 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001103 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001104
Johannes Doerfertdef99282019-08-14 21:29:37 +00001105 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001106 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001107 auto Size = RVS.RetValsMap[&Val].size();
1108 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1109 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1110 RVS.Changed |= Inserted;
1111 LLVM_DEBUG({
1112 if (Inserted)
1113 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1114 << " => " << RVS.RetInsts.size() << "\n";
1115 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001116 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001117 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001118
Johannes Doerfertdef99282019-08-14 21:29:37 +00001119 // Helper method to invoke the generic value traversal.
1120 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1121 IRPosition RetValPos = IRPosition::value(RV);
1122 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1123 RVS, VisitValueCB);
1124 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001125
Johannes Doerfertdef99282019-08-14 21:29:37 +00001126 // Callback for all "return intructions" live in the associated function.
1127 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1128 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001129 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001130 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001131 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1132 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001133
Johannes Doerfertdef99282019-08-14 21:29:37 +00001134 // Start by discovering returned values from all live returned instructions in
1135 // the associated function.
1136 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1137 return indicatePessimisticFixpoint();
1138
1139 // Once returned values "directly" present in the code are handled we try to
1140 // resolve returned calls.
1141 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001142 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001143 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1144 << " by #" << It.second.size() << " RIs\n");
1145 CallBase *CB = dyn_cast<CallBase>(It.first);
1146 if (!CB || UnresolvedCalls.count(CB))
1147 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001148
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001149 if (!CB->getCalledFunction()) {
1150 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1151 << "\n");
1152 UnresolvedCalls.insert(CB);
1153 continue;
1154 }
1155
1156 // TODO: use the function scope once we have call site AAReturnedValues.
1157 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1158 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001159 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
1160 << static_cast<const AbstractAttribute &>(RetValAA)
1161 << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001162
1163 // Skip dead ends, thus if we do not know anything about the returned
1164 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001165 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001166 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1167 << "\n");
1168 UnresolvedCalls.insert(CB);
1169 continue;
1170 }
1171
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001172 // Do not try to learn partial information. If the callee has unresolved
1173 // return values we will treat the call as unresolved/opaque.
1174 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1175 if (!RetValAAUnresolvedCalls.empty()) {
1176 UnresolvedCalls.insert(CB);
1177 continue;
1178 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001179
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001180 // Now check if we can track transitively returned values. If possible, thus
1181 // if all return value can be represented in the current scope, do so.
1182 bool Unresolved = false;
1183 for (auto &RetValAAIt : RetValAA.returned_values()) {
1184 Value *RetVal = RetValAAIt.first;
1185 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1186 isa<Constant>(RetVal))
1187 continue;
1188 // Anything that did not fit in the above categories cannot be resolved,
1189 // mark the call as unresolved.
1190 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1191 "cannot be translated: "
1192 << *RetVal << "\n");
1193 UnresolvedCalls.insert(CB);
1194 Unresolved = true;
1195 break;
1196 }
1197
1198 if (Unresolved)
1199 continue;
1200
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001201 // Now track transitively returned values.
1202 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1203 if (NumRetAA == RetValAA.getNumReturnValues()) {
1204 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1205 "changed since it was seen last\n");
1206 continue;
1207 }
1208 NumRetAA = RetValAA.getNumReturnValues();
1209
Johannes Doerfertdef99282019-08-14 21:29:37 +00001210 for (auto &RetValAAIt : RetValAA.returned_values()) {
1211 Value *RetVal = RetValAAIt.first;
1212 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1213 // Arguments are mapped to call site operands and we begin the traversal
1214 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001215 bool Unused = false;
1216 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001217 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1218 continue;
1219 } else if (isa<CallBase>(RetVal)) {
1220 // Call sites are resolved by the callee attribute over time, no need to
1221 // do anything for us.
1222 continue;
1223 } else if (isa<Constant>(RetVal)) {
1224 // Constants are valid everywhere, we can simply take them.
1225 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1226 continue;
1227 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001228 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001229 }
1230
Johannes Doerfertdef99282019-08-14 21:29:37 +00001231 // To avoid modifications to the ReturnedValues map while we iterate over it
1232 // we kept record of potential new entries in a copy map, NewRVsMap.
1233 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001234 assert(!It.second.empty() && "Entry does not add anything.");
1235 auto &ReturnInsts = ReturnedValues[It.first];
1236 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001237 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001238 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1239 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001240 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001241 }
1242 }
1243
Johannes Doerfertdef99282019-08-14 21:29:37 +00001244 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1245 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001246}
1247
Johannes Doerfertdef99282019-08-14 21:29:37 +00001248struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1249 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1250
1251 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001252 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001253};
1254
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001255/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001256struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1257 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1258
1259 /// See AbstractAttribute::initialize(...).
1260 void initialize(Attributor &A) override {
1261 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001262 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001263 // sense to specialize attributes for call sites instead of
1264 // redirecting requests to the callee.
1265 llvm_unreachable("Abstract attributes for returned values are not "
1266 "supported for call sites yet!");
1267 }
1268
1269 /// See AbstractAttribute::updateImpl(...).
1270 ChangeStatus updateImpl(Attributor &A) override {
1271 return indicatePessimisticFixpoint();
1272 }
1273
1274 /// See AbstractAttribute::trackStatistics()
1275 void trackStatistics() const override {}
1276};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001277
Stefan Stipanovic06263672019-07-11 21:37:40 +00001278/// ------------------------ NoSync Function Attribute -------------------------
1279
Johannes Doerfert344d0382019-08-07 22:34:26 +00001280struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001281 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001282
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001283 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001284 return getAssumed() ? "nosync" : "may-sync";
1285 }
1286
1287 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001288 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001289
Stefan Stipanovic06263672019-07-11 21:37:40 +00001290 /// Helper function used to determine whether an instruction is non-relaxed
1291 /// atomic. In other words, if an atomic instruction does not have unordered
1292 /// or monotonic ordering
1293 static bool isNonRelaxedAtomic(Instruction *I);
1294
1295 /// Helper function used to determine whether an instruction is volatile.
1296 static bool isVolatile(Instruction *I);
1297
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001298 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1299 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001300 static bool isNoSyncIntrinsic(Instruction *I);
1301};
1302
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001303bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001304 if (!I->isAtomic())
1305 return false;
1306
1307 AtomicOrdering Ordering;
1308 switch (I->getOpcode()) {
1309 case Instruction::AtomicRMW:
1310 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1311 break;
1312 case Instruction::Store:
1313 Ordering = cast<StoreInst>(I)->getOrdering();
1314 break;
1315 case Instruction::Load:
1316 Ordering = cast<LoadInst>(I)->getOrdering();
1317 break;
1318 case Instruction::Fence: {
1319 auto *FI = cast<FenceInst>(I);
1320 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1321 return false;
1322 Ordering = FI->getOrdering();
1323 break;
1324 }
1325 case Instruction::AtomicCmpXchg: {
1326 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1327 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1328 // Only if both are relaxed, than it can be treated as relaxed.
1329 // Otherwise it is non-relaxed.
1330 if (Success != AtomicOrdering::Unordered &&
1331 Success != AtomicOrdering::Monotonic)
1332 return true;
1333 if (Failure != AtomicOrdering::Unordered &&
1334 Failure != AtomicOrdering::Monotonic)
1335 return true;
1336 return false;
1337 }
1338 default:
1339 llvm_unreachable(
1340 "New atomic operations need to be known in the attributor.");
1341 }
1342
1343 // Relaxed.
1344 if (Ordering == AtomicOrdering::Unordered ||
1345 Ordering == AtomicOrdering::Monotonic)
1346 return false;
1347 return true;
1348}
1349
1350/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1351/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001352bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001353 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1354 switch (II->getIntrinsicID()) {
1355 /// Element wise atomic memory intrinsics are can only be unordered,
1356 /// therefore nosync.
1357 case Intrinsic::memset_element_unordered_atomic:
1358 case Intrinsic::memmove_element_unordered_atomic:
1359 case Intrinsic::memcpy_element_unordered_atomic:
1360 return true;
1361 case Intrinsic::memset:
1362 case Intrinsic::memmove:
1363 case Intrinsic::memcpy:
1364 if (!cast<MemIntrinsic>(II)->isVolatile())
1365 return true;
1366 return false;
1367 default:
1368 return false;
1369 }
1370 }
1371 return false;
1372}
1373
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001374bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001375 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1376 "Calls should not be checked here");
1377
1378 switch (I->getOpcode()) {
1379 case Instruction::AtomicRMW:
1380 return cast<AtomicRMWInst>(I)->isVolatile();
1381 case Instruction::Store:
1382 return cast<StoreInst>(I)->isVolatile();
1383 case Instruction::Load:
1384 return cast<LoadInst>(I)->isVolatile();
1385 case Instruction::AtomicCmpXchg:
1386 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1387 default:
1388 return false;
1389 }
1390}
1391
Johannes Doerfertece81902019-08-12 22:05:53 +00001392ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001393
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001394 auto CheckRWInstForNoSync = [&](Instruction &I) {
1395 /// We are looking for volatile instructions or Non-Relaxed atomics.
1396 /// FIXME: We should ipmrove the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001397
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001398 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1399 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001400
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001401 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1402 if (ICS.hasFnAttr(Attribute::NoSync))
1403 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001404
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001405 const auto &NoSyncAA =
1406 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1407 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001408 return true;
1409 return false;
1410 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001411
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001412 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1413 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001414
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001415 return false;
1416 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001417
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001418 auto CheckForNoSync = [&](Instruction &I) {
1419 // At this point we handled all read/write effects and they are all
1420 // nosync, so they can be skipped.
1421 if (I.mayReadOrWriteMemory())
1422 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001423
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001424 // non-convergent and readnone imply nosync.
1425 return !ImmutableCallSite(&I).isConvergent();
1426 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001427
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001428 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1429 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001430 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001431
Stefan Stipanovic06263672019-07-11 21:37:40 +00001432 return ChangeStatus::UNCHANGED;
1433}
1434
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001435struct AANoSyncFunction final : public AANoSyncImpl {
1436 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1437
1438 /// See AbstractAttribute::trackStatistics()
1439 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1440};
1441
1442/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001443struct AANoSyncCallSite final : AANoSyncImpl {
1444 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1445
1446 /// See AbstractAttribute::initialize(...).
1447 void initialize(Attributor &A) override {
1448 AANoSyncImpl::initialize(A);
1449 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001450 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001451 indicatePessimisticFixpoint();
1452 }
1453
1454 /// See AbstractAttribute::updateImpl(...).
1455 ChangeStatus updateImpl(Attributor &A) override {
1456 // TODO: Once we have call site specific value information we can provide
1457 // call site specific liveness information and then it makes
1458 // sense to specialize attributes for call sites arguments instead of
1459 // redirecting requests to the callee argument.
1460 Function *F = getAssociatedFunction();
1461 const IRPosition &FnPos = IRPosition::function(*F);
1462 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1463 return clampStateAndIndicateChange(
1464 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1465 }
1466
1467 /// See AbstractAttribute::trackStatistics()
1468 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1469};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001470
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001471/// ------------------------ No-Free Attributes ----------------------------
1472
Johannes Doerfert344d0382019-08-07 22:34:26 +00001473struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001474 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001475
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001476 /// See AbstractAttribute::updateImpl(...).
1477 ChangeStatus updateImpl(Attributor &A) override {
1478 auto CheckForNoFree = [&](Instruction &I) {
1479 ImmutableCallSite ICS(&I);
1480 if (ICS.hasFnAttr(Attribute::NoFree))
1481 return true;
1482
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001483 const auto &NoFreeAA =
1484 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1485 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001486 };
1487
1488 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1489 return indicatePessimisticFixpoint();
1490 return ChangeStatus::UNCHANGED;
1491 }
1492
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001493 /// See AbstractAttribute::getAsStr().
1494 const std::string getAsStr() const override {
1495 return getAssumed() ? "nofree" : "may-free";
1496 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001497};
1498
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001499struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001500 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001501
1502 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001503 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001504};
1505
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001506/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001507struct AANoFreeCallSite final : AANoFreeImpl {
1508 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1509
1510 /// See AbstractAttribute::initialize(...).
1511 void initialize(Attributor &A) override {
1512 AANoFreeImpl::initialize(A);
1513 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001514 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001515 indicatePessimisticFixpoint();
1516 }
1517
1518 /// See AbstractAttribute::updateImpl(...).
1519 ChangeStatus updateImpl(Attributor &A) override {
1520 // TODO: Once we have call site specific value information we can provide
1521 // call site specific liveness information and then it makes
1522 // sense to specialize attributes for call sites arguments instead of
1523 // redirecting requests to the callee argument.
1524 Function *F = getAssociatedFunction();
1525 const IRPosition &FnPos = IRPosition::function(*F);
1526 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1527 return clampStateAndIndicateChange(
1528 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1529 }
1530
1531 /// See AbstractAttribute::trackStatistics()
1532 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1533};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001534
Hideto Ueno54869ec2019-07-15 06:49:04 +00001535/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001536static int64_t getKnownNonNullAndDerefBytesForUse(
1537 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1538 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001539 TrackUse = false;
1540
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001541 const Value *UseV = U->get();
1542 if (!UseV->getType()->isPointerTy())
1543 return 0;
1544
1545 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001546 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001547 bool NullPointerIsDefined =
1548 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001549 const DataLayout &DL = A.getInfoCache().getDL();
1550 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1551 if (ICS.isBundleOperand(U))
1552 return 0;
1553
1554 if (ICS.isCallee(U)) {
1555 IsNonNull |= !NullPointerIsDefined;
1556 return 0;
1557 }
1558
1559 unsigned ArgNo = ICS.getArgumentNo(U);
1560 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
1561 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP);
1562 IsNonNull |= DerefAA.isKnownNonNull();
1563 return DerefAA.getKnownDereferenceableBytes();
1564 }
1565
1566 int64_t Offset;
1567 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001568 if (Base == &AssociatedValue && getPointerOperand(I) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001569 int64_t DerefBytes =
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001570 Offset + (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType());
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001571
1572 IsNonNull |= !NullPointerIsDefined;
1573 return DerefBytes;
1574 }
1575 }
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001576 if (const Value *Base =
1577 GetPointerBaseWithConstantOffset(UseV, Offset, DL,
1578 /*AllowNonInbounds*/ false)) {
1579 auto &DerefAA =
1580 A.getAAFor<AADereferenceable>(QueryingAA, IRPosition::value(*Base));
1581 IsNonNull |= (!NullPointerIsDefined && DerefAA.isKnownNonNull());
1582 IsNonNull |= (!NullPointerIsDefined && (Offset != 0));
1583 int64_t DerefBytes = DerefAA.getKnownDereferenceableBytes();
1584 return std::max(int64_t(0), DerefBytes - Offset);
1585 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001586
1587 return 0;
1588}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001589
Johannes Doerfert344d0382019-08-07 22:34:26 +00001590struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001591 AANonNullImpl(const IRPosition &IRP)
1592 : AANonNull(IRP),
1593 NullIsDefined(NullPointerIsDefined(
1594 getAnchorScope(),
1595 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001596
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001597 /// See AbstractAttribute::initialize(...).
1598 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001599 if (!NullIsDefined &&
1600 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001601 indicateOptimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001602 else
1603 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001604 }
1605
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001606 /// See AAFromMustBeExecutedContext
1607 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1608 bool IsNonNull = false;
1609 bool TrackUse = false;
1610 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1611 IsNonNull, TrackUse);
1612 takeKnownMaximum(IsNonNull);
1613 return TrackUse;
1614 }
1615
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001616 /// See AbstractAttribute::getAsStr().
1617 const std::string getAsStr() const override {
1618 return getAssumed() ? "nonnull" : "may-null";
1619 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001620
1621 /// Flag to determine if the underlying value can be null and still allow
1622 /// valid accesses.
1623 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001624};
1625
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001626/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001627struct AANonNullFloating
1628 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1629 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1630 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001631
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001632 /// See AbstractAttribute::initialize(...).
1633 void initialize(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001634 Base::initialize(A);
Hideto Ueno54869ec2019-07-15 06:49:04 +00001635
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001636 if (isAtFixpoint())
1637 return;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001638
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001639 const IRPosition &IRP = getIRPosition();
1640 const Value &V = IRP.getAssociatedValue();
1641 const DataLayout &DL = A.getDataLayout();
Hideto Ueno54869ec2019-07-15 06:49:04 +00001642
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001643 // TODO: This context sensitive query should be removed once we can do
1644 // context sensitive queries in the genericValueTraversal below.
1645 if (isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, IRP.getCtxI(),
1646 /* TODO: DT */ nullptr))
1647 indicateOptimisticFixpoint();
1648 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001649
1650 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001651 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001652 ChangeStatus Change = Base::updateImpl(A);
1653 if (isKnownNonNull())
1654 return Change;
1655
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001656 if (!NullIsDefined) {
1657 const auto &DerefAA = A.getAAFor<AADereferenceable>(*this, getIRPosition());
1658 if (DerefAA.getAssumedDereferenceableBytes())
1659 return Change;
1660 }
1661
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001662 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001663
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001664 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
1665 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001666 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1667 if (!Stripped && this == &AA) {
1668 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr,
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001669 /* CtxI */ getCtxI(),
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001670 /* TODO: DT */ nullptr))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001671 T.indicatePessimisticFixpoint();
1672 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001673 // Use abstract attribute information.
1674 const AANonNull::StateType &NS =
1675 static_cast<const AANonNull::StateType &>(AA.getState());
1676 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001677 }
1678 return T.isValidState();
1679 };
1680
1681 StateType T;
1682 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
1683 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001684 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001685
1686 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001687 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001688
1689 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001690 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001691};
1692
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001693/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001694struct AANonNullReturned final
1695 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001696 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001697 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001698
1699 /// See AbstractAttribute::trackStatistics()
1700 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
1701};
1702
Hideto Ueno54869ec2019-07-15 06:49:04 +00001703/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001704struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001705 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1706 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001707 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001708 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1709 AANonNullImpl>(
1710 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001711
1712 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001713 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001714};
1715
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001716struct AANonNullCallSiteArgument final : AANonNullFloating {
1717 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001718
1719 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00001720 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001721};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001722
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001723/// NonNull attribute for a call site return position.
1724struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001725 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1726 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001727 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001728 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1729 AANonNullImpl>(
1730 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001731
1732 /// See AbstractAttribute::trackStatistics()
1733 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
1734};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001735
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001736/// ------------------------ No-Recurse Attributes ----------------------------
1737
1738struct AANoRecurseImpl : public AANoRecurse {
1739 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
1740
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001741 /// See AbstractAttribute::getAsStr()
1742 const std::string getAsStr() const override {
1743 return getAssumed() ? "norecurse" : "may-recurse";
1744 }
1745};
1746
1747struct AANoRecurseFunction final : AANoRecurseImpl {
1748 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1749
Hideto Ueno63f60662019-09-21 15:13:19 +00001750 /// See AbstractAttribute::initialize(...).
1751 void initialize(Attributor &A) override {
1752 AANoRecurseImpl::initialize(A);
1753 if (const Function *F = getAnchorScope())
1754 if (A.getInfoCache().getSccSize(*F) == 1)
1755 return;
1756 indicatePessimisticFixpoint();
1757 }
1758
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001759 /// See AbstractAttribute::updateImpl(...).
1760 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00001761
1762 auto CheckForNoRecurse = [&](Instruction &I) {
1763 ImmutableCallSite ICS(&I);
1764 if (ICS.hasFnAttr(Attribute::NoRecurse))
1765 return true;
1766
1767 const auto &NoRecurseAA =
1768 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
1769 if (!NoRecurseAA.isAssumedNoRecurse())
1770 return false;
1771
1772 // Recursion to the same function
1773 if (ICS.getCalledFunction() == getAnchorScope())
1774 return false;
1775
1776 return true;
1777 };
1778
1779 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
1780 return indicatePessimisticFixpoint();
1781 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001782 }
1783
1784 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
1785};
1786
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001787/// NoRecurse attribute deduction for a call sites.
1788struct AANoRecurseCallSite final : AANoRecurseImpl {
1789 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1790
1791 /// See AbstractAttribute::initialize(...).
1792 void initialize(Attributor &A) override {
1793 AANoRecurseImpl::initialize(A);
1794 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001795 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001796 indicatePessimisticFixpoint();
1797 }
1798
1799 /// See AbstractAttribute::updateImpl(...).
1800 ChangeStatus updateImpl(Attributor &A) override {
1801 // TODO: Once we have call site specific value information we can provide
1802 // call site specific liveness information and then it makes
1803 // sense to specialize attributes for call sites arguments instead of
1804 // redirecting requests to the callee argument.
1805 Function *F = getAssociatedFunction();
1806 const IRPosition &FnPos = IRPosition::function(*F);
1807 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
1808 return clampStateAndIndicateChange(
1809 getState(),
1810 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
1811 }
1812
1813 /// See AbstractAttribute::trackStatistics()
1814 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
1815};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001816
Hideto Ueno11d37102019-07-17 15:15:43 +00001817/// ------------------------ Will-Return Attributes ----------------------------
1818
Hideto Ueno11d37102019-07-17 15:15:43 +00001819// Helper function that checks whether a function has any cycle.
1820// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001821static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00001822 SmallPtrSet<BasicBlock *, 32> Visited;
1823
1824 // Traverse BB by dfs and check whether successor is already visited.
1825 for (BasicBlock *BB : depth_first(&F)) {
1826 Visited.insert(BB);
1827 for (auto *SuccBB : successors(BB)) {
1828 if (Visited.count(SuccBB))
1829 return true;
1830 }
1831 }
1832 return false;
1833}
1834
1835// Helper function that checks the function have a loop which might become an
1836// endless loop
1837// FIXME: Any cycle is regarded as endless loop for now.
1838// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001839static bool containsPossiblyEndlessLoop(Function *F) {
1840 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00001841}
1842
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001843struct AAWillReturnImpl : public AAWillReturn {
1844 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00001845
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001846 /// See AbstractAttribute::initialize(...).
1847 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001848 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00001849
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001850 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001851 if (containsPossiblyEndlessLoop(F))
1852 indicatePessimisticFixpoint();
1853 }
Hideto Ueno11d37102019-07-17 15:15:43 +00001854
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001855 /// See AbstractAttribute::updateImpl(...).
1856 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001857 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001858 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
1859 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
1860 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001861 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001862 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001863 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001864 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
1865 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001866 };
1867
1868 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
1869 return indicatePessimisticFixpoint();
1870
1871 return ChangeStatus::UNCHANGED;
1872 }
1873
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001874 /// See AbstractAttribute::getAsStr()
1875 const std::string getAsStr() const override {
1876 return getAssumed() ? "willreturn" : "may-noreturn";
1877 }
1878};
1879
1880struct AAWillReturnFunction final : AAWillReturnImpl {
1881 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1882
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001883 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001884 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001885};
Hideto Ueno11d37102019-07-17 15:15:43 +00001886
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001887/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001888struct AAWillReturnCallSite final : AAWillReturnImpl {
1889 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1890
1891 /// See AbstractAttribute::initialize(...).
1892 void initialize(Attributor &A) override {
1893 AAWillReturnImpl::initialize(A);
1894 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001895 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001896 indicatePessimisticFixpoint();
1897 }
1898
1899 /// See AbstractAttribute::updateImpl(...).
1900 ChangeStatus updateImpl(Attributor &A) override {
1901 // TODO: Once we have call site specific value information we can provide
1902 // call site specific liveness information and then it makes
1903 // sense to specialize attributes for call sites arguments instead of
1904 // redirecting requests to the callee argument.
1905 Function *F = getAssociatedFunction();
1906 const IRPosition &FnPos = IRPosition::function(*F);
1907 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
1908 return clampStateAndIndicateChange(
1909 getState(),
1910 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
1911 }
1912
1913 /// See AbstractAttribute::trackStatistics()
1914 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
1915};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001916
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001917/// ------------------------ NoAlias Argument Attribute ------------------------
1918
Johannes Doerfert344d0382019-08-07 22:34:26 +00001919struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001920 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001921
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001922 const std::string getAsStr() const override {
1923 return getAssumed() ? "noalias" : "may-alias";
1924 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001925};
1926
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001927/// NoAlias attribute for a floating value.
1928struct AANoAliasFloating final : AANoAliasImpl {
1929 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1930
Hideto Uenocbab3342019-08-29 05:52:00 +00001931 /// See AbstractAttribute::initialize(...).
1932 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001933 AANoAliasImpl::initialize(A);
Johannes Doerfert72adda12019-10-10 05:33:21 +00001934 Value &Val = getAssociatedValue();
1935 if (isa<AllocaInst>(Val))
1936 indicateOptimisticFixpoint();
1937 if (isa<ConstantPointerNull>(Val) &&
1938 Val.getType()->getPointerAddressSpace() == 0)
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001939 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001940 }
1941
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001942 /// See AbstractAttribute::updateImpl(...).
1943 ChangeStatus updateImpl(Attributor &A) override {
1944 // TODO: Implement this.
1945 return indicatePessimisticFixpoint();
1946 }
1947
1948 /// See AbstractAttribute::trackStatistics()
1949 void trackStatistics() const override {
1950 STATS_DECLTRACK_FLOATING_ATTR(noalias)
1951 }
1952};
1953
1954/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00001955struct AANoAliasArgument final
1956 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
1957 AANoAliasArgument(const IRPosition &IRP)
1958 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001959
1960 /// See AbstractAttribute::trackStatistics()
1961 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
1962};
1963
1964struct AANoAliasCallSiteArgument final : AANoAliasImpl {
1965 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1966
Hideto Uenocbab3342019-08-29 05:52:00 +00001967 /// See AbstractAttribute::initialize(...).
1968 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00001969 // See callsite argument attribute and callee argument attribute.
1970 ImmutableCallSite ICS(&getAnchorValue());
1971 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
1972 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001973 }
1974
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001975 /// See AbstractAttribute::updateImpl(...).
1976 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001977 // We can deduce "noalias" if the following conditions hold.
1978 // (i) Associated value is assumed to be noalias in the definition.
1979 // (ii) Associated value is assumed to be no-capture in all the uses
1980 // possibly executed before this callsite.
1981 // (iii) There is no other pointer argument which could alias with the
1982 // value.
1983
1984 const Value &V = getAssociatedValue();
1985 const IRPosition IRP = IRPosition::value(V);
1986
1987 // (i) Check whether noalias holds in the definition.
1988
1989 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
1990
1991 if (!NoAliasAA.isAssumedNoAlias())
1992 return indicatePessimisticFixpoint();
1993
1994 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
1995 << " is assumed NoAlias in the definition\n");
1996
1997 // (ii) Check whether the value is captured in the scope using AANoCapture.
1998 // FIXME: This is conservative though, it is better to look at CFG and
1999 // check only uses possibly executed before this callsite.
2000
2001 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert72adda12019-10-10 05:33:21 +00002002 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2003 LLVM_DEBUG(
2004 dbgs() << "[Attributor][AANoAliasCSArg] " << V
2005 << " cannot be noalias as it is potentially captured\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002006 return indicatePessimisticFixpoint();
Johannes Doerfert72adda12019-10-10 05:33:21 +00002007 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002008
2009 // (iii) Check there is no other pointer argument which could alias with the
2010 // value.
2011 ImmutableCallSite ICS(&getAnchorValue());
2012 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
2013 if (getArgNo() == (int)i)
2014 continue;
2015 const Value *ArgOp = ICS.getArgOperand(i);
2016 if (!ArgOp->getType()->isPointerTy())
2017 continue;
2018
Hideto Ueno30d86f12019-09-17 06:53:27 +00002019 if (const Function *F = getAnchorScope()) {
2020 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
Johannes Doerfert72adda12019-10-10 05:33:21 +00002021 bool IsAliasing = AAR->isNoAlias(&getAssociatedValue(), ArgOp);
Hideto Ueno30d86f12019-09-17 06:53:27 +00002022 LLVM_DEBUG(dbgs()
2023 << "[Attributor][NoAliasCSArg] Check alias between "
2024 "callsite arguments "
2025 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
Johannes Doerfert72adda12019-10-10 05:33:21 +00002026 << getAssociatedValue() << " " << *ArgOp << " => "
2027 << (IsAliasing ? "" : "no-") << "alias \n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002028
Johannes Doerfert72adda12019-10-10 05:33:21 +00002029 if (IsAliasing)
Hideto Ueno30d86f12019-09-17 06:53:27 +00002030 continue;
2031 }
2032 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002033 return indicatePessimisticFixpoint();
2034 }
2035
2036 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002037 }
2038
2039 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002040 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002041};
2042
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002043/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002044struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002045 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002046
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002047 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002048 virtual ChangeStatus updateImpl(Attributor &A) override {
2049
2050 auto CheckReturnValue = [&](Value &RV) -> bool {
2051 if (Constant *C = dyn_cast<Constant>(&RV))
2052 if (C->isNullValue() || isa<UndefValue>(C))
2053 return true;
2054
2055 /// For now, we can only deduce noalias if we have call sites.
2056 /// FIXME: add more support.
2057 ImmutableCallSite ICS(&RV);
2058 if (!ICS)
2059 return false;
2060
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002061 const IRPosition &RVPos = IRPosition::value(RV);
2062 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002063 if (!NoAliasAA.isAssumedNoAlias())
2064 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002065
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002066 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2067 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002068 };
2069
2070 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2071 return indicatePessimisticFixpoint();
2072
2073 return ChangeStatus::UNCHANGED;
2074 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002075
2076 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002077 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002078};
2079
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002080/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002081struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2082 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2083
2084 /// See AbstractAttribute::initialize(...).
2085 void initialize(Attributor &A) override {
2086 AANoAliasImpl::initialize(A);
2087 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002088 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002089 indicatePessimisticFixpoint();
2090 }
2091
2092 /// See AbstractAttribute::updateImpl(...).
2093 ChangeStatus updateImpl(Attributor &A) override {
2094 // TODO: Once we have call site specific value information we can provide
2095 // call site specific liveness information and then it makes
2096 // sense to specialize attributes for call sites arguments instead of
2097 // redirecting requests to the callee argument.
2098 Function *F = getAssociatedFunction();
2099 const IRPosition &FnPos = IRPosition::returned(*F);
2100 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2101 return clampStateAndIndicateChange(
2102 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2103 }
2104
2105 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002106 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002107};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002108
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002109/// -------------------AAIsDead Function Attribute-----------------------
2110
Johannes Doerfert344d0382019-08-07 22:34:26 +00002111struct AAIsDeadImpl : public AAIsDead {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002112 AAIsDeadImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002113
Johannes Doerfertece81902019-08-12 22:05:53 +00002114 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002115 const Function *F = getAssociatedFunction();
Johannes Doerfert97fd5822019-09-04 16:26:20 +00002116 if (F && !F->isDeclaration())
2117 exploreFromEntry(A, F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002118 }
2119
2120 void exploreFromEntry(Attributor &A, const Function *F) {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002121 ToBeExploredPaths.insert(&(F->getEntryBlock().front()));
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002122
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002123 for (size_t i = 0; i < ToBeExploredPaths.size(); ++i)
Johannes Doerfert4361da22019-08-04 18:38:53 +00002124 if (const Instruction *NextNoReturnI =
2125 findNextNoReturn(A, ToBeExploredPaths[i]))
2126 NoReturnCalls.insert(NextNoReturnI);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00002127
2128 // Mark the block live after we looked for no-return instructions.
2129 assumeLive(A, F->getEntryBlock());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002130 }
2131
Johannes Doerfert4361da22019-08-04 18:38:53 +00002132 /// Find the next assumed noreturn instruction in the block of \p I starting
2133 /// from, thus including, \p I.
2134 ///
2135 /// The caller is responsible to monitor the ToBeExploredPaths set as new
2136 /// instructions discovered in other basic block will be placed in there.
2137 ///
2138 /// \returns The next assumed noreturn instructions in the block of \p I
2139 /// starting from, thus including, \p I.
2140 const Instruction *findNextNoReturn(Attributor &A, const Instruction *I);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002141
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002142 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002143 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002144 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002145 std::to_string(getAssociatedFunction()->size()) + "][#NRI " +
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002146 std::to_string(NoReturnCalls.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002147 }
2148
2149 /// See AbstractAttribute::manifest(...).
2150 ChangeStatus manifest(Attributor &A) override {
2151 assert(getState().isValidState() &&
2152 "Attempted to manifest an invalid state!");
2153
2154 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002155 Function &F = *getAssociatedFunction();
2156
2157 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002158 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002159 return ChangeStatus::CHANGED;
2160 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00002161
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002162 // Flag to determine if we can change an invoke to a call assuming the
2163 // callee is nounwind. This is not possible if the personality of the
2164 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002165 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002166
Johannes Doerfert4361da22019-08-04 18:38:53 +00002167 for (const Instruction *NRC : NoReturnCalls) {
2168 Instruction *I = const_cast<Instruction *>(NRC);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002169 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002170 Instruction *SplitPos = I->getNextNode();
Johannes Doerfertd4108052019-08-21 20:56:41 +00002171 // TODO: mark stuff before unreachable instructions as dead.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002172
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002173 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002174 // If we keep the invoke the split position is at the beginning of the
2175 // normal desitination block (it invokes a noreturn function after all).
2176 BasicBlock *NormalDestBB = II->getNormalDest();
2177 SplitPos = &NormalDestBB->front();
2178
Johannes Doerfert4361da22019-08-04 18:38:53 +00002179 /// Invoke is replaced with a call and unreachable is placed after it if
2180 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
2181 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002182 if (Invoke2CallAllowed) {
Michael Liaoa99086d2019-08-20 21:02:31 +00002183 if (II->getCalledFunction()) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002184 const IRPosition &IPos = IRPosition::callsite_function(*II);
2185 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2186 if (AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert924d2132019-08-05 21:34:45 +00002187 LLVM_DEBUG(dbgs()
2188 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002189 // We do not need an invoke (II) but instead want a call followed
2190 // by an unreachable. However, we do not remove II as other
2191 // abstract attributes might have it cached as part of their
2192 // results. Given that we modify the CFG anyway, we simply keep II
2193 // around but in a new dead block. To avoid II being live through
2194 // a different edge we have to ensure the block we place it in is
2195 // only reached from the current block of II and then not reached
2196 // at all when we insert the unreachable.
2197 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
2198 CallInst *CI = createCallMatchingInvoke(II);
2199 CI->insertBefore(II);
2200 CI->takeName(II);
2201 II->replaceAllUsesWith(CI);
2202 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002203 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002204 }
2205 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002206
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002207 if (SplitPos == &NormalDestBB->front()) {
2208 // If this is an invoke of a noreturn function the edge to the normal
2209 // destination block is dead but not necessarily the block itself.
2210 // TODO: We need to move to an edge based system during deduction and
2211 // also manifest.
2212 assert(!NormalDestBB->isLandingPad() &&
2213 "Expected the normal destination not to be a landingpad!");
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002214 if (NormalDestBB->getUniquePredecessor() == BB) {
2215 assumeLive(A, *NormalDestBB);
2216 } else {
2217 BasicBlock *SplitBB =
2218 SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2219 // The split block is live even if it contains only an unreachable
2220 // instruction at the end.
2221 assumeLive(A, *SplitBB);
2222 SplitPos = SplitBB->getTerminator();
2223 HasChanged = ChangeStatus::CHANGED;
2224 }
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002225 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002226 }
2227
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002228 if (isa_and_nonnull<UnreachableInst>(SplitPos))
2229 continue;
2230
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002231 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002232 SplitBlock(BB, SplitPos);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002233 changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
2234 HasChanged = ChangeStatus::CHANGED;
2235 }
2236
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002237 for (BasicBlock &BB : F)
2238 if (!AssumedLiveBlocks.count(&BB))
2239 A.deleteAfterManifest(BB);
2240
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002241 return HasChanged;
2242 }
2243
2244 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002245 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002246
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002247 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002248 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002249 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002250 "BB must be in the same anchor scope function.");
2251
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002252 if (!getAssumed())
2253 return false;
2254 return !AssumedLiveBlocks.count(BB);
2255 }
2256
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002257 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002258 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002259 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002260 }
2261
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002262 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002263 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002264 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002265 "Instruction must be in the same anchor scope function.");
2266
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002267 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002268 return false;
2269
2270 // If it is not in AssumedLiveBlocks then it for sure dead.
2271 // Otherwise, it can still be after noreturn call in a live block.
2272 if (!AssumedLiveBlocks.count(I->getParent()))
2273 return true;
2274
2275 // If it is not after a noreturn call, than it is live.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002276 return isAfterNoReturn(I);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002277 }
2278
2279 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002280 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002281 return getKnown() && isAssumedDead(I);
2282 }
2283
2284 /// Check if instruction is after noreturn call, in other words, assumed dead.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002285 bool isAfterNoReturn(const Instruction *I) const;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002286
Johannes Doerfert924d2132019-08-05 21:34:45 +00002287 /// Determine if \p F might catch asynchronous exceptions.
2288 static bool mayCatchAsynchronousExceptions(const Function &F) {
2289 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2290 }
2291
Johannes Doerfert2f622062019-09-04 16:35:20 +00002292 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2293 /// that internal function called from \p BB should now be looked at.
2294 void assumeLive(Attributor &A, const BasicBlock &BB) {
2295 if (!AssumedLiveBlocks.insert(&BB).second)
2296 return;
2297
2298 // We assume that all of BB is (probably) live now and if there are calls to
2299 // internal functions we will assume that those are now live as well. This
2300 // is a performance optimization for blocks with calls to a lot of internal
2301 // functions. It can however cause dead functions to be treated as live.
2302 for (const Instruction &I : BB)
2303 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
2304 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00002305 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00002306 A.markLiveInternalFunction(*F);
2307 }
2308
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002309 /// Collection of to be explored paths.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002310 SmallSetVector<const Instruction *, 8> ToBeExploredPaths;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002311
2312 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002313 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002314
2315 /// Collection of calls with noreturn attribute, assumed or knwon.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002316 SmallSetVector<const Instruction *, 4> NoReturnCalls;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002317};
2318
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002319struct AAIsDeadFunction final : public AAIsDeadImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002320 AAIsDeadFunction(const IRPosition &IRP) : AAIsDeadImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002321
2322 /// See AbstractAttribute::trackStatistics()
2323 void trackStatistics() const override {
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002324 STATS_DECL(PartiallyDeadBlocks, Function,
2325 "Number of basic blocks classified as partially dead");
2326 BUILD_STAT_NAME(PartiallyDeadBlocks, Function) += NoReturnCalls.size();
2327 }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002328};
2329
2330bool AAIsDeadImpl::isAfterNoReturn(const Instruction *I) const {
Johannes Doerfert4361da22019-08-04 18:38:53 +00002331 const Instruction *PrevI = I->getPrevNode();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002332 while (PrevI) {
2333 if (NoReturnCalls.count(PrevI))
2334 return true;
2335 PrevI = PrevI->getPrevNode();
2336 }
2337 return false;
2338}
2339
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002340const Instruction *AAIsDeadImpl::findNextNoReturn(Attributor &A,
2341 const Instruction *I) {
Johannes Doerfert4361da22019-08-04 18:38:53 +00002342 const BasicBlock *BB = I->getParent();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002343 const Function &F = *BB->getParent();
2344
2345 // Flag to determine if we can change an invoke to a call assuming the callee
2346 // is nounwind. This is not possible if the personality of the function allows
2347 // to catch asynchronous exceptions.
2348 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002349
2350 // TODO: We should have a function that determines if an "edge" is dead.
2351 // Edges could be from an instruction to the next or from a terminator
2352 // to the successor. For now, we need to special case the unwind block
2353 // of InvokeInst below.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002354
2355 while (I) {
2356 ImmutableCallSite ICS(I);
2357
2358 if (ICS) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002359 const IRPosition &IPos = IRPosition::callsite_function(ICS);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002360 // Regarless of the no-return property of an invoke instruction we only
2361 // learn that the regular successor is not reachable through this
2362 // instruction but the unwind block might still be.
2363 if (auto *Invoke = dyn_cast<InvokeInst>(I)) {
2364 // Use nounwind to justify the unwind block is dead as well.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002365 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2366 if (!Invoke2CallAllowed || !AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002367 assumeLive(A, *Invoke->getUnwindDest());
Johannes Doerfert4361da22019-08-04 18:38:53 +00002368 ToBeExploredPaths.insert(&Invoke->getUnwindDest()->front());
2369 }
2370 }
2371
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002372 const auto &NoReturnAA = A.getAAFor<AANoReturn>(*this, IPos);
2373 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert4361da22019-08-04 18:38:53 +00002374 return I;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002375 }
2376
2377 I = I->getNextNode();
2378 }
2379
2380 // get new paths (reachable blocks).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002381 for (const BasicBlock *SuccBB : successors(BB)) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002382 assumeLive(A, *SuccBB);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002383 ToBeExploredPaths.insert(&SuccBB->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002384 }
2385
Johannes Doerfert4361da22019-08-04 18:38:53 +00002386 // No noreturn instruction found.
2387 return nullptr;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002388}
2389
Johannes Doerfertece81902019-08-12 22:05:53 +00002390ChangeStatus AAIsDeadImpl::updateImpl(Attributor &A) {
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002391 ChangeStatus Status = ChangeStatus::UNCHANGED;
2392
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002393 // Temporary collection to iterate over existing noreturn instructions. This
2394 // will alow easier modification of NoReturnCalls collection
Johannes Doerfert4361da22019-08-04 18:38:53 +00002395 SmallVector<const Instruction *, 8> NoReturnChanged;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002396
Johannes Doerfert4361da22019-08-04 18:38:53 +00002397 for (const Instruction *I : NoReturnCalls)
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002398 NoReturnChanged.push_back(I);
2399
Johannes Doerfert4361da22019-08-04 18:38:53 +00002400 for (const Instruction *I : NoReturnChanged) {
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002401 size_t Size = ToBeExploredPaths.size();
2402
Johannes Doerfert4361da22019-08-04 18:38:53 +00002403 const Instruction *NextNoReturnI = findNextNoReturn(A, I);
2404 if (NextNoReturnI != I) {
2405 Status = ChangeStatus::CHANGED;
2406 NoReturnCalls.remove(I);
2407 if (NextNoReturnI)
2408 NoReturnCalls.insert(NextNoReturnI);
2409 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002410
Johannes Doerfert4361da22019-08-04 18:38:53 +00002411 // Explore new paths.
2412 while (Size != ToBeExploredPaths.size()) {
2413 Status = ChangeStatus::CHANGED;
2414 if (const Instruction *NextNoReturnI =
2415 findNextNoReturn(A, ToBeExploredPaths[Size++]))
2416 NoReturnCalls.insert(NextNoReturnI);
2417 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002418 }
2419
Johannes Doerfertdef99282019-08-14 21:29:37 +00002420 LLVM_DEBUG(dbgs() << "[AAIsDead] AssumedLiveBlocks: "
2421 << AssumedLiveBlocks.size() << " Total number of blocks: "
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002422 << getAssociatedFunction()->size() << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002423
Johannes Doerfertd6207812019-08-07 22:32:38 +00002424 // If we know everything is live there is no need to query for liveness.
2425 if (NoReturnCalls.empty() &&
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002426 getAssociatedFunction()->size() == AssumedLiveBlocks.size()) {
Johannes Doerfertd6207812019-08-07 22:32:38 +00002427 // Indicating a pessimistic fixpoint will cause the state to be "invalid"
2428 // which will cause the Attributor to not return the AAIsDead on request,
2429 // which will prevent us from querying isAssumedDead().
2430 indicatePessimisticFixpoint();
2431 assert(!isValidState() && "Expected an invalid state!");
Johannes Doerfert62a9c1d2019-08-29 01:26:58 +00002432 Status = ChangeStatus::CHANGED;
Johannes Doerfertd6207812019-08-07 22:32:38 +00002433 }
2434
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002435 return Status;
2436}
2437
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002438/// Liveness information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002439struct AAIsDeadCallSite final : AAIsDeadImpl {
2440 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadImpl(IRP) {}
2441
2442 /// See AbstractAttribute::initialize(...).
2443 void initialize(Attributor &A) override {
2444 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002445 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002446 // sense to specialize attributes for call sites instead of
2447 // redirecting requests to the callee.
2448 llvm_unreachable("Abstract attributes for liveness are not "
2449 "supported for call sites yet!");
2450 }
2451
2452 /// See AbstractAttribute::updateImpl(...).
2453 ChangeStatus updateImpl(Attributor &A) override {
2454 return indicatePessimisticFixpoint();
2455 }
2456
2457 /// See AbstractAttribute::trackStatistics()
2458 void trackStatistics() const override {}
2459};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002460
Hideto Ueno19c07af2019-07-23 08:16:17 +00002461/// -------------------- Dereferenceable Argument Attribute --------------------
2462
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002463template <>
2464ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
2465 const DerefState &R) {
2466 ChangeStatus CS0 = clampStateAndIndicateChange<IntegerState>(
2467 S.DerefBytesState, R.DerefBytesState);
2468 ChangeStatus CS1 =
2469 clampStateAndIndicateChange<IntegerState>(S.GlobalState, R.GlobalState);
2470 return CS0 | CS1;
2471}
2472
Hideto Ueno70576ca2019-08-22 14:18:29 +00002473struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002474 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00002475 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00002476
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002477 void initialize(Attributor &A) override {
2478 SmallVector<Attribute, 4> Attrs;
2479 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
2480 Attrs);
2481 for (const Attribute &Attr : Attrs)
2482 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
2483
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002484 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002485
2486 const IRPosition &IRP = this->getIRPosition();
2487 bool IsFnInterface = IRP.isFnInterfaceKind();
2488 const Function *FnScope = IRP.getAnchorScope();
2489 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
2490 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002491 }
2492
Hideto Ueno19c07af2019-07-23 08:16:17 +00002493 /// See AbstractAttribute::getState()
2494 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00002495 StateType &getState() override { return *this; }
2496 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002497 /// }
2498
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002499 /// See AAFromMustBeExecutedContext
2500 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
2501 bool IsNonNull = false;
2502 bool TrackUse = false;
2503 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
2504 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
2505 takeKnownDerefBytesMaximum(DerefBytes);
2506 return TrackUse;
2507 }
2508
Johannes Doerferteccdf082019-08-05 23:35:12 +00002509 void getDeducedAttributes(LLVMContext &Ctx,
2510 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002511 // TODO: Add *_globally support
2512 if (isAssumedNonNull())
2513 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
2514 Ctx, getAssumedDereferenceableBytes()));
2515 else
2516 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
2517 Ctx, getAssumedDereferenceableBytes()));
2518 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002519
2520 /// See AbstractAttribute::getAsStr().
2521 const std::string getAsStr() const override {
2522 if (!getAssumedDereferenceableBytes())
2523 return "unknown-dereferenceable";
2524 return std::string("dereferenceable") +
2525 (isAssumedNonNull() ? "" : "_or_null") +
2526 (isAssumedGlobal() ? "_globally" : "") + "<" +
2527 std::to_string(getKnownDereferenceableBytes()) + "-" +
2528 std::to_string(getAssumedDereferenceableBytes()) + ">";
2529 }
2530};
2531
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002532/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002533struct AADereferenceableFloating
2534 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
2535 using Base =
2536 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
2537 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00002538
2539 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002540 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002541 ChangeStatus Change = Base::updateImpl(A);
2542
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002543 const DataLayout &DL = A.getDataLayout();
2544
2545 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
2546 unsigned IdxWidth =
2547 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
2548 APInt Offset(IdxWidth, 0);
2549 const Value *Base =
2550 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
2551
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002552 const auto &AA =
2553 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002554 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002555 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002556 // Use IR information if we did not strip anything.
2557 // TODO: track globally.
2558 bool CanBeNull;
2559 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
2560 T.GlobalState.indicatePessimisticFixpoint();
2561 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002562 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002563 DerefBytes = DS.DerefBytesState.getAssumed();
2564 T.GlobalState &= DS.GlobalState;
2565 }
2566
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002567 // For now we do not try to "increase" dereferenceability due to negative
2568 // indices as we first have to come up with code to deal with loops and
2569 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00002570 int64_t OffsetSExt = Offset.getSExtValue();
2571 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00002572 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002573
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002574 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00002575 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002576
Johannes Doerfert785fad32019-08-23 17:29:23 +00002577 if (this == &AA) {
2578 if (!Stripped) {
2579 // If nothing was stripped IR information is all we got.
2580 T.takeKnownDerefBytesMaximum(
2581 std::max(int64_t(0), DerefBytes - OffsetSExt));
2582 T.indicatePessimisticFixpoint();
2583 } else if (OffsetSExt > 0) {
2584 // If something was stripped but there is circular reasoning we look
2585 // for the offset. If it is positive we basically decrease the
2586 // dereferenceable bytes in a circluar loop now, which will simply
2587 // drive them down to the known value in a very slow way which we
2588 // can accelerate.
2589 T.indicatePessimisticFixpoint();
2590 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002591 }
2592
2593 return T.isValidState();
2594 };
2595
2596 DerefState T;
2597 if (!genericValueTraversal<AADereferenceable, DerefState>(
2598 A, getIRPosition(), *this, T, VisitValueCB))
2599 return indicatePessimisticFixpoint();
2600
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002601 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002602 }
2603
2604 /// See AbstractAttribute::trackStatistics()
2605 void trackStatistics() const override {
2606 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
2607 }
2608};
2609
2610/// Dereferenceable attribute for a return value.
2611struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002612 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2613 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002614 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002615 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2616 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002617
2618 /// See AbstractAttribute::trackStatistics()
2619 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002620 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002621 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002622};
2623
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002624/// Dereferenceable attribute for an argument
2625struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002626 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2627 AADereferenceable, AADereferenceableImpl, DerefState> {
2628 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2629 AADereferenceable, AADereferenceableImpl, DerefState>;
2630 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002631
2632 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002633 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00002634 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
2635 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002636};
2637
Hideto Ueno19c07af2019-07-23 08:16:17 +00002638/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002639struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002640 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002641 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002642
2643 /// See AbstractAttribute::trackStatistics()
2644 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002645 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002646 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002647};
2648
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002649/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002650struct AADereferenceableCallSiteReturned final
2651 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2652 AADereferenceable, AADereferenceableImpl> {
2653 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2654 AADereferenceable, AADereferenceableImpl>;
2655 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002656
2657 /// See AbstractAttribute::initialize(...).
2658 void initialize(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002659 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002660 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002661 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002662 indicatePessimisticFixpoint();
2663 }
2664
2665 /// See AbstractAttribute::updateImpl(...).
2666 ChangeStatus updateImpl(Attributor &A) override {
2667 // TODO: Once we have call site specific value information we can provide
2668 // call site specific liveness information and then it makes
2669 // sense to specialize attributes for call sites arguments instead of
2670 // redirecting requests to the callee argument.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002671
2672 ChangeStatus Change = Base::updateImpl(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002673 Function *F = getAssociatedFunction();
2674 const IRPosition &FnPos = IRPosition::returned(*F);
2675 auto &FnAA = A.getAAFor<AADereferenceable>(*this, FnPos);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002676 return Change |
2677 clampStateAndIndicateChange(
2678 getState(), static_cast<const DerefState &>(FnAA.getState()));
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002679 }
2680
2681 /// See AbstractAttribute::trackStatistics()
2682 void trackStatistics() const override {
2683 STATS_DECLTRACK_CS_ATTR(dereferenceable);
2684 }
2685};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002686
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002687// ------------------------ Align Argument Attribute ------------------------
2688
Johannes Doerfert344d0382019-08-07 22:34:26 +00002689struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002690 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002691
2692 // Max alignemnt value allowed in IR
2693 static const unsigned MAX_ALIGN = 1U << 29;
2694
Johannes Doerfert234eda52019-08-16 19:51:23 +00002695 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002696 void initialize(Attributor &A) override {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002697 takeAssumedMinimum(MAX_ALIGN);
2698
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002699 SmallVector<Attribute, 4> Attrs;
2700 getAttrs({Attribute::Alignment}, Attrs);
2701 for (const Attribute &Attr : Attrs)
2702 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00002703
2704 if (getIRPosition().isFnInterfaceKind() &&
2705 (!getAssociatedFunction() ||
2706 !getAssociatedFunction()->hasExactDefinition()))
2707 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002708 }
2709
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002710 /// See AbstractAttribute::manifest(...).
2711 ChangeStatus manifest(Attributor &A) override {
2712 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2713
2714 // Check for users that allow alignment annotations.
2715 Value &AnchorVal = getIRPosition().getAnchorValue();
2716 for (const Use &U : AnchorVal.uses()) {
2717 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
2718 if (SI->getPointerOperand() == &AnchorVal)
2719 if (SI->getAlignment() < getAssumedAlign()) {
2720 STATS_DECLTRACK(AAAlign, Store,
2721 "Number of times alignemnt added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00002722 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002723 Changed = ChangeStatus::CHANGED;
2724 }
2725 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
2726 if (LI->getPointerOperand() == &AnchorVal)
2727 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00002728 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002729 STATS_DECLTRACK(AAAlign, Load,
2730 "Number of times alignemnt added to a load");
2731 Changed = ChangeStatus::CHANGED;
2732 }
2733 }
2734 }
2735
Johannes Doerfert81df4522019-08-30 15:22:28 +00002736 return AAAlign::manifest(A) | Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002737 }
2738
Johannes Doerfert81df4522019-08-30 15:22:28 +00002739 // TODO: Provide a helper to determine the implied ABI alignment and check in
2740 // the existing manifest method and a new one for AAAlignImpl that value
2741 // to avoid making the alignment explicit if it did not improve.
2742
2743 /// See AbstractAttribute::getDeducedAttributes
2744 virtual void
2745 getDeducedAttributes(LLVMContext &Ctx,
2746 SmallVectorImpl<Attribute> &Attrs) const override {
2747 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00002748 Attrs.emplace_back(
2749 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00002750 }
2751
2752 /// See AbstractAttribute::getAsStr().
2753 const std::string getAsStr() const override {
2754 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
2755 "-" + std::to_string(getAssumedAlign()) + ">")
2756 : "unknown-align";
2757 }
2758};
2759
2760/// Align attribute for a floating value.
2761struct AAAlignFloating : AAAlignImpl {
2762 AAAlignFloating(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2763
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002764 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00002765 ChangeStatus updateImpl(Attributor &A) override {
2766 const DataLayout &DL = A.getDataLayout();
2767
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002768 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
2769 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002770 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
2771 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002772 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00002773 const MaybeAlign PA = V.getPointerAlignment(DL);
2774 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00002775 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002776 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002777 // Use abstract attribute information.
2778 const AAAlign::StateType &DS =
2779 static_cast<const AAAlign::StateType &>(AA.getState());
2780 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00002781 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002782 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002783 };
2784
2785 StateType T;
2786 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
2787 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002788 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002789
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00002790 // TODO: If we know we visited all incoming values, thus no are assumed
2791 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00002792 return clampStateAndIndicateChange(getState(), T);
2793 }
2794
2795 /// See AbstractAttribute::trackStatistics()
2796 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
2797};
2798
2799/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002800struct AAAlignReturned final
2801 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002802 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002803 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002804
2805 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002806 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002807};
2808
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002809/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002810struct AAAlignArgument final
2811 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002812 AAAlignArgument(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002813 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002814
2815 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00002816 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002817};
2818
Johannes Doerfert234eda52019-08-16 19:51:23 +00002819struct AAAlignCallSiteArgument final : AAAlignFloating {
2820 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002821
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002822 /// See AbstractAttribute::manifest(...).
2823 ChangeStatus manifest(Attributor &A) override {
2824 return AAAlignImpl::manifest(A);
2825 }
2826
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002827 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002828 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002829};
2830
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002831/// Align attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002832struct AAAlignCallSiteReturned final : AAAlignImpl {
2833 AAAlignCallSiteReturned(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2834
2835 /// See AbstractAttribute::initialize(...).
2836 void initialize(Attributor &A) override {
2837 AAAlignImpl::initialize(A);
2838 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002839 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002840 indicatePessimisticFixpoint();
2841 }
2842
2843 /// See AbstractAttribute::updateImpl(...).
2844 ChangeStatus updateImpl(Attributor &A) override {
2845 // TODO: Once we have call site specific value information we can provide
2846 // call site specific liveness information and then it makes
2847 // sense to specialize attributes for call sites arguments instead of
2848 // redirecting requests to the callee argument.
2849 Function *F = getAssociatedFunction();
2850 const IRPosition &FnPos = IRPosition::returned(*F);
2851 auto &FnAA = A.getAAFor<AAAlign>(*this, FnPos);
2852 return clampStateAndIndicateChange(
2853 getState(), static_cast<const AAAlign::StateType &>(FnAA.getState()));
2854 }
2855
2856 /// See AbstractAttribute::trackStatistics()
2857 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
2858};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002859
Johannes Doerferte83f3032019-08-05 23:22:05 +00002860/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00002861struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002862 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00002863
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00002864 /// See AbstractAttribute::initialize(...).
2865 void initialize(Attributor &A) override {
2866 AANoReturn::initialize(A);
2867 Function *F = getAssociatedFunction();
2868 if (!F || F->hasFnAttribute(Attribute::WillReturn))
2869 indicatePessimisticFixpoint();
2870 }
2871
Johannes Doerferte83f3032019-08-05 23:22:05 +00002872 /// See AbstractAttribute::getAsStr().
2873 const std::string getAsStr() const override {
2874 return getAssumed() ? "noreturn" : "may-return";
2875 }
2876
Johannes Doerferte83f3032019-08-05 23:22:05 +00002877 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00002878 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00002879 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, getIRPosition());
2880 if (WillReturnAA.isKnownWillReturn())
2881 return indicatePessimisticFixpoint();
Johannes Doerfertd0f64002019-08-06 00:32:43 +00002882 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002883 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00002884 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00002885 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00002886 return ChangeStatus::UNCHANGED;
2887 }
2888};
2889
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002890struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002891 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002892
2893 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002894 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002895};
2896
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002897/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002898struct AANoReturnCallSite final : AANoReturnImpl {
2899 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
2900
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002901 /// See AbstractAttribute::updateImpl(...).
2902 ChangeStatus updateImpl(Attributor &A) override {
2903 // TODO: Once we have call site specific value information we can provide
2904 // call site specific liveness information and then it makes
2905 // sense to specialize attributes for call sites arguments instead of
2906 // redirecting requests to the callee argument.
2907 Function *F = getAssociatedFunction();
2908 const IRPosition &FnPos = IRPosition::function(*F);
2909 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
2910 return clampStateAndIndicateChange(
2911 getState(),
2912 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
2913 }
2914
2915 /// See AbstractAttribute::trackStatistics()
2916 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
2917};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002918
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002919/// ----------------------- Variable Capturing ---------------------------------
2920
2921/// A class to hold the state of for no-capture attributes.
2922struct AANoCaptureImpl : public AANoCapture {
2923 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
2924
2925 /// See AbstractAttribute::initialize(...).
2926 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002927 AANoCapture::initialize(A);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002928
Johannes Doerfert72adda12019-10-10 05:33:21 +00002929 // You cannot "capture" null in the default address space.
2930 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
2931 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
2932 indicateOptimisticFixpoint();
2933 return;
2934 }
2935
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002936 const IRPosition &IRP = getIRPosition();
2937 const Function *F =
2938 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
2939
2940 // Check what state the associated function can actually capture.
2941 if (F)
Johannes Doerfert3839b572019-10-21 00:48:42 +00002942 determineFunctionCaptureCapabilities(IRP, *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002943 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002944 indicatePessimisticFixpoint();
2945 }
2946
2947 /// See AbstractAttribute::updateImpl(...).
2948 ChangeStatus updateImpl(Attributor &A) override;
2949
2950 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
2951 virtual void
2952 getDeducedAttributes(LLVMContext &Ctx,
2953 SmallVectorImpl<Attribute> &Attrs) const override {
2954 if (!isAssumedNoCaptureMaybeReturned())
2955 return;
2956
Hideto Ueno37367642019-09-11 06:52:11 +00002957 if (getArgNo() >= 0) {
2958 if (isAssumedNoCapture())
2959 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
2960 else if (ManifestInternal)
2961 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
2962 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002963 }
2964
2965 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
2966 /// depending on the ability of the function associated with \p IRP to capture
2967 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00002968 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
2969 const Function &F,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002970 IntegerState &State) {
2971 // TODO: Once we have memory behavior attributes we should use them here.
2972
2973 // If we know we cannot communicate or write to memory, we do not care about
2974 // ptr2int anymore.
2975 if (F.onlyReadsMemory() && F.doesNotThrow() &&
2976 F.getReturnType()->isVoidTy()) {
2977 State.addKnownBits(NO_CAPTURE);
2978 return;
2979 }
2980
2981 // A function cannot capture state in memory if it only reads memory, it can
2982 // however return/throw state and the state might be influenced by the
2983 // pointer value, e.g., loading from a returned pointer might reveal a bit.
2984 if (F.onlyReadsMemory())
2985 State.addKnownBits(NOT_CAPTURED_IN_MEM);
2986
2987 // A function cannot communicate state back if it does not through
2988 // exceptions and doesn not return values.
2989 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
2990 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00002991
2992 // Check existing "returned" attributes.
2993 int ArgNo = IRP.getArgNo();
2994 if (F.doesNotThrow() && ArgNo >= 0) {
2995 for (unsigned u = 0, e = F.arg_size(); u< e; ++u)
2996 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00002997 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00002998 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
2999 else if (F.onlyReadsMemory())
3000 State.addKnownBits(NO_CAPTURE);
3001 else
3002 State.addKnownBits(NOT_CAPTURED_IN_RET);
3003 break;
3004 }
3005 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003006 }
3007
3008 /// See AbstractState::getAsStr().
3009 const std::string getAsStr() const override {
3010 if (isKnownNoCapture())
3011 return "known not-captured";
3012 if (isAssumedNoCapture())
3013 return "assumed not-captured";
3014 if (isKnownNoCaptureMaybeReturned())
3015 return "known not-captured-maybe-returned";
3016 if (isAssumedNoCaptureMaybeReturned())
3017 return "assumed not-captured-maybe-returned";
3018 return "assumed-captured";
3019 }
3020};
3021
3022/// Attributor-aware capture tracker.
3023struct AACaptureUseTracker final : public CaptureTracker {
3024
3025 /// Create a capture tracker that can lookup in-flight abstract attributes
3026 /// through the Attributor \p A.
3027 ///
3028 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
3029 /// search is stopped. If a use leads to a return instruction,
3030 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
3031 /// If a use leads to a ptr2int which may capture the value,
3032 /// \p CapturedInInteger is set. If a use is found that is currently assumed
3033 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
3034 /// set. All values in \p PotentialCopies are later tracked as well. For every
3035 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
3036 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
3037 /// conservatively set to true.
3038 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
3039 const AAIsDead &IsDeadAA, IntegerState &State,
3040 SmallVectorImpl<const Value *> &PotentialCopies,
3041 unsigned &RemainingUsesToExplore)
3042 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
3043 PotentialCopies(PotentialCopies),
3044 RemainingUsesToExplore(RemainingUsesToExplore) {}
3045
3046 /// Determine if \p V maybe captured. *Also updates the state!*
3047 bool valueMayBeCaptured(const Value *V) {
3048 if (V->getType()->isPointerTy()) {
3049 PointerMayBeCaptured(V, this);
3050 } else {
3051 State.indicatePessimisticFixpoint();
3052 }
3053 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3054 }
3055
3056 /// See CaptureTracker::tooManyUses().
3057 void tooManyUses() override {
3058 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
3059 }
3060
3061 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
3062 if (CaptureTracker::isDereferenceableOrNull(O, DL))
3063 return true;
3064 const auto &DerefAA =
3065 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
3066 return DerefAA.getAssumedDereferenceableBytes();
3067 }
3068
3069 /// See CaptureTracker::captured(...).
3070 bool captured(const Use *U) override {
3071 Instruction *UInst = cast<Instruction>(U->getUser());
3072 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3073 << "\n");
3074
3075 // Because we may reuse the tracker multiple times we keep track of the
3076 // number of explored uses ourselves as well.
3077 if (RemainingUsesToExplore-- == 0) {
3078 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3079 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3080 /* Return */ true);
3081 }
3082
3083 // Deal with ptr2int by following uses.
3084 if (isa<PtrToIntInst>(UInst)) {
3085 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3086 return valueMayBeCaptured(UInst);
3087 }
3088
3089 // Explicitly catch return instructions.
3090 if (isa<ReturnInst>(UInst))
3091 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3092 /* Return */ true);
3093
3094 // For now we only use special logic for call sites. However, the tracker
3095 // itself knows about a lot of other non-capturing cases already.
3096 CallSite CS(UInst);
3097 if (!CS || !CS.isArgOperand(U))
3098 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3099 /* Return */ true);
3100
3101 unsigned ArgNo = CS.getArgumentNo(U);
3102 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3103 // If we have a abstract no-capture attribute for the argument we can use
3104 // it to justify a non-capture attribute here. This allows recursion!
3105 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3106 if (ArgNoCaptureAA.isAssumedNoCapture())
3107 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3108 /* Return */ false);
3109 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3110 addPotentialCopy(CS);
3111 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3112 /* Return */ false);
3113 }
3114
3115 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3116 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3117 /* Return */ true);
3118 }
3119
3120 /// Register \p CS as potential copy of the value we are checking.
3121 void addPotentialCopy(CallSite CS) {
3122 PotentialCopies.push_back(CS.getInstruction());
3123 }
3124
3125 /// See CaptureTracker::shouldExplore(...).
3126 bool shouldExplore(const Use *U) override {
3127 // Check liveness.
3128 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3129 }
3130
3131 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3132 /// \p CapturedInRet, then return the appropriate value for use in the
3133 /// CaptureTracker::captured() interface.
3134 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3135 bool CapturedInRet) {
3136 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
3137 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
3138 if (CapturedInMem)
3139 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
3140 if (CapturedInInt)
3141 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
3142 if (CapturedInRet)
3143 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
3144 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3145 }
3146
3147private:
3148 /// The attributor providing in-flight abstract attributes.
3149 Attributor &A;
3150
3151 /// The abstract attribute currently updated.
3152 AANoCapture &NoCaptureAA;
3153
3154 /// The abstract liveness state.
3155 const AAIsDead &IsDeadAA;
3156
3157 /// The state currently updated.
3158 IntegerState &State;
3159
3160 /// Set of potential copies of the tracked value.
3161 SmallVectorImpl<const Value *> &PotentialCopies;
3162
3163 /// Global counter to limit the number of explored uses.
3164 unsigned &RemainingUsesToExplore;
3165};
3166
3167ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
3168 const IRPosition &IRP = getIRPosition();
3169 const Value *V =
3170 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
3171 if (!V)
3172 return indicatePessimisticFixpoint();
3173
3174 const Function *F =
3175 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
3176 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00003177 const IRPosition &FnPos = IRPosition::function(*F);
3178 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, FnPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003179
3180 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003181
Johannes Doerfert3839b572019-10-21 00:48:42 +00003182 // Readonly means we cannot capture through memory.
3183 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3184 if (FnMemAA.isAssumedReadOnly()) {
3185 T.addKnownBits(NOT_CAPTURED_IN_MEM);
3186 if (FnMemAA.isKnownReadOnly())
3187 addKnownBits(NOT_CAPTURED_IN_MEM);
3188 }
3189
3190 // Make sure all returned values are different than the underlying value.
3191 // TODO: we could do this in a more sophisticated way inside
3192 // AAReturnedValues, e.g., track all values that escape through returns
3193 // directly somehow.
3194 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
3195 bool SeenConstant = false;
3196 for (auto &It : RVAA.returned_values()) {
3197 if (isa<Constant>(It.first)) {
3198 if (SeenConstant)
3199 return false;
3200 SeenConstant = true;
3201 } else if (!isa<Argument>(It.first) ||
3202 It.first == getAssociatedArgument())
3203 return false;
3204 }
3205 return true;
3206 };
3207
3208 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, FnPos);
3209 if (NoUnwindAA.isAssumedNoUnwind()) {
3210 bool IsVoidTy = F->getReturnType()->isVoidTy();
3211 const AAReturnedValues *RVAA =
3212 IsVoidTy ? nullptr : &A.getAAFor<AAReturnedValues>(*this, FnPos);
3213 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
3214 T.addKnownBits(NOT_CAPTURED_IN_RET);
3215 if (T.isKnown(NOT_CAPTURED_IN_MEM))
3216 return ChangeStatus::UNCHANGED;
3217 if (NoUnwindAA.isKnownNoUnwind() &&
3218 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
3219 addKnownBits(NOT_CAPTURED_IN_RET);
3220 if (isKnown(NOT_CAPTURED_IN_MEM))
3221 return indicateOptimisticFixpoint();
3222 }
3223 }
3224 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003225
3226 // Use the CaptureTracker interface and logic with the specialized tracker,
3227 // defined in AACaptureUseTracker, that can look at in-flight abstract
3228 // attributes and directly updates the assumed state.
3229 SmallVector<const Value *, 4> PotentialCopies;
3230 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
3231 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
3232 RemainingUsesToExplore);
3233
3234 // Check all potential copies of the associated value until we can assume
3235 // none will be captured or we have to assume at least one might be.
3236 unsigned Idx = 0;
3237 PotentialCopies.push_back(V);
3238 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
3239 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
3240
3241 AAAlign::StateType &S = getState();
3242 auto Assumed = S.getAssumed();
3243 S.intersectAssumedBits(T.getAssumed());
3244 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3245 : ChangeStatus::CHANGED;
3246}
3247
3248/// NoCapture attribute for function arguments.
3249struct AANoCaptureArgument final : AANoCaptureImpl {
3250 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3251
3252 /// See AbstractAttribute::trackStatistics()
3253 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
3254};
3255
3256/// NoCapture attribute for call site arguments.
3257struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
3258 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3259
3260 /// See AbstractAttribute::updateImpl(...).
3261 ChangeStatus updateImpl(Attributor &A) override {
3262 // TODO: Once we have call site specific value information we can provide
3263 // call site specific liveness information and then it makes
3264 // sense to specialize attributes for call sites arguments instead of
3265 // redirecting requests to the callee argument.
3266 Argument *Arg = getAssociatedArgument();
3267 if (!Arg)
3268 return indicatePessimisticFixpoint();
3269 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3270 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
3271 return clampStateAndIndicateChange(
3272 getState(),
3273 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3274 }
3275
3276 /// See AbstractAttribute::trackStatistics()
3277 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
3278};
3279
3280/// NoCapture attribute for floating values.
3281struct AANoCaptureFloating final : AANoCaptureImpl {
3282 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3283
3284 /// See AbstractAttribute::trackStatistics()
3285 void trackStatistics() const override {
3286 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
3287 }
3288};
3289
3290/// NoCapture attribute for function return value.
3291struct AANoCaptureReturned final : AANoCaptureImpl {
3292 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
3293 llvm_unreachable("NoCapture is not applicable to function returns!");
3294 }
3295
3296 /// See AbstractAttribute::initialize(...).
3297 void initialize(Attributor &A) override {
3298 llvm_unreachable("NoCapture is not applicable to function returns!");
3299 }
3300
3301 /// See AbstractAttribute::updateImpl(...).
3302 ChangeStatus updateImpl(Attributor &A) override {
3303 llvm_unreachable("NoCapture is not applicable to function returns!");
3304 }
3305
3306 /// See AbstractAttribute::trackStatistics()
3307 void trackStatistics() const override {}
3308};
3309
3310/// NoCapture attribute deduction for a call site return value.
3311struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
3312 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3313
3314 /// See AbstractAttribute::trackStatistics()
3315 void trackStatistics() const override {
3316 STATS_DECLTRACK_CSRET_ATTR(nocapture)
3317 }
3318};
3319
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003320/// ------------------ Value Simplify Attribute ----------------------------
3321struct AAValueSimplifyImpl : AAValueSimplify {
3322 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
3323
3324 /// See AbstractAttribute::getAsStr().
3325 const std::string getAsStr() const override {
3326 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
3327 : "not-simple";
3328 }
3329
3330 /// See AbstractAttribute::trackStatistics()
3331 void trackStatistics() const override {}
3332
3333 /// See AAValueSimplify::getAssumedSimplifiedValue()
3334 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
3335 if (!getAssumed())
3336 return const_cast<Value *>(&getAssociatedValue());
3337 return SimplifiedAssociatedValue;
3338 }
3339 void initialize(Attributor &A) override {}
3340
3341 /// Helper function for querying AAValueSimplify and updating candicate.
3342 /// \param QueryingValue Value trying to unify with SimplifiedValue
3343 /// \param AccumulatedSimplifiedValue Current simplification result.
3344 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
3345 Value &QueryingValue,
3346 Optional<Value *> &AccumulatedSimplifiedValue) {
3347 // FIXME: Add a typecast support.
3348
3349 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
3350 QueryingAA, IRPosition::value(QueryingValue));
3351
3352 Optional<Value *> QueryingValueSimplified =
3353 ValueSimpifyAA.getAssumedSimplifiedValue(A);
3354
3355 if (!QueryingValueSimplified.hasValue())
3356 return true;
3357
3358 if (!QueryingValueSimplified.getValue())
3359 return false;
3360
3361 Value &QueryingValueSimplifiedUnwrapped =
3362 *QueryingValueSimplified.getValue();
3363
3364 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
3365 return true;
3366
3367 if (AccumulatedSimplifiedValue.hasValue())
3368 return AccumulatedSimplifiedValue == QueryingValueSimplified;
3369
3370 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
3371 << " is assumed to be "
3372 << QueryingValueSimplifiedUnwrapped << "\n");
3373
3374 AccumulatedSimplifiedValue = QueryingValueSimplified;
3375 return true;
3376 }
3377
3378 /// See AbstractAttribute::manifest(...).
3379 ChangeStatus manifest(Attributor &A) override {
3380 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3381
3382 if (!SimplifiedAssociatedValue.hasValue() ||
3383 !SimplifiedAssociatedValue.getValue())
3384 return Changed;
3385
3386 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
3387 // We can replace the AssociatedValue with the constant.
3388 Value &V = getAssociatedValue();
3389 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
3390 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
3391 << "\n");
3392 V.replaceAllUsesWith(C);
3393 Changed = ChangeStatus::CHANGED;
3394 }
3395 }
3396
3397 return Changed | AAValueSimplify::manifest(A);
3398 }
3399
3400protected:
3401 // An assumed simplified value. Initially, it is set to Optional::None, which
3402 // means that the value is not clear under current assumption. If in the
3403 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
3404 // returns orignal associated value.
3405 Optional<Value *> SimplifiedAssociatedValue;
3406};
3407
3408struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
3409 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3410
3411 /// See AbstractAttribute::updateImpl(...).
3412 ChangeStatus updateImpl(Attributor &A) override {
3413 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3414
Johannes Doerfert661db042019-10-07 23:14:58 +00003415 auto PredForCallSite = [&](AbstractCallSite ACS) {
3416 // Check if we have an associated argument or not (which can happen for
3417 // callback calls).
3418 if (Value *ArgOp = ACS.getCallArgOperand(getArgNo()))
3419 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
3420 return false;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003421 };
3422
3423 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
3424 return indicatePessimisticFixpoint();
3425
3426 // If a candicate was found in this update, return CHANGED.
3427 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3428 ? ChangeStatus::UNCHANGED
3429 : ChangeStatus ::CHANGED;
3430 }
3431
3432 /// See AbstractAttribute::trackStatistics()
3433 void trackStatistics() const override {
3434 STATS_DECLTRACK_ARG_ATTR(value_simplify)
3435 }
3436};
3437
3438struct AAValueSimplifyReturned : AAValueSimplifyImpl {
3439 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3440
3441 /// See AbstractAttribute::updateImpl(...).
3442 ChangeStatus updateImpl(Attributor &A) override {
3443 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3444
3445 auto PredForReturned = [&](Value &V) {
3446 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3447 };
3448
3449 if (!A.checkForAllReturnedValues(PredForReturned, *this))
3450 return indicatePessimisticFixpoint();
3451
3452 // If a candicate was found in this update, return CHANGED.
3453 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3454 ? ChangeStatus::UNCHANGED
3455 : ChangeStatus ::CHANGED;
3456 }
3457 /// See AbstractAttribute::trackStatistics()
3458 void trackStatistics() const override {
3459 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
3460 }
3461};
3462
3463struct AAValueSimplifyFloating : AAValueSimplifyImpl {
3464 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3465
3466 /// See AbstractAttribute::initialize(...).
3467 void initialize(Attributor &A) override {
3468 Value &V = getAnchorValue();
3469
3470 // TODO: add other stuffs
3471 if (isa<Constant>(V) || isa<UndefValue>(V))
3472 indicatePessimisticFixpoint();
3473 }
3474
3475 /// See AbstractAttribute::updateImpl(...).
3476 ChangeStatus updateImpl(Attributor &A) override {
3477 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3478
3479 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
3480 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
3481 if (!Stripped && this == &AA) {
3482 // TODO: Look the instruction and check recursively.
3483 LLVM_DEBUG(
3484 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
3485 << V << "\n");
3486 indicatePessimisticFixpoint();
3487 return false;
3488 }
3489 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3490 };
3491
3492 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
3493 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
3494 VisitValueCB))
3495 return indicatePessimisticFixpoint();
3496
3497 // If a candicate was found in this update, return CHANGED.
3498
3499 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3500 ? ChangeStatus::UNCHANGED
3501 : ChangeStatus ::CHANGED;
3502 }
3503
3504 /// See AbstractAttribute::trackStatistics()
3505 void trackStatistics() const override {
3506 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
3507 }
3508};
3509
3510struct AAValueSimplifyFunction : AAValueSimplifyImpl {
3511 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3512
3513 /// See AbstractAttribute::initialize(...).
3514 void initialize(Attributor &A) override {
3515 SimplifiedAssociatedValue = &getAnchorValue();
3516 indicateOptimisticFixpoint();
3517 }
3518 /// See AbstractAttribute::initialize(...).
3519 ChangeStatus updateImpl(Attributor &A) override {
3520 llvm_unreachable(
3521 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
3522 }
3523 /// See AbstractAttribute::trackStatistics()
3524 void trackStatistics() const override {
3525 STATS_DECLTRACK_FN_ATTR(value_simplify)
3526 }
3527};
3528
3529struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
3530 AAValueSimplifyCallSite(const IRPosition &IRP)
3531 : AAValueSimplifyFunction(IRP) {}
3532 /// See AbstractAttribute::trackStatistics()
3533 void trackStatistics() const override {
3534 STATS_DECLTRACK_CS_ATTR(value_simplify)
3535 }
3536};
3537
3538struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
3539 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
3540 : AAValueSimplifyReturned(IRP) {}
3541
3542 void trackStatistics() const override {
3543 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
3544 }
3545};
3546struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
3547 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
3548 : AAValueSimplifyFloating(IRP) {}
3549
3550 void trackStatistics() const override {
3551 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
3552 }
3553};
3554
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003555/// ----------------------- Heap-To-Stack Conversion ---------------------------
3556struct AAHeapToStackImpl : public AAHeapToStack {
3557 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
3558
3559 const std::string getAsStr() const override {
3560 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
3561 }
3562
3563 ChangeStatus manifest(Attributor &A) override {
3564 assert(getState().isValidState() &&
3565 "Attempted to manifest an invalid state!");
3566
3567 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
3568 Function *F = getAssociatedFunction();
3569 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3570
3571 for (Instruction *MallocCall : MallocCalls) {
3572 // This malloc cannot be replaced.
3573 if (BadMallocCalls.count(MallocCall))
3574 continue;
3575
3576 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
3577 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
3578 A.deleteAfterManifest(*FreeCall);
3579 HasChanged = ChangeStatus::CHANGED;
3580 }
3581
3582 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
3583 << "\n");
3584
3585 Constant *Size;
3586 if (isCallocLikeFn(MallocCall, TLI)) {
3587 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
3588 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
3589 APInt TotalSize = SizeT->getValue() * Num->getValue();
3590 Size =
3591 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
3592 } else {
3593 Size = cast<ConstantInt>(MallocCall->getOperand(0));
3594 }
3595
3596 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
3597 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
3598 Size, "", MallocCall->getNextNode());
3599
3600 if (AI->getType() != MallocCall->getType())
3601 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
3602 AI->getNextNode());
3603
3604 MallocCall->replaceAllUsesWith(AI);
3605
3606 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
3607 auto *NBB = II->getNormalDest();
3608 BranchInst::Create(NBB, MallocCall->getParent());
3609 A.deleteAfterManifest(*MallocCall);
3610 } else {
3611 A.deleteAfterManifest(*MallocCall);
3612 }
3613
3614 if (isCallocLikeFn(MallocCall, TLI)) {
3615 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
3616 AI->getNextNode());
3617 Value *Ops[] = {
3618 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
3619 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
3620
3621 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
3622 Module *M = F->getParent();
3623 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
3624 CallInst::Create(Fn, Ops, "", BI->getNextNode());
3625 }
3626 HasChanged = ChangeStatus::CHANGED;
3627 }
3628
3629 return HasChanged;
3630 }
3631
3632 /// Collection of all malloc calls in a function.
3633 SmallSetVector<Instruction *, 4> MallocCalls;
3634
3635 /// Collection of malloc calls that cannot be converted.
3636 DenseSet<const Instruction *> BadMallocCalls;
3637
3638 /// A map for each malloc call to the set of associated free calls.
3639 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
3640
3641 ChangeStatus updateImpl(Attributor &A) override;
3642};
3643
3644ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
3645 const Function *F = getAssociatedFunction();
3646 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3647
3648 auto UsesCheck = [&](Instruction &I) {
3649 SmallPtrSet<const Use *, 8> Visited;
3650 SmallVector<const Use *, 8> Worklist;
3651
3652 for (Use &U : I.uses())
3653 Worklist.push_back(&U);
3654
3655 while (!Worklist.empty()) {
3656 const Use *U = Worklist.pop_back_val();
3657 if (!Visited.insert(U).second)
3658 continue;
3659
3660 auto *UserI = U->getUser();
3661
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003662 if (isa<LoadInst>(UserI))
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003663 continue;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003664 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
3665 if (SI->getValueOperand() == U->get()) {
3666 LLVM_DEBUG(dbgs() << "[H2S] escaping store to memory: " << *UserI << "\n");
3667 return false;
3668 }
3669 // A store into the malloc'ed memory is fine.
3670 continue;
3671 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003672
3673 // NOTE: Right now, if a function that has malloc pointer as an argument
3674 // frees memory, we assume that the malloc pointer is freed.
3675
3676 // TODO: Add nofree callsite argument attribute to indicate that pointer
3677 // argument is not freed.
3678 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3679 if (!CB->isArgOperand(U))
3680 continue;
3681
3682 if (CB->isLifetimeStartOrEnd())
3683 continue;
3684
3685 // Record malloc.
3686 if (isFreeCall(UserI, TLI)) {
3687 FreesForMalloc[&I].insert(
3688 cast<Instruction>(const_cast<User *>(UserI)));
3689 continue;
3690 }
3691
3692 // If a function does not free memory we are fine
3693 const auto &NoFreeAA =
3694 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(*CB));
3695
3696 unsigned ArgNo = U - CB->arg_begin();
3697 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
3698 *this, IRPosition::callsite_argument(*CB, ArgNo));
3699
3700 if (!NoCaptureAA.isAssumedNoCapture() || !NoFreeAA.isAssumedNoFree()) {
3701 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
3702 return false;
3703 }
3704 continue;
3705 }
3706
3707 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI)) {
3708 for (Use &U : UserI->uses())
3709 Worklist.push_back(&U);
3710 continue;
3711 }
3712
3713 // Unknown user.
3714 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
3715 return false;
3716 }
3717 return true;
3718 };
3719
3720 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003721 if (BadMallocCalls.count(&I))
3722 return true;
3723
3724 bool IsMalloc = isMallocLikeFn(&I, TLI);
3725 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
3726 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003727 BadMallocCalls.insert(&I);
3728 return true;
3729 }
3730
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003731 if (IsMalloc) {
3732 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
3733 if (Size->getValue().sle(MaxHeapToStackSize))
3734 if (UsesCheck(I)) {
3735 MallocCalls.insert(&I);
3736 return true;
3737 }
3738 } else if (IsCalloc) {
3739 bool Overflow = false;
3740 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
3741 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
3742 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
3743 .sle(MaxHeapToStackSize))
3744 if (!Overflow && UsesCheck(I)) {
3745 MallocCalls.insert(&I);
3746 return true;
3747 }
3748 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003749
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003750 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003751 return true;
3752 };
3753
3754 size_t NumBadMallocs = BadMallocCalls.size();
3755
3756 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
3757
3758 if (NumBadMallocs != BadMallocCalls.size())
3759 return ChangeStatus::CHANGED;
3760
3761 return ChangeStatus::UNCHANGED;
3762}
3763
3764struct AAHeapToStackFunction final : public AAHeapToStackImpl {
3765 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
3766
3767 /// See AbstractAttribute::trackStatistics()
3768 void trackStatistics() const override {
3769 STATS_DECL(MallocCalls, Function,
3770 "Number of MallocCalls converted to allocas");
3771 BUILD_STAT_NAME(MallocCalls, Function) += MallocCalls.size();
3772 }
3773};
3774
Johannes Doerfert1097fab2019-10-07 21:07:57 +00003775/// -------------------- Memory Behavior Attributes ----------------------------
3776/// Includes read-none, read-only, and write-only.
3777/// ----------------------------------------------------------------------------
3778struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
3779 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
3780
3781 /// See AbstractAttribute::initialize(...).
3782 void initialize(Attributor &A) override {
3783 intersectAssumedBits(BEST_STATE);
3784 getKnownStateFromValue(getIRPosition(), getState());
3785 IRAttribute::initialize(A);
3786 }
3787
3788 /// Return the memory behavior information encoded in the IR for \p IRP.
3789 static void getKnownStateFromValue(const IRPosition &IRP,
3790 IntegerState &State) {
3791 SmallVector<Attribute, 2> Attrs;
3792 IRP.getAttrs(AttrKinds, Attrs);
3793 for (const Attribute &Attr : Attrs) {
3794 switch (Attr.getKindAsEnum()) {
3795 case Attribute::ReadNone:
3796 State.addKnownBits(NO_ACCESSES);
3797 break;
3798 case Attribute::ReadOnly:
3799 State.addKnownBits(NO_WRITES);
3800 break;
3801 case Attribute::WriteOnly:
3802 State.addKnownBits(NO_READS);
3803 break;
3804 default:
3805 llvm_unreachable("Unexpcted attribute!");
3806 }
3807 }
3808
3809 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
3810 if (!I->mayReadFromMemory())
3811 State.addKnownBits(NO_READS);
3812 if (!I->mayWriteToMemory())
3813 State.addKnownBits(NO_WRITES);
3814 }
3815 }
3816
3817 /// See AbstractAttribute::getDeducedAttributes(...).
3818 void getDeducedAttributes(LLVMContext &Ctx,
3819 SmallVectorImpl<Attribute> &Attrs) const override {
3820 assert(Attrs.size() == 0);
3821 if (isAssumedReadNone())
3822 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
3823 else if (isAssumedReadOnly())
3824 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
3825 else if (isAssumedWriteOnly())
3826 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
3827 assert(Attrs.size() <= 1);
3828 }
3829
3830 /// See AbstractAttribute::manifest(...).
3831 ChangeStatus manifest(Attributor &A) override {
3832 IRPosition &IRP = getIRPosition();
3833
3834 // Check if we would improve the existing attributes first.
3835 SmallVector<Attribute, 4> DeducedAttrs;
3836 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
3837 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
3838 return IRP.hasAttr(Attr.getKindAsEnum(),
3839 /* IgnoreSubsumingPositions */ true);
3840 }))
3841 return ChangeStatus::UNCHANGED;
3842
3843 // Clear existing attributes.
3844 IRP.removeAttrs(AttrKinds);
3845
3846 // Use the generic manifest method.
3847 return IRAttribute::manifest(A);
3848 }
3849
3850 /// See AbstractState::getAsStr().
3851 const std::string getAsStr() const override {
3852 if (isAssumedReadNone())
3853 return "readnone";
3854 if (isAssumedReadOnly())
3855 return "readonly";
3856 if (isAssumedWriteOnly())
3857 return "writeonly";
3858 return "may-read/write";
3859 }
3860
3861 /// The set of IR attributes AAMemoryBehavior deals with.
3862 static const Attribute::AttrKind AttrKinds[3];
3863};
3864
3865const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
3866 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
3867
3868/// Memory behavior attribute for a floating value.
3869struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
3870 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
3871
3872 /// See AbstractAttribute::initialize(...).
3873 void initialize(Attributor &A) override {
3874 AAMemoryBehaviorImpl::initialize(A);
3875 // Initialize the use vector with all direct uses of the associated value.
3876 for (const Use &U : getAssociatedValue().uses())
3877 Uses.insert(&U);
3878 }
3879
3880 /// See AbstractAttribute::updateImpl(...).
3881 ChangeStatus updateImpl(Attributor &A) override;
3882
3883 /// See AbstractAttribute::trackStatistics()
3884 void trackStatistics() const override {
3885 if (isAssumedReadNone())
3886 STATS_DECLTRACK_FLOATING_ATTR(readnone)
3887 else if (isAssumedReadOnly())
3888 STATS_DECLTRACK_FLOATING_ATTR(readonly)
3889 else if (isAssumedWriteOnly())
3890 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
3891 }
3892
3893private:
3894 /// Return true if users of \p UserI might access the underlying
3895 /// variable/location described by \p U and should therefore be analyzed.
3896 bool followUsersOfUseIn(Attributor &A, const Use *U,
3897 const Instruction *UserI);
3898
3899 /// Update the state according to the effect of use \p U in \p UserI.
3900 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
3901
3902protected:
3903 /// Container for (transitive) uses of the associated argument.
3904 SetVector<const Use *> Uses;
3905};
3906
3907/// Memory behavior attribute for function argument.
3908struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
3909 AAMemoryBehaviorArgument(const IRPosition &IRP)
3910 : AAMemoryBehaviorFloating(IRP) {}
3911
3912 /// See AbstractAttribute::initialize(...).
3913 void initialize(Attributor &A) override {
3914 AAMemoryBehaviorFloating::initialize(A);
3915
Johannes Doerfert1097fab2019-10-07 21:07:57 +00003916 // Initialize the use vector with all direct uses of the associated value.
3917 Argument *Arg = getAssociatedArgument();
3918 if (!Arg || !Arg->getParent()->hasExactDefinition())
3919 indicatePessimisticFixpoint();
3920 }
3921
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00003922 ChangeStatus manifest(Attributor &A) override {
3923 // TODO: From readattrs.ll: "inalloca parameters are always
3924 // considered written"
3925 if (hasAttr({Attribute::InAlloca})) {
3926 removeKnownBits(NO_WRITES);
3927 removeAssumedBits(NO_WRITES);
3928 }
3929 return AAMemoryBehaviorFloating::manifest(A);
3930 }
3931
3932
Johannes Doerfert1097fab2019-10-07 21:07:57 +00003933 /// See AbstractAttribute::trackStatistics()
3934 void trackStatistics() const override {
3935 if (isAssumedReadNone())
3936 STATS_DECLTRACK_ARG_ATTR(readnone)
3937 else if (isAssumedReadOnly())
3938 STATS_DECLTRACK_ARG_ATTR(readonly)
3939 else if (isAssumedWriteOnly())
3940 STATS_DECLTRACK_ARG_ATTR(writeonly)
3941 }
3942};
3943
3944struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
3945 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
3946 : AAMemoryBehaviorArgument(IRP) {}
3947
3948 /// See AbstractAttribute::updateImpl(...).
3949 ChangeStatus updateImpl(Attributor &A) override {
3950 // TODO: Once we have call site specific value information we can provide
3951 // call site specific liveness liveness information and then it makes
3952 // sense to specialize attributes for call sites arguments instead of
3953 // redirecting requests to the callee argument.
3954 Argument *Arg = getAssociatedArgument();
3955 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3956 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
3957 return clampStateAndIndicateChange(
3958 getState(),
3959 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3960 }
3961
3962 /// See AbstractAttribute::trackStatistics()
3963 void trackStatistics() const override {
3964 if (isAssumedReadNone())
3965 STATS_DECLTRACK_CSARG_ATTR(readnone)
3966 else if (isAssumedReadOnly())
3967 STATS_DECLTRACK_CSARG_ATTR(readonly)
3968 else if (isAssumedWriteOnly())
3969 STATS_DECLTRACK_CSARG_ATTR(writeonly)
3970 }
3971};
3972
3973/// Memory behavior attribute for a call site return position.
3974struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
3975 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
3976 : AAMemoryBehaviorFloating(IRP) {}
3977
3978 /// See AbstractAttribute::manifest(...).
3979 ChangeStatus manifest(Attributor &A) override {
3980 // We do not annotate returned values.
3981 return ChangeStatus::UNCHANGED;
3982 }
3983
3984 /// See AbstractAttribute::trackStatistics()
3985 void trackStatistics() const override {}
3986};
3987
3988/// An AA to represent the memory behavior function attributes.
3989struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
3990 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
3991
3992 /// See AbstractAttribute::updateImpl(Attributor &A).
3993 virtual ChangeStatus updateImpl(Attributor &A) override;
3994
3995 /// See AbstractAttribute::manifest(...).
3996 ChangeStatus manifest(Attributor &A) override {
3997 Function &F = cast<Function>(getAnchorValue());
3998 if (isAssumedReadNone()) {
3999 F.removeFnAttr(Attribute::ArgMemOnly);
4000 F.removeFnAttr(Attribute::InaccessibleMemOnly);
4001 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
4002 }
4003 return AAMemoryBehaviorImpl::manifest(A);
4004 }
4005
4006 /// See AbstractAttribute::trackStatistics()
4007 void trackStatistics() const override {
4008 if (isAssumedReadNone())
4009 STATS_DECLTRACK_FN_ATTR(readnone)
4010 else if (isAssumedReadOnly())
4011 STATS_DECLTRACK_FN_ATTR(readonly)
4012 else if (isAssumedWriteOnly())
4013 STATS_DECLTRACK_FN_ATTR(writeonly)
4014 }
4015};
4016
4017/// AAMemoryBehavior attribute for call sites.
4018struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
4019 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4020
4021 /// See AbstractAttribute::initialize(...).
4022 void initialize(Attributor &A) override {
4023 AAMemoryBehaviorImpl::initialize(A);
4024 Function *F = getAssociatedFunction();
4025 if (!F || !F->hasExactDefinition())
4026 indicatePessimisticFixpoint();
4027 }
4028
4029 /// See AbstractAttribute::updateImpl(...).
4030 ChangeStatus updateImpl(Attributor &A) override {
4031 // TODO: Once we have call site specific value information we can provide
4032 // call site specific liveness liveness information and then it makes
4033 // sense to specialize attributes for call sites arguments instead of
4034 // redirecting requests to the callee argument.
4035 Function *F = getAssociatedFunction();
4036 const IRPosition &FnPos = IRPosition::function(*F);
4037 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4038 return clampStateAndIndicateChange(
4039 getState(), static_cast<const AAAlign::StateType &>(FnAA.getState()));
4040 }
4041
4042 /// See AbstractAttribute::trackStatistics()
4043 void trackStatistics() const override {
4044 if (isAssumedReadNone())
4045 STATS_DECLTRACK_CS_ATTR(readnone)
4046 else if (isAssumedReadOnly())
4047 STATS_DECLTRACK_CS_ATTR(readonly)
4048 else if (isAssumedWriteOnly())
4049 STATS_DECLTRACK_CS_ATTR(writeonly)
4050 }
4051};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00004052} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004053
4054ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
4055
4056 // The current assumed state used to determine a change.
4057 auto AssumedState = getAssumed();
4058
4059 auto CheckRWInst = [&](Instruction &I) {
4060 // If the instruction has an own memory behavior state, use it to restrict
4061 // the local state. No further analysis is required as the other memory
4062 // state is as optimistic as it gets.
4063 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
4064 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
4065 *this, IRPosition::callsite_function(ICS));
4066 intersectAssumedBits(MemBehaviorAA.getAssumed());
4067 return !isAtFixpoint();
4068 }
4069
4070 // Remove access kind modifiers if necessary.
4071 if (I.mayReadFromMemory())
4072 removeAssumedBits(NO_READS);
4073 if (I.mayWriteToMemory())
4074 removeAssumedBits(NO_WRITES);
4075 return !isAtFixpoint();
4076 };
4077
4078 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
4079 return indicatePessimisticFixpoint();
4080
4081 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4082 : ChangeStatus::UNCHANGED;
4083}
4084
4085ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
4086
4087 const IRPosition &IRP = getIRPosition();
4088 const IRPosition &FnPos = IRPosition::function_scope(IRP);
4089 AAMemoryBehavior::StateType &S = getState();
4090
4091 // First, check the function scope. We take the known information and we avoid
4092 // work if the assumed information implies the current assumed information for
4093 // this attribute.
4094 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4095 S.addKnownBits(FnMemAA.getKnown());
4096 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
4097 return ChangeStatus::UNCHANGED;
4098
4099 // Make sure the value is not captured (except through "return"), if
4100 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004101 // check the potential aliases introduced by the capture. However, no need
4102 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004103 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004104 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
4105 S.intersectAssumedBits(FnMemAA.getAssumed());
4106 return ChangeStatus::CHANGED;
4107 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004108
4109 // The current assumed state used to determine a change.
4110 auto AssumedState = S.getAssumed();
4111
4112 // Liveness information to exclude dead users.
4113 // TODO: Take the FnPos once we have call site specific liveness information.
4114 const auto &LivenessAA = A.getAAFor<AAIsDead>(
4115 *this, IRPosition::function(*IRP.getAssociatedFunction()));
4116
4117 // Visit and expand uses until all are analyzed or a fixpoint is reached.
4118 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
4119 const Use *U = Uses[i];
4120 Instruction *UserI = cast<Instruction>(U->getUser());
4121 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
4122 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
4123 << "]\n");
4124 if (LivenessAA.isAssumedDead(UserI))
4125 continue;
4126
4127 // Check if the users of UserI should also be visited.
4128 if (followUsersOfUseIn(A, U, UserI))
4129 for (const Use &UserIUse : UserI->uses())
4130 Uses.insert(&UserIUse);
4131
4132 // If UserI might touch memory we analyze the use in detail.
4133 if (UserI->mayReadOrWriteMemory())
4134 analyzeUseIn(A, U, UserI);
4135 }
4136
4137 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4138 : ChangeStatus::UNCHANGED;
4139}
4140
4141bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
4142 const Instruction *UserI) {
4143 // The loaded value is unrelated to the pointer argument, no need to
4144 // follow the users of the load.
4145 if (isa<LoadInst>(UserI))
4146 return false;
4147
4148 // By default we follow all uses assuming UserI might leak information on U,
4149 // we have special handling for call sites operands though.
4150 ImmutableCallSite ICS(UserI);
4151 if (!ICS || !ICS.isArgOperand(U))
4152 return true;
4153
4154 // If the use is a call argument known not to be captured, the users of
4155 // the call do not need to be visited because they have to be unrelated to
4156 // the input. Note that this check is not trivial even though we disallow
4157 // general capturing of the underlying argument. The reason is that the
4158 // call might the argument "through return", which we allow and for which we
4159 // need to check call users.
4160 unsigned ArgNo = ICS.getArgumentNo(U);
4161 const auto &ArgNoCaptureAA =
4162 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
4163 return !ArgNoCaptureAA.isAssumedNoCapture();
4164}
4165
4166void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
4167 const Instruction *UserI) {
4168 assert(UserI->mayReadOrWriteMemory());
4169
4170 switch (UserI->getOpcode()) {
4171 default:
4172 // TODO: Handle all atomics and other side-effect operations we know of.
4173 break;
4174 case Instruction::Load:
4175 // Loads cause the NO_READS property to disappear.
4176 removeAssumedBits(NO_READS);
4177 return;
4178
4179 case Instruction::Store:
4180 // Stores cause the NO_WRITES property to disappear if the use is the
4181 // pointer operand. Note that we do assume that capturing was taken care of
4182 // somewhere else.
4183 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
4184 removeAssumedBits(NO_WRITES);
4185 return;
4186
4187 case Instruction::Call:
4188 case Instruction::CallBr:
4189 case Instruction::Invoke: {
4190 // For call sites we look at the argument memory behavior attribute (this
4191 // could be recursive!) in order to restrict our own state.
4192 ImmutableCallSite ICS(UserI);
4193
4194 // Give up on operand bundles.
4195 if (ICS.isBundleOperand(U)) {
4196 indicatePessimisticFixpoint();
4197 return;
4198 }
4199
4200 // Calling a function does read the function pointer, maybe write it if the
4201 // function is self-modifying.
4202 if (ICS.isCallee(U)) {
4203 removeAssumedBits(NO_READS);
4204 break;
4205 }
4206
4207 // Adjust the possible access behavior based on the information on the
4208 // argument.
4209 unsigned ArgNo = ICS.getArgumentNo(U);
4210 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
4211 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4212 // "assumed" has at most the same bits as the MemBehaviorAA assumed
4213 // and at least "known".
4214 intersectAssumedBits(MemBehaviorAA.getAssumed());
4215 return;
4216 }
4217 };
4218
4219 // Generally, look at the "may-properties" and adjust the assumed state if we
4220 // did not trigger special handling before.
4221 if (UserI->mayReadFromMemory())
4222 removeAssumedBits(NO_READS);
4223 if (UserI->mayWriteToMemory())
4224 removeAssumedBits(NO_WRITES);
4225}
4226
Johannes Doerfertaade7822019-06-05 03:02:24 +00004227/// ----------------------------------------------------------------------------
4228/// Attributor
4229/// ----------------------------------------------------------------------------
4230
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004231bool Attributor::isAssumedDead(const AbstractAttribute &AA,
4232 const AAIsDead *LivenessAA) {
4233 const Instruction *CtxI = AA.getIRPosition().getCtxI();
4234 if (!CtxI)
4235 return false;
4236
4237 if (!LivenessAA)
4238 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00004239 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
4240 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00004241
4242 // Don't check liveness for AAIsDead.
4243 if (&AA == LivenessAA)
4244 return false;
4245
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004246 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004247 return false;
4248
Johannes Doerfert19b00432019-08-26 17:48:05 +00004249 // We actually used liveness information so we have to record a dependence.
4250 recordDependence(*LivenessAA, AA);
4251
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004252 return true;
4253}
4254
Johannes Doerfert661db042019-10-07 23:14:58 +00004255bool Attributor::checkForAllCallSites(
4256 const function_ref<bool(AbstractCallSite)> &Pred,
4257 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004258 // We can try to determine information from
4259 // the call sites. However, this is only possible all call sites are known,
4260 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004261 const IRPosition &IRP = QueryingAA.getIRPosition();
4262 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00004263 if (!AssociatedFunction) {
4264 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
4265 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004266 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00004267 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004268
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004269 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
4270 &QueryingAA);
4271}
4272
4273bool Attributor::checkForAllCallSites(
4274 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
4275 bool RequireAllCallSites, const AbstractAttribute *QueryingAA) {
4276 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004277 LLVM_DEBUG(
4278 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004279 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00004280 << " has no internal linkage, hence not all call sites are known\n");
4281 return false;
4282 }
4283
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004284 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00004285 AbstractCallSite ACS(&U);
4286 if (!ACS) {
4287 LLVM_DEBUG(dbgs() << "[Attributor] Function "
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004288 << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00004289 << " has non call site use " << *U.get() << " in "
4290 << *U.getUser() << "\n");
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004291 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00004292 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004293
Johannes Doerfert661db042019-10-07 23:14:58 +00004294 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004295 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004296
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004297 const auto *LivenessAA =
4298 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Johannes Doerfert661db042019-10-07 23:14:58 +00004299 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004300
4301 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004302 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00004303 // We actually used liveness information so we have to record a
4304 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004305 if (QueryingAA)
4306 recordDependence(*LivenessAA, *QueryingAA);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004307 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004308 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004309
Johannes Doerfert661db042019-10-07 23:14:58 +00004310 const Use *EffectiveUse =
4311 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
4312 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004313 if (!RequireAllCallSites)
4314 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00004315 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004316 << " is an invalid use of "
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004317 << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004318 return false;
4319 }
4320
Johannes Doerfert661db042019-10-07 23:14:58 +00004321 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00004322 continue;
4323
Johannes Doerfert5304b722019-08-14 22:04:28 +00004324 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00004325 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004326 return false;
4327 }
4328
4329 return true;
4330}
4331
Johannes Doerfert14a04932019-08-07 22:27:24 +00004332bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004333 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00004334 &Pred,
4335 const AbstractAttribute &QueryingAA) {
4336
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004337 const IRPosition &IRP = QueryingAA.getIRPosition();
4338 // Since we need to provide return instructions we have to have an exact
4339 // definition.
4340 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004341 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004342 return false;
4343
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004344 // If this is a call site query we use the call site specific return values
4345 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004346 // TODO: use the function scope once we have call site AAReturnedValues.
4347 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004348 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004349 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004350 return false;
4351
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004352 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00004353}
4354
4355bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004356 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00004357 const AbstractAttribute &QueryingAA) {
4358
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004359 const IRPosition &IRP = QueryingAA.getIRPosition();
4360 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004361 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004362 return false;
4363
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004364 // TODO: use the function scope once we have call site AAReturnedValues.
4365 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004366 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004367 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004368 return false;
4369
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004370 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004371 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00004372 return Pred(RV);
4373 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00004374}
4375
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004376static bool
4377checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
4378 const function_ref<bool(Instruction &)> &Pred,
4379 const AAIsDead *LivenessAA, bool &AnyDead,
4380 const ArrayRef<unsigned> &Opcodes) {
4381 for (unsigned Opcode : Opcodes) {
4382 for (Instruction *I : OpcodeInstMap[Opcode]) {
4383 // Skip dead instructions.
4384 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
4385 AnyDead = true;
4386 continue;
4387 }
4388
4389 if (!Pred(*I))
4390 return false;
4391 }
4392 }
4393 return true;
4394}
4395
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004396bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004397 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004398 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004399
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004400 const IRPosition &IRP = QueryingAA.getIRPosition();
4401 // Since we need to provide instructions we have to have an exact definition.
4402 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004403 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004404 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004405
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004406 // TODO: use the function scope once we have call site AAReturnedValues.
4407 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004408 const auto &LivenessAA =
4409 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
4410 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004411
4412 auto &OpcodeInstMap =
4413 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004414 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
4415 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004416 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004417
Johannes Doerfert19b00432019-08-26 17:48:05 +00004418 // If we actually used liveness information so we have to record a dependence.
4419 if (AnyDead)
4420 recordDependence(LivenessAA, QueryingAA);
4421
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004422 return true;
4423}
4424
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004425bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004426 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004427 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004428
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004429 const Function *AssociatedFunction =
4430 QueryingAA.getIRPosition().getAssociatedFunction();
4431 if (!AssociatedFunction)
4432 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004433
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004434 // TODO: use the function scope once we have call site AAReturnedValues.
4435 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
4436 const auto &LivenessAA =
4437 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004438 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004439
4440 for (Instruction *I :
4441 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004442 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00004443 if (LivenessAA.isAssumedDead(I)) {
4444 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004445 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004446 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004447
4448 if (!Pred(*I))
4449 return false;
4450 }
4451
Johannes Doerfert19b00432019-08-26 17:48:05 +00004452 // If we actually used liveness information so we have to record a dependence.
4453 if (AnyDead)
4454 recordDependence(LivenessAA, QueryingAA);
4455
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004456 return true;
4457}
4458
Johannes Doerfert2f622062019-09-04 16:35:20 +00004459ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004460 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
4461 << AllAbstractAttributes.size()
4462 << " abstract attributes.\n");
4463
Stefan Stipanovic53605892019-06-27 11:27:54 +00004464 // Now that all abstract attributes are collected and initialized we start
4465 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00004466
4467 unsigned IterationCounter = 1;
4468
4469 SmallVector<AbstractAttribute *, 64> ChangedAAs;
4470 SetVector<AbstractAttribute *> Worklist;
4471 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
4472
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004473 bool RecomputeDependences = false;
4474
Johannes Doerfertaade7822019-06-05 03:02:24 +00004475 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004476 // Remember the size to determine new attributes.
4477 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004478 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
4479 << ", Worklist size: " << Worklist.size() << "\n");
4480
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004481 // If dependences (=QueryMap) are recomputed we have to look at all abstract
4482 // attributes again, regardless of what changed in the last iteration.
4483 if (RecomputeDependences) {
4484 LLVM_DEBUG(
4485 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
4486 QueryMap.clear();
4487 ChangedAAs.clear();
4488 Worklist.insert(AllAbstractAttributes.begin(),
4489 AllAbstractAttributes.end());
4490 }
4491
Johannes Doerfertaade7822019-06-05 03:02:24 +00004492 // Add all abstract attributes that are potentially dependent on one that
4493 // changed to the work list.
4494 for (AbstractAttribute *ChangedAA : ChangedAAs) {
4495 auto &QuerriedAAs = QueryMap[ChangedAA];
4496 Worklist.insert(QuerriedAAs.begin(), QuerriedAAs.end());
4497 }
4498
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004499 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
4500 << ", Worklist+Dependent size: " << Worklist.size()
4501 << "\n");
4502
Johannes Doerfertaade7822019-06-05 03:02:24 +00004503 // Reset the changed set.
4504 ChangedAAs.clear();
4505
4506 // Update all abstract attribute in the work list and record the ones that
4507 // changed.
4508 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004509 if (!isAssumedDead(*AA, nullptr))
4510 if (AA->update(*this) == ChangeStatus::CHANGED)
4511 ChangedAAs.push_back(AA);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004512
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004513 // Check if we recompute the dependences in the next iteration.
4514 RecomputeDependences = (DepRecomputeInterval > 0 &&
4515 IterationCounter % DepRecomputeInterval == 0);
4516
Johannes Doerfert9543f142019-08-23 15:24:57 +00004517 // Add attributes to the changed set if they have been created in the last
4518 // iteration.
4519 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
4520 AllAbstractAttributes.end());
4521
Johannes Doerfertaade7822019-06-05 03:02:24 +00004522 // Reset the work list and repopulate with the changed abstract attributes.
4523 // Note that dependent ones are added above.
4524 Worklist.clear();
4525 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
4526
Johannes Doerfertbf112132019-08-29 01:29:44 +00004527 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
4528 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004529
Johannes Doerfertaade7822019-06-05 03:02:24 +00004530 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
4531 << IterationCounter << "/" << MaxFixpointIterations
4532 << " iterations\n");
4533
Johannes Doerfertbf112132019-08-29 01:29:44 +00004534 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004535
Johannes Doerfertaade7822019-06-05 03:02:24 +00004536 // Reset abstract arguments not settled in a sound fixpoint by now. This
4537 // happens when we stopped the fixpoint iteration early. Note that only the
4538 // ones marked as "changed" *and* the ones transitively depending on them
4539 // need to be reverted to a pessimistic state. Others might not be in a
4540 // fixpoint state but we can use the optimistic results for them anyway.
4541 SmallPtrSet<AbstractAttribute *, 32> Visited;
4542 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
4543 AbstractAttribute *ChangedAA = ChangedAAs[u];
4544 if (!Visited.insert(ChangedAA).second)
4545 continue;
4546
4547 AbstractState &State = ChangedAA->getState();
4548 if (!State.isAtFixpoint()) {
4549 State.indicatePessimisticFixpoint();
4550
4551 NumAttributesTimedOut++;
4552 }
4553
4554 auto &QuerriedAAs = QueryMap[ChangedAA];
4555 ChangedAAs.append(QuerriedAAs.begin(), QuerriedAAs.end());
4556 }
4557
4558 LLVM_DEBUG({
4559 if (!Visited.empty())
4560 dbgs() << "\n[Attributor] Finalized " << Visited.size()
4561 << " abstract attributes.\n";
4562 });
4563
4564 unsigned NumManifested = 0;
4565 unsigned NumAtFixpoint = 0;
4566 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
4567 for (AbstractAttribute *AA : AllAbstractAttributes) {
4568 AbstractState &State = AA->getState();
4569
4570 // If there is not already a fixpoint reached, we can now take the
4571 // optimistic state. This is correct because we enforced a pessimistic one
4572 // on abstract attributes that were transitively dependent on a changed one
4573 // already above.
4574 if (!State.isAtFixpoint())
4575 State.indicateOptimisticFixpoint();
4576
4577 // If the state is invalid, we do not try to manifest it.
4578 if (!State.isValidState())
4579 continue;
4580
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004581 // Skip dead code.
4582 if (isAssumedDead(*AA, nullptr))
4583 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004584 // Manifest the state and record if we changed the IR.
4585 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00004586 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
4587 AA->trackStatistics();
4588
Johannes Doerfertaade7822019-06-05 03:02:24 +00004589 ManifestChange = ManifestChange | LocalChange;
4590
4591 NumAtFixpoint++;
4592 NumManifested += (LocalChange == ChangeStatus::CHANGED);
4593 }
4594
4595 (void)NumManifested;
4596 (void)NumAtFixpoint;
4597 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
4598 << " arguments while " << NumAtFixpoint
4599 << " were in a valid fixpoint state\n");
4600
Johannes Doerfertaade7822019-06-05 03:02:24 +00004601 NumAttributesManifested += NumManifested;
4602 NumAttributesValidFixpoint += NumAtFixpoint;
4603
Fangrui Songf1826172019-08-20 07:21:43 +00004604 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004605 assert(
4606 NumFinalAAs == AllAbstractAttributes.size() &&
4607 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00004608
4609 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00004610 {
4611 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
4612 << ToBeDeletedFunctions.size() << " functions and "
4613 << ToBeDeletedBlocks.size() << " blocks and "
4614 << ToBeDeletedInsts.size() << " instructions\n");
4615 for (Instruction *I : ToBeDeletedInsts) {
4616 if (!I->use_empty())
4617 I->replaceAllUsesWith(UndefValue::get(I->getType()));
4618 I->eraseFromParent();
4619 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00004620
Johannes Doerfert2f622062019-09-04 16:35:20 +00004621 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
4622 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
4623 ToBeDeletedBBs.reserve(NumDeadBlocks);
4624 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
4625 DeleteDeadBlocks(ToBeDeletedBBs);
4626 STATS_DECLTRACK(AAIsDead, BasicBlock,
4627 "Number of dead basic blocks deleted.");
4628 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00004629
Johannes Doerfert2f622062019-09-04 16:35:20 +00004630 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
4631 for (Function *Fn : ToBeDeletedFunctions) {
4632 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
4633 Fn->eraseFromParent();
4634 STATS_TRACK(AAIsDead, Function);
4635 }
4636
4637 // Identify dead internal functions and delete them. This happens outside
4638 // the other fixpoint analysis as we might treat potentially dead functions
4639 // as live to lower the number of iterations. If they happen to be dead, the
4640 // below fixpoint loop will identify and eliminate them.
4641 SmallVector<Function *, 8> InternalFns;
4642 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00004643 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00004644 InternalFns.push_back(&F);
4645
4646 bool FoundDeadFn = true;
4647 while (FoundDeadFn) {
4648 FoundDeadFn = false;
4649 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
4650 Function *F = InternalFns[u];
4651 if (!F)
4652 continue;
4653
4654 const auto *LivenessAA =
4655 lookupAAFor<AAIsDead>(IRPosition::function(*F));
4656 if (LivenessAA &&
Johannes Doerfert661db042019-10-07 23:14:58 +00004657 !checkForAllCallSites([](AbstractCallSite ACS) { return false; },
Johannes Doerfert2f622062019-09-04 16:35:20 +00004658 *LivenessAA, true))
4659 continue;
4660
4661 STATS_TRACK(AAIsDead, Function);
4662 F->replaceAllUsesWith(UndefValue::get(F->getType()));
4663 F->eraseFromParent();
4664 InternalFns[u] = nullptr;
4665 FoundDeadFn = true;
4666 }
4667 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00004668 }
4669
Johannes Doerfertbf112132019-08-29 01:29:44 +00004670 if (VerifyMaxFixpointIterations &&
4671 IterationCounter != MaxFixpointIterations) {
4672 errs() << "\n[Attributor] Fixpoint iteration done after: "
4673 << IterationCounter << "/" << MaxFixpointIterations
4674 << " iterations\n";
4675 llvm_unreachable("The fixpoint was not reached with exactly the number of "
4676 "specified iterations!");
4677 }
4678
Johannes Doerfertaade7822019-06-05 03:02:24 +00004679 return ManifestChange;
4680}
4681
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004682void Attributor::initializeInformationCache(Function &F) {
4683
4684 // Walk all instructions to find interesting instructions that might be
4685 // queried by abstract attributes during their initialization or update.
4686 // This has to happen before we create attributes.
4687 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
4688 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
4689
4690 for (Instruction &I : instructions(&F)) {
4691 bool IsInterestingOpcode = false;
4692
4693 // To allow easy access to all instructions in a function with a given
4694 // opcode we store them in the InfoCache. As not all opcodes are interesting
4695 // to concrete attributes we only cache the ones that are as identified in
4696 // the following switch.
4697 // Note: There are no concrete attributes now so this is initially empty.
4698 switch (I.getOpcode()) {
4699 default:
4700 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
4701 "New call site/base instruction type needs to be known int the "
4702 "Attributor.");
4703 break;
4704 case Instruction::Load:
4705 // The alignment of a pointer is interesting for loads.
4706 case Instruction::Store:
4707 // The alignment of a pointer is interesting for stores.
4708 case Instruction::Call:
4709 case Instruction::CallBr:
4710 case Instruction::Invoke:
4711 case Instruction::CleanupRet:
4712 case Instruction::CatchSwitch:
4713 case Instruction::Resume:
4714 case Instruction::Ret:
4715 IsInterestingOpcode = true;
4716 }
4717 if (IsInterestingOpcode)
4718 InstOpcodeMap[I.getOpcode()].push_back(&I);
4719 if (I.mayReadOrWriteMemory())
4720 ReadOrWriteInsts.push_back(&I);
4721 }
4722}
4723
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004724void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00004725 if (!VisitedFunctions.insert(&F).second)
4726 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004727
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004728 IRPosition FPos = IRPosition::function(F);
4729
Johannes Doerfert305b9612019-08-04 18:40:01 +00004730 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00004731 // We need dead instruction detection because we do not want to deal with
4732 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004733 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00004734
4735 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004736 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00004737
Stefan Stipanovic53605892019-06-27 11:27:54 +00004738 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004739 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00004740
Stefan Stipanovic06263672019-07-11 21:37:40 +00004741 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004742 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00004743
Hideto Ueno65bbaf92019-07-12 17:38:51 +00004744 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004745 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00004746
Johannes Doerferte83f3032019-08-05 23:22:05 +00004747 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004748 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00004749
Hideto Ueno63f60662019-09-21 15:13:19 +00004750 // Every function might be "no-recurse".
4751 getOrCreateAAFor<AANoRecurse>(FPos);
4752
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004753 // Every function might be "readnone/readonly/writeonly/...".
4754 getOrCreateAAFor<AAMemoryBehavior>(FPos);
4755
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004756 // Every function might be applicable for Heap-To-Stack conversion.
4757 if (EnableHeapToStack)
4758 getOrCreateAAFor<AAHeapToStack>(FPos);
4759
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00004760 // Return attributes are only appropriate if the return type is non void.
4761 Type *ReturnType = F.getReturnType();
4762 if (!ReturnType->isVoidTy()) {
4763 // Argument attribute "returned" --- Create only one per function even
4764 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004765 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00004766
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004767 IRPosition RetPos = IRPosition::returned(F);
4768
4769 // Every function might be simplified.
4770 getOrCreateAAFor<AAValueSimplify>(RetPos);
4771
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004772 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004773
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004774 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004775 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004776
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004777 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004778 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004779
4780 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004781 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004782
4783 // Every function with pointer return type might be marked
4784 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004785 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004786 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004787 }
4788
Hideto Ueno54869ec2019-07-15 06:49:04 +00004789 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004790 IRPosition ArgPos = IRPosition::argument(Arg);
4791
4792 // Every argument might be simplified.
4793 getOrCreateAAFor<AAValueSimplify>(ArgPos);
4794
Hideto Ueno19c07af2019-07-23 08:16:17 +00004795 if (Arg.getType()->isPointerTy()) {
4796 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004797 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004798
Hideto Uenocbab3342019-08-29 05:52:00 +00004799 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004800 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00004801
Hideto Ueno19c07af2019-07-23 08:16:17 +00004802 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004803 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004804
4805 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004806 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004807
4808 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004809 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004810
4811 // Every argument with pointer type might be marked
4812 // "readnone/readonly/writeonly/..."
4813 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004814 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00004815 }
4816
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004817 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004818 CallSite CS(&I);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004819 if (CS.getCalledFunction()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004820 for (int i = 0, e = CS.getCalledFunction()->arg_size(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004821
4822 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
4823
4824 // Call site argument might be simplified.
4825 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
4826
Hideto Ueno54869ec2019-07-15 06:49:04 +00004827 if (!CS.getArgument(i)->getType()->isPointerTy())
4828 continue;
4829
4830 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004831 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004832
Hideto Uenocbab3342019-08-29 05:52:00 +00004833 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004834 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00004835
Hideto Ueno19c07af2019-07-23 08:16:17 +00004836 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004837 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004838
4839 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004840 getOrCreateAAFor<AAAlign>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00004841 }
4842 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004843 return true;
4844 };
4845
4846 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
4847 bool Success, AnyDead = false;
4848 Success = checkForAllInstructionsImpl(
4849 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
4850 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
4851 (unsigned)Instruction::Call});
4852 (void)Success;
4853 assert(Success && !AnyDead && "Expected the check call to be successful!");
4854
4855 auto LoadStorePred = [&](Instruction &I) -> bool {
4856 if (isa<LoadInst>(I))
4857 getOrCreateAAFor<AAAlign>(
4858 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
4859 else
4860 getOrCreateAAFor<AAAlign>(
4861 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
4862 return true;
4863 };
4864 Success = checkForAllInstructionsImpl(
4865 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
4866 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
4867 (void)Success;
4868 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00004869}
4870
4871/// Helpers to ease debugging through output streams and print calls.
4872///
4873///{
4874raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
4875 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
4876}
4877
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004878raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004879 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004880 case IRPosition::IRP_INVALID:
4881 return OS << "inv";
4882 case IRPosition::IRP_FLOAT:
4883 return OS << "flt";
4884 case IRPosition::IRP_RETURNED:
4885 return OS << "fn_ret";
4886 case IRPosition::IRP_CALL_SITE_RETURNED:
4887 return OS << "cs_ret";
4888 case IRPosition::IRP_FUNCTION:
4889 return OS << "fn";
4890 case IRPosition::IRP_CALL_SITE:
4891 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004892 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00004893 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004894 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00004895 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00004896 }
4897 llvm_unreachable("Unknown attribute position!");
4898}
4899
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004900raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004901 const Value &AV = Pos.getAssociatedValue();
4902 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004903 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
4904}
4905
Johannes Doerfertacc80792019-08-12 22:07:34 +00004906raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerState &S) {
4907 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
4908 << static_cast<const AbstractState &>(S);
4909}
4910
Johannes Doerfertaade7822019-06-05 03:02:24 +00004911raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
4912 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
4913}
4914
4915raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
4916 AA.print(OS);
4917 return OS;
4918}
4919
4920void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004921 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
4922 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00004923}
4924///}
4925
4926/// ----------------------------------------------------------------------------
4927/// Pass (Manager) Boilerplate
4928/// ----------------------------------------------------------------------------
4929
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004930static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004931 if (DisableAttributor)
4932 return false;
4933
4934 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
4935 << " functions.\n");
4936
4937 // Create an Attributor and initially empty information cache that is filled
4938 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00004939 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004940 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004941
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004942 for (Function &F : M)
4943 A.initializeInformationCache(F);
4944
Johannes Doerfertaade7822019-06-05 03:02:24 +00004945 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004946 if (F.hasExactDefinition())
4947 NumFnWithExactDefinition++;
4948 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00004949 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004950
Johannes Doerfert2f622062019-09-04 16:35:20 +00004951 // We look at internal functions only on-demand but if any use is not a
4952 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00004953 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00004954 if (llvm::all_of(F.uses(), [](const Use &U) {
4955 return ImmutableCallSite(U.getUser()) &&
4956 ImmutableCallSite(U.getUser()).isCallee(&U);
4957 }))
4958 continue;
4959 }
4960
Johannes Doerfertaade7822019-06-05 03:02:24 +00004961 // Populate the Attributor with abstract attribute opportunities in the
4962 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004963 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004964 }
4965
Johannes Doerfert2f622062019-09-04 16:35:20 +00004966 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004967}
4968
4969PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00004970 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004971 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004972 // FIXME: Think about passes we will preserve and add them here.
4973 return PreservedAnalyses::none();
4974 }
4975 return PreservedAnalyses::all();
4976}
4977
4978namespace {
4979
4980struct AttributorLegacyPass : public ModulePass {
4981 static char ID;
4982
4983 AttributorLegacyPass() : ModulePass(ID) {
4984 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
4985 }
4986
4987 bool runOnModule(Module &M) override {
4988 if (skipModule(M))
4989 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004990
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004991 AnalysisGetter AG;
4992 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004993 }
4994
4995 void getAnalysisUsage(AnalysisUsage &AU) const override {
4996 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004997 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004998 }
4999};
5000
5001} // end anonymous namespace
5002
5003Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
5004
5005char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005006
5007const char AAReturnedValues::ID = 0;
5008const char AANoUnwind::ID = 0;
5009const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00005010const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005011const char AANonNull::ID = 0;
5012const char AANoRecurse::ID = 0;
5013const char AAWillReturn::ID = 0;
5014const char AANoAlias::ID = 0;
5015const char AANoReturn::ID = 0;
5016const char AAIsDead::ID = 0;
5017const char AADereferenceable::ID = 0;
5018const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005019const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005020const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005021const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005022const char AAMemoryBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005023
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005024// Macro magic to create the static generator function for attributes that
5025// follow the naming scheme.
5026
5027#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
5028 case IRPosition::PK: \
5029 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
5030
5031#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
5032 case IRPosition::PK: \
5033 AA = new CLASS##SUFFIX(IRP); \
5034 break;
5035
5036#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5037 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5038 CLASS *AA = nullptr; \
5039 switch (IRP.getPositionKind()) { \
5040 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5041 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5042 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5043 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5044 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5045 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5046 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5047 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5048 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005049 return *AA; \
5050 }
5051
5052#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5053 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5054 CLASS *AA = nullptr; \
5055 switch (IRP.getPositionKind()) { \
5056 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5057 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
5058 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5059 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5060 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5061 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5062 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5063 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5064 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005065 return *AA; \
5066 }
5067
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005068#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5069 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5070 CLASS *AA = nullptr; \
5071 switch (IRP.getPositionKind()) { \
5072 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5073 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5074 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5075 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5076 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5077 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5078 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5079 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5080 } \
5081 return *AA; \
5082 }
5083
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005084#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5085 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5086 CLASS *AA = nullptr; \
5087 switch (IRP.getPositionKind()) { \
5088 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5089 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5090 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5091 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5092 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5093 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5094 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5095 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5096 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005097 return *AA; \
5098 }
5099
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005100#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5101 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5102 CLASS *AA = nullptr; \
5103 switch (IRP.getPositionKind()) { \
5104 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5105 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5106 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5107 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5108 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5109 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5110 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5111 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5112 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005113 return *AA; \
5114 }
5115
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005116CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
5117CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
5118CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
5119CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
5120CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
5121CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
5122CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
5123CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
5124
5125CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
5126CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
5127CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
5128CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005129CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005130
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005131CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
5132
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005133CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
5134
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005135CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
5136
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005137#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005138#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005139#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005140#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005141#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005142#undef SWITCH_PK_CREATE
5143#undef SWITCH_PK_INV
5144
Johannes Doerfertaade7822019-06-05 03:02:24 +00005145INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
5146 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005147INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00005148INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
5149 "Deduce and propagate attributes", false, false)