blob: fa0ea7e0ff1476e3fc61efe953ec3f355da73a18 [file] [log] [blame]
Johannes Doerfertaade7822019-06-05 03:02:24 +00001//===- Attributor.cpp - Module-wide attribute deduction -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements an inter procedural pass that deduces and/or propagating
10// attributes. This is done in an abstract interpretation style fixpoint
11// iteration. See the Attributor.h file comment and the class descriptions in
12// that file for more information.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Transforms/IPO/Attributor.h"
17
Hideto Ueno11d37102019-07-17 15:15:43 +000018#include "llvm/ADT/DepthFirstIterator.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000019#include "llvm/ADT/STLExtras.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000020#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/Statistic.h"
Stefan Stipanovic69ebb022019-07-22 19:36:27 +000023#include "llvm/Analysis/CaptureTracking.h"
Johannes Doerfert924d2132019-08-05 21:34:45 +000024#include "llvm/Analysis/EHPersonalities.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000025#include "llvm/Analysis/GlobalsModRef.h"
Hideto Ueno19c07af2019-07-23 08:16:17 +000026#include "llvm/Analysis/Loads.h"
Stefan Stipanovic431141c2019-09-15 21:47:41 +000027#include "llvm/Analysis/MemoryBuiltins.h"
Hideto Ueno54869ec2019-07-15 06:49:04 +000028#include "llvm/Analysis/ValueTracking.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000029#include "llvm/IR/Argument.h"
30#include "llvm/IR/Attributes.h"
Hideto Ueno11d37102019-07-17 15:15:43 +000031#include "llvm/IR/CFG.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000032#include "llvm/IR/InstIterator.h"
Stefan Stipanovic06263672019-07-11 21:37:40 +000033#include "llvm/IR/IntrinsicInst.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000034#include "llvm/Support/CommandLine.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/raw_ostream.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000037#include "llvm/Transforms/Utils/BasicBlockUtils.h"
38#include "llvm/Transforms/Utils/Local.h"
39
Johannes Doerfertaade7822019-06-05 03:02:24 +000040#include <cassert>
41
42using namespace llvm;
43
44#define DEBUG_TYPE "attributor"
45
46STATISTIC(NumFnWithExactDefinition,
47 "Number of function with exact definitions");
48STATISTIC(NumFnWithoutExactDefinition,
49 "Number of function without exact definitions");
50STATISTIC(NumAttributesTimedOut,
51 "Number of abstract attributes timed out before fixpoint");
52STATISTIC(NumAttributesValidFixpoint,
53 "Number of abstract attributes in a valid fixpoint state");
54STATISTIC(NumAttributesManifested,
55 "Number of abstract attributes manifested in IR");
56
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000057// Some helper macros to deal with statistics tracking.
58//
59// Usage:
60// For simple IR attribute tracking overload trackStatistics in the abstract
Johannes Doerfert17b578b2019-08-14 21:46:25 +000061// attribute and choose the right STATS_DECLTRACK_********* macro,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000062// e.g.,:
63// void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +000064// STATS_DECLTRACK_ARG_ATTR(returned)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000065// }
66// If there is a single "increment" side one can use the macro
Johannes Doerfert17b578b2019-08-14 21:46:25 +000067// STATS_DECLTRACK with a custom message. If there are multiple increment
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000068// sides, STATS_DECL and STATS_TRACK can also be used separatly.
69//
70#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
71 ("Number of " #TYPE " marked '" #NAME "'")
72#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
Johannes Doerferta7a3b3a2019-09-04 19:01:08 +000073#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
74#define STATS_DECL(NAME, TYPE, MSG) \
75 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000076#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
Johannes Doerfert17b578b2019-08-14 21:46:25 +000077#define STATS_DECLTRACK(NAME, TYPE, MSG) \
Johannes Doerfert169af992019-08-20 06:09:56 +000078 { \
79 STATS_DECL(NAME, TYPE, MSG) \
80 STATS_TRACK(NAME, TYPE) \
81 }
Johannes Doerfert17b578b2019-08-14 21:46:25 +000082#define STATS_DECLTRACK_ARG_ATTR(NAME) \
83 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
84#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
85 STATS_DECLTRACK(NAME, CSArguments, \
86 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
87#define STATS_DECLTRACK_FN_ATTR(NAME) \
88 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
89#define STATS_DECLTRACK_CS_ATTR(NAME) \
90 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
91#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
92 STATS_DECLTRACK(NAME, FunctionReturn, \
Johannes Doerfert2db85282019-08-21 20:56:56 +000093 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
Johannes Doerfert17b578b2019-08-14 21:46:25 +000094#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
95 STATS_DECLTRACK(NAME, CSReturn, \
96 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
97#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
98 STATS_DECLTRACK(NAME, Floating, \
99 ("Number of floating values known to be '" #NAME "'"))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000100
Johannes Doerfertaade7822019-06-05 03:02:24 +0000101// TODO: Determine a good default value.
102//
103// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
104// (when run with the first 5 abstract attributes). The results also indicate
105// that we never reach 32 iterations but always find a fixpoint sooner.
106//
107// This will become more evolved once we perform two interleaved fixpoint
108// iterations: bottom-up and top-down.
109static cl::opt<unsigned>
110 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
111 cl::desc("Maximal number of fixpoint iterations."),
112 cl::init(32));
Johannes Doerfertb504eb82019-08-26 18:55:47 +0000113static cl::opt<bool> VerifyMaxFixpointIterations(
114 "attributor-max-iterations-verify", cl::Hidden,
115 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
116 cl::init(false));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000117
118static cl::opt<bool> DisableAttributor(
119 "attributor-disable", cl::Hidden,
120 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +0000121 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000122
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500123static cl::opt<bool> AnnotateDeclarationCallSites(
124 "attributor-annotate-decl-cs", cl::Hidden,
125 cl::desc("Annoate call sites of function declarations."), cl::init(false));
126
Johannes Doerfert7516a5e2019-09-03 20:37:24 +0000127static cl::opt<bool> ManifestInternal(
128 "attributor-manifest-internal", cl::Hidden,
129 cl::desc("Manifest Attributor internal string attributes."),
130 cl::init(false));
131
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000132static cl::opt<unsigned> DepRecInterval(
133 "attributor-dependence-recompute-interval", cl::Hidden,
134 cl::desc("Number of iterations until dependences are recomputed."),
135 cl::init(4));
136
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000137static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
138 cl::init(true), cl::Hidden);
139
Johannes Doerfert1c2afae2019-10-10 05:34:21 +0000140static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
141 cl::Hidden);
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000142
Johannes Doerfertaade7822019-06-05 03:02:24 +0000143/// Logic operators for the change status enum class.
144///
145///{
146ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
147 return l == ChangeStatus::CHANGED ? l : r;
148}
149ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
150 return l == ChangeStatus::UNCHANGED ? l : r;
151}
152///}
153
Johannes Doerfertdef99282019-08-14 21:29:37 +0000154/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000155/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000156/// with the "returned" attribute. Once we cannot look through the value any
157/// further, the callback \p VisitValueCB is invoked and passed the current
158/// value, the \p State, and a flag to indicate if we stripped anything. To
159/// limit how much effort is invested, we will never visit more values than
160/// specified by \p MaxValues.
161template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000162static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000163 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000164 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000165 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000166
Johannes Doerfertdef99282019-08-14 21:29:37 +0000167 const AAIsDead *LivenessAA = nullptr;
168 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000169 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000170 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
171 /* TrackDependence */ false);
172 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000173
174 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000175 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000176 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000177 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000178
179 int Iteration = 0;
180 do {
181 Value *V = Worklist.pop_back_val();
182
183 // Check if we should process the current value. To prevent endless
184 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000185 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000186 continue;
187
188 // Make sure we limit the compile time for complex expressions.
189 if (Iteration++ >= MaxValues)
190 return false;
191
192 // Explicitly look through calls with a "returned" attribute if we do
193 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000194 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000195 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000196 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000197 } else {
198 CallSite CS(V);
199 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000200 for (Argument &Arg : CS.getCalledFunction()->args())
201 if (Arg.hasReturnedAttr()) {
202 NewV = CS.getArgOperand(Arg.getArgNo());
203 break;
204 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000205 }
206 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000207 if (NewV && NewV != V) {
208 Worklist.push_back(NewV);
209 continue;
210 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000211
212 // Look through select instructions, visit both potential values.
213 if (auto *SI = dyn_cast<SelectInst>(V)) {
214 Worklist.push_back(SI->getTrueValue());
215 Worklist.push_back(SI->getFalseValue());
216 continue;
217 }
218
Johannes Doerfertdef99282019-08-14 21:29:37 +0000219 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000220 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000221 assert(LivenessAA &&
222 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000223 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
224 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000225 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000226 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000227 continue;
228 }
229 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000230 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000231 continue;
232 }
233
234 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000235 if (!VisitValueCB(*V, State, Iteration > 1))
236 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000237 } while (!Worklist.empty());
238
Johannes Doerfert19b00432019-08-26 17:48:05 +0000239 // If we actually used liveness information so we have to record a dependence.
240 if (AnyDead)
241 A.recordDependence(*LivenessAA, QueryingAA);
242
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000243 // All values have been visited.
244 return true;
245}
246
Johannes Doerfertaade7822019-06-05 03:02:24 +0000247/// Return true if \p New is equal or worse than \p Old.
248static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
249 if (!Old.isIntAttribute())
250 return true;
251
252 return Old.getValueAsInt() >= New.getValueAsInt();
253}
254
255/// Return true if the information provided by \p Attr was added to the
256/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000257/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000258static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000259 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000260
261 if (Attr.isEnumAttribute()) {
262 Attribute::AttrKind Kind = Attr.getKindAsEnum();
263 if (Attrs.hasAttribute(AttrIdx, Kind))
264 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
265 return false;
266 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
267 return true;
268 }
269 if (Attr.isStringAttribute()) {
270 StringRef Kind = Attr.getKindAsString();
271 if (Attrs.hasAttribute(AttrIdx, Kind))
272 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
273 return false;
274 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
275 return true;
276 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000277 if (Attr.isIntAttribute()) {
278 Attribute::AttrKind Kind = Attr.getKindAsEnum();
279 if (Attrs.hasAttribute(AttrIdx, Kind))
280 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
281 return false;
282 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
283 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
284 return true;
285 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000286
287 llvm_unreachable("Expected enum or string attribute!");
288}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000289static const Value *getPointerOperand(const Instruction *I) {
290 if (auto *LI = dyn_cast<LoadInst>(I))
291 if (!LI->isVolatile())
292 return LI->getPointerOperand();
293
294 if (auto *SI = dyn_cast<StoreInst>(I))
295 if (!SI->isVolatile())
296 return SI->getPointerOperand();
297
298 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I))
299 if (!CXI->isVolatile())
300 return CXI->getPointerOperand();
301
302 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I))
303 if (!RMWI->isVolatile())
304 return RMWI->getPointerOperand();
305
306 return nullptr;
307}
308static const Value *getBasePointerOfAccessPointerOperand(const Instruction *I,
309 int64_t &BytesOffset,
310 const DataLayout &DL) {
311 const Value *Ptr = getPointerOperand(I);
312 if (!Ptr)
313 return nullptr;
314
315 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
316 /*AllowNonInbounds*/ false);
317}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000318
Johannes Doerfertece81902019-08-12 22:05:53 +0000319ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000320 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
321 if (getState().isAtFixpoint())
322 return HasChanged;
323
324 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
325
Johannes Doerfertece81902019-08-12 22:05:53 +0000326 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000327
328 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
329 << "\n");
330
331 return HasChanged;
332}
333
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000334ChangeStatus
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500335IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000336 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000337 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000338 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000339
Johannes Doerfertaade7822019-06-05 03:02:24 +0000340 // In the following some generic code that will manifest attributes in
341 // DeducedAttrs if they improve the current IR. Due to the different
342 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000343
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000344 AttributeList Attrs;
345 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000346 case IRPosition::IRP_INVALID:
347 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000348 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000349 case IRPosition::IRP_ARGUMENT:
350 case IRPosition::IRP_FUNCTION:
351 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000352 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000353 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000354 case IRPosition::IRP_CALL_SITE:
355 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000356 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000357 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000358 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000359 }
360
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000361 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000362 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000363 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000364 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000365 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000366
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000367 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000368 }
369
370 if (HasChanged == ChangeStatus::UNCHANGED)
371 return HasChanged;
372
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000373 switch (PK) {
374 case IRPosition::IRP_ARGUMENT:
375 case IRPosition::IRP_FUNCTION:
376 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000377 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000378 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000379 case IRPosition::IRP_CALL_SITE:
380 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000381 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000382 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000383 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000384 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000385 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000386 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000387 }
388
389 return HasChanged;
390}
391
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000392const IRPosition IRPosition::EmptyKey(255);
393const IRPosition IRPosition::TombstoneKey(256);
394
395SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
396 IRPositions.emplace_back(IRP);
397
398 ImmutableCallSite ICS(&IRP.getAnchorValue());
399 switch (IRP.getPositionKind()) {
400 case IRPosition::IRP_INVALID:
401 case IRPosition::IRP_FLOAT:
402 case IRPosition::IRP_FUNCTION:
403 return;
404 case IRPosition::IRP_ARGUMENT:
405 case IRPosition::IRP_RETURNED:
406 IRPositions.emplace_back(
407 IRPosition::function(*IRP.getAssociatedFunction()));
408 return;
409 case IRPosition::IRP_CALL_SITE:
410 assert(ICS && "Expected call site!");
411 // TODO: We need to look at the operand bundles similar to the redirection
412 // in CallBase.
413 if (!ICS.hasOperandBundles())
414 if (const Function *Callee = ICS.getCalledFunction())
415 IRPositions.emplace_back(IRPosition::function(*Callee));
416 return;
417 case IRPosition::IRP_CALL_SITE_RETURNED:
418 assert(ICS && "Expected call site!");
419 // TODO: We need to look at the operand bundles similar to the redirection
420 // in CallBase.
421 if (!ICS.hasOperandBundles()) {
422 if (const Function *Callee = ICS.getCalledFunction()) {
423 IRPositions.emplace_back(IRPosition::returned(*Callee));
424 IRPositions.emplace_back(IRPosition::function(*Callee));
425 }
426 }
427 IRPositions.emplace_back(
428 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
429 return;
430 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
431 int ArgNo = IRP.getArgNo();
432 assert(ICS && ArgNo >= 0 && "Expected call site!");
433 // TODO: We need to look at the operand bundles similar to the redirection
434 // in CallBase.
435 if (!ICS.hasOperandBundles()) {
436 const Function *Callee = ICS.getCalledFunction();
437 if (Callee && Callee->arg_size() > unsigned(ArgNo))
438 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
439 if (Callee)
440 IRPositions.emplace_back(IRPosition::function(*Callee));
441 }
442 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
443 return;
444 }
445 }
446}
447
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000448bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
449 bool IgnoreSubsumingPositions) const {
450 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000451 for (Attribute::AttrKind AK : AKs)
452 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
453 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000454 // The first position returned by the SubsumingPositionIterator is
455 // always the position itself. If we ignore subsuming positions we
456 // are done after the first iteration.
457 if (IgnoreSubsumingPositions)
458 break;
459 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000460 return false;
461}
462
463void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
464 SmallVectorImpl<Attribute> &Attrs) const {
465 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this))
466 for (Attribute::AttrKind AK : AKs) {
467 const Attribute &Attr = EquivIRP.getAttr(AK);
468 if (Attr.getKindAsEnum() == AK)
469 Attrs.push_back(Attr);
470 }
471}
472
473void IRPosition::verify() {
474 switch (KindOrArgNo) {
475 default:
476 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
477 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
478 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000479 if (isa<Argument>(AnchorVal)) {
480 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000481 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000482 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
483 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000484 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000485 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000486 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000487 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
488 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000489 "Associated value mismatch!");
490 }
491 break;
492 case IRP_INVALID:
493 assert(!AnchorVal && "Expected no value for an invalid position!");
494 break;
495 case IRP_FLOAT:
496 assert((!isa<CallBase>(&getAssociatedValue()) &&
497 !isa<Argument>(&getAssociatedValue())) &&
498 "Expected specialized kind for call base and argument values!");
499 break;
500 case IRP_RETURNED:
501 assert(isa<Function>(AnchorVal) &&
502 "Expected function for a 'returned' position!");
503 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
504 break;
505 case IRP_CALL_SITE_RETURNED:
506 assert((isa<CallBase>(AnchorVal)) &&
507 "Expected call base for 'call site returned' position!");
508 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
509 break;
510 case IRP_CALL_SITE:
511 assert((isa<CallBase>(AnchorVal)) &&
512 "Expected call base for 'call site function' position!");
513 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
514 break;
515 case IRP_FUNCTION:
516 assert(isa<Function>(AnchorVal) &&
517 "Expected function for a 'function' position!");
518 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
519 break;
520 }
521}
522
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000523namespace {
Johannes Doerfert1a746452019-10-20 22:28:49 -0500524/// Helper function to clamp a state \p S of type \p StateType with the
Johannes Doerfert234eda52019-08-16 19:51:23 +0000525/// information in \p R and indicate/return if \p S did change (as-in update is
526/// required to be run again).
Johannes Doerfert234eda52019-08-16 19:51:23 +0000527template <typename StateType>
Johannes Doerfert1a746452019-10-20 22:28:49 -0500528ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000529 auto Assumed = S.getAssumed();
530 S ^= R;
531 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
532 : ChangeStatus::CHANGED;
533}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000534
Johannes Doerfert234eda52019-08-16 19:51:23 +0000535/// Clamp the information known for all returned values of a function
536/// (identified by \p QueryingAA) into \p S.
537template <typename AAType, typename StateType = typename AAType::StateType>
538static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
539 StateType &S) {
540 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
541 << static_cast<const AbstractAttribute &>(QueryingAA)
542 << " into " << S << "\n");
543
544 assert((QueryingAA.getIRPosition().getPositionKind() ==
545 IRPosition::IRP_RETURNED ||
546 QueryingAA.getIRPosition().getPositionKind() ==
547 IRPosition::IRP_CALL_SITE_RETURNED) &&
548 "Can only clamp returned value states for a function returned or call "
549 "site returned position!");
550
551 // Use an optional state as there might not be any return values and we want
552 // to join (IntegerState::operator&) the state of all there are.
553 Optional<StateType> T;
554
555 // Callback for each possibly returned value.
556 auto CheckReturnValue = [&](Value &RV) -> bool {
557 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000558 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
559 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
560 << " @ " << RVPos << "\n");
561 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000562 if (T.hasValue())
563 *T &= AAS;
564 else
565 T = AAS;
566 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
567 << "\n");
568 return T->isValidState();
569 };
570
571 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
572 S.indicatePessimisticFixpoint();
573 else if (T.hasValue())
574 S ^= *T;
575}
576
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000577/// Helper class to compose two generic deduction
578template <typename AAType, typename Base, typename StateType,
579 template <typename...> class F, template <typename...> class G>
580struct AAComposeTwoGenericDeduction
581 : public F<AAType, G<AAType, Base, StateType>, StateType> {
582 AAComposeTwoGenericDeduction(const IRPosition &IRP)
583 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
584
585 /// See AbstractAttribute::updateImpl(...).
586 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000587 ChangeStatus ChangedF = F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
588 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
589 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000590 }
591};
592
Johannes Doerfert234eda52019-08-16 19:51:23 +0000593/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000594template <typename AAType, typename Base,
595 typename StateType = typename AAType::StateType>
596struct AAReturnedFromReturnedValues : public Base {
597 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000598
599 /// See AbstractAttribute::updateImpl(...).
600 ChangeStatus updateImpl(Attributor &A) override {
601 StateType S;
602 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000603 // TODO: If we know we visited all returned values, thus no are assumed
604 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000605 return clampStateAndIndicateChange<StateType>(this->getState(), S);
606 }
607};
608
609/// Clamp the information known at all call sites for a given argument
610/// (identified by \p QueryingAA) into \p S.
611template <typename AAType, typename StateType = typename AAType::StateType>
612static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
613 StateType &S) {
614 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
615 << static_cast<const AbstractAttribute &>(QueryingAA)
616 << " into " << S << "\n");
617
618 assert(QueryingAA.getIRPosition().getPositionKind() ==
619 IRPosition::IRP_ARGUMENT &&
620 "Can only clamp call site argument states for an argument position!");
621
622 // Use an optional state as there might not be any return values and we want
623 // to join (IntegerState::operator&) the state of all there are.
624 Optional<StateType> T;
625
626 // The argument number which is also the call site argument number.
627 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
628
Johannes Doerfert661db042019-10-07 23:14:58 +0000629 auto CallSiteCheck = [&](AbstractCallSite ACS) {
630 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
631 // Check if a coresponding argument was found or if it is on not associated
632 // (which can happen for callback calls).
633 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
634 return false;
635
636 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
637 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
638 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000639 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000640 if (T.hasValue())
641 *T &= AAS;
642 else
643 T = AAS;
644 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
645 << "\n");
646 return T->isValidState();
647 };
648
649 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true))
650 S.indicatePessimisticFixpoint();
651 else if (T.hasValue())
652 S ^= *T;
653}
654
655/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000656template <typename AAType, typename Base,
657 typename StateType = typename AAType::StateType>
658struct AAArgumentFromCallSiteArguments : public Base {
659 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000660
661 /// See AbstractAttribute::updateImpl(...).
662 ChangeStatus updateImpl(Attributor &A) override {
663 StateType S;
664 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000665 // TODO: If we know we visited all incoming values, thus no are assumed
666 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000667 return clampStateAndIndicateChange<StateType>(this->getState(), S);
668 }
669};
670
671/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000672template <typename AAType, typename Base,
673 typename StateType = typename AAType::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000674struct AACallSiteReturnedFromReturned : public Base {
675 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000676
677 /// See AbstractAttribute::updateImpl(...).
678 ChangeStatus updateImpl(Attributor &A) override {
679 assert(this->getIRPosition().getPositionKind() ==
680 IRPosition::IRP_CALL_SITE_RETURNED &&
681 "Can only wrap function returned positions for call site returned "
682 "positions!");
683 auto &S = this->getState();
684
685 const Function *AssociatedFunction =
686 this->getIRPosition().getAssociatedFunction();
687 if (!AssociatedFunction)
688 return S.indicatePessimisticFixpoint();
689
690 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000691 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000692 return clampStateAndIndicateChange(
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000693 S, static_cast<const typename AAType::StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000694 }
695};
696
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000697/// Helper class for generic deduction using must-be-executed-context
698/// Base class is required to have `followUse` method.
699
700/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000701/// U - Underlying use.
702/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000703/// `followUse` returns true if the value should be tracked transitively.
704
705template <typename AAType, typename Base,
706 typename StateType = typename AAType::StateType>
707struct AAFromMustBeExecutedContext : public Base {
708 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
709
710 void initialize(Attributor &A) override {
711 Base::initialize(A);
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500712 const IRPosition &IRP = this->getIRPosition();
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000713 Instruction *CtxI = IRP.getCtxI();
714
715 if (!CtxI)
716 return;
717
718 for (const Use &U : IRP.getAssociatedValue().uses())
719 Uses.insert(&U);
720 }
721
722 /// See AbstractAttribute::updateImpl(...).
723 ChangeStatus updateImpl(Attributor &A) override {
724 auto BeforeState = this->getState();
725 auto &S = this->getState();
726 Instruction *CtxI = this->getIRPosition().getCtxI();
727 if (!CtxI)
728 return ChangeStatus::UNCHANGED;
729
730 MustBeExecutedContextExplorer &Explorer =
731 A.getInfoCache().getMustBeExecutedContextExplorer();
732
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500733 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500734 for (unsigned u = 0 ; u < Uses.size(); ++u) {
735 const Use *U = Uses[u];
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000736 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500737 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000738 if (Found && Base::followUse(A, U, UserI))
739 for (const Use &Us : UserI->uses())
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500740 Uses.insert(&Us);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000741 }
742 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000743
744 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
745 }
746
747private:
748 /// Container for (transitive) uses of the associated value.
749 SetVector<const Use *> Uses;
750};
751
752template <typename AAType, typename Base,
753 typename StateType = typename AAType::StateType>
754using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
755 AAComposeTwoGenericDeduction<AAType, Base, StateType,
756 AAFromMustBeExecutedContext,
757 AAArgumentFromCallSiteArguments>;
758
759template <typename AAType, typename Base,
760 typename StateType = typename AAType::StateType>
761using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
762 AAComposeTwoGenericDeduction<AAType, Base, StateType,
763 AAFromMustBeExecutedContext,
764 AACallSiteReturnedFromReturned>;
765
Stefan Stipanovic53605892019-06-27 11:27:54 +0000766/// -----------------------NoUnwind Function Attribute--------------------------
767
Johannes Doerfert344d0382019-08-07 22:34:26 +0000768struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000769 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000770
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000771 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000772 return getAssumed() ? "nounwind" : "may-unwind";
773 }
774
775 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000776 ChangeStatus updateImpl(Attributor &A) override {
777 auto Opcodes = {
778 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
779 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
780 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
781
782 auto CheckForNoUnwind = [&](Instruction &I) {
783 if (!I.mayThrow())
784 return true;
785
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000786 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
787 const auto &NoUnwindAA =
788 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
789 return NoUnwindAA.isAssumedNoUnwind();
790 }
791 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000792 };
793
794 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
795 return indicatePessimisticFixpoint();
796
797 return ChangeStatus::UNCHANGED;
798 }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000799};
800
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000801struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000802 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000803
804 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000805 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000806};
807
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000808/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000809struct AANoUnwindCallSite final : AANoUnwindImpl {
810 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
811
812 /// See AbstractAttribute::initialize(...).
813 void initialize(Attributor &A) override {
814 AANoUnwindImpl::initialize(A);
815 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000816 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000817 indicatePessimisticFixpoint();
818 }
819
820 /// See AbstractAttribute::updateImpl(...).
821 ChangeStatus updateImpl(Attributor &A) override {
822 // TODO: Once we have call site specific value information we can provide
823 // call site specific liveness information and then it makes
824 // sense to specialize attributes for call sites arguments instead of
825 // redirecting requests to the callee argument.
826 Function *F = getAssociatedFunction();
827 const IRPosition &FnPos = IRPosition::function(*F);
828 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
829 return clampStateAndIndicateChange(
830 getState(),
831 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
832 }
833
834 /// See AbstractAttribute::trackStatistics()
835 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
836};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000837
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000838/// --------------------- Function Return Values -------------------------------
839
840/// "Attribute" that collects all potential returned values and the return
841/// instructions that they arise from.
842///
843/// If there is a unique returned value R, the manifest method will:
844/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +0000845class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000846
847 /// Mapping of values potentially returned by the associated function to the
848 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +0000849 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000850
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000851 /// Mapping to remember the number of returned values for a call site such
852 /// that we can avoid updates if nothing changed.
853 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
854
855 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +0000856 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000857
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000858 /// State flags
859 ///
860 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000861 bool IsFixed = false;
862 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000863 ///}
864
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000865public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000866 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000867
868 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +0000869 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000870 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000871 IsFixed = false;
872 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000873 ReturnedValues.clear();
874
Johannes Doerfertdef99282019-08-14 21:29:37 +0000875 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000876 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000877 indicatePessimisticFixpoint();
878 return;
879 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000880
881 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000882 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000883
884 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000885 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000886 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000887 auto &ReturnInstSet = ReturnedValues[&Arg];
888 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
889 ReturnInstSet.insert(cast<ReturnInst>(RI));
890
891 indicateOptimisticFixpoint();
892 return;
893 }
894 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000895
896 if (!F->hasExactDefinition())
897 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000898 }
899
900 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000901 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000902
903 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000904 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000905
906 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000907 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000908
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000909 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +0000910 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000911
Johannes Doerfertdef99282019-08-14 21:29:37 +0000912 llvm::iterator_range<iterator> returned_values() override {
913 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
914 }
915
916 llvm::iterator_range<const_iterator> returned_values() const override {
917 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
918 }
919
Johannes Doerfert695089e2019-08-23 15:23:49 +0000920 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000921 return UnresolvedCalls;
922 }
923
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000924 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000925 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000926 return isValidState() ? ReturnedValues.size() : -1;
927 }
928
929 /// Return an assumed unique return value if a single candidate is found. If
930 /// there cannot be one, return a nullptr. If it is not clear yet, return the
931 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000932 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000933
Johannes Doerfert14a04932019-08-07 22:27:24 +0000934 /// See AbstractState::checkForAllReturnedValues(...).
935 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +0000936 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +0000937 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000938
939 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000940 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000941
942 /// See AbstractState::isAtFixpoint().
943 bool isAtFixpoint() const override { return IsFixed; }
944
945 /// See AbstractState::isValidState().
946 bool isValidState() const override { return IsValidState; }
947
948 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000949 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000950 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000951 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000952 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000953
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000954 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000955 IsFixed = true;
956 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000957 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000958 }
959};
960
961ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
962 ChangeStatus Changed = ChangeStatus::UNCHANGED;
963
964 // Bookkeeping.
965 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000966 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
967 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000968
969 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000970 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000971
972 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
973 return Changed;
974
975 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000976 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
977 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000978
Johannes Doerfert23400e612019-08-23 17:41:37 +0000979 // Callback to replace the uses of CB with the constant C.
980 auto ReplaceCallSiteUsersWith = [](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +0000981 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +0000982 return ChangeStatus::UNCHANGED;
983 CB.replaceAllUsesWith(&C);
984 return ChangeStatus::CHANGED;
985 };
986
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000987 // If the assumed unique return value is an argument, annotate it.
988 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500989 // TODO: This should be handled differently!
990 this->AnchorVal = UniqueRVArg;
991 this->KindOrArgNo = UniqueRVArg->getArgNo();
Johannes Doerfert23400e612019-08-23 17:41:37 +0000992 Changed = IRAttribute::manifest(A);
993 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
994 // We can replace the returned value with the unique returned constant.
995 Value &AnchorValue = getAnchorValue();
996 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
997 for (const Use &U : F->uses())
998 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +0000999 if (CB->isCallee(&U)) {
1000 Constant *RVCCast =
1001 ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
1002 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1003 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001004 } else {
1005 assert(isa<CallBase>(AnchorValue) &&
1006 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001007 Constant *RVCCast =
1008 ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
1009 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001010 }
1011 if (Changed == ChangeStatus::CHANGED)
1012 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1013 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001014 }
1015
1016 return Changed;
1017}
1018
1019const std::string AAReturnedValuesImpl::getAsStr() const {
1020 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001021 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001022 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001023}
1024
Johannes Doerfert14a04932019-08-07 22:27:24 +00001025Optional<Value *>
1026AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1027 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001028 // undef values that can also be present, it is assumed to be the actual
1029 // return value and forwarded to the caller of this method. If there are
1030 // multiple, a nullptr is returned indicating there cannot be a unique
1031 // returned value.
1032 Optional<Value *> UniqueRV;
1033
Johannes Doerfert14a04932019-08-07 22:27:24 +00001034 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001035 // If we found a second returned value and neither the current nor the saved
1036 // one is an undef, there is no unique returned value. Undefs are special
1037 // since we can pretend they have any value.
1038 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1039 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1040 UniqueRV = nullptr;
1041 return false;
1042 }
1043
1044 // Do not overwrite a value with an undef.
1045 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1046 UniqueRV = &RV;
1047
1048 return true;
1049 };
1050
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001051 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001052 UniqueRV = nullptr;
1053
1054 return UniqueRV;
1055}
1056
Johannes Doerfert14a04932019-08-07 22:27:24 +00001057bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001058 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001059 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001060 if (!isValidState())
1061 return false;
1062
1063 // Check all returned values but ignore call sites as long as we have not
1064 // encountered an overdefined one during an update.
1065 for (auto &It : ReturnedValues) {
1066 Value *RV = It.first;
1067
Johannes Doerfertdef99282019-08-14 21:29:37 +00001068 CallBase *CB = dyn_cast<CallBase>(RV);
1069 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001070 continue;
1071
Johannes Doerfert695089e2019-08-23 15:23:49 +00001072 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001073 return false;
1074 }
1075
1076 return true;
1077}
1078
Johannes Doerfertece81902019-08-12 22:05:53 +00001079ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001080 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1081 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001082
Johannes Doerfertdef99282019-08-14 21:29:37 +00001083 // State used in the value traversals starting in returned values.
1084 struct RVState {
1085 // The map in which we collect return values -> return instrs.
1086 decltype(ReturnedValues) &RetValsMap;
1087 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001088 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001089 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001090 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001091 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001092
Johannes Doerfertdef99282019-08-14 21:29:37 +00001093 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001094 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001095 auto Size = RVS.RetValsMap[&Val].size();
1096 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1097 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1098 RVS.Changed |= Inserted;
1099 LLVM_DEBUG({
1100 if (Inserted)
1101 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1102 << " => " << RVS.RetInsts.size() << "\n";
1103 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001104 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001105 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001106
Johannes Doerfertdef99282019-08-14 21:29:37 +00001107 // Helper method to invoke the generic value traversal.
1108 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1109 IRPosition RetValPos = IRPosition::value(RV);
1110 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1111 RVS, VisitValueCB);
1112 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001113
Johannes Doerfertdef99282019-08-14 21:29:37 +00001114 // Callback for all "return intructions" live in the associated function.
1115 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1116 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001117 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001118 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001119 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1120 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001121
Johannes Doerfertdef99282019-08-14 21:29:37 +00001122 // Start by discovering returned values from all live returned instructions in
1123 // the associated function.
1124 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1125 return indicatePessimisticFixpoint();
1126
1127 // Once returned values "directly" present in the code are handled we try to
1128 // resolve returned calls.
1129 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001130 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001131 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1132 << " by #" << It.second.size() << " RIs\n");
1133 CallBase *CB = dyn_cast<CallBase>(It.first);
1134 if (!CB || UnresolvedCalls.count(CB))
1135 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001136
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001137 if (!CB->getCalledFunction()) {
1138 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1139 << "\n");
1140 UnresolvedCalls.insert(CB);
1141 continue;
1142 }
1143
1144 // TODO: use the function scope once we have call site AAReturnedValues.
1145 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1146 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001147 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
1148 << static_cast<const AbstractAttribute &>(RetValAA)
1149 << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001150
1151 // Skip dead ends, thus if we do not know anything about the returned
1152 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001153 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001154 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1155 << "\n");
1156 UnresolvedCalls.insert(CB);
1157 continue;
1158 }
1159
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001160 // Do not try to learn partial information. If the callee has unresolved
1161 // return values we will treat the call as unresolved/opaque.
1162 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1163 if (!RetValAAUnresolvedCalls.empty()) {
1164 UnresolvedCalls.insert(CB);
1165 continue;
1166 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001167
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001168 // Now check if we can track transitively returned values. If possible, thus
1169 // if all return value can be represented in the current scope, do so.
1170 bool Unresolved = false;
1171 for (auto &RetValAAIt : RetValAA.returned_values()) {
1172 Value *RetVal = RetValAAIt.first;
1173 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1174 isa<Constant>(RetVal))
1175 continue;
1176 // Anything that did not fit in the above categories cannot be resolved,
1177 // mark the call as unresolved.
1178 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1179 "cannot be translated: "
1180 << *RetVal << "\n");
1181 UnresolvedCalls.insert(CB);
1182 Unresolved = true;
1183 break;
1184 }
1185
1186 if (Unresolved)
1187 continue;
1188
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001189 // Now track transitively returned values.
1190 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1191 if (NumRetAA == RetValAA.getNumReturnValues()) {
1192 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1193 "changed since it was seen last\n");
1194 continue;
1195 }
1196 NumRetAA = RetValAA.getNumReturnValues();
1197
Johannes Doerfertdef99282019-08-14 21:29:37 +00001198 for (auto &RetValAAIt : RetValAA.returned_values()) {
1199 Value *RetVal = RetValAAIt.first;
1200 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1201 // Arguments are mapped to call site operands and we begin the traversal
1202 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001203 bool Unused = false;
1204 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001205 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1206 continue;
1207 } else if (isa<CallBase>(RetVal)) {
1208 // Call sites are resolved by the callee attribute over time, no need to
1209 // do anything for us.
1210 continue;
1211 } else if (isa<Constant>(RetVal)) {
1212 // Constants are valid everywhere, we can simply take them.
1213 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1214 continue;
1215 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001216 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001217 }
1218
Johannes Doerfertdef99282019-08-14 21:29:37 +00001219 // To avoid modifications to the ReturnedValues map while we iterate over it
1220 // we kept record of potential new entries in a copy map, NewRVsMap.
1221 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001222 assert(!It.second.empty() && "Entry does not add anything.");
1223 auto &ReturnInsts = ReturnedValues[It.first];
1224 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001225 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001226 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1227 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001228 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001229 }
1230 }
1231
Johannes Doerfertdef99282019-08-14 21:29:37 +00001232 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1233 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001234}
1235
Johannes Doerfertdef99282019-08-14 21:29:37 +00001236struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1237 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1238
1239 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001240 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001241};
1242
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001243/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001244struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1245 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1246
1247 /// See AbstractAttribute::initialize(...).
1248 void initialize(Attributor &A) override {
1249 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001250 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001251 // sense to specialize attributes for call sites instead of
1252 // redirecting requests to the callee.
1253 llvm_unreachable("Abstract attributes for returned values are not "
1254 "supported for call sites yet!");
1255 }
1256
1257 /// See AbstractAttribute::updateImpl(...).
1258 ChangeStatus updateImpl(Attributor &A) override {
1259 return indicatePessimisticFixpoint();
1260 }
1261
1262 /// See AbstractAttribute::trackStatistics()
1263 void trackStatistics() const override {}
1264};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001265
Stefan Stipanovic06263672019-07-11 21:37:40 +00001266/// ------------------------ NoSync Function Attribute -------------------------
1267
Johannes Doerfert344d0382019-08-07 22:34:26 +00001268struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001269 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001270
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001271 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001272 return getAssumed() ? "nosync" : "may-sync";
1273 }
1274
1275 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001276 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001277
Stefan Stipanovic06263672019-07-11 21:37:40 +00001278 /// Helper function used to determine whether an instruction is non-relaxed
1279 /// atomic. In other words, if an atomic instruction does not have unordered
1280 /// or monotonic ordering
1281 static bool isNonRelaxedAtomic(Instruction *I);
1282
1283 /// Helper function used to determine whether an instruction is volatile.
1284 static bool isVolatile(Instruction *I);
1285
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001286 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1287 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001288 static bool isNoSyncIntrinsic(Instruction *I);
1289};
1290
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001291bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001292 if (!I->isAtomic())
1293 return false;
1294
1295 AtomicOrdering Ordering;
1296 switch (I->getOpcode()) {
1297 case Instruction::AtomicRMW:
1298 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1299 break;
1300 case Instruction::Store:
1301 Ordering = cast<StoreInst>(I)->getOrdering();
1302 break;
1303 case Instruction::Load:
1304 Ordering = cast<LoadInst>(I)->getOrdering();
1305 break;
1306 case Instruction::Fence: {
1307 auto *FI = cast<FenceInst>(I);
1308 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1309 return false;
1310 Ordering = FI->getOrdering();
1311 break;
1312 }
1313 case Instruction::AtomicCmpXchg: {
1314 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1315 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1316 // Only if both are relaxed, than it can be treated as relaxed.
1317 // Otherwise it is non-relaxed.
1318 if (Success != AtomicOrdering::Unordered &&
1319 Success != AtomicOrdering::Monotonic)
1320 return true;
1321 if (Failure != AtomicOrdering::Unordered &&
1322 Failure != AtomicOrdering::Monotonic)
1323 return true;
1324 return false;
1325 }
1326 default:
1327 llvm_unreachable(
1328 "New atomic operations need to be known in the attributor.");
1329 }
1330
1331 // Relaxed.
1332 if (Ordering == AtomicOrdering::Unordered ||
1333 Ordering == AtomicOrdering::Monotonic)
1334 return false;
1335 return true;
1336}
1337
1338/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1339/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001340bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001341 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1342 switch (II->getIntrinsicID()) {
1343 /// Element wise atomic memory intrinsics are can only be unordered,
1344 /// therefore nosync.
1345 case Intrinsic::memset_element_unordered_atomic:
1346 case Intrinsic::memmove_element_unordered_atomic:
1347 case Intrinsic::memcpy_element_unordered_atomic:
1348 return true;
1349 case Intrinsic::memset:
1350 case Intrinsic::memmove:
1351 case Intrinsic::memcpy:
1352 if (!cast<MemIntrinsic>(II)->isVolatile())
1353 return true;
1354 return false;
1355 default:
1356 return false;
1357 }
1358 }
1359 return false;
1360}
1361
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001362bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001363 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1364 "Calls should not be checked here");
1365
1366 switch (I->getOpcode()) {
1367 case Instruction::AtomicRMW:
1368 return cast<AtomicRMWInst>(I)->isVolatile();
1369 case Instruction::Store:
1370 return cast<StoreInst>(I)->isVolatile();
1371 case Instruction::Load:
1372 return cast<LoadInst>(I)->isVolatile();
1373 case Instruction::AtomicCmpXchg:
1374 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1375 default:
1376 return false;
1377 }
1378}
1379
Johannes Doerfertece81902019-08-12 22:05:53 +00001380ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001381
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001382 auto CheckRWInstForNoSync = [&](Instruction &I) {
1383 /// We are looking for volatile instructions or Non-Relaxed atomics.
1384 /// FIXME: We should ipmrove the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001385
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001386 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1387 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001388
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001389 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1390 if (ICS.hasFnAttr(Attribute::NoSync))
1391 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001392
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001393 const auto &NoSyncAA =
1394 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1395 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001396 return true;
1397 return false;
1398 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001399
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001400 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1401 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001402
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001403 return false;
1404 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001405
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001406 auto CheckForNoSync = [&](Instruction &I) {
1407 // At this point we handled all read/write effects and they are all
1408 // nosync, so they can be skipped.
1409 if (I.mayReadOrWriteMemory())
1410 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001411
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001412 // non-convergent and readnone imply nosync.
1413 return !ImmutableCallSite(&I).isConvergent();
1414 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001415
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001416 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1417 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001418 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001419
Stefan Stipanovic06263672019-07-11 21:37:40 +00001420 return ChangeStatus::UNCHANGED;
1421}
1422
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001423struct AANoSyncFunction final : public AANoSyncImpl {
1424 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1425
1426 /// See AbstractAttribute::trackStatistics()
1427 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1428};
1429
1430/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001431struct AANoSyncCallSite final : AANoSyncImpl {
1432 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1433
1434 /// See AbstractAttribute::initialize(...).
1435 void initialize(Attributor &A) override {
1436 AANoSyncImpl::initialize(A);
1437 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001438 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001439 indicatePessimisticFixpoint();
1440 }
1441
1442 /// See AbstractAttribute::updateImpl(...).
1443 ChangeStatus updateImpl(Attributor &A) override {
1444 // TODO: Once we have call site specific value information we can provide
1445 // call site specific liveness information and then it makes
1446 // sense to specialize attributes for call sites arguments instead of
1447 // redirecting requests to the callee argument.
1448 Function *F = getAssociatedFunction();
1449 const IRPosition &FnPos = IRPosition::function(*F);
1450 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1451 return clampStateAndIndicateChange(
1452 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1453 }
1454
1455 /// See AbstractAttribute::trackStatistics()
1456 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1457};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001458
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001459/// ------------------------ No-Free Attributes ----------------------------
1460
Johannes Doerfert344d0382019-08-07 22:34:26 +00001461struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001462 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001463
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001464 /// See AbstractAttribute::updateImpl(...).
1465 ChangeStatus updateImpl(Attributor &A) override {
1466 auto CheckForNoFree = [&](Instruction &I) {
1467 ImmutableCallSite ICS(&I);
1468 if (ICS.hasFnAttr(Attribute::NoFree))
1469 return true;
1470
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001471 const auto &NoFreeAA =
1472 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1473 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001474 };
1475
1476 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1477 return indicatePessimisticFixpoint();
1478 return ChangeStatus::UNCHANGED;
1479 }
1480
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001481 /// See AbstractAttribute::getAsStr().
1482 const std::string getAsStr() const override {
1483 return getAssumed() ? "nofree" : "may-free";
1484 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001485};
1486
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001487struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001488 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001489
1490 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001491 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001492};
1493
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001494/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001495struct AANoFreeCallSite final : AANoFreeImpl {
1496 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1497
1498 /// See AbstractAttribute::initialize(...).
1499 void initialize(Attributor &A) override {
1500 AANoFreeImpl::initialize(A);
1501 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001502 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001503 indicatePessimisticFixpoint();
1504 }
1505
1506 /// See AbstractAttribute::updateImpl(...).
1507 ChangeStatus updateImpl(Attributor &A) override {
1508 // TODO: Once we have call site specific value information we can provide
1509 // call site specific liveness information and then it makes
1510 // sense to specialize attributes for call sites arguments instead of
1511 // redirecting requests to the callee argument.
1512 Function *F = getAssociatedFunction();
1513 const IRPosition &FnPos = IRPosition::function(*F);
1514 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1515 return clampStateAndIndicateChange(
1516 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1517 }
1518
1519 /// See AbstractAttribute::trackStatistics()
1520 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1521};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001522
Hideto Ueno54869ec2019-07-15 06:49:04 +00001523/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001524static int64_t getKnownNonNullAndDerefBytesForUse(
1525 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1526 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001527 TrackUse = false;
1528
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001529 const Value *UseV = U->get();
1530 if (!UseV->getType()->isPointerTy())
1531 return 0;
1532
1533 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001534 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001535 bool NullPointerIsDefined =
1536 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001537 const DataLayout &DL = A.getInfoCache().getDL();
1538 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1539 if (ICS.isBundleOperand(U))
1540 return 0;
1541
1542 if (ICS.isCallee(U)) {
1543 IsNonNull |= !NullPointerIsDefined;
1544 return 0;
1545 }
1546
1547 unsigned ArgNo = ICS.getArgumentNo(U);
1548 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
1549 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP);
1550 IsNonNull |= DerefAA.isKnownNonNull();
1551 return DerefAA.getKnownDereferenceableBytes();
1552 }
1553
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001554 // We need to follow common pointer manipulation uses to the accesses they
1555 // feed into. We can try to be smart to avoid looking through things we do not
1556 // like for now, e.g., non-inbounds GEPs.
1557 if (isa<CastInst>(I)) {
1558 TrackUse = true;
1559 return 0;
1560 }
1561 if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
1562 if (GEP->hasAllZeroIndices() ||
1563 (GEP->isInBounds() && GEP->hasAllConstantIndices())) {
1564 TrackUse = true;
1565 return 0;
1566 }
1567
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001568 int64_t Offset;
1569 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001570 if (Base == &AssociatedValue && getPointerOperand(I) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001571 int64_t DerefBytes =
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001572 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType()) + Offset;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001573
1574 IsNonNull |= !NullPointerIsDefined;
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001575 return std::max(int64_t(0), DerefBytes);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001576 }
1577 }
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001578 if (const Value *Base =
1579 GetPointerBaseWithConstantOffset(UseV, Offset, DL,
1580 /*AllowNonInbounds*/ false)) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001581 if (Base == &AssociatedValue) {
1582 auto &DerefAA =
1583 A.getAAFor<AADereferenceable>(QueryingAA, IRPosition::value(*Base));
1584 IsNonNull |= (!NullPointerIsDefined && DerefAA.isKnownNonNull());
1585 IsNonNull |= (!NullPointerIsDefined && (Offset != 0));
1586 int64_t DerefBytes = DerefAA.getKnownDereferenceableBytes();
1587 return std::max(int64_t(0), DerefBytes - std::max(int64_t(0), Offset));
1588 }
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001589 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001590
1591 return 0;
1592}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001593
Johannes Doerfert344d0382019-08-07 22:34:26 +00001594struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001595 AANonNullImpl(const IRPosition &IRP)
1596 : AANonNull(IRP),
1597 NullIsDefined(NullPointerIsDefined(
1598 getAnchorScope(),
1599 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001600
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001601 /// See AbstractAttribute::initialize(...).
1602 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001603 if (!NullIsDefined &&
1604 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001605 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001606 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1607 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001608 else
1609 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001610 }
1611
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001612 /// See AAFromMustBeExecutedContext
1613 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1614 bool IsNonNull = false;
1615 bool TrackUse = false;
1616 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1617 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001618 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001619 return TrackUse;
1620 }
1621
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001622 /// See AbstractAttribute::getAsStr().
1623 const std::string getAsStr() const override {
1624 return getAssumed() ? "nonnull" : "may-null";
1625 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001626
1627 /// Flag to determine if the underlying value can be null and still allow
1628 /// valid accesses.
1629 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001630};
1631
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001632/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001633struct AANonNullFloating
1634 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1635 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1636 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001637
Hideto Ueno54869ec2019-07-15 06:49:04 +00001638 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001639 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001640 ChangeStatus Change = Base::updateImpl(A);
1641 if (isKnownNonNull())
1642 return Change;
1643
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001644 if (!NullIsDefined) {
1645 const auto &DerefAA = A.getAAFor<AADereferenceable>(*this, getIRPosition());
1646 if (DerefAA.getAssumedDereferenceableBytes())
1647 return Change;
1648 }
1649
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001650 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001651
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001652 DominatorTree *DT = nullptr;
1653 InformationCache &InfoCache = A.getInfoCache();
1654 if (const Function *Fn = getAnchorScope())
1655 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
1656
Johannes Doerfert1a746452019-10-20 22:28:49 -05001657 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001658 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001659 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1660 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001661 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001662 T.indicatePessimisticFixpoint();
1663 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001664 // Use abstract attribute information.
1665 const AANonNull::StateType &NS =
1666 static_cast<const AANonNull::StateType &>(AA.getState());
1667 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001668 }
1669 return T.isValidState();
1670 };
1671
1672 StateType T;
1673 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
1674 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001675 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001676
1677 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001678 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001679
1680 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001681 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001682};
1683
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001684/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001685struct AANonNullReturned final
1686 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001687 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001688 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001689
1690 /// See AbstractAttribute::trackStatistics()
1691 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
1692};
1693
Hideto Ueno54869ec2019-07-15 06:49:04 +00001694/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001695struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001696 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1697 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001698 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001699 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1700 AANonNullImpl>(
1701 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001702
1703 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001704 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001705};
1706
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001707struct AANonNullCallSiteArgument final : AANonNullFloating {
1708 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001709
1710 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00001711 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001712};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001713
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001714/// NonNull attribute for a call site return position.
1715struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001716 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1717 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001718 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001719 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1720 AANonNullImpl>(
1721 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001722
1723 /// See AbstractAttribute::trackStatistics()
1724 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
1725};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001726
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001727/// ------------------------ No-Recurse Attributes ----------------------------
1728
1729struct AANoRecurseImpl : public AANoRecurse {
1730 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
1731
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001732 /// See AbstractAttribute::getAsStr()
1733 const std::string getAsStr() const override {
1734 return getAssumed() ? "norecurse" : "may-recurse";
1735 }
1736};
1737
1738struct AANoRecurseFunction final : AANoRecurseImpl {
1739 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1740
Hideto Ueno63f60662019-09-21 15:13:19 +00001741 /// See AbstractAttribute::initialize(...).
1742 void initialize(Attributor &A) override {
1743 AANoRecurseImpl::initialize(A);
1744 if (const Function *F = getAnchorScope())
1745 if (A.getInfoCache().getSccSize(*F) == 1)
1746 return;
1747 indicatePessimisticFixpoint();
1748 }
1749
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001750 /// See AbstractAttribute::updateImpl(...).
1751 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00001752
1753 auto CheckForNoRecurse = [&](Instruction &I) {
1754 ImmutableCallSite ICS(&I);
1755 if (ICS.hasFnAttr(Attribute::NoRecurse))
1756 return true;
1757
1758 const auto &NoRecurseAA =
1759 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
1760 if (!NoRecurseAA.isAssumedNoRecurse())
1761 return false;
1762
1763 // Recursion to the same function
1764 if (ICS.getCalledFunction() == getAnchorScope())
1765 return false;
1766
1767 return true;
1768 };
1769
1770 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
1771 return indicatePessimisticFixpoint();
1772 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001773 }
1774
1775 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
1776};
1777
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001778/// NoRecurse attribute deduction for a call sites.
1779struct AANoRecurseCallSite final : AANoRecurseImpl {
1780 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1781
1782 /// See AbstractAttribute::initialize(...).
1783 void initialize(Attributor &A) override {
1784 AANoRecurseImpl::initialize(A);
1785 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001786 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001787 indicatePessimisticFixpoint();
1788 }
1789
1790 /// See AbstractAttribute::updateImpl(...).
1791 ChangeStatus updateImpl(Attributor &A) override {
1792 // TODO: Once we have call site specific value information we can provide
1793 // call site specific liveness information and then it makes
1794 // sense to specialize attributes for call sites arguments instead of
1795 // redirecting requests to the callee argument.
1796 Function *F = getAssociatedFunction();
1797 const IRPosition &FnPos = IRPosition::function(*F);
1798 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
1799 return clampStateAndIndicateChange(
1800 getState(),
1801 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
1802 }
1803
1804 /// See AbstractAttribute::trackStatistics()
1805 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
1806};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001807
Hideto Ueno11d37102019-07-17 15:15:43 +00001808/// ------------------------ Will-Return Attributes ----------------------------
1809
Hideto Ueno11d37102019-07-17 15:15:43 +00001810// Helper function that checks whether a function has any cycle.
1811// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001812static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00001813 SmallPtrSet<BasicBlock *, 32> Visited;
1814
1815 // Traverse BB by dfs and check whether successor is already visited.
1816 for (BasicBlock *BB : depth_first(&F)) {
1817 Visited.insert(BB);
1818 for (auto *SuccBB : successors(BB)) {
1819 if (Visited.count(SuccBB))
1820 return true;
1821 }
1822 }
1823 return false;
1824}
1825
1826// Helper function that checks the function have a loop which might become an
1827// endless loop
1828// FIXME: Any cycle is regarded as endless loop for now.
1829// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001830static bool containsPossiblyEndlessLoop(Function *F) {
1831 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00001832}
1833
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001834struct AAWillReturnImpl : public AAWillReturn {
1835 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00001836
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001837 /// See AbstractAttribute::initialize(...).
1838 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001839 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00001840
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001841 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001842 if (containsPossiblyEndlessLoop(F))
1843 indicatePessimisticFixpoint();
1844 }
Hideto Ueno11d37102019-07-17 15:15:43 +00001845
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001846 /// See AbstractAttribute::updateImpl(...).
1847 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001848 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001849 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
1850 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
1851 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001852 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001853 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001854 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001855 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
1856 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001857 };
1858
1859 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
1860 return indicatePessimisticFixpoint();
1861
1862 return ChangeStatus::UNCHANGED;
1863 }
1864
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001865 /// See AbstractAttribute::getAsStr()
1866 const std::string getAsStr() const override {
1867 return getAssumed() ? "willreturn" : "may-noreturn";
1868 }
1869};
1870
1871struct AAWillReturnFunction final : AAWillReturnImpl {
1872 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1873
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001874 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001875 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001876};
Hideto Ueno11d37102019-07-17 15:15:43 +00001877
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001878/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001879struct AAWillReturnCallSite final : AAWillReturnImpl {
1880 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1881
1882 /// See AbstractAttribute::initialize(...).
1883 void initialize(Attributor &A) override {
1884 AAWillReturnImpl::initialize(A);
1885 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001886 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001887 indicatePessimisticFixpoint();
1888 }
1889
1890 /// See AbstractAttribute::updateImpl(...).
1891 ChangeStatus updateImpl(Attributor &A) override {
1892 // TODO: Once we have call site specific value information we can provide
1893 // call site specific liveness information and then it makes
1894 // sense to specialize attributes for call sites arguments instead of
1895 // redirecting requests to the callee argument.
1896 Function *F = getAssociatedFunction();
1897 const IRPosition &FnPos = IRPosition::function(*F);
1898 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
1899 return clampStateAndIndicateChange(
1900 getState(),
1901 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
1902 }
1903
1904 /// See AbstractAttribute::trackStatistics()
1905 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
1906};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001907
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001908/// ------------------------ NoAlias Argument Attribute ------------------------
1909
Johannes Doerfert344d0382019-08-07 22:34:26 +00001910struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001911 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001912
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001913 const std::string getAsStr() const override {
1914 return getAssumed() ? "noalias" : "may-alias";
1915 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001916};
1917
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001918/// NoAlias attribute for a floating value.
1919struct AANoAliasFloating final : AANoAliasImpl {
1920 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1921
Hideto Uenocbab3342019-08-29 05:52:00 +00001922 /// See AbstractAttribute::initialize(...).
1923 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001924 AANoAliasImpl::initialize(A);
Johannes Doerfert72adda12019-10-10 05:33:21 +00001925 Value &Val = getAssociatedValue();
1926 if (isa<AllocaInst>(Val))
1927 indicateOptimisticFixpoint();
1928 if (isa<ConstantPointerNull>(Val) &&
1929 Val.getType()->getPointerAddressSpace() == 0)
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001930 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001931 }
1932
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001933 /// See AbstractAttribute::updateImpl(...).
1934 ChangeStatus updateImpl(Attributor &A) override {
1935 // TODO: Implement this.
1936 return indicatePessimisticFixpoint();
1937 }
1938
1939 /// See AbstractAttribute::trackStatistics()
1940 void trackStatistics() const override {
1941 STATS_DECLTRACK_FLOATING_ATTR(noalias)
1942 }
1943};
1944
1945/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00001946struct AANoAliasArgument final
1947 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
1948 AANoAliasArgument(const IRPosition &IRP)
1949 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001950
1951 /// See AbstractAttribute::trackStatistics()
1952 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
1953};
1954
1955struct AANoAliasCallSiteArgument final : AANoAliasImpl {
1956 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1957
Hideto Uenocbab3342019-08-29 05:52:00 +00001958 /// See AbstractAttribute::initialize(...).
1959 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00001960 // See callsite argument attribute and callee argument attribute.
1961 ImmutableCallSite ICS(&getAnchorValue());
1962 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
1963 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001964 }
1965
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001966 /// See AbstractAttribute::updateImpl(...).
1967 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001968 // We can deduce "noalias" if the following conditions hold.
1969 // (i) Associated value is assumed to be noalias in the definition.
1970 // (ii) Associated value is assumed to be no-capture in all the uses
1971 // possibly executed before this callsite.
1972 // (iii) There is no other pointer argument which could alias with the
1973 // value.
1974
1975 const Value &V = getAssociatedValue();
1976 const IRPosition IRP = IRPosition::value(V);
1977
1978 // (i) Check whether noalias holds in the definition.
1979
1980 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
1981
1982 if (!NoAliasAA.isAssumedNoAlias())
1983 return indicatePessimisticFixpoint();
1984
1985 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
1986 << " is assumed NoAlias in the definition\n");
1987
1988 // (ii) Check whether the value is captured in the scope using AANoCapture.
1989 // FIXME: This is conservative though, it is better to look at CFG and
1990 // check only uses possibly executed before this callsite.
1991
1992 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert72adda12019-10-10 05:33:21 +00001993 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
1994 LLVM_DEBUG(
1995 dbgs() << "[Attributor][AANoAliasCSArg] " << V
1996 << " cannot be noalias as it is potentially captured\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001997 return indicatePessimisticFixpoint();
Johannes Doerfert72adda12019-10-10 05:33:21 +00001998 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001999
2000 // (iii) Check there is no other pointer argument which could alias with the
2001 // value.
2002 ImmutableCallSite ICS(&getAnchorValue());
2003 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
2004 if (getArgNo() == (int)i)
2005 continue;
2006 const Value *ArgOp = ICS.getArgOperand(i);
2007 if (!ArgOp->getType()->isPointerTy())
2008 continue;
2009
Hideto Ueno30d86f12019-09-17 06:53:27 +00002010 if (const Function *F = getAnchorScope()) {
2011 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
Johannes Doerfert72adda12019-10-10 05:33:21 +00002012 bool IsAliasing = AAR->isNoAlias(&getAssociatedValue(), ArgOp);
Hideto Ueno30d86f12019-09-17 06:53:27 +00002013 LLVM_DEBUG(dbgs()
2014 << "[Attributor][NoAliasCSArg] Check alias between "
2015 "callsite arguments "
2016 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
Johannes Doerfert72adda12019-10-10 05:33:21 +00002017 << getAssociatedValue() << " " << *ArgOp << " => "
2018 << (IsAliasing ? "" : "no-") << "alias \n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002019
Johannes Doerfert72adda12019-10-10 05:33:21 +00002020 if (IsAliasing)
Hideto Ueno30d86f12019-09-17 06:53:27 +00002021 continue;
2022 }
2023 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002024 return indicatePessimisticFixpoint();
2025 }
2026
2027 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002028 }
2029
2030 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002031 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002032};
2033
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002034/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002035struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002036 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002037
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002038 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002039 virtual ChangeStatus updateImpl(Attributor &A) override {
2040
2041 auto CheckReturnValue = [&](Value &RV) -> bool {
2042 if (Constant *C = dyn_cast<Constant>(&RV))
2043 if (C->isNullValue() || isa<UndefValue>(C))
2044 return true;
2045
2046 /// For now, we can only deduce noalias if we have call sites.
2047 /// FIXME: add more support.
2048 ImmutableCallSite ICS(&RV);
2049 if (!ICS)
2050 return false;
2051
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002052 const IRPosition &RVPos = IRPosition::value(RV);
2053 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002054 if (!NoAliasAA.isAssumedNoAlias())
2055 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002056
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002057 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2058 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002059 };
2060
2061 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2062 return indicatePessimisticFixpoint();
2063
2064 return ChangeStatus::UNCHANGED;
2065 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002066
2067 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002068 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002069};
2070
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002071/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002072struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2073 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2074
2075 /// See AbstractAttribute::initialize(...).
2076 void initialize(Attributor &A) override {
2077 AANoAliasImpl::initialize(A);
2078 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002079 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002080 indicatePessimisticFixpoint();
2081 }
2082
2083 /// See AbstractAttribute::updateImpl(...).
2084 ChangeStatus updateImpl(Attributor &A) override {
2085 // TODO: Once we have call site specific value information we can provide
2086 // call site specific liveness information and then it makes
2087 // sense to specialize attributes for call sites arguments instead of
2088 // redirecting requests to the callee argument.
2089 Function *F = getAssociatedFunction();
2090 const IRPosition &FnPos = IRPosition::returned(*F);
2091 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2092 return clampStateAndIndicateChange(
2093 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2094 }
2095
2096 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002097 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002098};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002099
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002100/// -------------------AAIsDead Function Attribute-----------------------
2101
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002102struct AAIsDeadValueImpl : public AAIsDead {
2103 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002104
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002105 /// See AAIsDead::isAssumedDead().
2106 bool isAssumedDead() const override { return getAssumed(); }
2107
2108 /// See AAIsDead::isAssumedDead(BasicBlock *).
2109 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2110
2111 /// See AAIsDead::isKnownDead(BasicBlock *).
2112 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2113
2114 /// See AAIsDead::isAssumedDead(Instruction *I).
2115 bool isAssumedDead(const Instruction *I) const override {
2116 return I == getCtxI() && isAssumedDead();
2117 }
2118
2119 /// See AAIsDead::isKnownDead(Instruction *I).
2120 bool isKnownDead(const Instruction *I) const override {
2121 return I == getCtxI() && getKnown();
2122 }
2123
2124 /// See AbstractAttribute::getAsStr().
2125 const std::string getAsStr() const override {
2126 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2127 }
2128};
2129
2130struct AAIsDeadFloating : public AAIsDeadValueImpl {
2131 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2132
2133 /// See AbstractAttribute::initialize(...).
2134 void initialize(Attributor &A) override {
2135 if (Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()))
2136 if (!wouldInstructionBeTriviallyDead(I))
2137 indicatePessimisticFixpoint();
2138 if (isa<UndefValue>(getAssociatedValue()))
2139 indicatePessimisticFixpoint();
2140 }
2141
2142 /// See AbstractAttribute::updateImpl(...).
2143 ChangeStatus updateImpl(Attributor &A) override {
2144 auto UsePred = [&](const Use &U, bool &Follow) {
2145 Instruction *UserI = cast<Instruction>(U.getUser());
2146 if (CallSite CS = CallSite(UserI)) {
2147 if (!CS.isArgOperand(&U))
2148 return false;
2149 const IRPosition &CSArgPos =
2150 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
2151 const auto &CSArgIsDead = A.getAAFor<AAIsDead>(*this, CSArgPos);
2152 return CSArgIsDead.isAssumedDead();
2153 }
2154 if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
2155 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
2156 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, RetPos);
2157 return RetIsDeadAA.isAssumedDead();
2158 }
2159 Follow = true;
2160 return wouldInstructionBeTriviallyDead(UserI);
2161 };
2162
2163 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
2164 return indicatePessimisticFixpoint();
2165 return ChangeStatus::UNCHANGED;
2166 }
2167
2168 /// See AbstractAttribute::manifest(...).
2169 ChangeStatus manifest(Attributor &A) override {
2170 Value &V = getAssociatedValue();
2171 if (auto *I = dyn_cast<Instruction>(&V))
2172 if (wouldInstructionBeTriviallyDead(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002173 A.deleteAfterManifest(*I);
2174 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002175 }
2176
2177 if (V.use_empty())
2178 return ChangeStatus::UNCHANGED;
2179
2180 UndefValue &UV = *UndefValue::get(V.getType());
2181 bool AnyChange = false;
2182 for (Use &U : V.uses())
2183 AnyChange |= A.changeUseAfterManifest(U, UV);
2184 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2185 }
2186
2187 /// See AbstractAttribute::trackStatistics()
2188 void trackStatistics() const override {
2189 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2190 }
2191};
2192
2193struct AAIsDeadArgument : public AAIsDeadFloating {
2194 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2195
2196 /// See AbstractAttribute::initialize(...).
2197 void initialize(Attributor &A) override {
2198 if (!getAssociatedFunction()->hasExactDefinition())
2199 indicatePessimisticFixpoint();
2200 }
2201
2202 /// See AbstractAttribute::trackStatistics()
2203 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
2204};
2205
2206struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
2207 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2208
2209 /// See AbstractAttribute::initialize(...).
2210 void initialize(Attributor &A) override {
2211 if (isa<UndefValue>(getAssociatedValue()))
2212 indicatePessimisticFixpoint();
2213 }
2214
2215 /// See AbstractAttribute::updateImpl(...).
2216 ChangeStatus updateImpl(Attributor &A) override {
2217 // TODO: Once we have call site specific value information we can provide
2218 // call site specific liveness information and then it makes
2219 // sense to specialize attributes for call sites arguments instead of
2220 // redirecting requests to the callee argument.
2221 Argument *Arg = getAssociatedArgument();
2222 if (!Arg)
2223 return indicatePessimisticFixpoint();
2224 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2225 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
2226 return clampStateAndIndicateChange(
2227 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
2228 }
2229
2230 /// See AbstractAttribute::manifest(...).
2231 ChangeStatus manifest(Attributor &A) override {
2232 CallBase &CB = cast<CallBase>(getAnchorValue());
2233 Use &U = CB.getArgOperandUse(getArgNo());
2234 assert(!isa<UndefValue>(U.get()) &&
2235 "Expected undef values to be filtered out!");
2236 UndefValue &UV = *UndefValue::get(U->getType());
2237 if (A.changeUseAfterManifest(U, UV))
2238 return ChangeStatus::CHANGED;
2239 return ChangeStatus::UNCHANGED;
2240 }
2241
2242 /// See AbstractAttribute::trackStatistics()
2243 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
2244};
2245
2246struct AAIsDeadReturned : public AAIsDeadValueImpl {
2247 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2248
2249 /// See AbstractAttribute::updateImpl(...).
2250 ChangeStatus updateImpl(Attributor &A) override {
2251
2252 auto PredForCallSite = [&](AbstractCallSite ACS) {
2253 if (ACS.isCallbackCall())
2254 return false;
2255 const IRPosition &CSRetPos =
2256 IRPosition::callsite_returned(ACS.getCallSite());
2257 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, CSRetPos);
2258 return RetIsDeadAA.isAssumedDead();
2259 };
2260
2261 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
2262 return indicatePessimisticFixpoint();
2263
2264 return ChangeStatus::UNCHANGED;
2265 }
2266
2267 /// See AbstractAttribute::manifest(...).
2268 ChangeStatus manifest(Attributor &A) override {
2269 // TODO: Rewrite the signature to return void?
2270 bool AnyChange = false;
2271 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
2272 auto RetInstPred = [&](Instruction &I) {
2273 ReturnInst &RI = cast<ReturnInst>(I);
2274 if (!isa<UndefValue>(RI.getReturnValue()))
2275 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
2276 return true;
2277 };
2278 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
2279 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2280 }
2281
2282 /// See AbstractAttribute::trackStatistics()
2283 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
2284};
2285
2286struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
2287 AAIsDeadCallSiteReturned(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2288
2289 /// See AbstractAttribute::initialize(...).
2290 void initialize(Attributor &A) override {}
2291
2292 /// See AbstractAttribute::trackStatistics()
2293 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(IsDead) }
2294};
2295
2296struct AAIsDeadFunction : public AAIsDead {
2297 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
2298
2299 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002300 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002301 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002302 if (F && !F->isDeclaration()) {
2303 ToBeExploredFrom.insert(&F->getEntryBlock().front());
2304 assumeLive(A, F->getEntryBlock());
2305 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002306 }
2307
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002308 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002309 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002310 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002311 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002312 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
2313 std::to_string(KnownDeadEnds.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002314 }
2315
2316 /// See AbstractAttribute::manifest(...).
2317 ChangeStatus manifest(Attributor &A) override {
2318 assert(getState().isValidState() &&
2319 "Attempted to manifest an invalid state!");
2320
2321 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002322 Function &F = *getAssociatedFunction();
2323
2324 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002325 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002326 return ChangeStatus::CHANGED;
2327 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00002328
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002329 // Flag to determine if we can change an invoke to a call assuming the
2330 // callee is nounwind. This is not possible if the personality of the
2331 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002332 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002333
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002334 KnownDeadEnds.set_union(ToBeExploredFrom);
2335 for (const Instruction *DeadEndI : KnownDeadEnds) {
2336 auto *CB = dyn_cast<CallBase>(DeadEndI);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002337 if (!CB)
2338 continue;
2339 const auto &NoReturnAA =
2340 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
2341 if (!NoReturnAA.isAssumedNoReturn())
2342 continue;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002343 Instruction *I = const_cast<Instruction *>(DeadEndI);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002344 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002345 Instruction *SplitPos = I->getNextNode();
Johannes Doerfertd4108052019-08-21 20:56:41 +00002346 // TODO: mark stuff before unreachable instructions as dead.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002347
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002348 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002349 // If we keep the invoke the split position is at the beginning of the
2350 // normal desitination block (it invokes a noreturn function after all).
2351 BasicBlock *NormalDestBB = II->getNormalDest();
2352 SplitPos = &NormalDestBB->front();
2353
Johannes Doerfert4361da22019-08-04 18:38:53 +00002354 /// Invoke is replaced with a call and unreachable is placed after it if
2355 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
2356 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002357 if (Invoke2CallAllowed) {
Michael Liaoa99086d2019-08-20 21:02:31 +00002358 if (II->getCalledFunction()) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002359 const IRPosition &IPos = IRPosition::callsite_function(*II);
2360 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2361 if (AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert924d2132019-08-05 21:34:45 +00002362 LLVM_DEBUG(dbgs()
2363 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002364 // We do not need an invoke (II) but instead want a call followed
2365 // by an unreachable. However, we do not remove II as other
2366 // abstract attributes might have it cached as part of their
2367 // results. Given that we modify the CFG anyway, we simply keep II
2368 // around but in a new dead block. To avoid II being live through
2369 // a different edge we have to ensure the block we place it in is
2370 // only reached from the current block of II and then not reached
2371 // at all when we insert the unreachable.
2372 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
2373 CallInst *CI = createCallMatchingInvoke(II);
2374 CI->insertBefore(II);
2375 CI->takeName(II);
2376 II->replaceAllUsesWith(CI);
2377 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002378 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002379 }
2380 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002381
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002382 if (SplitPos == &NormalDestBB->front()) {
2383 // If this is an invoke of a noreturn function the edge to the normal
2384 // destination block is dead but not necessarily the block itself.
2385 // TODO: We need to move to an edge based system during deduction and
2386 // also manifest.
2387 assert(!NormalDestBB->isLandingPad() &&
2388 "Expected the normal destination not to be a landingpad!");
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002389 if (NormalDestBB->getUniquePredecessor() == BB) {
2390 assumeLive(A, *NormalDestBB);
2391 } else {
2392 BasicBlock *SplitBB =
2393 SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2394 // The split block is live even if it contains only an unreachable
2395 // instruction at the end.
2396 assumeLive(A, *SplitBB);
2397 SplitPos = SplitBB->getTerminator();
2398 HasChanged = ChangeStatus::CHANGED;
2399 }
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002400 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002401 }
2402
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002403 if (isa_and_nonnull<UnreachableInst>(SplitPos))
2404 continue;
2405
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002406 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002407 SplitBlock(BB, SplitPos);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002408 changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
2409 HasChanged = ChangeStatus::CHANGED;
2410 }
2411
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002412 for (BasicBlock &BB : F)
2413 if (!AssumedLiveBlocks.count(&BB))
2414 A.deleteAfterManifest(BB);
2415
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002416 return HasChanged;
2417 }
2418
2419 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002420 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002421
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002422 /// See AbstractAttribute::trackStatistics()
2423 void trackStatistics() const override {}
2424
2425 /// Returns true if the function is assumed dead.
2426 bool isAssumedDead() const override { return false; }
2427
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002428 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002429 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002430 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002431 "BB must be in the same anchor scope function.");
2432
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002433 if (!getAssumed())
2434 return false;
2435 return !AssumedLiveBlocks.count(BB);
2436 }
2437
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002438 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002439 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002440 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002441 }
2442
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002443 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002444 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002445 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002446 "Instruction must be in the same anchor scope function.");
2447
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002448 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002449 return false;
2450
2451 // If it is not in AssumedLiveBlocks then it for sure dead.
2452 // Otherwise, it can still be after noreturn call in a live block.
2453 if (!AssumedLiveBlocks.count(I->getParent()))
2454 return true;
2455
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002456 // If it is not after a liveness barrier it is live.
2457 const Instruction *PrevI = I->getPrevNode();
2458 while (PrevI) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002459 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002460 return true;
2461 PrevI = PrevI->getPrevNode();
2462 }
2463 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002464 }
2465
2466 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002467 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002468 return getKnown() && isAssumedDead(I);
2469 }
2470
Johannes Doerfert924d2132019-08-05 21:34:45 +00002471 /// Determine if \p F might catch asynchronous exceptions.
2472 static bool mayCatchAsynchronousExceptions(const Function &F) {
2473 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2474 }
2475
Johannes Doerfert2f622062019-09-04 16:35:20 +00002476 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2477 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002478 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002479 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002480 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002481
2482 // We assume that all of BB is (probably) live now and if there are calls to
2483 // internal functions we will assume that those are now live as well. This
2484 // is a performance optimization for blocks with calls to a lot of internal
2485 // functions. It can however cause dead functions to be treated as live.
2486 for (const Instruction &I : BB)
2487 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
2488 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00002489 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00002490 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002491 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002492 }
2493
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002494 /// Collection of instructions that need to be explored again, e.g., we
2495 /// did assume they do not transfer control to (one of their) successors.
2496 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002497
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002498 /// Collection of instructions that are known to not transfer control.
2499 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
2500
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002501 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002502 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002503};
2504
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002505static bool
2506identifyAliveSuccessors(Attributor &A, const CallBase &CB,
2507 AbstractAttribute &AA,
2508 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2509 const IRPosition &IPos = IRPosition::callsite_function(CB);
2510
2511 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
2512 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002513 return !NoReturnAA.isKnownNoReturn();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002514 if (CB.isTerminator())
2515 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
2516 else
2517 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002518 return false;
2519}
2520
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002521static bool
2522identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
2523 AbstractAttribute &AA,
2524 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2525 bool UsedAssumedInformation =
2526 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00002527
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002528 // First, determine if we can change an invoke to a call assuming the
2529 // callee is nounwind. This is not possible if the personality of the
2530 // function allows to catch asynchronous exceptions.
2531 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
2532 AliveSuccessors.push_back(&II.getUnwindDest()->front());
2533 } else {
2534 const IRPosition &IPos = IRPosition::callsite_function(II);
2535 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002536 if (AANoUnw.isAssumedNoUnwind()) {
2537 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind();
2538 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002539 AliveSuccessors.push_back(&II.getUnwindDest()->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002540 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002541 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002542 return UsedAssumedInformation;
2543}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002544
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002545static Optional<ConstantInt *>
2546getAssumedConstant(Attributor &A, const Value &V, AbstractAttribute &AA,
2547 bool &UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002548 const auto &ValueSimplifyAA =
2549 A.getAAFor<AAValueSimplify>(AA, IRPosition::value(V));
2550 Optional<Value *> SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(A);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002551 UsedAssumedInformation |= !ValueSimplifyAA.isKnown();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002552 if (!SimplifiedV.hasValue())
2553 return llvm::None;
2554 if (isa_and_nonnull<UndefValue>(SimplifiedV.getValue()))
2555 return llvm::None;
2556 return dyn_cast_or_null<ConstantInt>(SimplifiedV.getValue());
2557}
2558
2559static bool
2560identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
2561 AbstractAttribute &AA,
2562 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2563 bool UsedAssumedInformation = false;
2564 if (BI.getNumSuccessors() == 1) {
2565 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
2566 } else {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002567 Optional<ConstantInt *> CI =
2568 getAssumedConstant(A, *BI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002569 if (!CI.hasValue()) {
2570 // No value yet, assume both edges are dead.
2571 } else if (CI.getValue()) {
2572 const BasicBlock *SuccBB =
2573 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
2574 AliveSuccessors.push_back(&SuccBB->front());
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002575 } else {
2576 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
2577 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002578 UsedAssumedInformation = false;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002579 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002580 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002581 return UsedAssumedInformation;
2582}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002583
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002584static bool
2585identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
2586 AbstractAttribute &AA,
2587 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002588 bool UsedAssumedInformation = false;
2589 Optional<ConstantInt *> CI =
2590 getAssumedConstant(A, *SI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002591 if (!CI.hasValue()) {
2592 // No value yet, assume all edges are dead.
2593 } else if (CI.getValue()) {
2594 for (auto &CaseIt : SI.cases()) {
2595 if (CaseIt.getCaseValue() == CI.getValue()) {
2596 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002597 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002598 }
2599 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05002600 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002601 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002602 } else {
2603 for (const BasicBlock *SuccBB : successors(SI.getParent()))
2604 AliveSuccessors.push_back(&SuccBB->front());
2605 }
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002606 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002607}
2608
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002609ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002610 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002611
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002612 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
2613 << getAssociatedFunction()->size() << "] BBs and "
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002614 << ToBeExploredFrom.size() << " exploration points and "
2615 << KnownDeadEnds.size() << " known dead ends\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002616
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002617 // Copy and clear the list of instructions we need to explore from. It is
2618 // refilled with instructions the next update has to look at.
2619 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
2620 ToBeExploredFrom.end());
2621 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002622
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002623 SmallVector<const Instruction *, 8> AliveSuccessors;
2624 while (!Worklist.empty()) {
2625 const Instruction *I = Worklist.pop_back_val();
2626 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002627
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002628 AliveSuccessors.clear();
2629
2630 bool UsedAssumedInformation = false;
2631 switch (I->getOpcode()) {
2632 // TODO: look for (assumed) UB to backwards propagate "deadness".
2633 default:
2634 if (I->isTerminator()) {
2635 for (const BasicBlock *SuccBB : successors(I->getParent()))
2636 AliveSuccessors.push_back(&SuccBB->front());
2637 } else {
2638 AliveSuccessors.push_back(I->getNextNode());
2639 }
2640 break;
2641 case Instruction::Call:
2642 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
2643 *this, AliveSuccessors);
2644 break;
2645 case Instruction::Invoke:
2646 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
2647 *this, AliveSuccessors);
2648 break;
2649 case Instruction::Br:
2650 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
2651 *this, AliveSuccessors);
2652 break;
2653 case Instruction::Switch:
2654 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
2655 *this, AliveSuccessors);
2656 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00002657 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002658
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002659 if (UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002660 NewToBeExploredFrom.insert(I);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002661 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002662 Change = ChangeStatus::CHANGED;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002663 if (AliveSuccessors.empty() ||
2664 (I->isTerminator() && AliveSuccessors.size() < I->getNumSuccessors()))
2665 KnownDeadEnds.insert(I);
2666 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002667
2668 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
2669 << AliveSuccessors.size() << " UsedAssumedInformation: "
2670 << UsedAssumedInformation << "\n");
2671
2672 for (const Instruction *AliveSuccessor : AliveSuccessors) {
2673 if (!I->isTerminator()) {
2674 assert(AliveSuccessors.size() == 1 &&
2675 "Non-terminator expected to have a single successor!");
2676 Worklist.push_back(AliveSuccessor);
2677 } else {
2678 if (assumeLive(A, *AliveSuccessor->getParent()))
2679 Worklist.push_back(AliveSuccessor);
2680 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002681 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002682 }
2683
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002684 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002685
Johannes Doerfertd6207812019-08-07 22:32:38 +00002686 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002687 // Instead, indicating a pessimistic fixpoint will cause the state to be
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002688 // "invalid" and all queries to be answered conservatively without lookups.
2689 // To be in this state we have to (1) finished the exploration and (3) not
2690 // discovered any non-trivial dead end and (2) not ruled unreachable code
2691 // dead.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002692 if (ToBeExploredFrom.empty() &&
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002693 getAssociatedFunction()->size() == AssumedLiveBlocks.size() &&
2694 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
2695 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
2696 }))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002697 return indicatePessimisticFixpoint();
2698 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002699}
2700
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002701/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002702struct AAIsDeadCallSite final : AAIsDeadFunction {
2703 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002704
2705 /// See AbstractAttribute::initialize(...).
2706 void initialize(Attributor &A) override {
2707 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002708 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002709 // sense to specialize attributes for call sites instead of
2710 // redirecting requests to the callee.
2711 llvm_unreachable("Abstract attributes for liveness are not "
2712 "supported for call sites yet!");
2713 }
2714
2715 /// See AbstractAttribute::updateImpl(...).
2716 ChangeStatus updateImpl(Attributor &A) override {
2717 return indicatePessimisticFixpoint();
2718 }
2719
2720 /// See AbstractAttribute::trackStatistics()
2721 void trackStatistics() const override {}
2722};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002723
Hideto Ueno19c07af2019-07-23 08:16:17 +00002724/// -------------------- Dereferenceable Argument Attribute --------------------
2725
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002726template <>
2727ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
2728 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05002729 ChangeStatus CS0 =
2730 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
2731 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002732 return CS0 | CS1;
2733}
2734
Hideto Ueno70576ca2019-08-22 14:18:29 +00002735struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002736 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00002737 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00002738
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002739 void initialize(Attributor &A) override {
2740 SmallVector<Attribute, 4> Attrs;
2741 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
2742 Attrs);
2743 for (const Attribute &Attr : Attrs)
2744 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
2745
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002746 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002747
2748 const IRPosition &IRP = this->getIRPosition();
2749 bool IsFnInterface = IRP.isFnInterfaceKind();
2750 const Function *FnScope = IRP.getAnchorScope();
2751 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
2752 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002753 }
2754
Hideto Ueno19c07af2019-07-23 08:16:17 +00002755 /// See AbstractAttribute::getState()
2756 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00002757 StateType &getState() override { return *this; }
2758 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002759 /// }
2760
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002761 /// See AAFromMustBeExecutedContext
2762 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
2763 bool IsNonNull = false;
2764 bool TrackUse = false;
2765 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
2766 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
2767 takeKnownDerefBytesMaximum(DerefBytes);
2768 return TrackUse;
2769 }
2770
Johannes Doerferteccdf082019-08-05 23:35:12 +00002771 void getDeducedAttributes(LLVMContext &Ctx,
2772 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002773 // TODO: Add *_globally support
2774 if (isAssumedNonNull())
2775 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
2776 Ctx, getAssumedDereferenceableBytes()));
2777 else
2778 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
2779 Ctx, getAssumedDereferenceableBytes()));
2780 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002781
2782 /// See AbstractAttribute::getAsStr().
2783 const std::string getAsStr() const override {
2784 if (!getAssumedDereferenceableBytes())
2785 return "unknown-dereferenceable";
2786 return std::string("dereferenceable") +
2787 (isAssumedNonNull() ? "" : "_or_null") +
2788 (isAssumedGlobal() ? "_globally" : "") + "<" +
2789 std::to_string(getKnownDereferenceableBytes()) + "-" +
2790 std::to_string(getAssumedDereferenceableBytes()) + ">";
2791 }
2792};
2793
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002794/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002795struct AADereferenceableFloating
2796 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
2797 using Base =
2798 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
2799 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00002800
2801 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002802 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002803 ChangeStatus Change = Base::updateImpl(A);
2804
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002805 const DataLayout &DL = A.getDataLayout();
2806
2807 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
2808 unsigned IdxWidth =
2809 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
2810 APInt Offset(IdxWidth, 0);
2811 const Value *Base =
2812 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
2813
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002814 const auto &AA =
2815 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002816 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002817 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002818 // Use IR information if we did not strip anything.
2819 // TODO: track globally.
2820 bool CanBeNull;
2821 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
2822 T.GlobalState.indicatePessimisticFixpoint();
2823 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002824 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002825 DerefBytes = DS.DerefBytesState.getAssumed();
2826 T.GlobalState &= DS.GlobalState;
2827 }
2828
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002829 // For now we do not try to "increase" dereferenceability due to negative
2830 // indices as we first have to come up with code to deal with loops and
2831 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00002832 int64_t OffsetSExt = Offset.getSExtValue();
2833 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00002834 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002835
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002836 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00002837 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002838
Johannes Doerfert785fad32019-08-23 17:29:23 +00002839 if (this == &AA) {
2840 if (!Stripped) {
2841 // If nothing was stripped IR information is all we got.
2842 T.takeKnownDerefBytesMaximum(
2843 std::max(int64_t(0), DerefBytes - OffsetSExt));
2844 T.indicatePessimisticFixpoint();
2845 } else if (OffsetSExt > 0) {
2846 // If something was stripped but there is circular reasoning we look
2847 // for the offset. If it is positive we basically decrease the
2848 // dereferenceable bytes in a circluar loop now, which will simply
2849 // drive them down to the known value in a very slow way which we
2850 // can accelerate.
2851 T.indicatePessimisticFixpoint();
2852 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002853 }
2854
2855 return T.isValidState();
2856 };
2857
2858 DerefState T;
2859 if (!genericValueTraversal<AADereferenceable, DerefState>(
2860 A, getIRPosition(), *this, T, VisitValueCB))
2861 return indicatePessimisticFixpoint();
2862
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002863 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002864 }
2865
2866 /// See AbstractAttribute::trackStatistics()
2867 void trackStatistics() const override {
2868 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
2869 }
2870};
2871
2872/// Dereferenceable attribute for a return value.
2873struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002874 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2875 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002876 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002877 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2878 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002879
2880 /// See AbstractAttribute::trackStatistics()
2881 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002882 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002883 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002884};
2885
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002886/// Dereferenceable attribute for an argument
2887struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002888 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2889 AADereferenceable, AADereferenceableImpl, DerefState> {
2890 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2891 AADereferenceable, AADereferenceableImpl, DerefState>;
2892 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002893
2894 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002895 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00002896 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
2897 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002898};
2899
Hideto Ueno19c07af2019-07-23 08:16:17 +00002900/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002901struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002902 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002903 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002904
2905 /// See AbstractAttribute::trackStatistics()
2906 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002907 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002908 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002909};
2910
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002911/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002912struct AADereferenceableCallSiteReturned final
2913 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2914 AADereferenceable, AADereferenceableImpl> {
2915 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2916 AADereferenceable, AADereferenceableImpl>;
2917 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002918
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002919 /// See AbstractAttribute::trackStatistics()
2920 void trackStatistics() const override {
2921 STATS_DECLTRACK_CS_ATTR(dereferenceable);
2922 }
2923};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002924
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002925// ------------------------ Align Argument Attribute ------------------------
2926
Johannes Doerfert344d0382019-08-07 22:34:26 +00002927struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002928 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002929
Johannes Doerfert234eda52019-08-16 19:51:23 +00002930 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002931 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002932 SmallVector<Attribute, 4> Attrs;
2933 getAttrs({Attribute::Alignment}, Attrs);
2934 for (const Attribute &Attr : Attrs)
2935 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00002936
2937 if (getIRPosition().isFnInterfaceKind() &&
2938 (!getAssociatedFunction() ||
2939 !getAssociatedFunction()->hasExactDefinition()))
2940 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002941 }
2942
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002943 /// See AbstractAttribute::manifest(...).
2944 ChangeStatus manifest(Attributor &A) override {
2945 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2946
2947 // Check for users that allow alignment annotations.
2948 Value &AnchorVal = getIRPosition().getAnchorValue();
2949 for (const Use &U : AnchorVal.uses()) {
2950 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
2951 if (SI->getPointerOperand() == &AnchorVal)
2952 if (SI->getAlignment() < getAssumedAlign()) {
2953 STATS_DECLTRACK(AAAlign, Store,
2954 "Number of times alignemnt added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00002955 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002956 Changed = ChangeStatus::CHANGED;
2957 }
2958 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
2959 if (LI->getPointerOperand() == &AnchorVal)
2960 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00002961 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002962 STATS_DECLTRACK(AAAlign, Load,
2963 "Number of times alignemnt added to a load");
2964 Changed = ChangeStatus::CHANGED;
2965 }
2966 }
2967 }
2968
Johannes Doerfert81df4522019-08-30 15:22:28 +00002969 return AAAlign::manifest(A) | Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002970 }
2971
Johannes Doerfert81df4522019-08-30 15:22:28 +00002972 // TODO: Provide a helper to determine the implied ABI alignment and check in
2973 // the existing manifest method and a new one for AAAlignImpl that value
2974 // to avoid making the alignment explicit if it did not improve.
2975
2976 /// See AbstractAttribute::getDeducedAttributes
2977 virtual void
2978 getDeducedAttributes(LLVMContext &Ctx,
2979 SmallVectorImpl<Attribute> &Attrs) const override {
2980 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00002981 Attrs.emplace_back(
2982 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00002983 }
2984
2985 /// See AbstractAttribute::getAsStr().
2986 const std::string getAsStr() const override {
2987 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
2988 "-" + std::to_string(getAssumedAlign()) + ">")
2989 : "unknown-align";
2990 }
2991};
2992
2993/// Align attribute for a floating value.
2994struct AAAlignFloating : AAAlignImpl {
2995 AAAlignFloating(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2996
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002997 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00002998 ChangeStatus updateImpl(Attributor &A) override {
2999 const DataLayout &DL = A.getDataLayout();
3000
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003001 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
3002 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003003 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
3004 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003005 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00003006 const MaybeAlign PA = V.getPointerAlignment(DL);
3007 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00003008 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003009 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003010 // Use abstract attribute information.
3011 const AAAlign::StateType &DS =
3012 static_cast<const AAAlign::StateType &>(AA.getState());
3013 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00003014 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003015 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003016 };
3017
3018 StateType T;
3019 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
3020 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003021 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003022
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003023 // TODO: If we know we visited all incoming values, thus no are assumed
3024 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003025 return clampStateAndIndicateChange(getState(), T);
3026 }
3027
3028 /// See AbstractAttribute::trackStatistics()
3029 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3030};
3031
3032/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003033struct AAAlignReturned final
3034 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003035 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003036 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003037
3038 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003039 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003040};
3041
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003042/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003043struct AAAlignArgument final
3044 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003045 AAAlignArgument(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003046 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003047
3048 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003049 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003050};
3051
Johannes Doerfert234eda52019-08-16 19:51:23 +00003052struct AAAlignCallSiteArgument final : AAAlignFloating {
3053 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003054
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003055 /// See AbstractAttribute::manifest(...).
3056 ChangeStatus manifest(Attributor &A) override {
3057 return AAAlignImpl::manifest(A);
3058 }
3059
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003060 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003061 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003062};
3063
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003064/// Align attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003065struct AAAlignCallSiteReturned final : AAAlignImpl {
3066 AAAlignCallSiteReturned(const IRPosition &IRP) : AAAlignImpl(IRP) {}
3067
3068 /// See AbstractAttribute::initialize(...).
3069 void initialize(Attributor &A) override {
3070 AAAlignImpl::initialize(A);
3071 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003072 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003073 indicatePessimisticFixpoint();
3074 }
3075
3076 /// See AbstractAttribute::updateImpl(...).
3077 ChangeStatus updateImpl(Attributor &A) override {
3078 // TODO: Once we have call site specific value information we can provide
3079 // call site specific liveness information and then it makes
3080 // sense to specialize attributes for call sites arguments instead of
3081 // redirecting requests to the callee argument.
3082 Function *F = getAssociatedFunction();
3083 const IRPosition &FnPos = IRPosition::returned(*F);
3084 auto &FnAA = A.getAAFor<AAAlign>(*this, FnPos);
3085 return clampStateAndIndicateChange(
3086 getState(), static_cast<const AAAlign::StateType &>(FnAA.getState()));
3087 }
3088
3089 /// See AbstractAttribute::trackStatistics()
3090 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3091};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003092
Johannes Doerferte83f3032019-08-05 23:22:05 +00003093/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00003094struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003095 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00003096
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003097 /// See AbstractAttribute::initialize(...).
3098 void initialize(Attributor &A) override {
3099 AANoReturn::initialize(A);
3100 Function *F = getAssociatedFunction();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05003101 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003102 indicatePessimisticFixpoint();
3103 }
3104
Johannes Doerferte83f3032019-08-05 23:22:05 +00003105 /// See AbstractAttribute::getAsStr().
3106 const std::string getAsStr() const override {
3107 return getAssumed() ? "noreturn" : "may-return";
3108 }
3109
Johannes Doerferte83f3032019-08-05 23:22:05 +00003110 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00003111 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003112 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003113 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003114 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00003115 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00003116 return ChangeStatus::UNCHANGED;
3117 }
3118};
3119
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003120struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003121 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003122
3123 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003124 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003125};
3126
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003127/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003128struct AANoReturnCallSite final : AANoReturnImpl {
3129 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
3130
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003131 /// See AbstractAttribute::updateImpl(...).
3132 ChangeStatus updateImpl(Attributor &A) override {
3133 // TODO: Once we have call site specific value information we can provide
3134 // call site specific liveness information and then it makes
3135 // sense to specialize attributes for call sites arguments instead of
3136 // redirecting requests to the callee argument.
3137 Function *F = getAssociatedFunction();
3138 const IRPosition &FnPos = IRPosition::function(*F);
3139 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
3140 return clampStateAndIndicateChange(
3141 getState(),
3142 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
3143 }
3144
3145 /// See AbstractAttribute::trackStatistics()
3146 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
3147};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003148
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003149/// ----------------------- Variable Capturing ---------------------------------
3150
3151/// A class to hold the state of for no-capture attributes.
3152struct AANoCaptureImpl : public AANoCapture {
3153 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
3154
3155 /// See AbstractAttribute::initialize(...).
3156 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003157 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
3158 indicateOptimisticFixpoint();
3159 return;
3160 }
3161 Function *AnchorScope = getAnchorScope();
3162 if (isFnInterfaceKind() &&
3163 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
3164 indicatePessimisticFixpoint();
3165 return;
3166 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003167
Johannes Doerfert72adda12019-10-10 05:33:21 +00003168 // You cannot "capture" null in the default address space.
3169 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
3170 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
3171 indicateOptimisticFixpoint();
3172 return;
3173 }
3174
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003175 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003176
3177 // Check what state the associated function can actually capture.
3178 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003179 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003180 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003181 indicatePessimisticFixpoint();
3182 }
3183
3184 /// See AbstractAttribute::updateImpl(...).
3185 ChangeStatus updateImpl(Attributor &A) override;
3186
3187 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
3188 virtual void
3189 getDeducedAttributes(LLVMContext &Ctx,
3190 SmallVectorImpl<Attribute> &Attrs) const override {
3191 if (!isAssumedNoCaptureMaybeReturned())
3192 return;
3193
Hideto Ueno37367642019-09-11 06:52:11 +00003194 if (getArgNo() >= 0) {
3195 if (isAssumedNoCapture())
3196 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
3197 else if (ManifestInternal)
3198 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
3199 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003200 }
3201
3202 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
3203 /// depending on the ability of the function associated with \p IRP to capture
3204 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00003205 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
3206 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05003207 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003208 // TODO: Once we have memory behavior attributes we should use them here.
3209
3210 // If we know we cannot communicate or write to memory, we do not care about
3211 // ptr2int anymore.
3212 if (F.onlyReadsMemory() && F.doesNotThrow() &&
3213 F.getReturnType()->isVoidTy()) {
3214 State.addKnownBits(NO_CAPTURE);
3215 return;
3216 }
3217
3218 // A function cannot capture state in memory if it only reads memory, it can
3219 // however return/throw state and the state might be influenced by the
3220 // pointer value, e.g., loading from a returned pointer might reveal a bit.
3221 if (F.onlyReadsMemory())
3222 State.addKnownBits(NOT_CAPTURED_IN_MEM);
3223
3224 // A function cannot communicate state back if it does not through
3225 // exceptions and doesn not return values.
3226 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
3227 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00003228
3229 // Check existing "returned" attributes.
3230 int ArgNo = IRP.getArgNo();
3231 if (F.doesNotThrow() && ArgNo >= 0) {
3232 for (unsigned u = 0, e = F.arg_size(); u< e; ++u)
3233 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00003234 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00003235 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
3236 else if (F.onlyReadsMemory())
3237 State.addKnownBits(NO_CAPTURE);
3238 else
3239 State.addKnownBits(NOT_CAPTURED_IN_RET);
3240 break;
3241 }
3242 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003243 }
3244
3245 /// See AbstractState::getAsStr().
3246 const std::string getAsStr() const override {
3247 if (isKnownNoCapture())
3248 return "known not-captured";
3249 if (isAssumedNoCapture())
3250 return "assumed not-captured";
3251 if (isKnownNoCaptureMaybeReturned())
3252 return "known not-captured-maybe-returned";
3253 if (isAssumedNoCaptureMaybeReturned())
3254 return "assumed not-captured-maybe-returned";
3255 return "assumed-captured";
3256 }
3257};
3258
3259/// Attributor-aware capture tracker.
3260struct AACaptureUseTracker final : public CaptureTracker {
3261
3262 /// Create a capture tracker that can lookup in-flight abstract attributes
3263 /// through the Attributor \p A.
3264 ///
3265 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
3266 /// search is stopped. If a use leads to a return instruction,
3267 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
3268 /// If a use leads to a ptr2int which may capture the value,
3269 /// \p CapturedInInteger is set. If a use is found that is currently assumed
3270 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
3271 /// set. All values in \p PotentialCopies are later tracked as well. For every
3272 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
3273 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
3274 /// conservatively set to true.
3275 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05003276 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003277 SmallVectorImpl<const Value *> &PotentialCopies,
3278 unsigned &RemainingUsesToExplore)
3279 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
3280 PotentialCopies(PotentialCopies),
3281 RemainingUsesToExplore(RemainingUsesToExplore) {}
3282
3283 /// Determine if \p V maybe captured. *Also updates the state!*
3284 bool valueMayBeCaptured(const Value *V) {
3285 if (V->getType()->isPointerTy()) {
3286 PointerMayBeCaptured(V, this);
3287 } else {
3288 State.indicatePessimisticFixpoint();
3289 }
3290 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3291 }
3292
3293 /// See CaptureTracker::tooManyUses().
3294 void tooManyUses() override {
3295 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
3296 }
3297
3298 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
3299 if (CaptureTracker::isDereferenceableOrNull(O, DL))
3300 return true;
3301 const auto &DerefAA =
3302 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
3303 return DerefAA.getAssumedDereferenceableBytes();
3304 }
3305
3306 /// See CaptureTracker::captured(...).
3307 bool captured(const Use *U) override {
3308 Instruction *UInst = cast<Instruction>(U->getUser());
3309 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3310 << "\n");
3311
3312 // Because we may reuse the tracker multiple times we keep track of the
3313 // number of explored uses ourselves as well.
3314 if (RemainingUsesToExplore-- == 0) {
3315 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3316 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3317 /* Return */ true);
3318 }
3319
3320 // Deal with ptr2int by following uses.
3321 if (isa<PtrToIntInst>(UInst)) {
3322 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3323 return valueMayBeCaptured(UInst);
3324 }
3325
3326 // Explicitly catch return instructions.
3327 if (isa<ReturnInst>(UInst))
3328 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3329 /* Return */ true);
3330
3331 // For now we only use special logic for call sites. However, the tracker
3332 // itself knows about a lot of other non-capturing cases already.
3333 CallSite CS(UInst);
3334 if (!CS || !CS.isArgOperand(U))
3335 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3336 /* Return */ true);
3337
3338 unsigned ArgNo = CS.getArgumentNo(U);
3339 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3340 // If we have a abstract no-capture attribute for the argument we can use
3341 // it to justify a non-capture attribute here. This allows recursion!
3342 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3343 if (ArgNoCaptureAA.isAssumedNoCapture())
3344 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3345 /* Return */ false);
3346 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3347 addPotentialCopy(CS);
3348 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3349 /* Return */ false);
3350 }
3351
3352 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3353 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3354 /* Return */ true);
3355 }
3356
3357 /// Register \p CS as potential copy of the value we are checking.
3358 void addPotentialCopy(CallSite CS) {
3359 PotentialCopies.push_back(CS.getInstruction());
3360 }
3361
3362 /// See CaptureTracker::shouldExplore(...).
3363 bool shouldExplore(const Use *U) override {
3364 // Check liveness.
3365 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3366 }
3367
3368 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3369 /// \p CapturedInRet, then return the appropriate value for use in the
3370 /// CaptureTracker::captured() interface.
3371 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3372 bool CapturedInRet) {
3373 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
3374 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
3375 if (CapturedInMem)
3376 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
3377 if (CapturedInInt)
3378 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
3379 if (CapturedInRet)
3380 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
3381 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3382 }
3383
3384private:
3385 /// The attributor providing in-flight abstract attributes.
3386 Attributor &A;
3387
3388 /// The abstract attribute currently updated.
3389 AANoCapture &NoCaptureAA;
3390
3391 /// The abstract liveness state.
3392 const AAIsDead &IsDeadAA;
3393
3394 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05003395 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003396
3397 /// Set of potential copies of the tracked value.
3398 SmallVectorImpl<const Value *> &PotentialCopies;
3399
3400 /// Global counter to limit the number of explored uses.
3401 unsigned &RemainingUsesToExplore;
3402};
3403
3404ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
3405 const IRPosition &IRP = getIRPosition();
3406 const Value *V =
3407 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
3408 if (!V)
3409 return indicatePessimisticFixpoint();
3410
3411 const Function *F =
3412 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
3413 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00003414 const IRPosition &FnPos = IRPosition::function(*F);
3415 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, FnPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003416
3417 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003418
Johannes Doerfert3839b572019-10-21 00:48:42 +00003419 // Readonly means we cannot capture through memory.
3420 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3421 if (FnMemAA.isAssumedReadOnly()) {
3422 T.addKnownBits(NOT_CAPTURED_IN_MEM);
3423 if (FnMemAA.isKnownReadOnly())
3424 addKnownBits(NOT_CAPTURED_IN_MEM);
3425 }
3426
3427 // Make sure all returned values are different than the underlying value.
3428 // TODO: we could do this in a more sophisticated way inside
3429 // AAReturnedValues, e.g., track all values that escape through returns
3430 // directly somehow.
3431 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
3432 bool SeenConstant = false;
3433 for (auto &It : RVAA.returned_values()) {
3434 if (isa<Constant>(It.first)) {
3435 if (SeenConstant)
3436 return false;
3437 SeenConstant = true;
3438 } else if (!isa<Argument>(It.first) ||
3439 It.first == getAssociatedArgument())
3440 return false;
3441 }
3442 return true;
3443 };
3444
3445 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, FnPos);
3446 if (NoUnwindAA.isAssumedNoUnwind()) {
3447 bool IsVoidTy = F->getReturnType()->isVoidTy();
3448 const AAReturnedValues *RVAA =
3449 IsVoidTy ? nullptr : &A.getAAFor<AAReturnedValues>(*this, FnPos);
3450 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
3451 T.addKnownBits(NOT_CAPTURED_IN_RET);
3452 if (T.isKnown(NOT_CAPTURED_IN_MEM))
3453 return ChangeStatus::UNCHANGED;
3454 if (NoUnwindAA.isKnownNoUnwind() &&
3455 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
3456 addKnownBits(NOT_CAPTURED_IN_RET);
3457 if (isKnown(NOT_CAPTURED_IN_MEM))
3458 return indicateOptimisticFixpoint();
3459 }
3460 }
3461 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003462
3463 // Use the CaptureTracker interface and logic with the specialized tracker,
3464 // defined in AACaptureUseTracker, that can look at in-flight abstract
3465 // attributes and directly updates the assumed state.
3466 SmallVector<const Value *, 4> PotentialCopies;
3467 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
3468 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
3469 RemainingUsesToExplore);
3470
3471 // Check all potential copies of the associated value until we can assume
3472 // none will be captured or we have to assume at least one might be.
3473 unsigned Idx = 0;
3474 PotentialCopies.push_back(V);
3475 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
3476 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
3477
Johannes Doerfert1a746452019-10-20 22:28:49 -05003478 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003479 auto Assumed = S.getAssumed();
3480 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05003481 if (!isAssumedNoCaptureMaybeReturned())
3482 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003483 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3484 : ChangeStatus::CHANGED;
3485}
3486
3487/// NoCapture attribute for function arguments.
3488struct AANoCaptureArgument final : AANoCaptureImpl {
3489 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3490
3491 /// See AbstractAttribute::trackStatistics()
3492 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
3493};
3494
3495/// NoCapture attribute for call site arguments.
3496struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
3497 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3498
3499 /// See AbstractAttribute::updateImpl(...).
3500 ChangeStatus updateImpl(Attributor &A) override {
3501 // TODO: Once we have call site specific value information we can provide
3502 // call site specific liveness information and then it makes
3503 // sense to specialize attributes for call sites arguments instead of
3504 // redirecting requests to the callee argument.
3505 Argument *Arg = getAssociatedArgument();
3506 if (!Arg)
3507 return indicatePessimisticFixpoint();
3508 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3509 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
3510 return clampStateAndIndicateChange(
3511 getState(),
3512 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3513 }
3514
3515 /// See AbstractAttribute::trackStatistics()
3516 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
3517};
3518
3519/// NoCapture attribute for floating values.
3520struct AANoCaptureFloating final : AANoCaptureImpl {
3521 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3522
3523 /// See AbstractAttribute::trackStatistics()
3524 void trackStatistics() const override {
3525 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
3526 }
3527};
3528
3529/// NoCapture attribute for function return value.
3530struct AANoCaptureReturned final : AANoCaptureImpl {
3531 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
3532 llvm_unreachable("NoCapture is not applicable to function returns!");
3533 }
3534
3535 /// See AbstractAttribute::initialize(...).
3536 void initialize(Attributor &A) override {
3537 llvm_unreachable("NoCapture is not applicable to function returns!");
3538 }
3539
3540 /// See AbstractAttribute::updateImpl(...).
3541 ChangeStatus updateImpl(Attributor &A) override {
3542 llvm_unreachable("NoCapture is not applicable to function returns!");
3543 }
3544
3545 /// See AbstractAttribute::trackStatistics()
3546 void trackStatistics() const override {}
3547};
3548
3549/// NoCapture attribute deduction for a call site return value.
3550struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
3551 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3552
3553 /// See AbstractAttribute::trackStatistics()
3554 void trackStatistics() const override {
3555 STATS_DECLTRACK_CSRET_ATTR(nocapture)
3556 }
3557};
3558
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003559/// ------------------ Value Simplify Attribute ----------------------------
3560struct AAValueSimplifyImpl : AAValueSimplify {
3561 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
3562
3563 /// See AbstractAttribute::getAsStr().
3564 const std::string getAsStr() const override {
3565 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
3566 : "not-simple";
3567 }
3568
3569 /// See AbstractAttribute::trackStatistics()
3570 void trackStatistics() const override {}
3571
3572 /// See AAValueSimplify::getAssumedSimplifiedValue()
3573 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
3574 if (!getAssumed())
3575 return const_cast<Value *>(&getAssociatedValue());
3576 return SimplifiedAssociatedValue;
3577 }
3578 void initialize(Attributor &A) override {}
3579
3580 /// Helper function for querying AAValueSimplify and updating candicate.
3581 /// \param QueryingValue Value trying to unify with SimplifiedValue
3582 /// \param AccumulatedSimplifiedValue Current simplification result.
3583 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
3584 Value &QueryingValue,
3585 Optional<Value *> &AccumulatedSimplifiedValue) {
3586 // FIXME: Add a typecast support.
3587
3588 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
3589 QueryingAA, IRPosition::value(QueryingValue));
3590
3591 Optional<Value *> QueryingValueSimplified =
3592 ValueSimpifyAA.getAssumedSimplifiedValue(A);
3593
3594 if (!QueryingValueSimplified.hasValue())
3595 return true;
3596
3597 if (!QueryingValueSimplified.getValue())
3598 return false;
3599
3600 Value &QueryingValueSimplifiedUnwrapped =
3601 *QueryingValueSimplified.getValue();
3602
3603 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
3604 return true;
3605
3606 if (AccumulatedSimplifiedValue.hasValue())
3607 return AccumulatedSimplifiedValue == QueryingValueSimplified;
3608
3609 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
3610 << " is assumed to be "
3611 << QueryingValueSimplifiedUnwrapped << "\n");
3612
3613 AccumulatedSimplifiedValue = QueryingValueSimplified;
3614 return true;
3615 }
3616
3617 /// See AbstractAttribute::manifest(...).
3618 ChangeStatus manifest(Attributor &A) override {
3619 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3620
3621 if (!SimplifiedAssociatedValue.hasValue() ||
3622 !SimplifiedAssociatedValue.getValue())
3623 return Changed;
3624
3625 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
3626 // We can replace the AssociatedValue with the constant.
3627 Value &V = getAssociatedValue();
3628 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
3629 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
3630 << "\n");
3631 V.replaceAllUsesWith(C);
3632 Changed = ChangeStatus::CHANGED;
3633 }
3634 }
3635
3636 return Changed | AAValueSimplify::manifest(A);
3637 }
3638
3639protected:
3640 // An assumed simplified value. Initially, it is set to Optional::None, which
3641 // means that the value is not clear under current assumption. If in the
3642 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
3643 // returns orignal associated value.
3644 Optional<Value *> SimplifiedAssociatedValue;
3645};
3646
3647struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
3648 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3649
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05003650 void initialize(Attributor &A) override {
3651 AAValueSimplifyImpl::initialize(A);
3652 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
3653 indicatePessimisticFixpoint();
3654 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
3655 /* IgnoreSubsumingPositions */ true))
3656 indicatePessimisticFixpoint();
3657 }
3658
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003659 /// See AbstractAttribute::updateImpl(...).
3660 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05003661 // Byval is only replacable if it is readonly otherwise we would write into
3662 // the replaced value and not the copy that byval creates implicitly.
3663 Argument *Arg = getAssociatedArgument();
3664 if (Arg->hasByValAttr()) {
3665 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
3666 if (!MemAA.isAssumedReadOnly())
3667 return indicatePessimisticFixpoint();
3668 }
3669
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003670 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3671
Johannes Doerfert661db042019-10-07 23:14:58 +00003672 auto PredForCallSite = [&](AbstractCallSite ACS) {
3673 // Check if we have an associated argument or not (which can happen for
3674 // callback calls).
Johannes Doerferte360ee62019-11-01 18:45:25 -05003675 Value *ArgOp = ACS.getCallArgOperand(getArgNo());
3676 if (!ArgOp)
3677 return false;
3678 // We can only propagate thread independent values through callbacks.
3679 // This is different to direct/indirect call sites because for them we
3680 // know the thread executing the caller and callee is the same. For
3681 // callbacks this is not guaranteed, thus a thread dependent value could
3682 // be different for the caller and callee, making it invalid to propagate.
3683 if (ACS.isCallbackCall())
3684 if (auto *C =dyn_cast<Constant>(ArgOp))
3685 if (C->isThreadDependent())
3686 return false;
3687 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003688 };
3689
3690 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
3691 return indicatePessimisticFixpoint();
3692
3693 // If a candicate was found in this update, return CHANGED.
3694 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3695 ? ChangeStatus::UNCHANGED
3696 : ChangeStatus ::CHANGED;
3697 }
3698
3699 /// See AbstractAttribute::trackStatistics()
3700 void trackStatistics() const override {
3701 STATS_DECLTRACK_ARG_ATTR(value_simplify)
3702 }
3703};
3704
3705struct AAValueSimplifyReturned : AAValueSimplifyImpl {
3706 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3707
3708 /// See AbstractAttribute::updateImpl(...).
3709 ChangeStatus updateImpl(Attributor &A) override {
3710 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3711
3712 auto PredForReturned = [&](Value &V) {
3713 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3714 };
3715
3716 if (!A.checkForAllReturnedValues(PredForReturned, *this))
3717 return indicatePessimisticFixpoint();
3718
3719 // If a candicate was found in this update, return CHANGED.
3720 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3721 ? ChangeStatus::UNCHANGED
3722 : ChangeStatus ::CHANGED;
3723 }
3724 /// See AbstractAttribute::trackStatistics()
3725 void trackStatistics() const override {
3726 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
3727 }
3728};
3729
3730struct AAValueSimplifyFloating : AAValueSimplifyImpl {
3731 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3732
3733 /// See AbstractAttribute::initialize(...).
3734 void initialize(Attributor &A) override {
3735 Value &V = getAnchorValue();
3736
3737 // TODO: add other stuffs
3738 if (isa<Constant>(V) || isa<UndefValue>(V))
3739 indicatePessimisticFixpoint();
3740 }
3741
3742 /// See AbstractAttribute::updateImpl(...).
3743 ChangeStatus updateImpl(Attributor &A) override {
3744 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3745
3746 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
3747 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
3748 if (!Stripped && this == &AA) {
3749 // TODO: Look the instruction and check recursively.
3750 LLVM_DEBUG(
3751 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
3752 << V << "\n");
3753 indicatePessimisticFixpoint();
3754 return false;
3755 }
3756 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3757 };
3758
3759 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
3760 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
3761 VisitValueCB))
3762 return indicatePessimisticFixpoint();
3763
3764 // If a candicate was found in this update, return CHANGED.
3765
3766 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3767 ? ChangeStatus::UNCHANGED
3768 : ChangeStatus ::CHANGED;
3769 }
3770
3771 /// See AbstractAttribute::trackStatistics()
3772 void trackStatistics() const override {
3773 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
3774 }
3775};
3776
3777struct AAValueSimplifyFunction : AAValueSimplifyImpl {
3778 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3779
3780 /// See AbstractAttribute::initialize(...).
3781 void initialize(Attributor &A) override {
3782 SimplifiedAssociatedValue = &getAnchorValue();
3783 indicateOptimisticFixpoint();
3784 }
3785 /// See AbstractAttribute::initialize(...).
3786 ChangeStatus updateImpl(Attributor &A) override {
3787 llvm_unreachable(
3788 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
3789 }
3790 /// See AbstractAttribute::trackStatistics()
3791 void trackStatistics() const override {
3792 STATS_DECLTRACK_FN_ATTR(value_simplify)
3793 }
3794};
3795
3796struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
3797 AAValueSimplifyCallSite(const IRPosition &IRP)
3798 : AAValueSimplifyFunction(IRP) {}
3799 /// See AbstractAttribute::trackStatistics()
3800 void trackStatistics() const override {
3801 STATS_DECLTRACK_CS_ATTR(value_simplify)
3802 }
3803};
3804
3805struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
3806 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
3807 : AAValueSimplifyReturned(IRP) {}
3808
3809 void trackStatistics() const override {
3810 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
3811 }
3812};
3813struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
3814 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
3815 : AAValueSimplifyFloating(IRP) {}
3816
3817 void trackStatistics() const override {
3818 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
3819 }
3820};
3821
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003822/// ----------------------- Heap-To-Stack Conversion ---------------------------
3823struct AAHeapToStackImpl : public AAHeapToStack {
3824 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
3825
3826 const std::string getAsStr() const override {
3827 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
3828 }
3829
3830 ChangeStatus manifest(Attributor &A) override {
3831 assert(getState().isValidState() &&
3832 "Attempted to manifest an invalid state!");
3833
3834 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
3835 Function *F = getAssociatedFunction();
3836 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3837
3838 for (Instruction *MallocCall : MallocCalls) {
3839 // This malloc cannot be replaced.
3840 if (BadMallocCalls.count(MallocCall))
3841 continue;
3842
3843 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
3844 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
3845 A.deleteAfterManifest(*FreeCall);
3846 HasChanged = ChangeStatus::CHANGED;
3847 }
3848
3849 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
3850 << "\n");
3851
3852 Constant *Size;
3853 if (isCallocLikeFn(MallocCall, TLI)) {
3854 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
3855 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
3856 APInt TotalSize = SizeT->getValue() * Num->getValue();
3857 Size =
3858 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
3859 } else {
3860 Size = cast<ConstantInt>(MallocCall->getOperand(0));
3861 }
3862
3863 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
3864 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
3865 Size, "", MallocCall->getNextNode());
3866
3867 if (AI->getType() != MallocCall->getType())
3868 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
3869 AI->getNextNode());
3870
3871 MallocCall->replaceAllUsesWith(AI);
3872
3873 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
3874 auto *NBB = II->getNormalDest();
3875 BranchInst::Create(NBB, MallocCall->getParent());
3876 A.deleteAfterManifest(*MallocCall);
3877 } else {
3878 A.deleteAfterManifest(*MallocCall);
3879 }
3880
3881 if (isCallocLikeFn(MallocCall, TLI)) {
3882 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
3883 AI->getNextNode());
3884 Value *Ops[] = {
3885 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
3886 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
3887
3888 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
3889 Module *M = F->getParent();
3890 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
3891 CallInst::Create(Fn, Ops, "", BI->getNextNode());
3892 }
3893 HasChanged = ChangeStatus::CHANGED;
3894 }
3895
3896 return HasChanged;
3897 }
3898
3899 /// Collection of all malloc calls in a function.
3900 SmallSetVector<Instruction *, 4> MallocCalls;
3901
3902 /// Collection of malloc calls that cannot be converted.
3903 DenseSet<const Instruction *> BadMallocCalls;
3904
3905 /// A map for each malloc call to the set of associated free calls.
3906 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
3907
3908 ChangeStatus updateImpl(Attributor &A) override;
3909};
3910
3911ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
3912 const Function *F = getAssociatedFunction();
3913 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3914
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003915 MustBeExecutedContextExplorer &Explorer =
3916 A.getInfoCache().getMustBeExecutedContextExplorer();
3917
3918 auto FreeCheck = [&](Instruction &I) {
3919 const auto &Frees = FreesForMalloc.lookup(&I);
3920 if (Frees.size() != 1)
3921 return false;
3922 Instruction *UniqueFree = *Frees.begin();
3923 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
3924 };
3925
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003926 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003927 bool ValidUsesOnly = true;
3928 bool MustUse = true;
3929
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003930 SmallPtrSet<const Use *, 8> Visited;
3931 SmallVector<const Use *, 8> Worklist;
3932
3933 for (Use &U : I.uses())
3934 Worklist.push_back(&U);
3935
3936 while (!Worklist.empty()) {
3937 const Use *U = Worklist.pop_back_val();
3938 if (!Visited.insert(U).second)
3939 continue;
3940
3941 auto *UserI = U->getUser();
3942
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003943 if (isa<LoadInst>(UserI))
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003944 continue;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003945 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
3946 if (SI->getValueOperand() == U->get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003947 LLVM_DEBUG(dbgs()
3948 << "[H2S] escaping store to memory: " << *UserI << "\n");
3949 ValidUsesOnly = false;
3950 } else {
3951 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003952 }
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003953 continue;
3954 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003955
3956 // NOTE: Right now, if a function that has malloc pointer as an argument
3957 // frees memory, we assume that the malloc pointer is freed.
3958
3959 // TODO: Add nofree callsite argument attribute to indicate that pointer
3960 // argument is not freed.
3961 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3962 if (!CB->isArgOperand(U))
3963 continue;
3964
3965 if (CB->isLifetimeStartOrEnd())
3966 continue;
3967
3968 // Record malloc.
3969 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003970 if (MustUse) {
3971 FreesForMalloc[&I].insert(
3972 cast<Instruction>(const_cast<User *>(UserI)));
3973 } else {
3974 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
3975 << *UserI << "\n");
3976 ValidUsesOnly = false;
3977 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003978 continue;
3979 }
3980
3981 // If a function does not free memory we are fine
3982 const auto &NoFreeAA =
3983 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(*CB));
3984
3985 unsigned ArgNo = U - CB->arg_begin();
3986 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
3987 *this, IRPosition::callsite_argument(*CB, ArgNo));
3988
3989 if (!NoCaptureAA.isAssumedNoCapture() || !NoFreeAA.isAssumedNoFree()) {
3990 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003991 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003992 }
3993 continue;
3994 }
3995
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05003996 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
3997 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
3998 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003999 for (Use &U : UserI->uses())
4000 Worklist.push_back(&U);
4001 continue;
4002 }
4003
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004004 // Unknown user for which we can not track uses further (in a way that
4005 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004006 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004007 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004008 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004009 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004010 };
4011
4012 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004013 if (BadMallocCalls.count(&I))
4014 return true;
4015
4016 bool IsMalloc = isMallocLikeFn(&I, TLI);
4017 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
4018 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004019 BadMallocCalls.insert(&I);
4020 return true;
4021 }
4022
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004023 if (IsMalloc) {
4024 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
4025 if (Size->getValue().sle(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004026 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004027 MallocCalls.insert(&I);
4028 return true;
4029 }
4030 } else if (IsCalloc) {
4031 bool Overflow = false;
4032 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
4033 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
4034 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
4035 .sle(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004036 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004037 MallocCalls.insert(&I);
4038 return true;
4039 }
4040 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004041
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004042 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004043 return true;
4044 };
4045
4046 size_t NumBadMallocs = BadMallocCalls.size();
4047
4048 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
4049
4050 if (NumBadMallocs != BadMallocCalls.size())
4051 return ChangeStatus::CHANGED;
4052
4053 return ChangeStatus::UNCHANGED;
4054}
4055
4056struct AAHeapToStackFunction final : public AAHeapToStackImpl {
4057 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
4058
4059 /// See AbstractAttribute::trackStatistics()
4060 void trackStatistics() const override {
4061 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004062 "Number of malloc calls converted to allocas");
4063 for (auto *C : MallocCalls)
4064 if (!BadMallocCalls.count(C))
4065 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004066 }
4067};
4068
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004069/// -------------------- Memory Behavior Attributes ----------------------------
4070/// Includes read-none, read-only, and write-only.
4071/// ----------------------------------------------------------------------------
4072struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
4073 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
4074
4075 /// See AbstractAttribute::initialize(...).
4076 void initialize(Attributor &A) override {
4077 intersectAssumedBits(BEST_STATE);
4078 getKnownStateFromValue(getIRPosition(), getState());
4079 IRAttribute::initialize(A);
4080 }
4081
4082 /// Return the memory behavior information encoded in the IR for \p IRP.
4083 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert1a746452019-10-20 22:28:49 -05004084 BitIntegerState &State) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004085 SmallVector<Attribute, 2> Attrs;
4086 IRP.getAttrs(AttrKinds, Attrs);
4087 for (const Attribute &Attr : Attrs) {
4088 switch (Attr.getKindAsEnum()) {
4089 case Attribute::ReadNone:
4090 State.addKnownBits(NO_ACCESSES);
4091 break;
4092 case Attribute::ReadOnly:
4093 State.addKnownBits(NO_WRITES);
4094 break;
4095 case Attribute::WriteOnly:
4096 State.addKnownBits(NO_READS);
4097 break;
4098 default:
4099 llvm_unreachable("Unexpcted attribute!");
4100 }
4101 }
4102
4103 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
4104 if (!I->mayReadFromMemory())
4105 State.addKnownBits(NO_READS);
4106 if (!I->mayWriteToMemory())
4107 State.addKnownBits(NO_WRITES);
4108 }
4109 }
4110
4111 /// See AbstractAttribute::getDeducedAttributes(...).
4112 void getDeducedAttributes(LLVMContext &Ctx,
4113 SmallVectorImpl<Attribute> &Attrs) const override {
4114 assert(Attrs.size() == 0);
4115 if (isAssumedReadNone())
4116 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
4117 else if (isAssumedReadOnly())
4118 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
4119 else if (isAssumedWriteOnly())
4120 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
4121 assert(Attrs.size() <= 1);
4122 }
4123
4124 /// See AbstractAttribute::manifest(...).
4125 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05004126 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004127
4128 // Check if we would improve the existing attributes first.
4129 SmallVector<Attribute, 4> DeducedAttrs;
4130 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
4131 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
4132 return IRP.hasAttr(Attr.getKindAsEnum(),
4133 /* IgnoreSubsumingPositions */ true);
4134 }))
4135 return ChangeStatus::UNCHANGED;
4136
4137 // Clear existing attributes.
4138 IRP.removeAttrs(AttrKinds);
4139
4140 // Use the generic manifest method.
4141 return IRAttribute::manifest(A);
4142 }
4143
4144 /// See AbstractState::getAsStr().
4145 const std::string getAsStr() const override {
4146 if (isAssumedReadNone())
4147 return "readnone";
4148 if (isAssumedReadOnly())
4149 return "readonly";
4150 if (isAssumedWriteOnly())
4151 return "writeonly";
4152 return "may-read/write";
4153 }
4154
4155 /// The set of IR attributes AAMemoryBehavior deals with.
4156 static const Attribute::AttrKind AttrKinds[3];
4157};
4158
4159const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
4160 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
4161
4162/// Memory behavior attribute for a floating value.
4163struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
4164 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4165
4166 /// See AbstractAttribute::initialize(...).
4167 void initialize(Attributor &A) override {
4168 AAMemoryBehaviorImpl::initialize(A);
4169 // Initialize the use vector with all direct uses of the associated value.
4170 for (const Use &U : getAssociatedValue().uses())
4171 Uses.insert(&U);
4172 }
4173
4174 /// See AbstractAttribute::updateImpl(...).
4175 ChangeStatus updateImpl(Attributor &A) override;
4176
4177 /// See AbstractAttribute::trackStatistics()
4178 void trackStatistics() const override {
4179 if (isAssumedReadNone())
4180 STATS_DECLTRACK_FLOATING_ATTR(readnone)
4181 else if (isAssumedReadOnly())
4182 STATS_DECLTRACK_FLOATING_ATTR(readonly)
4183 else if (isAssumedWriteOnly())
4184 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
4185 }
4186
4187private:
4188 /// Return true if users of \p UserI might access the underlying
4189 /// variable/location described by \p U and should therefore be analyzed.
4190 bool followUsersOfUseIn(Attributor &A, const Use *U,
4191 const Instruction *UserI);
4192
4193 /// Update the state according to the effect of use \p U in \p UserI.
4194 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
4195
4196protected:
4197 /// Container for (transitive) uses of the associated argument.
4198 SetVector<const Use *> Uses;
4199};
4200
4201/// Memory behavior attribute for function argument.
4202struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
4203 AAMemoryBehaviorArgument(const IRPosition &IRP)
4204 : AAMemoryBehaviorFloating(IRP) {}
4205
4206 /// See AbstractAttribute::initialize(...).
4207 void initialize(Attributor &A) override {
4208 AAMemoryBehaviorFloating::initialize(A);
4209
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004210 // Initialize the use vector with all direct uses of the associated value.
4211 Argument *Arg = getAssociatedArgument();
4212 if (!Arg || !Arg->getParent()->hasExactDefinition())
4213 indicatePessimisticFixpoint();
4214 }
4215
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004216 ChangeStatus manifest(Attributor &A) override {
4217 // TODO: From readattrs.ll: "inalloca parameters are always
4218 // considered written"
4219 if (hasAttr({Attribute::InAlloca})) {
4220 removeKnownBits(NO_WRITES);
4221 removeAssumedBits(NO_WRITES);
4222 }
4223 return AAMemoryBehaviorFloating::manifest(A);
4224 }
4225
4226
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004227 /// See AbstractAttribute::trackStatistics()
4228 void trackStatistics() const override {
4229 if (isAssumedReadNone())
4230 STATS_DECLTRACK_ARG_ATTR(readnone)
4231 else if (isAssumedReadOnly())
4232 STATS_DECLTRACK_ARG_ATTR(readonly)
4233 else if (isAssumedWriteOnly())
4234 STATS_DECLTRACK_ARG_ATTR(writeonly)
4235 }
4236};
4237
4238struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
4239 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
4240 : AAMemoryBehaviorArgument(IRP) {}
4241
4242 /// See AbstractAttribute::updateImpl(...).
4243 ChangeStatus updateImpl(Attributor &A) override {
4244 // TODO: Once we have call site specific value information we can provide
4245 // call site specific liveness liveness information and then it makes
4246 // sense to specialize attributes for call sites arguments instead of
4247 // redirecting requests to the callee argument.
4248 Argument *Arg = getAssociatedArgument();
4249 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4250 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4251 return clampStateAndIndicateChange(
4252 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05004253 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004254 }
4255
4256 /// See AbstractAttribute::trackStatistics()
4257 void trackStatistics() const override {
4258 if (isAssumedReadNone())
4259 STATS_DECLTRACK_CSARG_ATTR(readnone)
4260 else if (isAssumedReadOnly())
4261 STATS_DECLTRACK_CSARG_ATTR(readonly)
4262 else if (isAssumedWriteOnly())
4263 STATS_DECLTRACK_CSARG_ATTR(writeonly)
4264 }
4265};
4266
4267/// Memory behavior attribute for a call site return position.
4268struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
4269 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
4270 : AAMemoryBehaviorFloating(IRP) {}
4271
4272 /// See AbstractAttribute::manifest(...).
4273 ChangeStatus manifest(Attributor &A) override {
4274 // We do not annotate returned values.
4275 return ChangeStatus::UNCHANGED;
4276 }
4277
4278 /// See AbstractAttribute::trackStatistics()
4279 void trackStatistics() const override {}
4280};
4281
4282/// An AA to represent the memory behavior function attributes.
4283struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
4284 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4285
4286 /// See AbstractAttribute::updateImpl(Attributor &A).
4287 virtual ChangeStatus updateImpl(Attributor &A) override;
4288
4289 /// See AbstractAttribute::manifest(...).
4290 ChangeStatus manifest(Attributor &A) override {
4291 Function &F = cast<Function>(getAnchorValue());
4292 if (isAssumedReadNone()) {
4293 F.removeFnAttr(Attribute::ArgMemOnly);
4294 F.removeFnAttr(Attribute::InaccessibleMemOnly);
4295 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
4296 }
4297 return AAMemoryBehaviorImpl::manifest(A);
4298 }
4299
4300 /// See AbstractAttribute::trackStatistics()
4301 void trackStatistics() const override {
4302 if (isAssumedReadNone())
4303 STATS_DECLTRACK_FN_ATTR(readnone)
4304 else if (isAssumedReadOnly())
4305 STATS_DECLTRACK_FN_ATTR(readonly)
4306 else if (isAssumedWriteOnly())
4307 STATS_DECLTRACK_FN_ATTR(writeonly)
4308 }
4309};
4310
4311/// AAMemoryBehavior attribute for call sites.
4312struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
4313 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4314
4315 /// See AbstractAttribute::initialize(...).
4316 void initialize(Attributor &A) override {
4317 AAMemoryBehaviorImpl::initialize(A);
4318 Function *F = getAssociatedFunction();
4319 if (!F || !F->hasExactDefinition())
4320 indicatePessimisticFixpoint();
4321 }
4322
4323 /// See AbstractAttribute::updateImpl(...).
4324 ChangeStatus updateImpl(Attributor &A) override {
4325 // TODO: Once we have call site specific value information we can provide
4326 // call site specific liveness liveness information and then it makes
4327 // sense to specialize attributes for call sites arguments instead of
4328 // redirecting requests to the callee argument.
4329 Function *F = getAssociatedFunction();
4330 const IRPosition &FnPos = IRPosition::function(*F);
4331 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4332 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05004333 getState(),
4334 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004335 }
4336
4337 /// See AbstractAttribute::trackStatistics()
4338 void trackStatistics() const override {
4339 if (isAssumedReadNone())
4340 STATS_DECLTRACK_CS_ATTR(readnone)
4341 else if (isAssumedReadOnly())
4342 STATS_DECLTRACK_CS_ATTR(readonly)
4343 else if (isAssumedWriteOnly())
4344 STATS_DECLTRACK_CS_ATTR(writeonly)
4345 }
4346};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00004347} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004348
4349ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
4350
4351 // The current assumed state used to determine a change.
4352 auto AssumedState = getAssumed();
4353
4354 auto CheckRWInst = [&](Instruction &I) {
4355 // If the instruction has an own memory behavior state, use it to restrict
4356 // the local state. No further analysis is required as the other memory
4357 // state is as optimistic as it gets.
4358 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
4359 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
4360 *this, IRPosition::callsite_function(ICS));
4361 intersectAssumedBits(MemBehaviorAA.getAssumed());
4362 return !isAtFixpoint();
4363 }
4364
4365 // Remove access kind modifiers if necessary.
4366 if (I.mayReadFromMemory())
4367 removeAssumedBits(NO_READS);
4368 if (I.mayWriteToMemory())
4369 removeAssumedBits(NO_WRITES);
4370 return !isAtFixpoint();
4371 };
4372
4373 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
4374 return indicatePessimisticFixpoint();
4375
4376 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4377 : ChangeStatus::UNCHANGED;
4378}
4379
4380ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
4381
4382 const IRPosition &IRP = getIRPosition();
4383 const IRPosition &FnPos = IRPosition::function_scope(IRP);
4384 AAMemoryBehavior::StateType &S = getState();
4385
4386 // First, check the function scope. We take the known information and we avoid
4387 // work if the assumed information implies the current assumed information for
4388 // this attribute.
4389 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4390 S.addKnownBits(FnMemAA.getKnown());
4391 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
4392 return ChangeStatus::UNCHANGED;
4393
4394 // Make sure the value is not captured (except through "return"), if
4395 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004396 // check the potential aliases introduced by the capture. However, no need
4397 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004398 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004399 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
4400 S.intersectAssumedBits(FnMemAA.getAssumed());
4401 return ChangeStatus::CHANGED;
4402 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004403
4404 // The current assumed state used to determine a change.
4405 auto AssumedState = S.getAssumed();
4406
4407 // Liveness information to exclude dead users.
4408 // TODO: Take the FnPos once we have call site specific liveness information.
4409 const auto &LivenessAA = A.getAAFor<AAIsDead>(
4410 *this, IRPosition::function(*IRP.getAssociatedFunction()));
4411
4412 // Visit and expand uses until all are analyzed or a fixpoint is reached.
4413 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
4414 const Use *U = Uses[i];
4415 Instruction *UserI = cast<Instruction>(U->getUser());
4416 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
4417 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
4418 << "]\n");
4419 if (LivenessAA.isAssumedDead(UserI))
4420 continue;
4421
4422 // Check if the users of UserI should also be visited.
4423 if (followUsersOfUseIn(A, U, UserI))
4424 for (const Use &UserIUse : UserI->uses())
4425 Uses.insert(&UserIUse);
4426
4427 // If UserI might touch memory we analyze the use in detail.
4428 if (UserI->mayReadOrWriteMemory())
4429 analyzeUseIn(A, U, UserI);
4430 }
4431
4432 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4433 : ChangeStatus::UNCHANGED;
4434}
4435
4436bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
4437 const Instruction *UserI) {
4438 // The loaded value is unrelated to the pointer argument, no need to
4439 // follow the users of the load.
4440 if (isa<LoadInst>(UserI))
4441 return false;
4442
4443 // By default we follow all uses assuming UserI might leak information on U,
4444 // we have special handling for call sites operands though.
4445 ImmutableCallSite ICS(UserI);
4446 if (!ICS || !ICS.isArgOperand(U))
4447 return true;
4448
4449 // If the use is a call argument known not to be captured, the users of
4450 // the call do not need to be visited because they have to be unrelated to
4451 // the input. Note that this check is not trivial even though we disallow
4452 // general capturing of the underlying argument. The reason is that the
4453 // call might the argument "through return", which we allow and for which we
4454 // need to check call users.
4455 unsigned ArgNo = ICS.getArgumentNo(U);
4456 const auto &ArgNoCaptureAA =
4457 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
4458 return !ArgNoCaptureAA.isAssumedNoCapture();
4459}
4460
4461void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
4462 const Instruction *UserI) {
4463 assert(UserI->mayReadOrWriteMemory());
4464
4465 switch (UserI->getOpcode()) {
4466 default:
4467 // TODO: Handle all atomics and other side-effect operations we know of.
4468 break;
4469 case Instruction::Load:
4470 // Loads cause the NO_READS property to disappear.
4471 removeAssumedBits(NO_READS);
4472 return;
4473
4474 case Instruction::Store:
4475 // Stores cause the NO_WRITES property to disappear if the use is the
4476 // pointer operand. Note that we do assume that capturing was taken care of
4477 // somewhere else.
4478 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
4479 removeAssumedBits(NO_WRITES);
4480 return;
4481
4482 case Instruction::Call:
4483 case Instruction::CallBr:
4484 case Instruction::Invoke: {
4485 // For call sites we look at the argument memory behavior attribute (this
4486 // could be recursive!) in order to restrict our own state.
4487 ImmutableCallSite ICS(UserI);
4488
4489 // Give up on operand bundles.
4490 if (ICS.isBundleOperand(U)) {
4491 indicatePessimisticFixpoint();
4492 return;
4493 }
4494
4495 // Calling a function does read the function pointer, maybe write it if the
4496 // function is self-modifying.
4497 if (ICS.isCallee(U)) {
4498 removeAssumedBits(NO_READS);
4499 break;
4500 }
4501
4502 // Adjust the possible access behavior based on the information on the
4503 // argument.
4504 unsigned ArgNo = ICS.getArgumentNo(U);
4505 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
4506 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4507 // "assumed" has at most the same bits as the MemBehaviorAA assumed
4508 // and at least "known".
4509 intersectAssumedBits(MemBehaviorAA.getAssumed());
4510 return;
4511 }
4512 };
4513
4514 // Generally, look at the "may-properties" and adjust the assumed state if we
4515 // did not trigger special handling before.
4516 if (UserI->mayReadFromMemory())
4517 removeAssumedBits(NO_READS);
4518 if (UserI->mayWriteToMemory())
4519 removeAssumedBits(NO_WRITES);
4520}
4521
Johannes Doerfertaade7822019-06-05 03:02:24 +00004522/// ----------------------------------------------------------------------------
4523/// Attributor
4524/// ----------------------------------------------------------------------------
4525
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004526bool Attributor::isAssumedDead(const AbstractAttribute &AA,
4527 const AAIsDead *LivenessAA) {
4528 const Instruction *CtxI = AA.getIRPosition().getCtxI();
4529 if (!CtxI)
4530 return false;
4531
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004532 // TODO: Find a good way to utilize fine and coarse grained liveness
4533 // information.
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004534 if (!LivenessAA)
4535 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00004536 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
4537 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00004538
4539 // Don't check liveness for AAIsDead.
4540 if (&AA == LivenessAA)
4541 return false;
4542
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004543 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004544 return false;
4545
Johannes Doerfert19b00432019-08-26 17:48:05 +00004546 // We actually used liveness information so we have to record a dependence.
4547 recordDependence(*LivenessAA, AA);
4548
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004549 return true;
4550}
4551
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004552bool Attributor::checkForAllUses(
4553 const function_ref<bool(const Use &, bool &)> &Pred,
4554 const AbstractAttribute &QueryingAA, const Value &V) {
4555 const IRPosition &IRP = QueryingAA.getIRPosition();
4556 SmallVector<const Use *, 16> Worklist;
4557 SmallPtrSet<const Use *, 16> Visited;
4558
4559 for (const Use &U : V.uses())
4560 Worklist.push_back(&U);
4561
4562 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
4563 << " initial uses to check\n");
4564
4565 if (Worklist.empty())
4566 return true;
4567
4568 bool AnyDead = false;
4569 const Function *ScopeFn = IRP.getAnchorScope();
4570 const auto *LivenessAA =
4571 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
4572 /* TrackDependence */ false)
4573 : nullptr;
4574
4575 while (!Worklist.empty()) {
4576 const Use *U = Worklist.pop_back_val();
4577 if (!Visited.insert(U).second)
4578 continue;
4579 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << "\n");
4580 if (Instruction *UserI = dyn_cast<Instruction>(U->getUser()))
4581 if (LivenessAA && LivenessAA->isAssumedDead(UserI)) {
4582 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
4583 << static_cast<const AbstractAttribute &>(*LivenessAA)
4584 << "\n");
4585 AnyDead = true;
4586 continue;
4587 }
4588
4589 bool Follow = false;
4590 if (!Pred(*U, Follow))
4591 return false;
4592 if (!Follow)
4593 continue;
4594 for (const Use &UU : U->getUser()->uses())
4595 Worklist.push_back(&UU);
4596 }
4597
4598 if (AnyDead)
4599 recordDependence(*LivenessAA, QueryingAA);
4600
4601 return true;
4602}
4603
Johannes Doerfert661db042019-10-07 23:14:58 +00004604bool Attributor::checkForAllCallSites(
4605 const function_ref<bool(AbstractCallSite)> &Pred,
4606 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004607 // We can try to determine information from
4608 // the call sites. However, this is only possible all call sites are known,
4609 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004610 const IRPosition &IRP = QueryingAA.getIRPosition();
4611 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00004612 if (!AssociatedFunction) {
4613 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
4614 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004615 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00004616 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004617
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004618 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
4619 &QueryingAA);
4620}
4621
4622bool Attributor::checkForAllCallSites(
4623 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
4624 bool RequireAllCallSites, const AbstractAttribute *QueryingAA) {
4625 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004626 LLVM_DEBUG(
4627 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004628 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00004629 << " has no internal linkage, hence not all call sites are known\n");
4630 return false;
4631 }
4632
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004633 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00004634 AbstractCallSite ACS(&U);
4635 if (!ACS) {
4636 LLVM_DEBUG(dbgs() << "[Attributor] Function "
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004637 << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00004638 << " has non call site use " << *U.get() << " in "
4639 << *U.getUser() << "\n");
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004640 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00004641 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004642
Johannes Doerfert661db042019-10-07 23:14:58 +00004643 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004644 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004645
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004646 const auto *LivenessAA =
4647 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Johannes Doerfert661db042019-10-07 23:14:58 +00004648 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004649
4650 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004651 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00004652 // We actually used liveness information so we have to record a
4653 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004654 if (QueryingAA)
4655 recordDependence(*LivenessAA, *QueryingAA);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004656 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004657 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004658
Johannes Doerfert661db042019-10-07 23:14:58 +00004659 const Use *EffectiveUse =
4660 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
4661 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004662 if (!RequireAllCallSites)
4663 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00004664 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004665 << " is an invalid use of "
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004666 << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004667 return false;
4668 }
4669
Johannes Doerfert661db042019-10-07 23:14:58 +00004670 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00004671 continue;
4672
Johannes Doerfert5304b722019-08-14 22:04:28 +00004673 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00004674 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004675 return false;
4676 }
4677
4678 return true;
4679}
4680
Johannes Doerfert14a04932019-08-07 22:27:24 +00004681bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004682 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00004683 &Pred,
4684 const AbstractAttribute &QueryingAA) {
4685
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004686 const IRPosition &IRP = QueryingAA.getIRPosition();
4687 // Since we need to provide return instructions we have to have an exact
4688 // definition.
4689 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004690 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004691 return false;
4692
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004693 // If this is a call site query we use the call site specific return values
4694 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004695 // TODO: use the function scope once we have call site AAReturnedValues.
4696 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004697 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004698 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004699 return false;
4700
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004701 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00004702}
4703
4704bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004705 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00004706 const AbstractAttribute &QueryingAA) {
4707
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004708 const IRPosition &IRP = QueryingAA.getIRPosition();
4709 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004710 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004711 return false;
4712
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004713 // TODO: use the function scope once we have call site AAReturnedValues.
4714 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004715 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004716 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004717 return false;
4718
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004719 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004720 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00004721 return Pred(RV);
4722 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00004723}
4724
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004725static bool
4726checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
4727 const function_ref<bool(Instruction &)> &Pred,
4728 const AAIsDead *LivenessAA, bool &AnyDead,
4729 const ArrayRef<unsigned> &Opcodes) {
4730 for (unsigned Opcode : Opcodes) {
4731 for (Instruction *I : OpcodeInstMap[Opcode]) {
4732 // Skip dead instructions.
4733 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
4734 AnyDead = true;
4735 continue;
4736 }
4737
4738 if (!Pred(*I))
4739 return false;
4740 }
4741 }
4742 return true;
4743}
4744
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004745bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004746 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004747 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004748
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004749 const IRPosition &IRP = QueryingAA.getIRPosition();
4750 // Since we need to provide instructions we have to have an exact definition.
4751 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004752 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004753 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004754
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004755 // TODO: use the function scope once we have call site AAReturnedValues.
4756 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004757 const auto &LivenessAA =
4758 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
4759 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004760
4761 auto &OpcodeInstMap =
4762 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004763 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
4764 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004765 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004766
Johannes Doerfert19b00432019-08-26 17:48:05 +00004767 // If we actually used liveness information so we have to record a dependence.
4768 if (AnyDead)
4769 recordDependence(LivenessAA, QueryingAA);
4770
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004771 return true;
4772}
4773
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004774bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004775 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004776 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004777
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004778 const Function *AssociatedFunction =
4779 QueryingAA.getIRPosition().getAssociatedFunction();
4780 if (!AssociatedFunction)
4781 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004782
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004783 // TODO: use the function scope once we have call site AAReturnedValues.
4784 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
4785 const auto &LivenessAA =
4786 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004787 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004788
4789 for (Instruction *I :
4790 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004791 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00004792 if (LivenessAA.isAssumedDead(I)) {
4793 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004794 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004795 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004796
4797 if (!Pred(*I))
4798 return false;
4799 }
4800
Johannes Doerfert19b00432019-08-26 17:48:05 +00004801 // If we actually used liveness information so we have to record a dependence.
4802 if (AnyDead)
4803 recordDependence(LivenessAA, QueryingAA);
4804
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004805 return true;
4806}
4807
Johannes Doerfert2f622062019-09-04 16:35:20 +00004808ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004809 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
4810 << AllAbstractAttributes.size()
4811 << " abstract attributes.\n");
4812
Stefan Stipanovic53605892019-06-27 11:27:54 +00004813 // Now that all abstract attributes are collected and initialized we start
4814 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00004815
4816 unsigned IterationCounter = 1;
4817
4818 SmallVector<AbstractAttribute *, 64> ChangedAAs;
4819 SetVector<AbstractAttribute *> Worklist;
4820 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
4821
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004822 bool RecomputeDependences = false;
4823
Johannes Doerfertaade7822019-06-05 03:02:24 +00004824 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004825 // Remember the size to determine new attributes.
4826 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004827 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
4828 << ", Worklist size: " << Worklist.size() << "\n");
4829
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004830 // If dependences (=QueryMap) are recomputed we have to look at all abstract
4831 // attributes again, regardless of what changed in the last iteration.
4832 if (RecomputeDependences) {
4833 LLVM_DEBUG(
4834 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
4835 QueryMap.clear();
4836 ChangedAAs.clear();
4837 Worklist.insert(AllAbstractAttributes.begin(),
4838 AllAbstractAttributes.end());
4839 }
4840
Johannes Doerfertaade7822019-06-05 03:02:24 +00004841 // Add all abstract attributes that are potentially dependent on one that
4842 // changed to the work list.
4843 for (AbstractAttribute *ChangedAA : ChangedAAs) {
4844 auto &QuerriedAAs = QueryMap[ChangedAA];
4845 Worklist.insert(QuerriedAAs.begin(), QuerriedAAs.end());
4846 }
4847
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004848 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
4849 << ", Worklist+Dependent size: " << Worklist.size()
4850 << "\n");
4851
Johannes Doerfertaade7822019-06-05 03:02:24 +00004852 // Reset the changed set.
4853 ChangedAAs.clear();
4854
4855 // Update all abstract attribute in the work list and record the ones that
4856 // changed.
4857 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert2dad7292019-10-13 21:10:31 -05004858 if (!AA->getState().isAtFixpoint() && !isAssumedDead(*AA, nullptr)) {
4859 QueriedNonFixAA = false;
4860 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004861 ChangedAAs.push_back(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05004862 } else if (!QueriedNonFixAA) {
4863 // If the attribute did not query any non-fix information, the state
4864 // will not change and we can indicate that right away.
4865 AA->getState().indicateOptimisticFixpoint();
4866 }
4867 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00004868
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004869 // Check if we recompute the dependences in the next iteration.
4870 RecomputeDependences = (DepRecomputeInterval > 0 &&
4871 IterationCounter % DepRecomputeInterval == 0);
4872
Johannes Doerfert9543f142019-08-23 15:24:57 +00004873 // Add attributes to the changed set if they have been created in the last
4874 // iteration.
4875 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
4876 AllAbstractAttributes.end());
4877
Johannes Doerfertaade7822019-06-05 03:02:24 +00004878 // Reset the work list and repopulate with the changed abstract attributes.
4879 // Note that dependent ones are added above.
4880 Worklist.clear();
4881 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
4882
Johannes Doerfertbf112132019-08-29 01:29:44 +00004883 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
4884 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004885
Johannes Doerfertaade7822019-06-05 03:02:24 +00004886 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
4887 << IterationCounter << "/" << MaxFixpointIterations
4888 << " iterations\n");
4889
Johannes Doerfertbf112132019-08-29 01:29:44 +00004890 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004891
Johannes Doerfertaade7822019-06-05 03:02:24 +00004892 // Reset abstract arguments not settled in a sound fixpoint by now. This
4893 // happens when we stopped the fixpoint iteration early. Note that only the
4894 // ones marked as "changed" *and* the ones transitively depending on them
4895 // need to be reverted to a pessimistic state. Others might not be in a
4896 // fixpoint state but we can use the optimistic results for them anyway.
4897 SmallPtrSet<AbstractAttribute *, 32> Visited;
4898 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
4899 AbstractAttribute *ChangedAA = ChangedAAs[u];
4900 if (!Visited.insert(ChangedAA).second)
4901 continue;
4902
4903 AbstractState &State = ChangedAA->getState();
4904 if (!State.isAtFixpoint()) {
4905 State.indicatePessimisticFixpoint();
4906
4907 NumAttributesTimedOut++;
4908 }
4909
4910 auto &QuerriedAAs = QueryMap[ChangedAA];
4911 ChangedAAs.append(QuerriedAAs.begin(), QuerriedAAs.end());
4912 }
4913
4914 LLVM_DEBUG({
4915 if (!Visited.empty())
4916 dbgs() << "\n[Attributor] Finalized " << Visited.size()
4917 << " abstract attributes.\n";
4918 });
4919
4920 unsigned NumManifested = 0;
4921 unsigned NumAtFixpoint = 0;
4922 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
4923 for (AbstractAttribute *AA : AllAbstractAttributes) {
4924 AbstractState &State = AA->getState();
4925
4926 // If there is not already a fixpoint reached, we can now take the
4927 // optimistic state. This is correct because we enforced a pessimistic one
4928 // on abstract attributes that were transitively dependent on a changed one
4929 // already above.
4930 if (!State.isAtFixpoint())
4931 State.indicateOptimisticFixpoint();
4932
4933 // If the state is invalid, we do not try to manifest it.
4934 if (!State.isValidState())
4935 continue;
4936
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004937 // Skip dead code.
4938 if (isAssumedDead(*AA, nullptr))
4939 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004940 // Manifest the state and record if we changed the IR.
4941 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00004942 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
4943 AA->trackStatistics();
4944
Johannes Doerfertaade7822019-06-05 03:02:24 +00004945 ManifestChange = ManifestChange | LocalChange;
4946
4947 NumAtFixpoint++;
4948 NumManifested += (LocalChange == ChangeStatus::CHANGED);
4949 }
4950
4951 (void)NumManifested;
4952 (void)NumAtFixpoint;
4953 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
4954 << " arguments while " << NumAtFixpoint
4955 << " were in a valid fixpoint state\n");
4956
Johannes Doerfertaade7822019-06-05 03:02:24 +00004957 NumAttributesManifested += NumManifested;
4958 NumAttributesValidFixpoint += NumAtFixpoint;
4959
Fangrui Songf1826172019-08-20 07:21:43 +00004960 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004961 assert(
4962 NumFinalAAs == AllAbstractAttributes.size() &&
4963 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00004964
4965 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00004966 {
4967 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
4968 << ToBeDeletedFunctions.size() << " functions and "
4969 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004970 << ToBeDeletedInsts.size() << " instructions and "
4971 << ToBeChangedUses.size() << " uses\n");
4972
4973 SmallVector<Instruction *, 32> DeadInsts;
4974 SmallVector<Instruction *, 32> TerminatorsToFold;
4975 SmallVector<Instruction *, 32> UnreachablesToInsert;
4976
4977 for (auto &It : ToBeChangedUses) {
4978 Use *U = It.first;
4979 Value *NewV = It.second;
4980 Value *OldV = U->get();
4981 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
4982 << " instead of " << *OldV << "\n");
4983 U->set(NewV);
4984 if (Instruction *I = dyn_cast<Instruction>(OldV))
4985 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) && isInstructionTriviallyDead(I)) {
4986 DeadInsts.push_back(I);
4987 }
4988 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
4989 Instruction *UserI = cast<Instruction>(U->getUser());
4990 if (isa<UndefValue>(NewV)) {
4991 UnreachablesToInsert.push_back(UserI);
4992 } else {
4993 TerminatorsToFold.push_back(UserI);
4994 }
4995 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00004996 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004997 for (Instruction *I : UnreachablesToInsert)
4998 changeToUnreachable(I, /* UseLLVMTrap */ false);
4999 for (Instruction *I : TerminatorsToFold)
5000 ConstantFoldTerminator(I->getParent());
5001
5002 for (Instruction *I : ToBeDeletedInsts) {
5003 I->replaceAllUsesWith(UndefValue::get(I->getType()));
5004 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
5005 DeadInsts.push_back(I);
5006 else
5007 I->eraseFromParent();
5008 }
5009
5010 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00005011
Johannes Doerfert2f622062019-09-04 16:35:20 +00005012 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
5013 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
5014 ToBeDeletedBBs.reserve(NumDeadBlocks);
5015 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
Johannes Doerfert5e442a52019-10-30 17:34:59 -05005016 // Actually we do not delete the blocks but squash them into a single
5017 // unreachable but untangling branches that jump here is something we need
5018 // to do in a more generic way.
5019 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
5020 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
5021 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00005022 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00005023
Johannes Doerfert2f622062019-09-04 16:35:20 +00005024 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
5025 for (Function *Fn : ToBeDeletedFunctions) {
5026 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
5027 Fn->eraseFromParent();
5028 STATS_TRACK(AAIsDead, Function);
5029 }
5030
5031 // Identify dead internal functions and delete them. This happens outside
5032 // the other fixpoint analysis as we might treat potentially dead functions
5033 // as live to lower the number of iterations. If they happen to be dead, the
5034 // below fixpoint loop will identify and eliminate them.
5035 SmallVector<Function *, 8> InternalFns;
5036 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00005037 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00005038 InternalFns.push_back(&F);
5039
5040 bool FoundDeadFn = true;
5041 while (FoundDeadFn) {
5042 FoundDeadFn = false;
5043 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
5044 Function *F = InternalFns[u];
5045 if (!F)
5046 continue;
5047
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005048 if (!checkForAllCallSites([](AbstractCallSite ACS) { return false; },
5049 *F, true, nullptr))
Johannes Doerfert2f622062019-09-04 16:35:20 +00005050 continue;
5051
5052 STATS_TRACK(AAIsDead, Function);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005053 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00005054 F->replaceAllUsesWith(UndefValue::get(F->getType()));
5055 F->eraseFromParent();
5056 InternalFns[u] = nullptr;
5057 FoundDeadFn = true;
5058 }
5059 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00005060 }
5061
Johannes Doerfertbf112132019-08-29 01:29:44 +00005062 if (VerifyMaxFixpointIterations &&
5063 IterationCounter != MaxFixpointIterations) {
5064 errs() << "\n[Attributor] Fixpoint iteration done after: "
5065 << IterationCounter << "/" << MaxFixpointIterations
5066 << " iterations\n";
5067 llvm_unreachable("The fixpoint was not reached with exactly the number of "
5068 "specified iterations!");
5069 }
5070
Johannes Doerfertaade7822019-06-05 03:02:24 +00005071 return ManifestChange;
5072}
5073
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005074void Attributor::initializeInformationCache(Function &F) {
5075
5076 // Walk all instructions to find interesting instructions that might be
5077 // queried by abstract attributes during their initialization or update.
5078 // This has to happen before we create attributes.
5079 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
5080 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
5081
5082 for (Instruction &I : instructions(&F)) {
5083 bool IsInterestingOpcode = false;
5084
5085 // To allow easy access to all instructions in a function with a given
5086 // opcode we store them in the InfoCache. As not all opcodes are interesting
5087 // to concrete attributes we only cache the ones that are as identified in
5088 // the following switch.
5089 // Note: There are no concrete attributes now so this is initially empty.
5090 switch (I.getOpcode()) {
5091 default:
5092 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
5093 "New call site/base instruction type needs to be known int the "
5094 "Attributor.");
5095 break;
5096 case Instruction::Load:
5097 // The alignment of a pointer is interesting for loads.
5098 case Instruction::Store:
5099 // The alignment of a pointer is interesting for stores.
5100 case Instruction::Call:
5101 case Instruction::CallBr:
5102 case Instruction::Invoke:
5103 case Instruction::CleanupRet:
5104 case Instruction::CatchSwitch:
5105 case Instruction::Resume:
5106 case Instruction::Ret:
5107 IsInterestingOpcode = true;
5108 }
5109 if (IsInterestingOpcode)
5110 InstOpcodeMap[I.getOpcode()].push_back(&I);
5111 if (I.mayReadOrWriteMemory())
5112 ReadOrWriteInsts.push_back(&I);
5113 }
5114}
5115
Johannes Doerfert12173e62019-10-13 20:25:25 -05005116void Attributor::recordDependence(const AbstractAttribute &FromAA,
5117 const AbstractAttribute &ToAA) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005118 if (FromAA.getState().isAtFixpoint())
5119 return;
5120
5121 QueryMap[&FromAA].insert(const_cast<AbstractAttribute *>(&ToAA));
5122 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05005123}
5124
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005125void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00005126 if (!VisitedFunctions.insert(&F).second)
5127 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05005128 if (F.isDeclaration())
5129 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005130
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005131 IRPosition FPos = IRPosition::function(F);
5132
Johannes Doerfert305b9612019-08-04 18:40:01 +00005133 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00005134 // We need dead instruction detection because we do not want to deal with
5135 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005136 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00005137
5138 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005139 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00005140
Stefan Stipanovic53605892019-06-27 11:27:54 +00005141 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005142 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00005143
Stefan Stipanovic06263672019-07-11 21:37:40 +00005144 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005145 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00005146
Hideto Ueno65bbaf92019-07-12 17:38:51 +00005147 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005148 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00005149
Johannes Doerferte83f3032019-08-05 23:22:05 +00005150 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005151 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00005152
Hideto Ueno63f60662019-09-21 15:13:19 +00005153 // Every function might be "no-recurse".
5154 getOrCreateAAFor<AANoRecurse>(FPos);
5155
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005156 // Every function might be "readnone/readonly/writeonly/...".
5157 getOrCreateAAFor<AAMemoryBehavior>(FPos);
5158
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005159 // Every function might be applicable for Heap-To-Stack conversion.
5160 if (EnableHeapToStack)
5161 getOrCreateAAFor<AAHeapToStack>(FPos);
5162
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00005163 // Return attributes are only appropriate if the return type is non void.
5164 Type *ReturnType = F.getReturnType();
5165 if (!ReturnType->isVoidTy()) {
5166 // Argument attribute "returned" --- Create only one per function even
5167 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005168 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00005169
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005170 IRPosition RetPos = IRPosition::returned(F);
5171
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005172 // Every returned value might be dead.
5173 getOrCreateAAFor<AAIsDead>(RetPos);
5174
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005175 // Every function might be simplified.
5176 getOrCreateAAFor<AAValueSimplify>(RetPos);
5177
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005178 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005179
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005180 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005181 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005182
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005183 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005184 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005185
5186 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005187 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005188
5189 // Every function with pointer return type might be marked
5190 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005191 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005192 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00005193 }
5194
Hideto Ueno54869ec2019-07-15 06:49:04 +00005195 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005196 IRPosition ArgPos = IRPosition::argument(Arg);
5197
5198 // Every argument might be simplified.
5199 getOrCreateAAFor<AAValueSimplify>(ArgPos);
5200
Hideto Ueno19c07af2019-07-23 08:16:17 +00005201 if (Arg.getType()->isPointerTy()) {
5202 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005203 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005204
Hideto Uenocbab3342019-08-29 05:52:00 +00005205 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005206 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00005207
Hideto Ueno19c07af2019-07-23 08:16:17 +00005208 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005209 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005210
5211 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005212 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005213
5214 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005215 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005216
5217 // Every argument with pointer type might be marked
5218 // "readnone/readonly/writeonly/..."
5219 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005220 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00005221 }
5222
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005223 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005224 CallSite CS(&I);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005225 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05005226 // Skip declerations except if annotations on their call sites were
5227 // explicitly requested.
5228 if (!AnnotateDeclarationCallSites && Callee->isDeclaration())
5229 return true;
5230
5231 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005232 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
5233
5234 // Call site return values might be dead.
5235 getOrCreateAAFor<AAIsDead>(CSRetPos);
5236 }
5237
5238 for (int i = 0, e = Callee->arg_size(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005239
5240 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
5241
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005242 // Every call site argument might be dead.
5243 getOrCreateAAFor<AAIsDead>(CSArgPos);
5244
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005245 // Call site argument might be simplified.
5246 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
5247
Hideto Ueno54869ec2019-07-15 06:49:04 +00005248 if (!CS.getArgument(i)->getType()->isPointerTy())
5249 continue;
5250
5251 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005252 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005253
Hideto Uenocbab3342019-08-29 05:52:00 +00005254 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005255 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00005256
Hideto Ueno19c07af2019-07-23 08:16:17 +00005257 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005258 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005259
5260 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005261 getOrCreateAAFor<AAAlign>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00005262 }
5263 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005264 return true;
5265 };
5266
5267 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
5268 bool Success, AnyDead = false;
5269 Success = checkForAllInstructionsImpl(
5270 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
5271 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
5272 (unsigned)Instruction::Call});
5273 (void)Success;
5274 assert(Success && !AnyDead && "Expected the check call to be successful!");
5275
5276 auto LoadStorePred = [&](Instruction &I) -> bool {
5277 if (isa<LoadInst>(I))
5278 getOrCreateAAFor<AAAlign>(
5279 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
5280 else
5281 getOrCreateAAFor<AAAlign>(
5282 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
5283 return true;
5284 };
5285 Success = checkForAllInstructionsImpl(
5286 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
5287 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
5288 (void)Success;
5289 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00005290}
5291
5292/// Helpers to ease debugging through output streams and print calls.
5293///
5294///{
5295raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
5296 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
5297}
5298
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005299raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005300 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005301 case IRPosition::IRP_INVALID:
5302 return OS << "inv";
5303 case IRPosition::IRP_FLOAT:
5304 return OS << "flt";
5305 case IRPosition::IRP_RETURNED:
5306 return OS << "fn_ret";
5307 case IRPosition::IRP_CALL_SITE_RETURNED:
5308 return OS << "cs_ret";
5309 case IRPosition::IRP_FUNCTION:
5310 return OS << "fn";
5311 case IRPosition::IRP_CALL_SITE:
5312 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005313 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00005314 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005315 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00005316 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00005317 }
5318 llvm_unreachable("Unknown attribute position!");
5319}
5320
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005321raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005322 const Value &AV = Pos.getAssociatedValue();
5323 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005324 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
5325}
5326
Johannes Doerfert1a746452019-10-20 22:28:49 -05005327template <typename base_ty, base_ty BestState, base_ty WorstState>
5328raw_ostream &llvm::
5329operator<<(raw_ostream &OS,
5330 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00005331 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
5332 << static_cast<const AbstractState &>(S);
5333}
5334
Johannes Doerfertaade7822019-06-05 03:02:24 +00005335raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
5336 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
5337}
5338
5339raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
5340 AA.print(OS);
5341 return OS;
5342}
5343
5344void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005345 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
5346 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00005347}
5348///}
5349
5350/// ----------------------------------------------------------------------------
5351/// Pass (Manager) Boilerplate
5352/// ----------------------------------------------------------------------------
5353
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005354static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005355 if (DisableAttributor)
5356 return false;
5357
5358 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
5359 << " functions.\n");
5360
5361 // Create an Attributor and initially empty information cache that is filled
5362 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00005363 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005364 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005365
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005366 for (Function &F : M)
5367 A.initializeInformationCache(F);
5368
Johannes Doerfertaade7822019-06-05 03:02:24 +00005369 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005370 if (F.hasExactDefinition())
5371 NumFnWithExactDefinition++;
5372 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00005373 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005374
Johannes Doerfert2f622062019-09-04 16:35:20 +00005375 // We look at internal functions only on-demand but if any use is not a
5376 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00005377 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00005378 if (llvm::all_of(F.uses(), [](const Use &U) {
5379 return ImmutableCallSite(U.getUser()) &&
5380 ImmutableCallSite(U.getUser()).isCallee(&U);
5381 }))
5382 continue;
5383 }
5384
Johannes Doerfertaade7822019-06-05 03:02:24 +00005385 // Populate the Attributor with abstract attribute opportunities in the
5386 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005387 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005388 }
5389
Johannes Doerfert2f622062019-09-04 16:35:20 +00005390 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005391}
5392
5393PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00005394 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005395 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005396 // FIXME: Think about passes we will preserve and add them here.
5397 return PreservedAnalyses::none();
5398 }
5399 return PreservedAnalyses::all();
5400}
5401
5402namespace {
5403
5404struct AttributorLegacyPass : public ModulePass {
5405 static char ID;
5406
5407 AttributorLegacyPass() : ModulePass(ID) {
5408 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
5409 }
5410
5411 bool runOnModule(Module &M) override {
5412 if (skipModule(M))
5413 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005414
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005415 AnalysisGetter AG;
5416 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005417 }
5418
5419 void getAnalysisUsage(AnalysisUsage &AU) const override {
5420 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005421 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005422 }
5423};
5424
5425} // end anonymous namespace
5426
5427Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
5428
5429char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005430
5431const char AAReturnedValues::ID = 0;
5432const char AANoUnwind::ID = 0;
5433const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00005434const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005435const char AANonNull::ID = 0;
5436const char AANoRecurse::ID = 0;
5437const char AAWillReturn::ID = 0;
5438const char AANoAlias::ID = 0;
5439const char AANoReturn::ID = 0;
5440const char AAIsDead::ID = 0;
5441const char AADereferenceable::ID = 0;
5442const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005443const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005444const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005445const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005446const char AAMemoryBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005447
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005448// Macro magic to create the static generator function for attributes that
5449// follow the naming scheme.
5450
5451#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
5452 case IRPosition::PK: \
5453 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
5454
5455#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
5456 case IRPosition::PK: \
5457 AA = new CLASS##SUFFIX(IRP); \
5458 break;
5459
5460#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5461 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5462 CLASS *AA = nullptr; \
5463 switch (IRP.getPositionKind()) { \
5464 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5465 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5466 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5467 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5468 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5469 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5470 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5471 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5472 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005473 return *AA; \
5474 }
5475
5476#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5477 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5478 CLASS *AA = nullptr; \
5479 switch (IRP.getPositionKind()) { \
5480 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5481 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
5482 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5483 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5484 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5485 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5486 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5487 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5488 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005489 return *AA; \
5490 }
5491
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005492#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5493 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5494 CLASS *AA = nullptr; \
5495 switch (IRP.getPositionKind()) { \
5496 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5497 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5498 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5499 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5500 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5501 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5502 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5503 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5504 } \
5505 return *AA; \
5506 }
5507
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005508#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5509 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5510 CLASS *AA = nullptr; \
5511 switch (IRP.getPositionKind()) { \
5512 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5513 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5514 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5515 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5516 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5517 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5518 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5519 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5520 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005521 return *AA; \
5522 }
5523
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005524#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5525 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5526 CLASS *AA = nullptr; \
5527 switch (IRP.getPositionKind()) { \
5528 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5529 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5530 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5531 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5532 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5533 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5534 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5535 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5536 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005537 return *AA; \
5538 }
5539
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005540CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
5541CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
5542CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
5543CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
5544CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
5545CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005546CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
5547
5548CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
5549CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
5550CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
5551CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005552CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005553
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005554CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005555CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005556
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005557CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
5558
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005559CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
5560
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005561#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005562#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005563#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005564#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005565#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005566#undef SWITCH_PK_CREATE
5567#undef SWITCH_PK_INV
5568
Johannes Doerfertaade7822019-06-05 03:02:24 +00005569INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
5570 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005571INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00005572INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
5573 "Deduce and propagate attributes", false, false)