blob: 366c347daeb1e031c04a77537e5ea745f5ff7b3f [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"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080034#include "llvm/InitializePasses.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000035#include "llvm/Support/CommandLine.h"
36#include "llvm/Support/Debug.h"
37#include "llvm/Support/raw_ostream.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000038#include "llvm/Transforms/Utils/BasicBlockUtils.h"
39#include "llvm/Transforms/Utils/Local.h"
40
Johannes Doerfertaade7822019-06-05 03:02:24 +000041#include <cassert>
42
43using namespace llvm;
44
45#define DEBUG_TYPE "attributor"
46
47STATISTIC(NumFnWithExactDefinition,
48 "Number of function with exact definitions");
49STATISTIC(NumFnWithoutExactDefinition,
50 "Number of function without exact definitions");
51STATISTIC(NumAttributesTimedOut,
52 "Number of abstract attributes timed out before fixpoint");
53STATISTIC(NumAttributesValidFixpoint,
54 "Number of abstract attributes in a valid fixpoint state");
55STATISTIC(NumAttributesManifested,
56 "Number of abstract attributes manifested in IR");
Johannes Doerfert680f6382019-11-02 02:48:05 -050057STATISTIC(NumAttributesFixedDueToRequiredDependences,
58 "Number of abstract attributes fixed due to required dependences");
Johannes Doerfertaade7822019-06-05 03:02:24 +000059
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000060// Some helper macros to deal with statistics tracking.
61//
62// Usage:
63// For simple IR attribute tracking overload trackStatistics in the abstract
Johannes Doerfert17b578b2019-08-14 21:46:25 +000064// attribute and choose the right STATS_DECLTRACK_********* macro,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000065// e.g.,:
66// void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +000067// STATS_DECLTRACK_ARG_ATTR(returned)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000068// }
69// If there is a single "increment" side one can use the macro
Johannes Doerfert17b578b2019-08-14 21:46:25 +000070// STATS_DECLTRACK with a custom message. If there are multiple increment
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000071// sides, STATS_DECL and STATS_TRACK can also be used separatly.
72//
73#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
74 ("Number of " #TYPE " marked '" #NAME "'")
75#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
Johannes Doerferta7a3b3a2019-09-04 19:01:08 +000076#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
77#define STATS_DECL(NAME, TYPE, MSG) \
78 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000079#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
Johannes Doerfert17b578b2019-08-14 21:46:25 +000080#define STATS_DECLTRACK(NAME, TYPE, MSG) \
Johannes Doerfert169af992019-08-20 06:09:56 +000081 { \
82 STATS_DECL(NAME, TYPE, MSG) \
83 STATS_TRACK(NAME, TYPE) \
84 }
Johannes Doerfert17b578b2019-08-14 21:46:25 +000085#define STATS_DECLTRACK_ARG_ATTR(NAME) \
86 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
87#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
88 STATS_DECLTRACK(NAME, CSArguments, \
89 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
90#define STATS_DECLTRACK_FN_ATTR(NAME) \
91 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
92#define STATS_DECLTRACK_CS_ATTR(NAME) \
93 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
94#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
95 STATS_DECLTRACK(NAME, FunctionReturn, \
Johannes Doerfert2db85282019-08-21 20:56:56 +000096 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
Johannes Doerfert17b578b2019-08-14 21:46:25 +000097#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
98 STATS_DECLTRACK(NAME, CSReturn, \
99 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
100#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
101 STATS_DECLTRACK(NAME, Floating, \
102 ("Number of floating values known to be '" #NAME "'"))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000103
Johannes Doerfertaade7822019-06-05 03:02:24 +0000104// TODO: Determine a good default value.
105//
106// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
107// (when run with the first 5 abstract attributes). The results also indicate
108// that we never reach 32 iterations but always find a fixpoint sooner.
109//
110// This will become more evolved once we perform two interleaved fixpoint
111// iterations: bottom-up and top-down.
112static cl::opt<unsigned>
113 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
114 cl::desc("Maximal number of fixpoint iterations."),
115 cl::init(32));
Johannes Doerfertb504eb82019-08-26 18:55:47 +0000116static cl::opt<bool> VerifyMaxFixpointIterations(
117 "attributor-max-iterations-verify", cl::Hidden,
118 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
119 cl::init(false));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000120
121static cl::opt<bool> DisableAttributor(
122 "attributor-disable", cl::Hidden,
123 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +0000124 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000125
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500126static cl::opt<bool> AnnotateDeclarationCallSites(
127 "attributor-annotate-decl-cs", cl::Hidden,
128 cl::desc("Annoate call sites of function declarations."), cl::init(false));
129
Johannes Doerfert7516a5e2019-09-03 20:37:24 +0000130static cl::opt<bool> ManifestInternal(
131 "attributor-manifest-internal", cl::Hidden,
132 cl::desc("Manifest Attributor internal string attributes."),
133 cl::init(false));
134
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000135static cl::opt<unsigned> DepRecInterval(
136 "attributor-dependence-recompute-interval", cl::Hidden,
137 cl::desc("Number of iterations until dependences are recomputed."),
138 cl::init(4));
139
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000140static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
141 cl::init(true), cl::Hidden);
142
Johannes Doerfert1c2afae2019-10-10 05:34:21 +0000143static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
144 cl::Hidden);
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000145
Johannes Doerfertaade7822019-06-05 03:02:24 +0000146/// Logic operators for the change status enum class.
147///
148///{
149ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
150 return l == ChangeStatus::CHANGED ? l : r;
151}
152ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
153 return l == ChangeStatus::UNCHANGED ? l : r;
154}
155///}
156
Johannes Doerfertdef99282019-08-14 21:29:37 +0000157/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000158/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000159/// with the "returned" attribute. Once we cannot look through the value any
160/// further, the callback \p VisitValueCB is invoked and passed the current
161/// value, the \p State, and a flag to indicate if we stripped anything. To
162/// limit how much effort is invested, we will never visit more values than
163/// specified by \p MaxValues.
164template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000165static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000166 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000167 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000168 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000169
Johannes Doerfertdef99282019-08-14 21:29:37 +0000170 const AAIsDead *LivenessAA = nullptr;
171 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000172 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000173 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
174 /* TrackDependence */ false);
175 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000176
177 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000178 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000179 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000180 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000181
182 int Iteration = 0;
183 do {
184 Value *V = Worklist.pop_back_val();
185
186 // Check if we should process the current value. To prevent endless
187 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000188 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000189 continue;
190
191 // Make sure we limit the compile time for complex expressions.
192 if (Iteration++ >= MaxValues)
193 return false;
194
195 // Explicitly look through calls with a "returned" attribute if we do
196 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000197 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000198 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000199 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000200 } else {
201 CallSite CS(V);
202 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000203 for (Argument &Arg : CS.getCalledFunction()->args())
204 if (Arg.hasReturnedAttr()) {
205 NewV = CS.getArgOperand(Arg.getArgNo());
206 break;
207 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000208 }
209 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000210 if (NewV && NewV != V) {
211 Worklist.push_back(NewV);
212 continue;
213 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000214
215 // Look through select instructions, visit both potential values.
216 if (auto *SI = dyn_cast<SelectInst>(V)) {
217 Worklist.push_back(SI->getTrueValue());
218 Worklist.push_back(SI->getFalseValue());
219 continue;
220 }
221
Johannes Doerfertdef99282019-08-14 21:29:37 +0000222 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000223 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000224 assert(LivenessAA &&
225 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000226 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
227 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000228 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000229 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000230 continue;
231 }
232 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000233 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000234 continue;
235 }
236
237 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000238 if (!VisitValueCB(*V, State, Iteration > 1))
239 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000240 } while (!Worklist.empty());
241
Johannes Doerfert19b00432019-08-26 17:48:05 +0000242 // If we actually used liveness information so we have to record a dependence.
243 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -0500244 A.recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000245
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000246 // All values have been visited.
247 return true;
248}
249
Johannes Doerfertaade7822019-06-05 03:02:24 +0000250/// Return true if \p New is equal or worse than \p Old.
251static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
252 if (!Old.isIntAttribute())
253 return true;
254
255 return Old.getValueAsInt() >= New.getValueAsInt();
256}
257
258/// Return true if the information provided by \p Attr was added to the
259/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000260/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000261static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000262 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000263
264 if (Attr.isEnumAttribute()) {
265 Attribute::AttrKind Kind = Attr.getKindAsEnum();
266 if (Attrs.hasAttribute(AttrIdx, Kind))
267 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
268 return false;
269 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
270 return true;
271 }
272 if (Attr.isStringAttribute()) {
273 StringRef Kind = Attr.getKindAsString();
274 if (Attrs.hasAttribute(AttrIdx, Kind))
275 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
276 return false;
277 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
278 return true;
279 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000280 if (Attr.isIntAttribute()) {
281 Attribute::AttrKind Kind = Attr.getKindAsEnum();
282 if (Attrs.hasAttribute(AttrIdx, Kind))
283 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
284 return false;
285 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
286 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
287 return true;
288 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000289
290 llvm_unreachable("Expected enum or string attribute!");
291}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000292static const Value *getPointerOperand(const Instruction *I) {
293 if (auto *LI = dyn_cast<LoadInst>(I))
294 if (!LI->isVolatile())
295 return LI->getPointerOperand();
296
297 if (auto *SI = dyn_cast<StoreInst>(I))
298 if (!SI->isVolatile())
299 return SI->getPointerOperand();
300
301 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I))
302 if (!CXI->isVolatile())
303 return CXI->getPointerOperand();
304
305 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I))
306 if (!RMWI->isVolatile())
307 return RMWI->getPointerOperand();
308
309 return nullptr;
310}
311static const Value *getBasePointerOfAccessPointerOperand(const Instruction *I,
312 int64_t &BytesOffset,
313 const DataLayout &DL) {
314 const Value *Ptr = getPointerOperand(I);
315 if (!Ptr)
316 return nullptr;
317
318 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
319 /*AllowNonInbounds*/ false);
320}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000321
Johannes Doerfertece81902019-08-12 22:05:53 +0000322ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000323 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
324 if (getState().isAtFixpoint())
325 return HasChanged;
326
327 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
328
Johannes Doerfertece81902019-08-12 22:05:53 +0000329 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000330
331 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
332 << "\n");
333
334 return HasChanged;
335}
336
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000337ChangeStatus
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500338IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000339 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000340 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000341 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000342
Johannes Doerfertaade7822019-06-05 03:02:24 +0000343 // In the following some generic code that will manifest attributes in
344 // DeducedAttrs if they improve the current IR. Due to the different
345 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000346
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000347 AttributeList Attrs;
348 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000349 case IRPosition::IRP_INVALID:
350 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000351 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000352 case IRPosition::IRP_ARGUMENT:
353 case IRPosition::IRP_FUNCTION:
354 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000355 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000356 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000357 case IRPosition::IRP_CALL_SITE:
358 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000359 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000360 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000361 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000362 }
363
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000364 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000365 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000366 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000367 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000368 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000369
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000370 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000371 }
372
373 if (HasChanged == ChangeStatus::UNCHANGED)
374 return HasChanged;
375
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000376 switch (PK) {
377 case IRPosition::IRP_ARGUMENT:
378 case IRPosition::IRP_FUNCTION:
379 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000380 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000381 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000382 case IRPosition::IRP_CALL_SITE:
383 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000384 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000385 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000386 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000387 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000388 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000389 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000390 }
391
392 return HasChanged;
393}
394
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000395const IRPosition IRPosition::EmptyKey(255);
396const IRPosition IRPosition::TombstoneKey(256);
397
398SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
399 IRPositions.emplace_back(IRP);
400
401 ImmutableCallSite ICS(&IRP.getAnchorValue());
402 switch (IRP.getPositionKind()) {
403 case IRPosition::IRP_INVALID:
404 case IRPosition::IRP_FLOAT:
405 case IRPosition::IRP_FUNCTION:
406 return;
407 case IRPosition::IRP_ARGUMENT:
408 case IRPosition::IRP_RETURNED:
409 IRPositions.emplace_back(
410 IRPosition::function(*IRP.getAssociatedFunction()));
411 return;
412 case IRPosition::IRP_CALL_SITE:
413 assert(ICS && "Expected call site!");
414 // TODO: We need to look at the operand bundles similar to the redirection
415 // in CallBase.
416 if (!ICS.hasOperandBundles())
417 if (const Function *Callee = ICS.getCalledFunction())
418 IRPositions.emplace_back(IRPosition::function(*Callee));
419 return;
420 case IRPosition::IRP_CALL_SITE_RETURNED:
421 assert(ICS && "Expected call site!");
422 // TODO: We need to look at the operand bundles similar to the redirection
423 // in CallBase.
424 if (!ICS.hasOperandBundles()) {
425 if (const Function *Callee = ICS.getCalledFunction()) {
426 IRPositions.emplace_back(IRPosition::returned(*Callee));
427 IRPositions.emplace_back(IRPosition::function(*Callee));
428 }
429 }
430 IRPositions.emplace_back(
431 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
432 return;
433 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
434 int ArgNo = IRP.getArgNo();
435 assert(ICS && ArgNo >= 0 && "Expected call site!");
436 // TODO: We need to look at the operand bundles similar to the redirection
437 // in CallBase.
438 if (!ICS.hasOperandBundles()) {
439 const Function *Callee = ICS.getCalledFunction();
440 if (Callee && Callee->arg_size() > unsigned(ArgNo))
441 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
442 if (Callee)
443 IRPositions.emplace_back(IRPosition::function(*Callee));
444 }
445 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
446 return;
447 }
448 }
449}
450
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000451bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
452 bool IgnoreSubsumingPositions) const {
453 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000454 for (Attribute::AttrKind AK : AKs)
455 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
456 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000457 // The first position returned by the SubsumingPositionIterator is
458 // always the position itself. If we ignore subsuming positions we
459 // are done after the first iteration.
460 if (IgnoreSubsumingPositions)
461 break;
462 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000463 return false;
464}
465
466void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
467 SmallVectorImpl<Attribute> &Attrs) const {
468 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this))
469 for (Attribute::AttrKind AK : AKs) {
470 const Attribute &Attr = EquivIRP.getAttr(AK);
471 if (Attr.getKindAsEnum() == AK)
472 Attrs.push_back(Attr);
473 }
474}
475
476void IRPosition::verify() {
477 switch (KindOrArgNo) {
478 default:
479 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
480 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
481 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000482 if (isa<Argument>(AnchorVal)) {
483 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000484 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000485 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
486 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000487 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000488 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000489 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000490 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
491 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000492 "Associated value mismatch!");
493 }
494 break;
495 case IRP_INVALID:
496 assert(!AnchorVal && "Expected no value for an invalid position!");
497 break;
498 case IRP_FLOAT:
499 assert((!isa<CallBase>(&getAssociatedValue()) &&
500 !isa<Argument>(&getAssociatedValue())) &&
501 "Expected specialized kind for call base and argument values!");
502 break;
503 case IRP_RETURNED:
504 assert(isa<Function>(AnchorVal) &&
505 "Expected function for a 'returned' position!");
506 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
507 break;
508 case IRP_CALL_SITE_RETURNED:
509 assert((isa<CallBase>(AnchorVal)) &&
510 "Expected call base for 'call site returned' position!");
511 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
512 break;
513 case IRP_CALL_SITE:
514 assert((isa<CallBase>(AnchorVal)) &&
515 "Expected call base for 'call site function' position!");
516 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
517 break;
518 case IRP_FUNCTION:
519 assert(isa<Function>(AnchorVal) &&
520 "Expected function for a 'function' position!");
521 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
522 break;
523 }
524}
525
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000526namespace {
Johannes Doerfert1a746452019-10-20 22:28:49 -0500527/// Helper function to clamp a state \p S of type \p StateType with the
Johannes Doerfert234eda52019-08-16 19:51:23 +0000528/// information in \p R and indicate/return if \p S did change (as-in update is
529/// required to be run again).
Johannes Doerfert234eda52019-08-16 19:51:23 +0000530template <typename StateType>
Johannes Doerfert1a746452019-10-20 22:28:49 -0500531ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000532 auto Assumed = S.getAssumed();
533 S ^= R;
534 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
535 : ChangeStatus::CHANGED;
536}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000537
Johannes Doerfert234eda52019-08-16 19:51:23 +0000538/// Clamp the information known for all returned values of a function
539/// (identified by \p QueryingAA) into \p S.
540template <typename AAType, typename StateType = typename AAType::StateType>
541static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
542 StateType &S) {
543 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
544 << static_cast<const AbstractAttribute &>(QueryingAA)
545 << " into " << S << "\n");
546
547 assert((QueryingAA.getIRPosition().getPositionKind() ==
548 IRPosition::IRP_RETURNED ||
549 QueryingAA.getIRPosition().getPositionKind() ==
550 IRPosition::IRP_CALL_SITE_RETURNED) &&
551 "Can only clamp returned value states for a function returned or call "
552 "site returned position!");
553
554 // Use an optional state as there might not be any return values and we want
555 // to join (IntegerState::operator&) the state of all there are.
556 Optional<StateType> T;
557
558 // Callback for each possibly returned value.
559 auto CheckReturnValue = [&](Value &RV) -> bool {
560 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000561 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
562 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
563 << " @ " << RVPos << "\n");
564 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000565 if (T.hasValue())
566 *T &= AAS;
567 else
568 T = AAS;
569 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
570 << "\n");
571 return T->isValidState();
572 };
573
574 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
575 S.indicatePessimisticFixpoint();
576 else if (T.hasValue())
577 S ^= *T;
578}
579
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000580/// Helper class to compose two generic deduction
581template <typename AAType, typename Base, typename StateType,
582 template <typename...> class F, template <typename...> class G>
583struct AAComposeTwoGenericDeduction
584 : public F<AAType, G<AAType, Base, StateType>, StateType> {
585 AAComposeTwoGenericDeduction(const IRPosition &IRP)
586 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
587
588 /// See AbstractAttribute::updateImpl(...).
589 ChangeStatus updateImpl(Attributor &A) override {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100590 ChangeStatus ChangedF =
591 F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000592 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
593 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000594 }
595};
596
Johannes Doerfert234eda52019-08-16 19:51:23 +0000597/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000598template <typename AAType, typename Base,
599 typename StateType = typename AAType::StateType>
600struct AAReturnedFromReturnedValues : public Base {
601 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000602
603 /// See AbstractAttribute::updateImpl(...).
604 ChangeStatus updateImpl(Attributor &A) override {
605 StateType S;
606 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000607 // TODO: If we know we visited all returned values, thus no are assumed
608 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000609 return clampStateAndIndicateChange<StateType>(this->getState(), S);
610 }
611};
612
613/// Clamp the information known at all call sites for a given argument
614/// (identified by \p QueryingAA) into \p S.
615template <typename AAType, typename StateType = typename AAType::StateType>
616static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
617 StateType &S) {
618 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
619 << static_cast<const AbstractAttribute &>(QueryingAA)
620 << " into " << S << "\n");
621
622 assert(QueryingAA.getIRPosition().getPositionKind() ==
623 IRPosition::IRP_ARGUMENT &&
624 "Can only clamp call site argument states for an argument position!");
625
626 // Use an optional state as there might not be any return values and we want
627 // to join (IntegerState::operator&) the state of all there are.
628 Optional<StateType> T;
629
630 // The argument number which is also the call site argument number.
631 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
632
Johannes Doerfert661db042019-10-07 23:14:58 +0000633 auto CallSiteCheck = [&](AbstractCallSite ACS) {
634 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
635 // Check if a coresponding argument was found or if it is on not associated
636 // (which can happen for callback calls).
637 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
638 return false;
639
640 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
641 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
642 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000643 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000644 if (T.hasValue())
645 *T &= AAS;
646 else
647 T = AAS;
648 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
649 << "\n");
650 return T->isValidState();
651 };
652
653 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true))
654 S.indicatePessimisticFixpoint();
655 else if (T.hasValue())
656 S ^= *T;
657}
658
659/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000660template <typename AAType, typename Base,
661 typename StateType = typename AAType::StateType>
662struct AAArgumentFromCallSiteArguments : public Base {
663 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000664
665 /// See AbstractAttribute::updateImpl(...).
666 ChangeStatus updateImpl(Attributor &A) override {
667 StateType S;
668 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000669 // TODO: If we know we visited all incoming values, thus no are assumed
670 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000671 return clampStateAndIndicateChange<StateType>(this->getState(), S);
672 }
673};
674
675/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000676template <typename AAType, typename Base,
677 typename StateType = typename AAType::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000678struct AACallSiteReturnedFromReturned : public Base {
679 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000680
681 /// See AbstractAttribute::updateImpl(...).
682 ChangeStatus updateImpl(Attributor &A) override {
683 assert(this->getIRPosition().getPositionKind() ==
684 IRPosition::IRP_CALL_SITE_RETURNED &&
685 "Can only wrap function returned positions for call site returned "
686 "positions!");
687 auto &S = this->getState();
688
689 const Function *AssociatedFunction =
690 this->getIRPosition().getAssociatedFunction();
691 if (!AssociatedFunction)
692 return S.indicatePessimisticFixpoint();
693
694 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000695 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000696 return clampStateAndIndicateChange(
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000697 S, static_cast<const typename AAType::StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000698 }
699};
700
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000701/// Helper class for generic deduction using must-be-executed-context
702/// Base class is required to have `followUse` method.
703
704/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000705/// U - Underlying use.
706/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000707/// `followUse` returns true if the value should be tracked transitively.
708
709template <typename AAType, typename Base,
710 typename StateType = typename AAType::StateType>
711struct AAFromMustBeExecutedContext : public Base {
712 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
713
714 void initialize(Attributor &A) override {
715 Base::initialize(A);
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500716 const IRPosition &IRP = this->getIRPosition();
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000717 Instruction *CtxI = IRP.getCtxI();
718
719 if (!CtxI)
720 return;
721
722 for (const Use &U : IRP.getAssociatedValue().uses())
723 Uses.insert(&U);
724 }
725
726 /// See AbstractAttribute::updateImpl(...).
727 ChangeStatus updateImpl(Attributor &A) override {
728 auto BeforeState = this->getState();
729 auto &S = this->getState();
730 Instruction *CtxI = this->getIRPosition().getCtxI();
731 if (!CtxI)
732 return ChangeStatus::UNCHANGED;
733
734 MustBeExecutedContextExplorer &Explorer =
735 A.getInfoCache().getMustBeExecutedContextExplorer();
736
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500737 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100738 for (unsigned u = 0; u < Uses.size(); ++u) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500739 const Use *U = Uses[u];
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000740 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500741 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000742 if (Found && Base::followUse(A, U, UserI))
743 for (const Use &Us : UserI->uses())
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500744 Uses.insert(&Us);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000745 }
746 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000747
748 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
749 }
750
751private:
752 /// Container for (transitive) uses of the associated value.
753 SetVector<const Use *> Uses;
754};
755
756template <typename AAType, typename Base,
757 typename StateType = typename AAType::StateType>
758using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
759 AAComposeTwoGenericDeduction<AAType, Base, StateType,
760 AAFromMustBeExecutedContext,
761 AAArgumentFromCallSiteArguments>;
762
763template <typename AAType, typename Base,
764 typename StateType = typename AAType::StateType>
765using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
766 AAComposeTwoGenericDeduction<AAType, Base, StateType,
767 AAFromMustBeExecutedContext,
768 AACallSiteReturnedFromReturned>;
769
Stefan Stipanovic53605892019-06-27 11:27:54 +0000770/// -----------------------NoUnwind Function Attribute--------------------------
771
Johannes Doerfert344d0382019-08-07 22:34:26 +0000772struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000773 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000774
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000775 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000776 return getAssumed() ? "nounwind" : "may-unwind";
777 }
778
779 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000780 ChangeStatus updateImpl(Attributor &A) override {
781 auto Opcodes = {
782 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
783 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
784 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
785
786 auto CheckForNoUnwind = [&](Instruction &I) {
787 if (!I.mayThrow())
788 return true;
789
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000790 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
791 const auto &NoUnwindAA =
792 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
793 return NoUnwindAA.isAssumedNoUnwind();
794 }
795 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000796 };
797
798 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
799 return indicatePessimisticFixpoint();
800
801 return ChangeStatus::UNCHANGED;
802 }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000803};
804
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000805struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000806 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000807
808 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000809 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000810};
811
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000812/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000813struct AANoUnwindCallSite final : AANoUnwindImpl {
814 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
815
816 /// See AbstractAttribute::initialize(...).
817 void initialize(Attributor &A) override {
818 AANoUnwindImpl::initialize(A);
819 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000820 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000821 indicatePessimisticFixpoint();
822 }
823
824 /// See AbstractAttribute::updateImpl(...).
825 ChangeStatus updateImpl(Attributor &A) override {
826 // TODO: Once we have call site specific value information we can provide
827 // call site specific liveness information and then it makes
828 // sense to specialize attributes for call sites arguments instead of
829 // redirecting requests to the callee argument.
830 Function *F = getAssociatedFunction();
831 const IRPosition &FnPos = IRPosition::function(*F);
832 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
833 return clampStateAndIndicateChange(
834 getState(),
835 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
836 }
837
838 /// See AbstractAttribute::trackStatistics()
839 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
840};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000841
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000842/// --------------------- Function Return Values -------------------------------
843
844/// "Attribute" that collects all potential returned values and the return
845/// instructions that they arise from.
846///
847/// If there is a unique returned value R, the manifest method will:
848/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +0000849class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000850
851 /// Mapping of values potentially returned by the associated function to the
852 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +0000853 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000854
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000855 /// Mapping to remember the number of returned values for a call site such
856 /// that we can avoid updates if nothing changed.
857 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
858
859 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +0000860 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000861
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000862 /// State flags
863 ///
864 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000865 bool IsFixed = false;
866 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000867 ///}
868
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000869public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000870 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000871
872 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +0000873 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000874 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000875 IsFixed = false;
876 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000877 ReturnedValues.clear();
878
Johannes Doerfertdef99282019-08-14 21:29:37 +0000879 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000880 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000881 indicatePessimisticFixpoint();
882 return;
883 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000884
885 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000886 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000887
888 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000889 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000890 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000891 auto &ReturnInstSet = ReturnedValues[&Arg];
892 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
893 ReturnInstSet.insert(cast<ReturnInst>(RI));
894
895 indicateOptimisticFixpoint();
896 return;
897 }
898 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000899
900 if (!F->hasExactDefinition())
901 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000902 }
903
904 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000905 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000906
907 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000908 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000909
910 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000911 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000912
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000913 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +0000914 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000915
Johannes Doerfertdef99282019-08-14 21:29:37 +0000916 llvm::iterator_range<iterator> returned_values() override {
917 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
918 }
919
920 llvm::iterator_range<const_iterator> returned_values() const override {
921 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
922 }
923
Johannes Doerfert695089e2019-08-23 15:23:49 +0000924 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000925 return UnresolvedCalls;
926 }
927
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000928 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000929 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000930 return isValidState() ? ReturnedValues.size() : -1;
931 }
932
933 /// Return an assumed unique return value if a single candidate is found. If
934 /// there cannot be one, return a nullptr. If it is not clear yet, return the
935 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000936 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000937
Johannes Doerfert14a04932019-08-07 22:27:24 +0000938 /// See AbstractState::checkForAllReturnedValues(...).
939 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +0000940 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +0000941 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000942
943 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000944 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000945
946 /// See AbstractState::isAtFixpoint().
947 bool isAtFixpoint() const override { return IsFixed; }
948
949 /// See AbstractState::isValidState().
950 bool isValidState() const override { return IsValidState; }
951
952 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000953 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000954 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000955 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000956 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000957
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000958 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000959 IsFixed = true;
960 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000961 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000962 }
963};
964
965ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
966 ChangeStatus Changed = ChangeStatus::UNCHANGED;
967
968 // Bookkeeping.
969 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000970 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
971 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000972
973 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000974 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000975
976 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
977 return Changed;
978
979 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000980 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
981 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000982
Johannes Doerfert23400e612019-08-23 17:41:37 +0000983 // Callback to replace the uses of CB with the constant C.
984 auto ReplaceCallSiteUsersWith = [](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +0000985 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +0000986 return ChangeStatus::UNCHANGED;
987 CB.replaceAllUsesWith(&C);
988 return ChangeStatus::CHANGED;
989 };
990
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000991 // If the assumed unique return value is an argument, annotate it.
992 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500993 // TODO: This should be handled differently!
994 this->AnchorVal = UniqueRVArg;
995 this->KindOrArgNo = UniqueRVArg->getArgNo();
Johannes Doerfert23400e612019-08-23 17:41:37 +0000996 Changed = IRAttribute::manifest(A);
997 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
998 // We can replace the returned value with the unique returned constant.
999 Value &AnchorValue = getAnchorValue();
1000 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
1001 for (const Use &U : F->uses())
1002 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001003 if (CB->isCallee(&U)) {
1004 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001005 CB->getType() == RVC->getType()
1006 ? RVC
1007 : ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001008 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1009 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001010 } else {
1011 assert(isa<CallBase>(AnchorValue) &&
1012 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001013 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001014 AnchorValue.getType() == RVC->getType()
1015 ? RVC
1016 : ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001017 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001018 }
1019 if (Changed == ChangeStatus::CHANGED)
1020 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1021 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001022 }
1023
1024 return Changed;
1025}
1026
1027const std::string AAReturnedValuesImpl::getAsStr() const {
1028 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001029 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001030 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001031}
1032
Johannes Doerfert14a04932019-08-07 22:27:24 +00001033Optional<Value *>
1034AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1035 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001036 // undef values that can also be present, it is assumed to be the actual
1037 // return value and forwarded to the caller of this method. If there are
1038 // multiple, a nullptr is returned indicating there cannot be a unique
1039 // returned value.
1040 Optional<Value *> UniqueRV;
1041
Johannes Doerfert14a04932019-08-07 22:27:24 +00001042 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001043 // If we found a second returned value and neither the current nor the saved
1044 // one is an undef, there is no unique returned value. Undefs are special
1045 // since we can pretend they have any value.
1046 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1047 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1048 UniqueRV = nullptr;
1049 return false;
1050 }
1051
1052 // Do not overwrite a value with an undef.
1053 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1054 UniqueRV = &RV;
1055
1056 return true;
1057 };
1058
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001059 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001060 UniqueRV = nullptr;
1061
1062 return UniqueRV;
1063}
1064
Johannes Doerfert14a04932019-08-07 22:27:24 +00001065bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001066 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001067 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001068 if (!isValidState())
1069 return false;
1070
1071 // Check all returned values but ignore call sites as long as we have not
1072 // encountered an overdefined one during an update.
1073 for (auto &It : ReturnedValues) {
1074 Value *RV = It.first;
1075
Johannes Doerfertdef99282019-08-14 21:29:37 +00001076 CallBase *CB = dyn_cast<CallBase>(RV);
1077 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001078 continue;
1079
Johannes Doerfert695089e2019-08-23 15:23:49 +00001080 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001081 return false;
1082 }
1083
1084 return true;
1085}
1086
Johannes Doerfertece81902019-08-12 22:05:53 +00001087ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001088 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1089 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001090
Johannes Doerfertdef99282019-08-14 21:29:37 +00001091 // State used in the value traversals starting in returned values.
1092 struct RVState {
1093 // The map in which we collect return values -> return instrs.
1094 decltype(ReturnedValues) &RetValsMap;
1095 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001096 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001097 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001098 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001099 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001100
Johannes Doerfertdef99282019-08-14 21:29:37 +00001101 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001102 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001103 auto Size = RVS.RetValsMap[&Val].size();
1104 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1105 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1106 RVS.Changed |= Inserted;
1107 LLVM_DEBUG({
1108 if (Inserted)
1109 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1110 << " => " << RVS.RetInsts.size() << "\n";
1111 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001112 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001113 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001114
Johannes Doerfertdef99282019-08-14 21:29:37 +00001115 // Helper method to invoke the generic value traversal.
1116 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1117 IRPosition RetValPos = IRPosition::value(RV);
1118 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1119 RVS, VisitValueCB);
1120 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001121
Johannes Doerfertdef99282019-08-14 21:29:37 +00001122 // Callback for all "return intructions" live in the associated function.
1123 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1124 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001125 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001126 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001127 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1128 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001129
Johannes Doerfertdef99282019-08-14 21:29:37 +00001130 // Start by discovering returned values from all live returned instructions in
1131 // the associated function.
1132 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1133 return indicatePessimisticFixpoint();
1134
1135 // Once returned values "directly" present in the code are handled we try to
1136 // resolve returned calls.
1137 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001138 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001139 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1140 << " by #" << It.second.size() << " RIs\n");
1141 CallBase *CB = dyn_cast<CallBase>(It.first);
1142 if (!CB || UnresolvedCalls.count(CB))
1143 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001144
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001145 if (!CB->getCalledFunction()) {
1146 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1147 << "\n");
1148 UnresolvedCalls.insert(CB);
1149 continue;
1150 }
1151
1152 // TODO: use the function scope once we have call site AAReturnedValues.
1153 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1154 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001155 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
1156 << static_cast<const AbstractAttribute &>(RetValAA)
1157 << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001158
1159 // Skip dead ends, thus if we do not know anything about the returned
1160 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001161 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001162 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1163 << "\n");
1164 UnresolvedCalls.insert(CB);
1165 continue;
1166 }
1167
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001168 // Do not try to learn partial information. If the callee has unresolved
1169 // return values we will treat the call as unresolved/opaque.
1170 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1171 if (!RetValAAUnresolvedCalls.empty()) {
1172 UnresolvedCalls.insert(CB);
1173 continue;
1174 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001175
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001176 // Now check if we can track transitively returned values. If possible, thus
1177 // if all return value can be represented in the current scope, do so.
1178 bool Unresolved = false;
1179 for (auto &RetValAAIt : RetValAA.returned_values()) {
1180 Value *RetVal = RetValAAIt.first;
1181 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1182 isa<Constant>(RetVal))
1183 continue;
1184 // Anything that did not fit in the above categories cannot be resolved,
1185 // mark the call as unresolved.
1186 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1187 "cannot be translated: "
1188 << *RetVal << "\n");
1189 UnresolvedCalls.insert(CB);
1190 Unresolved = true;
1191 break;
1192 }
1193
1194 if (Unresolved)
1195 continue;
1196
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001197 // Now track transitively returned values.
1198 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1199 if (NumRetAA == RetValAA.getNumReturnValues()) {
1200 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1201 "changed since it was seen last\n");
1202 continue;
1203 }
1204 NumRetAA = RetValAA.getNumReturnValues();
1205
Johannes Doerfertdef99282019-08-14 21:29:37 +00001206 for (auto &RetValAAIt : RetValAA.returned_values()) {
1207 Value *RetVal = RetValAAIt.first;
1208 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1209 // Arguments are mapped to call site operands and we begin the traversal
1210 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001211 bool Unused = false;
1212 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001213 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1214 continue;
1215 } else if (isa<CallBase>(RetVal)) {
1216 // Call sites are resolved by the callee attribute over time, no need to
1217 // do anything for us.
1218 continue;
1219 } else if (isa<Constant>(RetVal)) {
1220 // Constants are valid everywhere, we can simply take them.
1221 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1222 continue;
1223 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001224 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001225 }
1226
Johannes Doerfertdef99282019-08-14 21:29:37 +00001227 // To avoid modifications to the ReturnedValues map while we iterate over it
1228 // we kept record of potential new entries in a copy map, NewRVsMap.
1229 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001230 assert(!It.second.empty() && "Entry does not add anything.");
1231 auto &ReturnInsts = ReturnedValues[It.first];
1232 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001233 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001234 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1235 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001236 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001237 }
1238 }
1239
Johannes Doerfertdef99282019-08-14 21:29:37 +00001240 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1241 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001242}
1243
Johannes Doerfertdef99282019-08-14 21:29:37 +00001244struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1245 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1246
1247 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001248 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001249};
1250
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001251/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001252struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1253 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1254
1255 /// See AbstractAttribute::initialize(...).
1256 void initialize(Attributor &A) override {
1257 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001258 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001259 // sense to specialize attributes for call sites instead of
1260 // redirecting requests to the callee.
1261 llvm_unreachable("Abstract attributes for returned values are not "
1262 "supported for call sites yet!");
1263 }
1264
1265 /// See AbstractAttribute::updateImpl(...).
1266 ChangeStatus updateImpl(Attributor &A) override {
1267 return indicatePessimisticFixpoint();
1268 }
1269
1270 /// See AbstractAttribute::trackStatistics()
1271 void trackStatistics() const override {}
1272};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001273
Stefan Stipanovic06263672019-07-11 21:37:40 +00001274/// ------------------------ NoSync Function Attribute -------------------------
1275
Johannes Doerfert344d0382019-08-07 22:34:26 +00001276struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001277 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001278
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001279 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001280 return getAssumed() ? "nosync" : "may-sync";
1281 }
1282
1283 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001284 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001285
Stefan Stipanovic06263672019-07-11 21:37:40 +00001286 /// Helper function used to determine whether an instruction is non-relaxed
1287 /// atomic. In other words, if an atomic instruction does not have unordered
1288 /// or monotonic ordering
1289 static bool isNonRelaxedAtomic(Instruction *I);
1290
1291 /// Helper function used to determine whether an instruction is volatile.
1292 static bool isVolatile(Instruction *I);
1293
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001294 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1295 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001296 static bool isNoSyncIntrinsic(Instruction *I);
1297};
1298
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001299bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001300 if (!I->isAtomic())
1301 return false;
1302
1303 AtomicOrdering Ordering;
1304 switch (I->getOpcode()) {
1305 case Instruction::AtomicRMW:
1306 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1307 break;
1308 case Instruction::Store:
1309 Ordering = cast<StoreInst>(I)->getOrdering();
1310 break;
1311 case Instruction::Load:
1312 Ordering = cast<LoadInst>(I)->getOrdering();
1313 break;
1314 case Instruction::Fence: {
1315 auto *FI = cast<FenceInst>(I);
1316 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1317 return false;
1318 Ordering = FI->getOrdering();
1319 break;
1320 }
1321 case Instruction::AtomicCmpXchg: {
1322 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1323 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1324 // Only if both are relaxed, than it can be treated as relaxed.
1325 // Otherwise it is non-relaxed.
1326 if (Success != AtomicOrdering::Unordered &&
1327 Success != AtomicOrdering::Monotonic)
1328 return true;
1329 if (Failure != AtomicOrdering::Unordered &&
1330 Failure != AtomicOrdering::Monotonic)
1331 return true;
1332 return false;
1333 }
1334 default:
1335 llvm_unreachable(
1336 "New atomic operations need to be known in the attributor.");
1337 }
1338
1339 // Relaxed.
1340 if (Ordering == AtomicOrdering::Unordered ||
1341 Ordering == AtomicOrdering::Monotonic)
1342 return false;
1343 return true;
1344}
1345
1346/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1347/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001348bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001349 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1350 switch (II->getIntrinsicID()) {
1351 /// Element wise atomic memory intrinsics are can only be unordered,
1352 /// therefore nosync.
1353 case Intrinsic::memset_element_unordered_atomic:
1354 case Intrinsic::memmove_element_unordered_atomic:
1355 case Intrinsic::memcpy_element_unordered_atomic:
1356 return true;
1357 case Intrinsic::memset:
1358 case Intrinsic::memmove:
1359 case Intrinsic::memcpy:
1360 if (!cast<MemIntrinsic>(II)->isVolatile())
1361 return true;
1362 return false;
1363 default:
1364 return false;
1365 }
1366 }
1367 return false;
1368}
1369
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001370bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001371 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1372 "Calls should not be checked here");
1373
1374 switch (I->getOpcode()) {
1375 case Instruction::AtomicRMW:
1376 return cast<AtomicRMWInst>(I)->isVolatile();
1377 case Instruction::Store:
1378 return cast<StoreInst>(I)->isVolatile();
1379 case Instruction::Load:
1380 return cast<LoadInst>(I)->isVolatile();
1381 case Instruction::AtomicCmpXchg:
1382 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1383 default:
1384 return false;
1385 }
1386}
1387
Johannes Doerfertece81902019-08-12 22:05:53 +00001388ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001389
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001390 auto CheckRWInstForNoSync = [&](Instruction &I) {
1391 /// We are looking for volatile instructions or Non-Relaxed atomics.
Pankaj Godeb9a26a82019-11-22 14:46:43 +05301392 /// FIXME: We should improve the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001393
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001394 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1395 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001396
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001397 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1398 if (ICS.hasFnAttr(Attribute::NoSync))
1399 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001400
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001401 const auto &NoSyncAA =
1402 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1403 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001404 return true;
1405 return false;
1406 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001407
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001408 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1409 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001410
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001411 return false;
1412 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001413
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001414 auto CheckForNoSync = [&](Instruction &I) {
1415 // At this point we handled all read/write effects and they are all
1416 // nosync, so they can be skipped.
1417 if (I.mayReadOrWriteMemory())
1418 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001419
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001420 // non-convergent and readnone imply nosync.
1421 return !ImmutableCallSite(&I).isConvergent();
1422 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001423
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001424 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1425 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001426 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001427
Stefan Stipanovic06263672019-07-11 21:37:40 +00001428 return ChangeStatus::UNCHANGED;
1429}
1430
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001431struct AANoSyncFunction final : public AANoSyncImpl {
1432 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1433
1434 /// See AbstractAttribute::trackStatistics()
1435 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1436};
1437
1438/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001439struct AANoSyncCallSite final : AANoSyncImpl {
1440 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1441
1442 /// See AbstractAttribute::initialize(...).
1443 void initialize(Attributor &A) override {
1444 AANoSyncImpl::initialize(A);
1445 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001446 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001447 indicatePessimisticFixpoint();
1448 }
1449
1450 /// See AbstractAttribute::updateImpl(...).
1451 ChangeStatus updateImpl(Attributor &A) override {
1452 // TODO: Once we have call site specific value information we can provide
1453 // call site specific liveness information and then it makes
1454 // sense to specialize attributes for call sites arguments instead of
1455 // redirecting requests to the callee argument.
1456 Function *F = getAssociatedFunction();
1457 const IRPosition &FnPos = IRPosition::function(*F);
1458 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1459 return clampStateAndIndicateChange(
1460 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1461 }
1462
1463 /// See AbstractAttribute::trackStatistics()
1464 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1465};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001466
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001467/// ------------------------ No-Free Attributes ----------------------------
1468
Johannes Doerfert344d0382019-08-07 22:34:26 +00001469struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001470 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001471
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001472 /// See AbstractAttribute::updateImpl(...).
1473 ChangeStatus updateImpl(Attributor &A) override {
1474 auto CheckForNoFree = [&](Instruction &I) {
1475 ImmutableCallSite ICS(&I);
1476 if (ICS.hasFnAttr(Attribute::NoFree))
1477 return true;
1478
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001479 const auto &NoFreeAA =
1480 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1481 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001482 };
1483
1484 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1485 return indicatePessimisticFixpoint();
1486 return ChangeStatus::UNCHANGED;
1487 }
1488
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001489 /// See AbstractAttribute::getAsStr().
1490 const std::string getAsStr() const override {
1491 return getAssumed() ? "nofree" : "may-free";
1492 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001493};
1494
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001495struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001496 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001497
1498 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001499 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001500};
1501
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001502/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001503struct AANoFreeCallSite final : AANoFreeImpl {
1504 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1505
1506 /// See AbstractAttribute::initialize(...).
1507 void initialize(Attributor &A) override {
1508 AANoFreeImpl::initialize(A);
1509 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001510 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001511 indicatePessimisticFixpoint();
1512 }
1513
1514 /// See AbstractAttribute::updateImpl(...).
1515 ChangeStatus updateImpl(Attributor &A) override {
1516 // TODO: Once we have call site specific value information we can provide
1517 // call site specific liveness information and then it makes
1518 // sense to specialize attributes for call sites arguments instead of
1519 // redirecting requests to the callee argument.
1520 Function *F = getAssociatedFunction();
1521 const IRPosition &FnPos = IRPosition::function(*F);
1522 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1523 return clampStateAndIndicateChange(
1524 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1525 }
1526
1527 /// See AbstractAttribute::trackStatistics()
1528 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1529};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001530
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001531/// NoFree attribute for floating values.
1532struct AANoFreeFloating : AANoFreeImpl {
1533 AANoFreeFloating(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1534
1535 /// See AbstractAttribute::trackStatistics()
1536 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
1537
1538 /// See Abstract Attribute::updateImpl(...).
1539 ChangeStatus updateImpl(Attributor &A) override {
1540 const IRPosition &IRP = getIRPosition();
1541 Function *F = IRP.getAnchorScope();
1542
1543 const AAIsDead &LivenessAA =
1544 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F));
1545
1546 const auto &NoFreeAA =
1547 A.getAAFor<AANoFree>(*this, IRPosition::function_scope(IRP));
1548 if (NoFreeAA.isAssumedNoFree())
1549 return ChangeStatus::UNCHANGED;
1550
1551 SmallPtrSet<const Use *, 8> Visited;
1552 SmallVector<const Use *, 8> Worklist;
1553
1554 Value &AssociatedValue = getIRPosition().getAssociatedValue();
1555 for (Use &U : AssociatedValue.uses())
1556 Worklist.push_back(&U);
1557
1558 while (!Worklist.empty()) {
1559 const Use *U = Worklist.pop_back_val();
1560 if (!Visited.insert(U).second)
1561 continue;
1562
1563 auto *UserI = U->getUser();
1564 if (!UserI)
1565 continue;
1566
1567 if (LivenessAA.isAssumedDead(cast<Instruction>(UserI)))
1568 continue;
1569
1570 if (auto *CB = dyn_cast<CallBase>(UserI)) {
1571 if (CB->isBundleOperand(U))
1572 return indicatePessimisticFixpoint();
1573 if (!CB->isArgOperand(U))
1574 continue;
1575
Stefan Stipanovicc250ebf2019-11-10 21:45:11 +01001576 unsigned ArgNo = CB->getArgOperandNo(U);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001577
1578 const auto &NoFreeArg = A.getAAFor<AANoFree>(
1579 *this, IRPosition::callsite_argument(*CB, ArgNo));
1580
1581 if (NoFreeArg.isAssumedNoFree())
1582 continue;
1583
1584 return indicatePessimisticFixpoint();
1585 }
1586
1587 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
1588 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
1589 for (Use &U : UserI->uses())
1590 Worklist.push_back(&U);
1591 continue;
1592 }
1593
1594 // Unknown user.
1595 return indicatePessimisticFixpoint();
1596 }
1597 return ChangeStatus::UNCHANGED;
1598 }
1599};
1600
1601/// NoFree attribute for a call site argument.
1602struct AANoFreeArgument final : AANoFreeFloating {
1603 AANoFreeArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1604
1605 /// See AbstractAttribute::trackStatistics()
1606 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
1607};
1608
1609/// NoFree attribute for call site arguments.
1610struct AANoFreeCallSiteArgument final : AANoFreeFloating {
1611 AANoFreeCallSiteArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1612
1613 /// See AbstractAttribute::updateImpl(...).
1614 ChangeStatus updateImpl(Attributor &A) override {
1615 // TODO: Once we have call site specific value information we can provide
1616 // call site specific liveness information and then it makes
1617 // sense to specialize attributes for call sites arguments instead of
1618 // redirecting requests to the callee argument.
1619 Argument *Arg = getAssociatedArgument();
1620 if (!Arg)
1621 return indicatePessimisticFixpoint();
1622 const IRPosition &ArgPos = IRPosition::argument(*Arg);
1623 auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos);
1624 return clampStateAndIndicateChange(
1625 getState(), static_cast<const AANoFree::StateType &>(ArgAA.getState()));
1626 }
1627
1628 /// See AbstractAttribute::trackStatistics()
1629 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
1630};
1631
1632/// NoFree attribute for function return value.
1633struct AANoFreeReturned final : AANoFreeFloating {
1634 AANoFreeReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {
1635 llvm_unreachable("NoFree is not applicable to function returns!");
1636 }
1637
1638 /// See AbstractAttribute::initialize(...).
1639 void initialize(Attributor &A) override {
1640 llvm_unreachable("NoFree is not applicable to function returns!");
1641 }
1642
1643 /// See AbstractAttribute::updateImpl(...).
1644 ChangeStatus updateImpl(Attributor &A) override {
1645 llvm_unreachable("NoFree is not applicable to function returns!");
1646 }
1647
1648 /// See AbstractAttribute::trackStatistics()
1649 void trackStatistics() const override {}
1650};
1651
1652/// NoFree attribute deduction for a call site return value.
1653struct AANoFreeCallSiteReturned final : AANoFreeFloating {
1654 AANoFreeCallSiteReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1655
1656 ChangeStatus manifest(Attributor &A) override {
1657 return ChangeStatus::UNCHANGED;
1658 }
1659 /// See AbstractAttribute::trackStatistics()
1660 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
1661};
1662
Hideto Ueno54869ec2019-07-15 06:49:04 +00001663/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001664static int64_t getKnownNonNullAndDerefBytesForUse(
1665 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1666 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001667 TrackUse = false;
1668
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001669 const Value *UseV = U->get();
1670 if (!UseV->getType()->isPointerTy())
1671 return 0;
1672
1673 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001674 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001675 bool NullPointerIsDefined =
1676 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001677 const DataLayout &DL = A.getInfoCache().getDL();
1678 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1679 if (ICS.isBundleOperand(U))
1680 return 0;
1681
1682 if (ICS.isCallee(U)) {
1683 IsNonNull |= !NullPointerIsDefined;
1684 return 0;
1685 }
1686
1687 unsigned ArgNo = ICS.getArgumentNo(U);
1688 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
Johannes Doerfert77a6b352019-11-02 14:47:45 -05001689 // As long as we only use known information there is no need to track
1690 // dependences here.
1691 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP,
1692 /* TrackDependence */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001693 IsNonNull |= DerefAA.isKnownNonNull();
1694 return DerefAA.getKnownDereferenceableBytes();
1695 }
1696
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001697 // We need to follow common pointer manipulation uses to the accesses they
1698 // feed into. We can try to be smart to avoid looking through things we do not
1699 // like for now, e.g., non-inbounds GEPs.
1700 if (isa<CastInst>(I)) {
1701 TrackUse = true;
1702 return 0;
1703 }
1704 if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
1705 if (GEP->hasAllZeroIndices() ||
1706 (GEP->isInBounds() && GEP->hasAllConstantIndices())) {
1707 TrackUse = true;
1708 return 0;
1709 }
1710
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001711 int64_t Offset;
1712 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001713 if (Base == &AssociatedValue && getPointerOperand(I) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001714 int64_t DerefBytes =
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001715 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType()) + Offset;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001716
1717 IsNonNull |= !NullPointerIsDefined;
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001718 return std::max(int64_t(0), DerefBytes);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001719 }
1720 }
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001721 if (const Value *Base =
1722 GetPointerBaseWithConstantOffset(UseV, Offset, DL,
1723 /*AllowNonInbounds*/ false)) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001724 if (Base == &AssociatedValue) {
Johannes Doerfert77a6b352019-11-02 14:47:45 -05001725 // As long as we only use known information there is no need to track
1726 // dependences here.
1727 auto &DerefAA = A.getAAFor<AADereferenceable>(
1728 QueryingAA, IRPosition::value(*Base), /* TrackDependence */ false);
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001729 IsNonNull |= (!NullPointerIsDefined && DerefAA.isKnownNonNull());
1730 IsNonNull |= (!NullPointerIsDefined && (Offset != 0));
1731 int64_t DerefBytes = DerefAA.getKnownDereferenceableBytes();
1732 return std::max(int64_t(0), DerefBytes - std::max(int64_t(0), Offset));
1733 }
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001734 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001735
1736 return 0;
1737}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001738
Johannes Doerfert344d0382019-08-07 22:34:26 +00001739struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001740 AANonNullImpl(const IRPosition &IRP)
1741 : AANonNull(IRP),
1742 NullIsDefined(NullPointerIsDefined(
1743 getAnchorScope(),
1744 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001745
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001746 /// See AbstractAttribute::initialize(...).
1747 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001748 if (!NullIsDefined &&
1749 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001750 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001751 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1752 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001753 else
1754 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001755 }
1756
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001757 /// See AAFromMustBeExecutedContext
1758 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1759 bool IsNonNull = false;
1760 bool TrackUse = false;
1761 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1762 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001763 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001764 return TrackUse;
1765 }
1766
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001767 /// See AbstractAttribute::getAsStr().
1768 const std::string getAsStr() const override {
1769 return getAssumed() ? "nonnull" : "may-null";
1770 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001771
1772 /// Flag to determine if the underlying value can be null and still allow
1773 /// valid accesses.
1774 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001775};
1776
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001777/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001778struct AANonNullFloating
1779 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1780 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1781 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001782
Hideto Ueno54869ec2019-07-15 06:49:04 +00001783 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001784 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001785 ChangeStatus Change = Base::updateImpl(A);
1786 if (isKnownNonNull())
1787 return Change;
1788
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001789 if (!NullIsDefined) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001790 const auto &DerefAA =
1791 A.getAAFor<AADereferenceable>(*this, getIRPosition());
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001792 if (DerefAA.getAssumedDereferenceableBytes())
1793 return Change;
1794 }
1795
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001796 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001797
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001798 DominatorTree *DT = nullptr;
1799 InformationCache &InfoCache = A.getInfoCache();
1800 if (const Function *Fn = getAnchorScope())
1801 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
1802
Johannes Doerfert1a746452019-10-20 22:28:49 -05001803 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001804 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001805 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1806 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001807 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001808 T.indicatePessimisticFixpoint();
1809 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001810 // Use abstract attribute information.
1811 const AANonNull::StateType &NS =
1812 static_cast<const AANonNull::StateType &>(AA.getState());
1813 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001814 }
1815 return T.isValidState();
1816 };
1817
1818 StateType T;
1819 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
1820 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001821 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001822
1823 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001824 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001825
1826 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001827 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001828};
1829
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001830/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001831struct AANonNullReturned final
1832 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001833 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001834 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001835
1836 /// See AbstractAttribute::trackStatistics()
1837 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
1838};
1839
Hideto Ueno54869ec2019-07-15 06:49:04 +00001840/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001841struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001842 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1843 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001844 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001845 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1846 AANonNullImpl>(
1847 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001848
1849 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001850 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001851};
1852
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001853struct AANonNullCallSiteArgument final : AANonNullFloating {
1854 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001855
1856 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00001857 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001858};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001859
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001860/// NonNull attribute for a call site return position.
1861struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001862 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1863 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001864 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001865 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1866 AANonNullImpl>(
1867 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001868
1869 /// See AbstractAttribute::trackStatistics()
1870 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
1871};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001872
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001873/// ------------------------ No-Recurse Attributes ----------------------------
1874
1875struct AANoRecurseImpl : public AANoRecurse {
1876 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
1877
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001878 /// See AbstractAttribute::getAsStr()
1879 const std::string getAsStr() const override {
1880 return getAssumed() ? "norecurse" : "may-recurse";
1881 }
1882};
1883
1884struct AANoRecurseFunction final : AANoRecurseImpl {
1885 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1886
Hideto Ueno63f60662019-09-21 15:13:19 +00001887 /// See AbstractAttribute::initialize(...).
1888 void initialize(Attributor &A) override {
1889 AANoRecurseImpl::initialize(A);
1890 if (const Function *F = getAnchorScope())
1891 if (A.getInfoCache().getSccSize(*F) == 1)
1892 return;
1893 indicatePessimisticFixpoint();
1894 }
1895
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001896 /// See AbstractAttribute::updateImpl(...).
1897 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00001898
1899 auto CheckForNoRecurse = [&](Instruction &I) {
1900 ImmutableCallSite ICS(&I);
1901 if (ICS.hasFnAttr(Attribute::NoRecurse))
1902 return true;
1903
1904 const auto &NoRecurseAA =
1905 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
1906 if (!NoRecurseAA.isAssumedNoRecurse())
1907 return false;
1908
1909 // Recursion to the same function
1910 if (ICS.getCalledFunction() == getAnchorScope())
1911 return false;
1912
1913 return true;
1914 };
1915
1916 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
1917 return indicatePessimisticFixpoint();
1918 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001919 }
1920
1921 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
1922};
1923
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001924/// NoRecurse attribute deduction for a call sites.
1925struct AANoRecurseCallSite final : AANoRecurseImpl {
1926 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1927
1928 /// See AbstractAttribute::initialize(...).
1929 void initialize(Attributor &A) override {
1930 AANoRecurseImpl::initialize(A);
1931 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001932 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001933 indicatePessimisticFixpoint();
1934 }
1935
1936 /// See AbstractAttribute::updateImpl(...).
1937 ChangeStatus updateImpl(Attributor &A) override {
1938 // TODO: Once we have call site specific value information we can provide
1939 // call site specific liveness information and then it makes
1940 // sense to specialize attributes for call sites arguments instead of
1941 // redirecting requests to the callee argument.
1942 Function *F = getAssociatedFunction();
1943 const IRPosition &FnPos = IRPosition::function(*F);
1944 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
1945 return clampStateAndIndicateChange(
1946 getState(),
1947 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
1948 }
1949
1950 /// See AbstractAttribute::trackStatistics()
1951 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
1952};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001953
Hideto Ueno11d37102019-07-17 15:15:43 +00001954/// ------------------------ Will-Return Attributes ----------------------------
1955
Hideto Ueno11d37102019-07-17 15:15:43 +00001956// Helper function that checks whether a function has any cycle.
1957// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001958static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00001959 SmallPtrSet<BasicBlock *, 32> Visited;
1960
1961 // Traverse BB by dfs and check whether successor is already visited.
1962 for (BasicBlock *BB : depth_first(&F)) {
1963 Visited.insert(BB);
1964 for (auto *SuccBB : successors(BB)) {
1965 if (Visited.count(SuccBB))
1966 return true;
1967 }
1968 }
1969 return false;
1970}
1971
1972// Helper function that checks the function have a loop which might become an
1973// endless loop
1974// FIXME: Any cycle is regarded as endless loop for now.
1975// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001976static bool containsPossiblyEndlessLoop(Function *F) {
1977 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00001978}
1979
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001980struct AAWillReturnImpl : public AAWillReturn {
1981 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00001982
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001983 /// See AbstractAttribute::initialize(...).
1984 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001985 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00001986
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001987 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001988 if (containsPossiblyEndlessLoop(F))
1989 indicatePessimisticFixpoint();
1990 }
Hideto Ueno11d37102019-07-17 15:15:43 +00001991
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001992 /// See AbstractAttribute::updateImpl(...).
1993 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001994 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001995 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
1996 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
1997 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001998 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001999 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002000 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002001 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
2002 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002003 };
2004
2005 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
2006 return indicatePessimisticFixpoint();
2007
2008 return ChangeStatus::UNCHANGED;
2009 }
2010
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002011 /// See AbstractAttribute::getAsStr()
2012 const std::string getAsStr() const override {
2013 return getAssumed() ? "willreturn" : "may-noreturn";
2014 }
2015};
2016
2017struct AAWillReturnFunction final : AAWillReturnImpl {
2018 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2019
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002020 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002021 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002022};
Hideto Ueno11d37102019-07-17 15:15:43 +00002023
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002024/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002025struct AAWillReturnCallSite final : AAWillReturnImpl {
2026 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2027
2028 /// See AbstractAttribute::initialize(...).
2029 void initialize(Attributor &A) override {
2030 AAWillReturnImpl::initialize(A);
2031 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002032 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002033 indicatePessimisticFixpoint();
2034 }
2035
2036 /// See AbstractAttribute::updateImpl(...).
2037 ChangeStatus updateImpl(Attributor &A) override {
2038 // TODO: Once we have call site specific value information we can provide
2039 // call site specific liveness information and then it makes
2040 // sense to specialize attributes for call sites arguments instead of
2041 // redirecting requests to the callee argument.
2042 Function *F = getAssociatedFunction();
2043 const IRPosition &FnPos = IRPosition::function(*F);
2044 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
2045 return clampStateAndIndicateChange(
2046 getState(),
2047 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
2048 }
2049
2050 /// See AbstractAttribute::trackStatistics()
2051 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
2052};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002053
Pankaj Gode04945c92019-11-22 18:40:47 +05302054/// -------------------AAReachability Attribute--------------------------
2055
2056struct AAReachabilityImpl : AAReachability {
2057 AAReachabilityImpl(const IRPosition &IRP) : AAReachability(IRP) {}
2058
2059 const std::string getAsStr() const override {
2060 // TODO: Return the number of reachable queries.
2061 return "reachable";
2062 }
2063
2064 /// See AbstractAttribute::initialize(...).
2065 void initialize(Attributor &A) override {
2066 indicatePessimisticFixpoint();
2067 }
2068
2069 /// See AbstractAttribute::updateImpl(...).
2070 ChangeStatus updateImpl(Attributor &A) override {
2071 return indicatePessimisticFixpoint();
2072 }
2073};
2074
2075struct AAReachabilityFunction final : public AAReachabilityImpl {
2076 AAReachabilityFunction(const IRPosition &IRP) : AAReachabilityImpl(IRP) {}
2077
2078 /// See AbstractAttribute::trackStatistics()
2079 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(reachable); }
2080};
2081
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002082/// ------------------------ NoAlias Argument Attribute ------------------------
2083
Johannes Doerfert344d0382019-08-07 22:34:26 +00002084struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002085 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002086
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002087 const std::string getAsStr() const override {
2088 return getAssumed() ? "noalias" : "may-alias";
2089 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002090};
2091
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002092/// NoAlias attribute for a floating value.
2093struct AANoAliasFloating final : AANoAliasImpl {
2094 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2095
Hideto Uenocbab3342019-08-29 05:52:00 +00002096 /// See AbstractAttribute::initialize(...).
2097 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002098 AANoAliasImpl::initialize(A);
Johannes Doerfert72adda12019-10-10 05:33:21 +00002099 Value &Val = getAssociatedValue();
2100 if (isa<AllocaInst>(Val))
2101 indicateOptimisticFixpoint();
2102 if (isa<ConstantPointerNull>(Val) &&
2103 Val.getType()->getPointerAddressSpace() == 0)
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002104 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002105 }
2106
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002107 /// See AbstractAttribute::updateImpl(...).
2108 ChangeStatus updateImpl(Attributor &A) override {
2109 // TODO: Implement this.
2110 return indicatePessimisticFixpoint();
2111 }
2112
2113 /// See AbstractAttribute::trackStatistics()
2114 void trackStatistics() const override {
2115 STATS_DECLTRACK_FLOATING_ATTR(noalias)
2116 }
2117};
2118
2119/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00002120struct AANoAliasArgument final
2121 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
2122 AANoAliasArgument(const IRPosition &IRP)
2123 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002124
2125 /// See AbstractAttribute::trackStatistics()
2126 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
2127};
2128
2129struct AANoAliasCallSiteArgument final : AANoAliasImpl {
2130 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2131
Hideto Uenocbab3342019-08-29 05:52:00 +00002132 /// See AbstractAttribute::initialize(...).
2133 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00002134 // See callsite argument attribute and callee argument attribute.
2135 ImmutableCallSite ICS(&getAnchorValue());
2136 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
2137 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002138 }
2139
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002140 /// See AbstractAttribute::updateImpl(...).
2141 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002142 // We can deduce "noalias" if the following conditions hold.
2143 // (i) Associated value is assumed to be noalias in the definition.
2144 // (ii) Associated value is assumed to be no-capture in all the uses
2145 // possibly executed before this callsite.
2146 // (iii) There is no other pointer argument which could alias with the
2147 // value.
2148
2149 const Value &V = getAssociatedValue();
2150 const IRPosition IRP = IRPosition::value(V);
2151
2152 // (i) Check whether noalias holds in the definition.
2153
2154 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
2155
2156 if (!NoAliasAA.isAssumedNoAlias())
2157 return indicatePessimisticFixpoint();
2158
2159 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
2160 << " is assumed NoAlias in the definition\n");
2161
2162 // (ii) Check whether the value is captured in the scope using AANoCapture.
2163 // FIXME: This is conservative though, it is better to look at CFG and
2164 // check only uses possibly executed before this callsite.
2165
2166 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert72adda12019-10-10 05:33:21 +00002167 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2168 LLVM_DEBUG(
2169 dbgs() << "[Attributor][AANoAliasCSArg] " << V
2170 << " cannot be noalias as it is potentially captured\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002171 return indicatePessimisticFixpoint();
Johannes Doerfert72adda12019-10-10 05:33:21 +00002172 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002173
2174 // (iii) Check there is no other pointer argument which could alias with the
2175 // value.
2176 ImmutableCallSite ICS(&getAnchorValue());
2177 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
2178 if (getArgNo() == (int)i)
2179 continue;
2180 const Value *ArgOp = ICS.getArgOperand(i);
2181 if (!ArgOp->getType()->isPointerTy())
2182 continue;
2183
Hideto Ueno30d86f12019-09-17 06:53:27 +00002184 if (const Function *F = getAnchorScope()) {
2185 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
Johannes Doerfert72adda12019-10-10 05:33:21 +00002186 bool IsAliasing = AAR->isNoAlias(&getAssociatedValue(), ArgOp);
Hideto Ueno30d86f12019-09-17 06:53:27 +00002187 LLVM_DEBUG(dbgs()
2188 << "[Attributor][NoAliasCSArg] Check alias between "
2189 "callsite arguments "
2190 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
Johannes Doerfert72adda12019-10-10 05:33:21 +00002191 << getAssociatedValue() << " " << *ArgOp << " => "
2192 << (IsAliasing ? "" : "no-") << "alias \n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002193
Johannes Doerfert72adda12019-10-10 05:33:21 +00002194 if (IsAliasing)
Hideto Ueno30d86f12019-09-17 06:53:27 +00002195 continue;
2196 }
2197 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002198 return indicatePessimisticFixpoint();
2199 }
2200
2201 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002202 }
2203
2204 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002205 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002206};
2207
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002208/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002209struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002210 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002211
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002212 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002213 virtual ChangeStatus updateImpl(Attributor &A) override {
2214
2215 auto CheckReturnValue = [&](Value &RV) -> bool {
2216 if (Constant *C = dyn_cast<Constant>(&RV))
2217 if (C->isNullValue() || isa<UndefValue>(C))
2218 return true;
2219
2220 /// For now, we can only deduce noalias if we have call sites.
2221 /// FIXME: add more support.
2222 ImmutableCallSite ICS(&RV);
2223 if (!ICS)
2224 return false;
2225
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002226 const IRPosition &RVPos = IRPosition::value(RV);
2227 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002228 if (!NoAliasAA.isAssumedNoAlias())
2229 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002230
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002231 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2232 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002233 };
2234
2235 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2236 return indicatePessimisticFixpoint();
2237
2238 return ChangeStatus::UNCHANGED;
2239 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002240
2241 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002242 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002243};
2244
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002245/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002246struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2247 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2248
2249 /// See AbstractAttribute::initialize(...).
2250 void initialize(Attributor &A) override {
2251 AANoAliasImpl::initialize(A);
2252 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002253 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002254 indicatePessimisticFixpoint();
2255 }
2256
2257 /// See AbstractAttribute::updateImpl(...).
2258 ChangeStatus updateImpl(Attributor &A) override {
2259 // TODO: Once we have call site specific value information we can provide
2260 // call site specific liveness information and then it makes
2261 // sense to specialize attributes for call sites arguments instead of
2262 // redirecting requests to the callee argument.
2263 Function *F = getAssociatedFunction();
2264 const IRPosition &FnPos = IRPosition::returned(*F);
2265 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2266 return clampStateAndIndicateChange(
2267 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2268 }
2269
2270 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002271 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002272};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002273
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002274/// -------------------AAIsDead Function Attribute-----------------------
2275
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002276struct AAIsDeadValueImpl : public AAIsDead {
2277 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002278
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002279 /// See AAIsDead::isAssumedDead().
2280 bool isAssumedDead() const override { return getAssumed(); }
2281
2282 /// See AAIsDead::isAssumedDead(BasicBlock *).
2283 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2284
2285 /// See AAIsDead::isKnownDead(BasicBlock *).
2286 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2287
2288 /// See AAIsDead::isAssumedDead(Instruction *I).
2289 bool isAssumedDead(const Instruction *I) const override {
2290 return I == getCtxI() && isAssumedDead();
2291 }
2292
2293 /// See AAIsDead::isKnownDead(Instruction *I).
2294 bool isKnownDead(const Instruction *I) const override {
2295 return I == getCtxI() && getKnown();
2296 }
2297
2298 /// See AbstractAttribute::getAsStr().
2299 const std::string getAsStr() const override {
2300 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2301 }
2302};
2303
2304struct AAIsDeadFloating : public AAIsDeadValueImpl {
2305 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2306
2307 /// See AbstractAttribute::initialize(...).
2308 void initialize(Attributor &A) override {
2309 if (Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()))
2310 if (!wouldInstructionBeTriviallyDead(I))
2311 indicatePessimisticFixpoint();
2312 if (isa<UndefValue>(getAssociatedValue()))
2313 indicatePessimisticFixpoint();
2314 }
2315
2316 /// See AbstractAttribute::updateImpl(...).
2317 ChangeStatus updateImpl(Attributor &A) override {
2318 auto UsePred = [&](const Use &U, bool &Follow) {
2319 Instruction *UserI = cast<Instruction>(U.getUser());
2320 if (CallSite CS = CallSite(UserI)) {
2321 if (!CS.isArgOperand(&U))
2322 return false;
2323 const IRPosition &CSArgPos =
2324 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
2325 const auto &CSArgIsDead = A.getAAFor<AAIsDead>(*this, CSArgPos);
2326 return CSArgIsDead.isAssumedDead();
2327 }
2328 if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
2329 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
2330 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, RetPos);
2331 return RetIsDeadAA.isAssumedDead();
2332 }
2333 Follow = true;
2334 return wouldInstructionBeTriviallyDead(UserI);
2335 };
2336
2337 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
2338 return indicatePessimisticFixpoint();
2339 return ChangeStatus::UNCHANGED;
2340 }
2341
2342 /// See AbstractAttribute::manifest(...).
2343 ChangeStatus manifest(Attributor &A) override {
2344 Value &V = getAssociatedValue();
2345 if (auto *I = dyn_cast<Instruction>(&V))
2346 if (wouldInstructionBeTriviallyDead(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002347 A.deleteAfterManifest(*I);
2348 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002349 }
2350
2351 if (V.use_empty())
2352 return ChangeStatus::UNCHANGED;
2353
2354 UndefValue &UV = *UndefValue::get(V.getType());
2355 bool AnyChange = false;
2356 for (Use &U : V.uses())
2357 AnyChange |= A.changeUseAfterManifest(U, UV);
2358 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2359 }
2360
2361 /// See AbstractAttribute::trackStatistics()
2362 void trackStatistics() const override {
2363 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2364 }
2365};
2366
2367struct AAIsDeadArgument : public AAIsDeadFloating {
2368 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2369
2370 /// See AbstractAttribute::initialize(...).
2371 void initialize(Attributor &A) override {
2372 if (!getAssociatedFunction()->hasExactDefinition())
2373 indicatePessimisticFixpoint();
2374 }
2375
2376 /// See AbstractAttribute::trackStatistics()
2377 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
2378};
2379
2380struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
2381 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2382
2383 /// See AbstractAttribute::initialize(...).
2384 void initialize(Attributor &A) override {
2385 if (isa<UndefValue>(getAssociatedValue()))
2386 indicatePessimisticFixpoint();
2387 }
2388
2389 /// See AbstractAttribute::updateImpl(...).
2390 ChangeStatus updateImpl(Attributor &A) override {
2391 // TODO: Once we have call site specific value information we can provide
2392 // call site specific liveness information and then it makes
2393 // sense to specialize attributes for call sites arguments instead of
2394 // redirecting requests to the callee argument.
2395 Argument *Arg = getAssociatedArgument();
2396 if (!Arg)
2397 return indicatePessimisticFixpoint();
2398 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2399 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
2400 return clampStateAndIndicateChange(
2401 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
2402 }
2403
2404 /// See AbstractAttribute::manifest(...).
2405 ChangeStatus manifest(Attributor &A) override {
2406 CallBase &CB = cast<CallBase>(getAnchorValue());
2407 Use &U = CB.getArgOperandUse(getArgNo());
2408 assert(!isa<UndefValue>(U.get()) &&
2409 "Expected undef values to be filtered out!");
2410 UndefValue &UV = *UndefValue::get(U->getType());
2411 if (A.changeUseAfterManifest(U, UV))
2412 return ChangeStatus::CHANGED;
2413 return ChangeStatus::UNCHANGED;
2414 }
2415
2416 /// See AbstractAttribute::trackStatistics()
2417 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
2418};
2419
2420struct AAIsDeadReturned : public AAIsDeadValueImpl {
2421 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2422
2423 /// See AbstractAttribute::updateImpl(...).
2424 ChangeStatus updateImpl(Attributor &A) override {
2425
2426 auto PredForCallSite = [&](AbstractCallSite ACS) {
2427 if (ACS.isCallbackCall())
2428 return false;
2429 const IRPosition &CSRetPos =
2430 IRPosition::callsite_returned(ACS.getCallSite());
2431 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, CSRetPos);
2432 return RetIsDeadAA.isAssumedDead();
2433 };
2434
2435 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
2436 return indicatePessimisticFixpoint();
2437
2438 return ChangeStatus::UNCHANGED;
2439 }
2440
2441 /// See AbstractAttribute::manifest(...).
2442 ChangeStatus manifest(Attributor &A) override {
2443 // TODO: Rewrite the signature to return void?
2444 bool AnyChange = false;
2445 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
2446 auto RetInstPred = [&](Instruction &I) {
2447 ReturnInst &RI = cast<ReturnInst>(I);
2448 if (!isa<UndefValue>(RI.getReturnValue()))
2449 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
2450 return true;
2451 };
2452 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
2453 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2454 }
2455
2456 /// See AbstractAttribute::trackStatistics()
2457 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
2458};
2459
2460struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
2461 AAIsDeadCallSiteReturned(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2462
2463 /// See AbstractAttribute::initialize(...).
2464 void initialize(Attributor &A) override {}
2465
2466 /// See AbstractAttribute::trackStatistics()
2467 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(IsDead) }
2468};
2469
2470struct AAIsDeadFunction : public AAIsDead {
2471 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
2472
2473 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002474 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002475 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002476 if (F && !F->isDeclaration()) {
2477 ToBeExploredFrom.insert(&F->getEntryBlock().front());
2478 assumeLive(A, F->getEntryBlock());
2479 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002480 }
2481
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002482 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002483 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002484 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002485 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002486 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
2487 std::to_string(KnownDeadEnds.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002488 }
2489
2490 /// See AbstractAttribute::manifest(...).
2491 ChangeStatus manifest(Attributor &A) override {
2492 assert(getState().isValidState() &&
2493 "Attempted to manifest an invalid state!");
2494
2495 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002496 Function &F = *getAssociatedFunction();
2497
2498 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002499 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002500 return ChangeStatus::CHANGED;
2501 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00002502
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002503 // Flag to determine if we can change an invoke to a call assuming the
2504 // callee is nounwind. This is not possible if the personality of the
2505 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002506 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002507
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002508 KnownDeadEnds.set_union(ToBeExploredFrom);
2509 for (const Instruction *DeadEndI : KnownDeadEnds) {
2510 auto *CB = dyn_cast<CallBase>(DeadEndI);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002511 if (!CB)
2512 continue;
2513 const auto &NoReturnAA =
2514 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002515 bool MayReturn = !NoReturnAA.isAssumedNoReturn();
2516 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002517 continue;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002518 Instruction *I = const_cast<Instruction *>(DeadEndI);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002519 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002520 Instruction *SplitPos = I->getNextNode();
Johannes Doerfertd4108052019-08-21 20:56:41 +00002521 // TODO: mark stuff before unreachable instructions as dead.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002522
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002523 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002524 // If we keep the invoke the split position is at the beginning of the
2525 // normal desitination block (it invokes a noreturn function after all).
2526 BasicBlock *NormalDestBB = II->getNormalDest();
2527 SplitPos = &NormalDestBB->front();
2528
Johannes Doerfert4361da22019-08-04 18:38:53 +00002529 /// Invoke is replaced with a call and unreachable is placed after it if
2530 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
2531 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002532 if (Invoke2CallAllowed) {
Michael Liaoa99086d2019-08-20 21:02:31 +00002533 if (II->getCalledFunction()) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002534 const IRPosition &IPos = IRPosition::callsite_function(*II);
2535 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2536 if (AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert924d2132019-08-05 21:34:45 +00002537 LLVM_DEBUG(dbgs()
2538 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002539 CallInst *CI = createCallMatchingInvoke(II);
2540 CI->insertBefore(II);
2541 CI->takeName(II);
2542 II->replaceAllUsesWith(CI);
2543
2544 // If this is a nounwind + mayreturn invoke we only remove the unwind edge.
2545 // This is done by moving the invoke into a new and dead block and connecting
2546 // the normal destination of the invoke with a branch that follows the call
2547 // replacement we created above.
2548 if (MayReturn) {
2549 BasicBlock *NewDeadBB = SplitBlock(BB, II, nullptr, nullptr, nullptr, ".i2c");
2550 assert(isa<BranchInst>(BB->getTerminator()) &&
2551 BB->getTerminator()->getNumSuccessors() == 1 &&
2552 BB->getTerminator()->getSuccessor(0) == NewDeadBB);
2553 new UnreachableInst(I->getContext(), NewDeadBB);
2554 BB->getTerminator()->setOperand(0, NormalDestBB);
2555 A.deleteAfterManifest(*II);
2556 continue;
2557 }
2558
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002559 // We do not need an invoke (II) but instead want a call followed
2560 // by an unreachable. However, we do not remove II as other
2561 // abstract attributes might have it cached as part of their
2562 // results. Given that we modify the CFG anyway, we simply keep II
2563 // around but in a new dead block. To avoid II being live through
2564 // a different edge we have to ensure the block we place it in is
2565 // only reached from the current block of II and then not reached
2566 // at all when we insert the unreachable.
2567 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002568 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002569 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002570 }
2571 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002572
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002573 if (SplitPos == &NormalDestBB->front()) {
2574 // If this is an invoke of a noreturn function the edge to the normal
2575 // destination block is dead but not necessarily the block itself.
2576 // TODO: We need to move to an edge based system during deduction and
2577 // also manifest.
2578 assert(!NormalDestBB->isLandingPad() &&
2579 "Expected the normal destination not to be a landingpad!");
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002580 if (NormalDestBB->getUniquePredecessor() == BB) {
2581 assumeLive(A, *NormalDestBB);
2582 } else {
2583 BasicBlock *SplitBB =
2584 SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2585 // The split block is live even if it contains only an unreachable
2586 // instruction at the end.
2587 assumeLive(A, *SplitBB);
2588 SplitPos = SplitBB->getTerminator();
2589 HasChanged = ChangeStatus::CHANGED;
2590 }
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002591 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002592 }
2593
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002594 if (isa_and_nonnull<UnreachableInst>(SplitPos))
2595 continue;
2596
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002597 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002598 SplitBlock(BB, SplitPos);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002599 changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
2600 HasChanged = ChangeStatus::CHANGED;
2601 }
2602
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002603 for (BasicBlock &BB : F)
2604 if (!AssumedLiveBlocks.count(&BB))
2605 A.deleteAfterManifest(BB);
2606
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002607 return HasChanged;
2608 }
2609
2610 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002611 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002612
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002613 /// See AbstractAttribute::trackStatistics()
2614 void trackStatistics() const override {}
2615
2616 /// Returns true if the function is assumed dead.
2617 bool isAssumedDead() const override { return false; }
2618
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002619 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002620 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002621 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002622 "BB must be in the same anchor scope function.");
2623
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002624 if (!getAssumed())
2625 return false;
2626 return !AssumedLiveBlocks.count(BB);
2627 }
2628
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002629 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002630 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002631 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002632 }
2633
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002634 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002635 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002636 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002637 "Instruction must be in the same anchor scope function.");
2638
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002639 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002640 return false;
2641
2642 // If it is not in AssumedLiveBlocks then it for sure dead.
2643 // Otherwise, it can still be after noreturn call in a live block.
2644 if (!AssumedLiveBlocks.count(I->getParent()))
2645 return true;
2646
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002647 // If it is not after a liveness barrier it is live.
2648 const Instruction *PrevI = I->getPrevNode();
2649 while (PrevI) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002650 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002651 return true;
2652 PrevI = PrevI->getPrevNode();
2653 }
2654 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002655 }
2656
2657 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002658 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002659 return getKnown() && isAssumedDead(I);
2660 }
2661
Johannes Doerfert924d2132019-08-05 21:34:45 +00002662 /// Determine if \p F might catch asynchronous exceptions.
2663 static bool mayCatchAsynchronousExceptions(const Function &F) {
2664 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2665 }
2666
Johannes Doerfert2f622062019-09-04 16:35:20 +00002667 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2668 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002669 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002670 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002671 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002672
2673 // We assume that all of BB is (probably) live now and if there are calls to
2674 // internal functions we will assume that those are now live as well. This
2675 // is a performance optimization for blocks with calls to a lot of internal
2676 // functions. It can however cause dead functions to be treated as live.
2677 for (const Instruction &I : BB)
2678 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
2679 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00002680 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00002681 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002682 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002683 }
2684
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002685 /// Collection of instructions that need to be explored again, e.g., we
2686 /// did assume they do not transfer control to (one of their) successors.
2687 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002688
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002689 /// Collection of instructions that are known to not transfer control.
2690 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
2691
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002692 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002693 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002694};
2695
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002696static bool
2697identifyAliveSuccessors(Attributor &A, const CallBase &CB,
2698 AbstractAttribute &AA,
2699 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2700 const IRPosition &IPos = IRPosition::callsite_function(CB);
2701
2702 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
2703 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002704 return !NoReturnAA.isKnownNoReturn();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002705 if (CB.isTerminator())
2706 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
2707 else
2708 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002709 return false;
2710}
2711
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002712static bool
2713identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
2714 AbstractAttribute &AA,
2715 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2716 bool UsedAssumedInformation =
2717 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00002718
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002719 // First, determine if we can change an invoke to a call assuming the
2720 // callee is nounwind. This is not possible if the personality of the
2721 // function allows to catch asynchronous exceptions.
2722 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
2723 AliveSuccessors.push_back(&II.getUnwindDest()->front());
2724 } else {
2725 const IRPosition &IPos = IRPosition::callsite_function(II);
2726 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002727 if (AANoUnw.isAssumedNoUnwind()) {
2728 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind();
2729 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002730 AliveSuccessors.push_back(&II.getUnwindDest()->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002731 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002732 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002733 return UsedAssumedInformation;
2734}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002735
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002736static Optional<ConstantInt *>
2737getAssumedConstant(Attributor &A, const Value &V, AbstractAttribute &AA,
2738 bool &UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002739 const auto &ValueSimplifyAA =
2740 A.getAAFor<AAValueSimplify>(AA, IRPosition::value(V));
2741 Optional<Value *> SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(A);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002742 UsedAssumedInformation |= !ValueSimplifyAA.isKnown();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002743 if (!SimplifiedV.hasValue())
2744 return llvm::None;
2745 if (isa_and_nonnull<UndefValue>(SimplifiedV.getValue()))
2746 return llvm::None;
2747 return dyn_cast_or_null<ConstantInt>(SimplifiedV.getValue());
2748}
2749
2750static bool
2751identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
2752 AbstractAttribute &AA,
2753 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2754 bool UsedAssumedInformation = false;
2755 if (BI.getNumSuccessors() == 1) {
2756 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
2757 } else {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002758 Optional<ConstantInt *> CI =
2759 getAssumedConstant(A, *BI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002760 if (!CI.hasValue()) {
2761 // No value yet, assume both edges are dead.
2762 } else if (CI.getValue()) {
2763 const BasicBlock *SuccBB =
2764 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
2765 AliveSuccessors.push_back(&SuccBB->front());
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002766 } else {
2767 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
2768 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002769 UsedAssumedInformation = false;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002770 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002771 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002772 return UsedAssumedInformation;
2773}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002774
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002775static bool
2776identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
2777 AbstractAttribute &AA,
2778 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002779 bool UsedAssumedInformation = false;
2780 Optional<ConstantInt *> CI =
2781 getAssumedConstant(A, *SI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002782 if (!CI.hasValue()) {
2783 // No value yet, assume all edges are dead.
2784 } else if (CI.getValue()) {
2785 for (auto &CaseIt : SI.cases()) {
2786 if (CaseIt.getCaseValue() == CI.getValue()) {
2787 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002788 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002789 }
2790 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05002791 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002792 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002793 } else {
2794 for (const BasicBlock *SuccBB : successors(SI.getParent()))
2795 AliveSuccessors.push_back(&SuccBB->front());
2796 }
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002797 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002798}
2799
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002800ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002801 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002802
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002803 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
2804 << getAssociatedFunction()->size() << "] BBs and "
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002805 << ToBeExploredFrom.size() << " exploration points and "
2806 << KnownDeadEnds.size() << " known dead ends\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002807
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002808 // Copy and clear the list of instructions we need to explore from. It is
2809 // refilled with instructions the next update has to look at.
2810 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
2811 ToBeExploredFrom.end());
2812 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002813
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002814 SmallVector<const Instruction *, 8> AliveSuccessors;
2815 while (!Worklist.empty()) {
2816 const Instruction *I = Worklist.pop_back_val();
2817 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002818
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002819 AliveSuccessors.clear();
2820
2821 bool UsedAssumedInformation = false;
2822 switch (I->getOpcode()) {
2823 // TODO: look for (assumed) UB to backwards propagate "deadness".
2824 default:
2825 if (I->isTerminator()) {
2826 for (const BasicBlock *SuccBB : successors(I->getParent()))
2827 AliveSuccessors.push_back(&SuccBB->front());
2828 } else {
2829 AliveSuccessors.push_back(I->getNextNode());
2830 }
2831 break;
2832 case Instruction::Call:
2833 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
2834 *this, AliveSuccessors);
2835 break;
2836 case Instruction::Invoke:
2837 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
2838 *this, AliveSuccessors);
2839 break;
2840 case Instruction::Br:
2841 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
2842 *this, AliveSuccessors);
2843 break;
2844 case Instruction::Switch:
2845 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
2846 *this, AliveSuccessors);
2847 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00002848 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002849
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002850 if (UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002851 NewToBeExploredFrom.insert(I);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002852 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002853 Change = ChangeStatus::CHANGED;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002854 if (AliveSuccessors.empty() ||
2855 (I->isTerminator() && AliveSuccessors.size() < I->getNumSuccessors()))
2856 KnownDeadEnds.insert(I);
2857 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002858
2859 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
2860 << AliveSuccessors.size() << " UsedAssumedInformation: "
2861 << UsedAssumedInformation << "\n");
2862
2863 for (const Instruction *AliveSuccessor : AliveSuccessors) {
2864 if (!I->isTerminator()) {
2865 assert(AliveSuccessors.size() == 1 &&
2866 "Non-terminator expected to have a single successor!");
2867 Worklist.push_back(AliveSuccessor);
2868 } else {
2869 if (assumeLive(A, *AliveSuccessor->getParent()))
2870 Worklist.push_back(AliveSuccessor);
2871 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002872 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002873 }
2874
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002875 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002876
Johannes Doerfertd6207812019-08-07 22:32:38 +00002877 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002878 // Instead, indicating a pessimistic fixpoint will cause the state to be
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002879 // "invalid" and all queries to be answered conservatively without lookups.
2880 // To be in this state we have to (1) finished the exploration and (3) not
2881 // discovered any non-trivial dead end and (2) not ruled unreachable code
2882 // dead.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002883 if (ToBeExploredFrom.empty() &&
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002884 getAssociatedFunction()->size() == AssumedLiveBlocks.size() &&
2885 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
2886 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
2887 }))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002888 return indicatePessimisticFixpoint();
2889 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002890}
2891
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002892/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002893struct AAIsDeadCallSite final : AAIsDeadFunction {
2894 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002895
2896 /// See AbstractAttribute::initialize(...).
2897 void initialize(Attributor &A) override {
2898 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002899 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002900 // sense to specialize attributes for call sites instead of
2901 // redirecting requests to the callee.
2902 llvm_unreachable("Abstract attributes for liveness are not "
2903 "supported for call sites yet!");
2904 }
2905
2906 /// See AbstractAttribute::updateImpl(...).
2907 ChangeStatus updateImpl(Attributor &A) override {
2908 return indicatePessimisticFixpoint();
2909 }
2910
2911 /// See AbstractAttribute::trackStatistics()
2912 void trackStatistics() const override {}
2913};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002914
Hideto Ueno19c07af2019-07-23 08:16:17 +00002915/// -------------------- Dereferenceable Argument Attribute --------------------
2916
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002917template <>
2918ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
2919 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05002920 ChangeStatus CS0 =
2921 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
2922 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002923 return CS0 | CS1;
2924}
2925
Hideto Ueno70576ca2019-08-22 14:18:29 +00002926struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002927 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00002928 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00002929
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002930 void initialize(Attributor &A) override {
2931 SmallVector<Attribute, 4> Attrs;
2932 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
2933 Attrs);
2934 for (const Attribute &Attr : Attrs)
2935 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
2936
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002937 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002938
2939 const IRPosition &IRP = this->getIRPosition();
2940 bool IsFnInterface = IRP.isFnInterfaceKind();
2941 const Function *FnScope = IRP.getAnchorScope();
2942 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
2943 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002944 }
2945
Hideto Ueno19c07af2019-07-23 08:16:17 +00002946 /// See AbstractAttribute::getState()
2947 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00002948 StateType &getState() override { return *this; }
2949 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002950 /// }
2951
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002952 /// See AAFromMustBeExecutedContext
2953 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
2954 bool IsNonNull = false;
2955 bool TrackUse = false;
2956 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
2957 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
2958 takeKnownDerefBytesMaximum(DerefBytes);
2959 return TrackUse;
2960 }
2961
Johannes Doerferteccdf082019-08-05 23:35:12 +00002962 void getDeducedAttributes(LLVMContext &Ctx,
2963 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002964 // TODO: Add *_globally support
2965 if (isAssumedNonNull())
2966 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
2967 Ctx, getAssumedDereferenceableBytes()));
2968 else
2969 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
2970 Ctx, getAssumedDereferenceableBytes()));
2971 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002972
2973 /// See AbstractAttribute::getAsStr().
2974 const std::string getAsStr() const override {
2975 if (!getAssumedDereferenceableBytes())
2976 return "unknown-dereferenceable";
2977 return std::string("dereferenceable") +
2978 (isAssumedNonNull() ? "" : "_or_null") +
2979 (isAssumedGlobal() ? "_globally" : "") + "<" +
2980 std::to_string(getKnownDereferenceableBytes()) + "-" +
2981 std::to_string(getAssumedDereferenceableBytes()) + ">";
2982 }
2983};
2984
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002985/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002986struct AADereferenceableFloating
2987 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
2988 using Base =
2989 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
2990 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00002991
2992 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002993 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002994 ChangeStatus Change = Base::updateImpl(A);
2995
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002996 const DataLayout &DL = A.getDataLayout();
2997
2998 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
2999 unsigned IdxWidth =
3000 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
3001 APInt Offset(IdxWidth, 0);
3002 const Value *Base =
3003 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
3004
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003005 const auto &AA =
3006 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003007 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003008 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003009 // Use IR information if we did not strip anything.
3010 // TODO: track globally.
3011 bool CanBeNull;
3012 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
3013 T.GlobalState.indicatePessimisticFixpoint();
3014 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003015 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003016 DerefBytes = DS.DerefBytesState.getAssumed();
3017 T.GlobalState &= DS.GlobalState;
3018 }
3019
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003020 // For now we do not try to "increase" dereferenceability due to negative
3021 // indices as we first have to come up with code to deal with loops and
3022 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00003023 int64_t OffsetSExt = Offset.getSExtValue();
3024 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00003025 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003026
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003027 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00003028 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003029
Johannes Doerfert785fad32019-08-23 17:29:23 +00003030 if (this == &AA) {
3031 if (!Stripped) {
3032 // If nothing was stripped IR information is all we got.
3033 T.takeKnownDerefBytesMaximum(
3034 std::max(int64_t(0), DerefBytes - OffsetSExt));
3035 T.indicatePessimisticFixpoint();
3036 } else if (OffsetSExt > 0) {
3037 // If something was stripped but there is circular reasoning we look
3038 // for the offset. If it is positive we basically decrease the
3039 // dereferenceable bytes in a circluar loop now, which will simply
3040 // drive them down to the known value in a very slow way which we
3041 // can accelerate.
3042 T.indicatePessimisticFixpoint();
3043 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003044 }
3045
3046 return T.isValidState();
3047 };
3048
3049 DerefState T;
3050 if (!genericValueTraversal<AADereferenceable, DerefState>(
3051 A, getIRPosition(), *this, T, VisitValueCB))
3052 return indicatePessimisticFixpoint();
3053
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003054 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003055 }
3056
3057 /// See AbstractAttribute::trackStatistics()
3058 void trackStatistics() const override {
3059 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
3060 }
3061};
3062
3063/// Dereferenceable attribute for a return value.
3064struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003065 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
3066 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003067 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003068 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
3069 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003070
3071 /// See AbstractAttribute::trackStatistics()
3072 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003073 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003074 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003075};
3076
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003077/// Dereferenceable attribute for an argument
3078struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003079 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
3080 AADereferenceable, AADereferenceableImpl, DerefState> {
3081 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
3082 AADereferenceable, AADereferenceableImpl, DerefState>;
3083 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003084
3085 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003086 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00003087 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
3088 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003089};
3090
Hideto Ueno19c07af2019-07-23 08:16:17 +00003091/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003092struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003093 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003094 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003095
3096 /// See AbstractAttribute::trackStatistics()
3097 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003098 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003099 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003100};
3101
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003102/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003103struct AADereferenceableCallSiteReturned final
3104 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3105 AADereferenceable, AADereferenceableImpl> {
3106 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3107 AADereferenceable, AADereferenceableImpl>;
3108 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003109
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003110 /// See AbstractAttribute::trackStatistics()
3111 void trackStatistics() const override {
3112 STATS_DECLTRACK_CS_ATTR(dereferenceable);
3113 }
3114};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003115
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003116// ------------------------ Align Argument Attribute ------------------------
3117
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003118static unsigned int getKnownAlignForUse(Attributor &A,
3119 AbstractAttribute &QueryingAA,
3120 Value &AssociatedValue, const Use *U,
3121 const Instruction *I, bool &TrackUse) {
Hideto Ueno78a75022019-11-26 07:51:59 +00003122 // We need to follow common pointer manipulation uses to the accesses they
3123 // feed into.
3124 if (isa<CastInst>(I)) {
3125 TrackUse = true;
3126 return 0;
3127 }
3128 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
3129 if (GEP->hasAllConstantIndices()) {
3130 TrackUse = true;
3131 return 0;
3132 }
3133 }
3134
3135 unsigned Alignment = 0;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003136 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
3137 if (ICS.isBundleOperand(U) || ICS.isCallee(U))
3138 return 0;
3139
3140 unsigned ArgNo = ICS.getArgumentNo(U);
3141 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
3142 // As long as we only use known information there is no need to track
3143 // dependences here.
3144 auto &AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP,
3145 /* TrackDependence */ false);
Hideto Ueno78a75022019-11-26 07:51:59 +00003146 Alignment = AlignAA.getKnownAlign();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003147 }
3148
Hideto Ueno78a75022019-11-26 07:51:59 +00003149 const Value *UseV = U->get();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003150 if (auto *SI = dyn_cast<StoreInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003151 Alignment = SI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003152 else if (auto *LI = dyn_cast<LoadInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003153 Alignment = LI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003154
Hideto Ueno78a75022019-11-26 07:51:59 +00003155 if (Alignment <= 1)
3156 return 0;
3157
3158 auto &DL = A.getDataLayout();
3159 int64_t Offset;
3160
3161 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
3162 if (Base == &AssociatedValue) {
3163 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
3164 // So we can say that the maximum power of two which is a divisor of
3165 // gcd(Offset, Alignment) is an alignment.
3166
3167 uint32_t gcd =
3168 greatestCommonDivisor(uint32_t(abs((int32_t)Offset)), Alignment);
3169 Alignment = llvm::PowerOf2Floor(gcd);
3170 }
3171 }
3172
3173 return Alignment;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003174}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003175struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003176 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003177
Johannes Doerfert234eda52019-08-16 19:51:23 +00003178 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003179 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003180 SmallVector<Attribute, 4> Attrs;
3181 getAttrs({Attribute::Alignment}, Attrs);
3182 for (const Attribute &Attr : Attrs)
3183 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003184
3185 if (getIRPosition().isFnInterfaceKind() &&
3186 (!getAssociatedFunction() ||
3187 !getAssociatedFunction()->hasExactDefinition()))
3188 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003189 }
3190
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003191 /// See AbstractAttribute::manifest(...).
3192 ChangeStatus manifest(Attributor &A) override {
3193 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3194
3195 // Check for users that allow alignment annotations.
3196 Value &AnchorVal = getIRPosition().getAnchorValue();
3197 for (const Use &U : AnchorVal.uses()) {
3198 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
3199 if (SI->getPointerOperand() == &AnchorVal)
3200 if (SI->getAlignment() < getAssumedAlign()) {
3201 STATS_DECLTRACK(AAAlign, Store,
3202 "Number of times alignemnt added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00003203 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003204 Changed = ChangeStatus::CHANGED;
3205 }
3206 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
3207 if (LI->getPointerOperand() == &AnchorVal)
3208 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00003209 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003210 STATS_DECLTRACK(AAAlign, Load,
3211 "Number of times alignemnt added to a load");
3212 Changed = ChangeStatus::CHANGED;
3213 }
3214 }
3215 }
3216
Johannes Doerfert81df4522019-08-30 15:22:28 +00003217 return AAAlign::manifest(A) | Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003218 }
3219
Johannes Doerfert81df4522019-08-30 15:22:28 +00003220 // TODO: Provide a helper to determine the implied ABI alignment and check in
3221 // the existing manifest method and a new one for AAAlignImpl that value
3222 // to avoid making the alignment explicit if it did not improve.
3223
3224 /// See AbstractAttribute::getDeducedAttributes
3225 virtual void
3226 getDeducedAttributes(LLVMContext &Ctx,
3227 SmallVectorImpl<Attribute> &Attrs) const override {
3228 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00003229 Attrs.emplace_back(
3230 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00003231 }
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003232 /// See AAFromMustBeExecutedContext
3233 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3234 bool TrackUse = false;
3235
3236 unsigned int KnownAlign = getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
3237 takeKnownMaximum(KnownAlign);
3238
3239 return TrackUse;
3240 }
Johannes Doerfert81df4522019-08-30 15:22:28 +00003241
3242 /// See AbstractAttribute::getAsStr().
3243 const std::string getAsStr() const override {
3244 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
3245 "-" + std::to_string(getAssumedAlign()) + ">")
3246 : "unknown-align";
3247 }
3248};
3249
3250/// Align attribute for a floating value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003251struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
3252 using Base = AAFromMustBeExecutedContext<AAAlign, AAAlignImpl>;
3253 AAAlignFloating(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert81df4522019-08-30 15:22:28 +00003254
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003255 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00003256 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003257 Base::updateImpl(A);
3258
Johannes Doerfert234eda52019-08-16 19:51:23 +00003259 const DataLayout &DL = A.getDataLayout();
3260
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003261 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
3262 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003263 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
3264 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003265 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00003266 const MaybeAlign PA = V.getPointerAlignment(DL);
3267 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00003268 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003269 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003270 // Use abstract attribute information.
3271 const AAAlign::StateType &DS =
3272 static_cast<const AAAlign::StateType &>(AA.getState());
3273 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00003274 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003275 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003276 };
3277
3278 StateType T;
3279 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
3280 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003281 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003282
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003283 // TODO: If we know we visited all incoming values, thus no are assumed
3284 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003285 return clampStateAndIndicateChange(getState(), T);
3286 }
3287
3288 /// See AbstractAttribute::trackStatistics()
3289 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3290};
3291
3292/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003293struct AAAlignReturned final
3294 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003295 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003296 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003297
3298 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003299 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003300};
3301
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003302/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003303struct AAAlignArgument final
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003304 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3305 AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003306 AAAlignArgument(const IRPosition &IRP)
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003307 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3308 AAAlignImpl>(
3309 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003310
3311 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003312 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003313};
3314
Johannes Doerfert234eda52019-08-16 19:51:23 +00003315struct AAAlignCallSiteArgument final : AAAlignFloating {
3316 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003317
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003318 /// See AbstractAttribute::manifest(...).
3319 ChangeStatus manifest(Attributor &A) override {
3320 return AAAlignImpl::manifest(A);
3321 }
3322
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003323 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003324 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003325};
3326
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003327/// Align attribute deduction for a call site return value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003328struct AAAlignCallSiteReturned final
3329 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3330 AAAlignImpl> {
3331 using Base =
3332 AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3333 AAAlignImpl>;
3334 AAAlignCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003335
3336 /// See AbstractAttribute::initialize(...).
3337 void initialize(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003338 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003339 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003340 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003341 indicatePessimisticFixpoint();
3342 }
3343
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003344 /// See AbstractAttribute::trackStatistics()
3345 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3346};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003347
Johannes Doerferte83f3032019-08-05 23:22:05 +00003348/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00003349struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003350 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00003351
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003352 /// See AbstractAttribute::initialize(...).
3353 void initialize(Attributor &A) override {
3354 AANoReturn::initialize(A);
3355 Function *F = getAssociatedFunction();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05003356 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003357 indicatePessimisticFixpoint();
3358 }
3359
Johannes Doerferte83f3032019-08-05 23:22:05 +00003360 /// See AbstractAttribute::getAsStr().
3361 const std::string getAsStr() const override {
3362 return getAssumed() ? "noreturn" : "may-return";
3363 }
3364
Johannes Doerferte83f3032019-08-05 23:22:05 +00003365 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00003366 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003367 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003368 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003369 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00003370 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00003371 return ChangeStatus::UNCHANGED;
3372 }
3373};
3374
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003375struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003376 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003377
3378 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003379 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003380};
3381
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003382/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003383struct AANoReturnCallSite final : AANoReturnImpl {
3384 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
3385
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003386 /// See AbstractAttribute::updateImpl(...).
3387 ChangeStatus updateImpl(Attributor &A) override {
3388 // TODO: Once we have call site specific value information we can provide
3389 // call site specific liveness information and then it makes
3390 // sense to specialize attributes for call sites arguments instead of
3391 // redirecting requests to the callee argument.
3392 Function *F = getAssociatedFunction();
3393 const IRPosition &FnPos = IRPosition::function(*F);
3394 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
3395 return clampStateAndIndicateChange(
3396 getState(),
3397 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
3398 }
3399
3400 /// See AbstractAttribute::trackStatistics()
3401 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
3402};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003403
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003404/// ----------------------- Variable Capturing ---------------------------------
3405
3406/// A class to hold the state of for no-capture attributes.
3407struct AANoCaptureImpl : public AANoCapture {
3408 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
3409
3410 /// See AbstractAttribute::initialize(...).
3411 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003412 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
3413 indicateOptimisticFixpoint();
3414 return;
3415 }
3416 Function *AnchorScope = getAnchorScope();
3417 if (isFnInterfaceKind() &&
3418 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
3419 indicatePessimisticFixpoint();
3420 return;
3421 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003422
Johannes Doerfert72adda12019-10-10 05:33:21 +00003423 // You cannot "capture" null in the default address space.
3424 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
3425 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
3426 indicateOptimisticFixpoint();
3427 return;
3428 }
3429
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003430 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003431
3432 // Check what state the associated function can actually capture.
3433 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003434 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003435 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003436 indicatePessimisticFixpoint();
3437 }
3438
3439 /// See AbstractAttribute::updateImpl(...).
3440 ChangeStatus updateImpl(Attributor &A) override;
3441
3442 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
3443 virtual void
3444 getDeducedAttributes(LLVMContext &Ctx,
3445 SmallVectorImpl<Attribute> &Attrs) const override {
3446 if (!isAssumedNoCaptureMaybeReturned())
3447 return;
3448
Hideto Ueno37367642019-09-11 06:52:11 +00003449 if (getArgNo() >= 0) {
3450 if (isAssumedNoCapture())
3451 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
3452 else if (ManifestInternal)
3453 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
3454 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003455 }
3456
3457 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
3458 /// depending on the ability of the function associated with \p IRP to capture
3459 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00003460 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
3461 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05003462 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003463 // TODO: Once we have memory behavior attributes we should use them here.
3464
3465 // If we know we cannot communicate or write to memory, we do not care about
3466 // ptr2int anymore.
3467 if (F.onlyReadsMemory() && F.doesNotThrow() &&
3468 F.getReturnType()->isVoidTy()) {
3469 State.addKnownBits(NO_CAPTURE);
3470 return;
3471 }
3472
3473 // A function cannot capture state in memory if it only reads memory, it can
3474 // however return/throw state and the state might be influenced by the
3475 // pointer value, e.g., loading from a returned pointer might reveal a bit.
3476 if (F.onlyReadsMemory())
3477 State.addKnownBits(NOT_CAPTURED_IN_MEM);
3478
3479 // A function cannot communicate state back if it does not through
3480 // exceptions and doesn not return values.
3481 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
3482 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00003483
3484 // Check existing "returned" attributes.
3485 int ArgNo = IRP.getArgNo();
3486 if (F.doesNotThrow() && ArgNo >= 0) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01003487 for (unsigned u = 0, e = F.arg_size(); u < e; ++u)
Johannes Doerfert3839b572019-10-21 00:48:42 +00003488 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00003489 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00003490 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
3491 else if (F.onlyReadsMemory())
3492 State.addKnownBits(NO_CAPTURE);
3493 else
3494 State.addKnownBits(NOT_CAPTURED_IN_RET);
3495 break;
3496 }
3497 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003498 }
3499
3500 /// See AbstractState::getAsStr().
3501 const std::string getAsStr() const override {
3502 if (isKnownNoCapture())
3503 return "known not-captured";
3504 if (isAssumedNoCapture())
3505 return "assumed not-captured";
3506 if (isKnownNoCaptureMaybeReturned())
3507 return "known not-captured-maybe-returned";
3508 if (isAssumedNoCaptureMaybeReturned())
3509 return "assumed not-captured-maybe-returned";
3510 return "assumed-captured";
3511 }
3512};
3513
3514/// Attributor-aware capture tracker.
3515struct AACaptureUseTracker final : public CaptureTracker {
3516
3517 /// Create a capture tracker that can lookup in-flight abstract attributes
3518 /// through the Attributor \p A.
3519 ///
3520 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
3521 /// search is stopped. If a use leads to a return instruction,
3522 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
3523 /// If a use leads to a ptr2int which may capture the value,
3524 /// \p CapturedInInteger is set. If a use is found that is currently assumed
3525 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
3526 /// set. All values in \p PotentialCopies are later tracked as well. For every
3527 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
3528 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
3529 /// conservatively set to true.
3530 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05003531 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003532 SmallVectorImpl<const Value *> &PotentialCopies,
3533 unsigned &RemainingUsesToExplore)
3534 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
3535 PotentialCopies(PotentialCopies),
3536 RemainingUsesToExplore(RemainingUsesToExplore) {}
3537
3538 /// Determine if \p V maybe captured. *Also updates the state!*
3539 bool valueMayBeCaptured(const Value *V) {
3540 if (V->getType()->isPointerTy()) {
3541 PointerMayBeCaptured(V, this);
3542 } else {
3543 State.indicatePessimisticFixpoint();
3544 }
3545 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3546 }
3547
3548 /// See CaptureTracker::tooManyUses().
3549 void tooManyUses() override {
3550 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
3551 }
3552
3553 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
3554 if (CaptureTracker::isDereferenceableOrNull(O, DL))
3555 return true;
3556 const auto &DerefAA =
3557 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
3558 return DerefAA.getAssumedDereferenceableBytes();
3559 }
3560
3561 /// See CaptureTracker::captured(...).
3562 bool captured(const Use *U) override {
3563 Instruction *UInst = cast<Instruction>(U->getUser());
3564 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3565 << "\n");
3566
3567 // Because we may reuse the tracker multiple times we keep track of the
3568 // number of explored uses ourselves as well.
3569 if (RemainingUsesToExplore-- == 0) {
3570 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3571 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3572 /* Return */ true);
3573 }
3574
3575 // Deal with ptr2int by following uses.
3576 if (isa<PtrToIntInst>(UInst)) {
3577 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3578 return valueMayBeCaptured(UInst);
3579 }
3580
3581 // Explicitly catch return instructions.
3582 if (isa<ReturnInst>(UInst))
3583 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3584 /* Return */ true);
3585
3586 // For now we only use special logic for call sites. However, the tracker
3587 // itself knows about a lot of other non-capturing cases already.
3588 CallSite CS(UInst);
3589 if (!CS || !CS.isArgOperand(U))
3590 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3591 /* Return */ true);
3592
3593 unsigned ArgNo = CS.getArgumentNo(U);
3594 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3595 // If we have a abstract no-capture attribute for the argument we can use
3596 // it to justify a non-capture attribute here. This allows recursion!
3597 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3598 if (ArgNoCaptureAA.isAssumedNoCapture())
3599 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3600 /* Return */ false);
3601 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3602 addPotentialCopy(CS);
3603 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3604 /* Return */ false);
3605 }
3606
3607 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3608 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3609 /* Return */ true);
3610 }
3611
3612 /// Register \p CS as potential copy of the value we are checking.
3613 void addPotentialCopy(CallSite CS) {
3614 PotentialCopies.push_back(CS.getInstruction());
3615 }
3616
3617 /// See CaptureTracker::shouldExplore(...).
3618 bool shouldExplore(const Use *U) override {
3619 // Check liveness.
3620 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3621 }
3622
3623 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3624 /// \p CapturedInRet, then return the appropriate value for use in the
3625 /// CaptureTracker::captured() interface.
3626 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3627 bool CapturedInRet) {
3628 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
3629 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
3630 if (CapturedInMem)
3631 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
3632 if (CapturedInInt)
3633 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
3634 if (CapturedInRet)
3635 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
3636 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3637 }
3638
3639private:
3640 /// The attributor providing in-flight abstract attributes.
3641 Attributor &A;
3642
3643 /// The abstract attribute currently updated.
3644 AANoCapture &NoCaptureAA;
3645
3646 /// The abstract liveness state.
3647 const AAIsDead &IsDeadAA;
3648
3649 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05003650 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003651
3652 /// Set of potential copies of the tracked value.
3653 SmallVectorImpl<const Value *> &PotentialCopies;
3654
3655 /// Global counter to limit the number of explored uses.
3656 unsigned &RemainingUsesToExplore;
3657};
3658
3659ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
3660 const IRPosition &IRP = getIRPosition();
3661 const Value *V =
3662 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
3663 if (!V)
3664 return indicatePessimisticFixpoint();
3665
3666 const Function *F =
3667 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
3668 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00003669 const IRPosition &FnPos = IRPosition::function(*F);
3670 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, FnPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003671
3672 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003673
Johannes Doerfert3839b572019-10-21 00:48:42 +00003674 // Readonly means we cannot capture through memory.
3675 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3676 if (FnMemAA.isAssumedReadOnly()) {
3677 T.addKnownBits(NOT_CAPTURED_IN_MEM);
3678 if (FnMemAA.isKnownReadOnly())
3679 addKnownBits(NOT_CAPTURED_IN_MEM);
3680 }
3681
3682 // Make sure all returned values are different than the underlying value.
3683 // TODO: we could do this in a more sophisticated way inside
3684 // AAReturnedValues, e.g., track all values that escape through returns
3685 // directly somehow.
3686 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
3687 bool SeenConstant = false;
3688 for (auto &It : RVAA.returned_values()) {
3689 if (isa<Constant>(It.first)) {
3690 if (SeenConstant)
3691 return false;
3692 SeenConstant = true;
3693 } else if (!isa<Argument>(It.first) ||
3694 It.first == getAssociatedArgument())
3695 return false;
3696 }
3697 return true;
3698 };
3699
3700 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, FnPos);
3701 if (NoUnwindAA.isAssumedNoUnwind()) {
3702 bool IsVoidTy = F->getReturnType()->isVoidTy();
3703 const AAReturnedValues *RVAA =
3704 IsVoidTy ? nullptr : &A.getAAFor<AAReturnedValues>(*this, FnPos);
3705 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
3706 T.addKnownBits(NOT_CAPTURED_IN_RET);
3707 if (T.isKnown(NOT_CAPTURED_IN_MEM))
3708 return ChangeStatus::UNCHANGED;
3709 if (NoUnwindAA.isKnownNoUnwind() &&
3710 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
3711 addKnownBits(NOT_CAPTURED_IN_RET);
3712 if (isKnown(NOT_CAPTURED_IN_MEM))
3713 return indicateOptimisticFixpoint();
3714 }
3715 }
3716 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003717
3718 // Use the CaptureTracker interface and logic with the specialized tracker,
3719 // defined in AACaptureUseTracker, that can look at in-flight abstract
3720 // attributes and directly updates the assumed state.
3721 SmallVector<const Value *, 4> PotentialCopies;
3722 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
3723 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
3724 RemainingUsesToExplore);
3725
3726 // Check all potential copies of the associated value until we can assume
3727 // none will be captured or we have to assume at least one might be.
3728 unsigned Idx = 0;
3729 PotentialCopies.push_back(V);
3730 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
3731 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
3732
Johannes Doerfert1a746452019-10-20 22:28:49 -05003733 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003734 auto Assumed = S.getAssumed();
3735 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05003736 if (!isAssumedNoCaptureMaybeReturned())
3737 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003738 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3739 : ChangeStatus::CHANGED;
3740}
3741
3742/// NoCapture attribute for function arguments.
3743struct AANoCaptureArgument final : AANoCaptureImpl {
3744 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3745
3746 /// See AbstractAttribute::trackStatistics()
3747 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
3748};
3749
3750/// NoCapture attribute for call site arguments.
3751struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
3752 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3753
3754 /// See AbstractAttribute::updateImpl(...).
3755 ChangeStatus updateImpl(Attributor &A) override {
3756 // TODO: Once we have call site specific value information we can provide
3757 // call site specific liveness information and then it makes
3758 // sense to specialize attributes for call sites arguments instead of
3759 // redirecting requests to the callee argument.
3760 Argument *Arg = getAssociatedArgument();
3761 if (!Arg)
3762 return indicatePessimisticFixpoint();
3763 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3764 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
3765 return clampStateAndIndicateChange(
3766 getState(),
3767 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3768 }
3769
3770 /// See AbstractAttribute::trackStatistics()
3771 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
3772};
3773
3774/// NoCapture attribute for floating values.
3775struct AANoCaptureFloating final : AANoCaptureImpl {
3776 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3777
3778 /// See AbstractAttribute::trackStatistics()
3779 void trackStatistics() const override {
3780 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
3781 }
3782};
3783
3784/// NoCapture attribute for function return value.
3785struct AANoCaptureReturned final : AANoCaptureImpl {
3786 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
3787 llvm_unreachable("NoCapture is not applicable to function returns!");
3788 }
3789
3790 /// See AbstractAttribute::initialize(...).
3791 void initialize(Attributor &A) override {
3792 llvm_unreachable("NoCapture is not applicable to function returns!");
3793 }
3794
3795 /// See AbstractAttribute::updateImpl(...).
3796 ChangeStatus updateImpl(Attributor &A) override {
3797 llvm_unreachable("NoCapture is not applicable to function returns!");
3798 }
3799
3800 /// See AbstractAttribute::trackStatistics()
3801 void trackStatistics() const override {}
3802};
3803
3804/// NoCapture attribute deduction for a call site return value.
3805struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
3806 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3807
3808 /// See AbstractAttribute::trackStatistics()
3809 void trackStatistics() const override {
3810 STATS_DECLTRACK_CSRET_ATTR(nocapture)
3811 }
3812};
3813
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003814/// ------------------ Value Simplify Attribute ----------------------------
3815struct AAValueSimplifyImpl : AAValueSimplify {
3816 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
3817
3818 /// See AbstractAttribute::getAsStr().
3819 const std::string getAsStr() const override {
3820 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
3821 : "not-simple";
3822 }
3823
3824 /// See AbstractAttribute::trackStatistics()
3825 void trackStatistics() const override {}
3826
3827 /// See AAValueSimplify::getAssumedSimplifiedValue()
3828 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
3829 if (!getAssumed())
3830 return const_cast<Value *>(&getAssociatedValue());
3831 return SimplifiedAssociatedValue;
3832 }
3833 void initialize(Attributor &A) override {}
3834
3835 /// Helper function for querying AAValueSimplify and updating candicate.
3836 /// \param QueryingValue Value trying to unify with SimplifiedValue
3837 /// \param AccumulatedSimplifiedValue Current simplification result.
3838 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
3839 Value &QueryingValue,
3840 Optional<Value *> &AccumulatedSimplifiedValue) {
3841 // FIXME: Add a typecast support.
3842
3843 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
3844 QueryingAA, IRPosition::value(QueryingValue));
3845
3846 Optional<Value *> QueryingValueSimplified =
3847 ValueSimpifyAA.getAssumedSimplifiedValue(A);
3848
3849 if (!QueryingValueSimplified.hasValue())
3850 return true;
3851
3852 if (!QueryingValueSimplified.getValue())
3853 return false;
3854
3855 Value &QueryingValueSimplifiedUnwrapped =
3856 *QueryingValueSimplified.getValue();
3857
3858 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
3859 return true;
3860
3861 if (AccumulatedSimplifiedValue.hasValue())
3862 return AccumulatedSimplifiedValue == QueryingValueSimplified;
3863
3864 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
3865 << " is assumed to be "
3866 << QueryingValueSimplifiedUnwrapped << "\n");
3867
3868 AccumulatedSimplifiedValue = QueryingValueSimplified;
3869 return true;
3870 }
3871
3872 /// See AbstractAttribute::manifest(...).
3873 ChangeStatus manifest(Attributor &A) override {
3874 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3875
3876 if (!SimplifiedAssociatedValue.hasValue() ||
3877 !SimplifiedAssociatedValue.getValue())
3878 return Changed;
3879
3880 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
3881 // We can replace the AssociatedValue with the constant.
3882 Value &V = getAssociatedValue();
3883 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
3884 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
3885 << "\n");
3886 V.replaceAllUsesWith(C);
3887 Changed = ChangeStatus::CHANGED;
3888 }
3889 }
3890
3891 return Changed | AAValueSimplify::manifest(A);
3892 }
3893
3894protected:
3895 // An assumed simplified value. Initially, it is set to Optional::None, which
3896 // means that the value is not clear under current assumption. If in the
3897 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
3898 // returns orignal associated value.
3899 Optional<Value *> SimplifiedAssociatedValue;
3900};
3901
3902struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
3903 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3904
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05003905 void initialize(Attributor &A) override {
3906 AAValueSimplifyImpl::initialize(A);
3907 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
3908 indicatePessimisticFixpoint();
3909 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
3910 /* IgnoreSubsumingPositions */ true))
3911 indicatePessimisticFixpoint();
3912 }
3913
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003914 /// See AbstractAttribute::updateImpl(...).
3915 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05003916 // Byval is only replacable if it is readonly otherwise we would write into
3917 // the replaced value and not the copy that byval creates implicitly.
3918 Argument *Arg = getAssociatedArgument();
3919 if (Arg->hasByValAttr()) {
3920 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
3921 if (!MemAA.isAssumedReadOnly())
3922 return indicatePessimisticFixpoint();
3923 }
3924
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003925 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3926
Johannes Doerfert661db042019-10-07 23:14:58 +00003927 auto PredForCallSite = [&](AbstractCallSite ACS) {
3928 // Check if we have an associated argument or not (which can happen for
3929 // callback calls).
Johannes Doerferte360ee62019-11-01 18:45:25 -05003930 Value *ArgOp = ACS.getCallArgOperand(getArgNo());
3931 if (!ArgOp)
3932 return false;
3933 // We can only propagate thread independent values through callbacks.
3934 // This is different to direct/indirect call sites because for them we
3935 // know the thread executing the caller and callee is the same. For
3936 // callbacks this is not guaranteed, thus a thread dependent value could
3937 // be different for the caller and callee, making it invalid to propagate.
3938 if (ACS.isCallbackCall())
3939 if (auto *C =dyn_cast<Constant>(ArgOp))
3940 if (C->isThreadDependent())
3941 return false;
3942 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003943 };
3944
3945 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
3946 return indicatePessimisticFixpoint();
3947
3948 // If a candicate was found in this update, return CHANGED.
3949 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3950 ? ChangeStatus::UNCHANGED
3951 : ChangeStatus ::CHANGED;
3952 }
3953
3954 /// See AbstractAttribute::trackStatistics()
3955 void trackStatistics() const override {
3956 STATS_DECLTRACK_ARG_ATTR(value_simplify)
3957 }
3958};
3959
3960struct AAValueSimplifyReturned : AAValueSimplifyImpl {
3961 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3962
3963 /// See AbstractAttribute::updateImpl(...).
3964 ChangeStatus updateImpl(Attributor &A) override {
3965 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3966
3967 auto PredForReturned = [&](Value &V) {
3968 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3969 };
3970
3971 if (!A.checkForAllReturnedValues(PredForReturned, *this))
3972 return indicatePessimisticFixpoint();
3973
3974 // If a candicate was found in this update, return CHANGED.
3975 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3976 ? ChangeStatus::UNCHANGED
3977 : ChangeStatus ::CHANGED;
3978 }
3979 /// See AbstractAttribute::trackStatistics()
3980 void trackStatistics() const override {
3981 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
3982 }
3983};
3984
3985struct AAValueSimplifyFloating : AAValueSimplifyImpl {
3986 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3987
3988 /// See AbstractAttribute::initialize(...).
3989 void initialize(Attributor &A) override {
3990 Value &V = getAnchorValue();
3991
3992 // TODO: add other stuffs
3993 if (isa<Constant>(V) || isa<UndefValue>(V))
3994 indicatePessimisticFixpoint();
3995 }
3996
3997 /// See AbstractAttribute::updateImpl(...).
3998 ChangeStatus updateImpl(Attributor &A) override {
3999 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4000
4001 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
4002 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
4003 if (!Stripped && this == &AA) {
4004 // TODO: Look the instruction and check recursively.
4005 LLVM_DEBUG(
4006 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
4007 << V << "\n");
4008 indicatePessimisticFixpoint();
4009 return false;
4010 }
4011 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4012 };
4013
4014 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
4015 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
4016 VisitValueCB))
4017 return indicatePessimisticFixpoint();
4018
4019 // If a candicate was found in this update, return CHANGED.
4020
4021 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4022 ? ChangeStatus::UNCHANGED
4023 : ChangeStatus ::CHANGED;
4024 }
4025
4026 /// See AbstractAttribute::trackStatistics()
4027 void trackStatistics() const override {
4028 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
4029 }
4030};
4031
4032struct AAValueSimplifyFunction : AAValueSimplifyImpl {
4033 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4034
4035 /// See AbstractAttribute::initialize(...).
4036 void initialize(Attributor &A) override {
4037 SimplifiedAssociatedValue = &getAnchorValue();
4038 indicateOptimisticFixpoint();
4039 }
4040 /// See AbstractAttribute::initialize(...).
4041 ChangeStatus updateImpl(Attributor &A) override {
4042 llvm_unreachable(
4043 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
4044 }
4045 /// See AbstractAttribute::trackStatistics()
4046 void trackStatistics() const override {
4047 STATS_DECLTRACK_FN_ATTR(value_simplify)
4048 }
4049};
4050
4051struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
4052 AAValueSimplifyCallSite(const IRPosition &IRP)
4053 : AAValueSimplifyFunction(IRP) {}
4054 /// See AbstractAttribute::trackStatistics()
4055 void trackStatistics() const override {
4056 STATS_DECLTRACK_CS_ATTR(value_simplify)
4057 }
4058};
4059
4060struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
4061 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
4062 : AAValueSimplifyReturned(IRP) {}
4063
4064 void trackStatistics() const override {
4065 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
4066 }
4067};
4068struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
4069 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
4070 : AAValueSimplifyFloating(IRP) {}
4071
4072 void trackStatistics() const override {
4073 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
4074 }
4075};
4076
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004077/// ----------------------- Heap-To-Stack Conversion ---------------------------
4078struct AAHeapToStackImpl : public AAHeapToStack {
4079 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
4080
4081 const std::string getAsStr() const override {
4082 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
4083 }
4084
4085 ChangeStatus manifest(Attributor &A) override {
4086 assert(getState().isValidState() &&
4087 "Attempted to manifest an invalid state!");
4088
4089 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4090 Function *F = getAssociatedFunction();
4091 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4092
4093 for (Instruction *MallocCall : MallocCalls) {
4094 // This malloc cannot be replaced.
4095 if (BadMallocCalls.count(MallocCall))
4096 continue;
4097
4098 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
4099 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
4100 A.deleteAfterManifest(*FreeCall);
4101 HasChanged = ChangeStatus::CHANGED;
4102 }
4103
4104 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
4105 << "\n");
4106
4107 Constant *Size;
4108 if (isCallocLikeFn(MallocCall, TLI)) {
4109 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
4110 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
4111 APInt TotalSize = SizeT->getValue() * Num->getValue();
4112 Size =
4113 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
4114 } else {
4115 Size = cast<ConstantInt>(MallocCall->getOperand(0));
4116 }
4117
4118 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
4119 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
4120 Size, "", MallocCall->getNextNode());
4121
4122 if (AI->getType() != MallocCall->getType())
4123 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
4124 AI->getNextNode());
4125
4126 MallocCall->replaceAllUsesWith(AI);
4127
4128 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
4129 auto *NBB = II->getNormalDest();
4130 BranchInst::Create(NBB, MallocCall->getParent());
4131 A.deleteAfterManifest(*MallocCall);
4132 } else {
4133 A.deleteAfterManifest(*MallocCall);
4134 }
4135
4136 if (isCallocLikeFn(MallocCall, TLI)) {
4137 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
4138 AI->getNextNode());
4139 Value *Ops[] = {
4140 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
4141 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
4142
4143 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
4144 Module *M = F->getParent();
4145 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
4146 CallInst::Create(Fn, Ops, "", BI->getNextNode());
4147 }
4148 HasChanged = ChangeStatus::CHANGED;
4149 }
4150
4151 return HasChanged;
4152 }
4153
4154 /// Collection of all malloc calls in a function.
4155 SmallSetVector<Instruction *, 4> MallocCalls;
4156
4157 /// Collection of malloc calls that cannot be converted.
4158 DenseSet<const Instruction *> BadMallocCalls;
4159
4160 /// A map for each malloc call to the set of associated free calls.
4161 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
4162
4163 ChangeStatus updateImpl(Attributor &A) override;
4164};
4165
4166ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
4167 const Function *F = getAssociatedFunction();
4168 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4169
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004170 MustBeExecutedContextExplorer &Explorer =
4171 A.getInfoCache().getMustBeExecutedContextExplorer();
4172
4173 auto FreeCheck = [&](Instruction &I) {
4174 const auto &Frees = FreesForMalloc.lookup(&I);
4175 if (Frees.size() != 1)
4176 return false;
4177 Instruction *UniqueFree = *Frees.begin();
4178 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
4179 };
4180
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004181 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004182 bool ValidUsesOnly = true;
4183 bool MustUse = true;
4184
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004185 SmallPtrSet<const Use *, 8> Visited;
4186 SmallVector<const Use *, 8> Worklist;
4187
4188 for (Use &U : I.uses())
4189 Worklist.push_back(&U);
4190
4191 while (!Worklist.empty()) {
4192 const Use *U = Worklist.pop_back_val();
4193 if (!Visited.insert(U).second)
4194 continue;
4195
4196 auto *UserI = U->getUser();
4197
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004198 if (isa<LoadInst>(UserI))
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004199 continue;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004200 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
4201 if (SI->getValueOperand() == U->get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004202 LLVM_DEBUG(dbgs()
4203 << "[H2S] escaping store to memory: " << *UserI << "\n");
4204 ValidUsesOnly = false;
4205 } else {
4206 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004207 }
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004208 continue;
4209 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004210
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004211 if (auto *CB = dyn_cast<CallBase>(UserI)) {
4212 if (!CB->isArgOperand(U))
4213 continue;
4214
4215 if (CB->isLifetimeStartOrEnd())
4216 continue;
4217
4218 // Record malloc.
4219 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004220 if (MustUse) {
4221 FreesForMalloc[&I].insert(
4222 cast<Instruction>(const_cast<User *>(UserI)));
4223 } else {
4224 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
4225 << *UserI << "\n");
4226 ValidUsesOnly = false;
4227 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004228 continue;
4229 }
4230
Stefan Stipanovicc250ebf2019-11-10 21:45:11 +01004231 unsigned ArgNo = CB->getArgOperandNo(U);
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004232
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004233 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
4234 *this, IRPosition::callsite_argument(*CB, ArgNo));
4235
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004236 // If a callsite argument use is nofree, we are fine.
4237 const auto &ArgNoFreeAA = A.getAAFor<AANoFree>(
4238 *this, IRPosition::callsite_argument(*CB, ArgNo));
4239
4240 if (!NoCaptureAA.isAssumedNoCapture() || !ArgNoFreeAA.isAssumedNoFree()) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004241 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004242 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004243 }
4244 continue;
4245 }
4246
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004247 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
4248 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
4249 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004250 for (Use &U : UserI->uses())
4251 Worklist.push_back(&U);
4252 continue;
4253 }
4254
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004255 // Unknown user for which we can not track uses further (in a way that
4256 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004257 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004258 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004259 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004260 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004261 };
4262
4263 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004264 if (BadMallocCalls.count(&I))
4265 return true;
4266
4267 bool IsMalloc = isMallocLikeFn(&I, TLI);
4268 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
4269 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004270 BadMallocCalls.insert(&I);
4271 return true;
4272 }
4273
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004274 if (IsMalloc) {
4275 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
4276 if (Size->getValue().sle(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004277 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004278 MallocCalls.insert(&I);
4279 return true;
4280 }
4281 } else if (IsCalloc) {
4282 bool Overflow = false;
4283 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
4284 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
4285 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01004286 .sle(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004287 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004288 MallocCalls.insert(&I);
4289 return true;
4290 }
4291 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004292
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004293 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004294 return true;
4295 };
4296
4297 size_t NumBadMallocs = BadMallocCalls.size();
4298
4299 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
4300
4301 if (NumBadMallocs != BadMallocCalls.size())
4302 return ChangeStatus::CHANGED;
4303
4304 return ChangeStatus::UNCHANGED;
4305}
4306
4307struct AAHeapToStackFunction final : public AAHeapToStackImpl {
4308 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
4309
4310 /// See AbstractAttribute::trackStatistics()
4311 void trackStatistics() const override {
4312 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004313 "Number of malloc calls converted to allocas");
4314 for (auto *C : MallocCalls)
4315 if (!BadMallocCalls.count(C))
4316 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004317 }
4318};
4319
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004320/// -------------------- Memory Behavior Attributes ----------------------------
4321/// Includes read-none, read-only, and write-only.
4322/// ----------------------------------------------------------------------------
4323struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
4324 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
4325
4326 /// See AbstractAttribute::initialize(...).
4327 void initialize(Attributor &A) override {
4328 intersectAssumedBits(BEST_STATE);
4329 getKnownStateFromValue(getIRPosition(), getState());
4330 IRAttribute::initialize(A);
4331 }
4332
4333 /// Return the memory behavior information encoded in the IR for \p IRP.
4334 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert1a746452019-10-20 22:28:49 -05004335 BitIntegerState &State) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004336 SmallVector<Attribute, 2> Attrs;
4337 IRP.getAttrs(AttrKinds, Attrs);
4338 for (const Attribute &Attr : Attrs) {
4339 switch (Attr.getKindAsEnum()) {
4340 case Attribute::ReadNone:
4341 State.addKnownBits(NO_ACCESSES);
4342 break;
4343 case Attribute::ReadOnly:
4344 State.addKnownBits(NO_WRITES);
4345 break;
4346 case Attribute::WriteOnly:
4347 State.addKnownBits(NO_READS);
4348 break;
4349 default:
4350 llvm_unreachable("Unexpcted attribute!");
4351 }
4352 }
4353
4354 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
4355 if (!I->mayReadFromMemory())
4356 State.addKnownBits(NO_READS);
4357 if (!I->mayWriteToMemory())
4358 State.addKnownBits(NO_WRITES);
4359 }
4360 }
4361
4362 /// See AbstractAttribute::getDeducedAttributes(...).
4363 void getDeducedAttributes(LLVMContext &Ctx,
4364 SmallVectorImpl<Attribute> &Attrs) const override {
4365 assert(Attrs.size() == 0);
4366 if (isAssumedReadNone())
4367 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
4368 else if (isAssumedReadOnly())
4369 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
4370 else if (isAssumedWriteOnly())
4371 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
4372 assert(Attrs.size() <= 1);
4373 }
4374
4375 /// See AbstractAttribute::manifest(...).
4376 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05004377 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004378
4379 // Check if we would improve the existing attributes first.
4380 SmallVector<Attribute, 4> DeducedAttrs;
4381 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
4382 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
4383 return IRP.hasAttr(Attr.getKindAsEnum(),
4384 /* IgnoreSubsumingPositions */ true);
4385 }))
4386 return ChangeStatus::UNCHANGED;
4387
4388 // Clear existing attributes.
4389 IRP.removeAttrs(AttrKinds);
4390
4391 // Use the generic manifest method.
4392 return IRAttribute::manifest(A);
4393 }
4394
4395 /// See AbstractState::getAsStr().
4396 const std::string getAsStr() const override {
4397 if (isAssumedReadNone())
4398 return "readnone";
4399 if (isAssumedReadOnly())
4400 return "readonly";
4401 if (isAssumedWriteOnly())
4402 return "writeonly";
4403 return "may-read/write";
4404 }
4405
4406 /// The set of IR attributes AAMemoryBehavior deals with.
4407 static const Attribute::AttrKind AttrKinds[3];
4408};
4409
4410const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
4411 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
4412
4413/// Memory behavior attribute for a floating value.
4414struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
4415 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4416
4417 /// See AbstractAttribute::initialize(...).
4418 void initialize(Attributor &A) override {
4419 AAMemoryBehaviorImpl::initialize(A);
4420 // Initialize the use vector with all direct uses of the associated value.
4421 for (const Use &U : getAssociatedValue().uses())
4422 Uses.insert(&U);
4423 }
4424
4425 /// See AbstractAttribute::updateImpl(...).
4426 ChangeStatus updateImpl(Attributor &A) override;
4427
4428 /// See AbstractAttribute::trackStatistics()
4429 void trackStatistics() const override {
4430 if (isAssumedReadNone())
4431 STATS_DECLTRACK_FLOATING_ATTR(readnone)
4432 else if (isAssumedReadOnly())
4433 STATS_DECLTRACK_FLOATING_ATTR(readonly)
4434 else if (isAssumedWriteOnly())
4435 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
4436 }
4437
4438private:
4439 /// Return true if users of \p UserI might access the underlying
4440 /// variable/location described by \p U and should therefore be analyzed.
4441 bool followUsersOfUseIn(Attributor &A, const Use *U,
4442 const Instruction *UserI);
4443
4444 /// Update the state according to the effect of use \p U in \p UserI.
4445 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
4446
4447protected:
4448 /// Container for (transitive) uses of the associated argument.
4449 SetVector<const Use *> Uses;
4450};
4451
4452/// Memory behavior attribute for function argument.
4453struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
4454 AAMemoryBehaviorArgument(const IRPosition &IRP)
4455 : AAMemoryBehaviorFloating(IRP) {}
4456
4457 /// See AbstractAttribute::initialize(...).
4458 void initialize(Attributor &A) override {
4459 AAMemoryBehaviorFloating::initialize(A);
4460
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004461 // Initialize the use vector with all direct uses of the associated value.
4462 Argument *Arg = getAssociatedArgument();
4463 if (!Arg || !Arg->getParent()->hasExactDefinition())
4464 indicatePessimisticFixpoint();
4465 }
4466
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004467 ChangeStatus manifest(Attributor &A) override {
4468 // TODO: From readattrs.ll: "inalloca parameters are always
4469 // considered written"
4470 if (hasAttr({Attribute::InAlloca})) {
4471 removeKnownBits(NO_WRITES);
4472 removeAssumedBits(NO_WRITES);
4473 }
4474 return AAMemoryBehaviorFloating::manifest(A);
4475 }
4476
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004477 /// See AbstractAttribute::trackStatistics()
4478 void trackStatistics() const override {
4479 if (isAssumedReadNone())
4480 STATS_DECLTRACK_ARG_ATTR(readnone)
4481 else if (isAssumedReadOnly())
4482 STATS_DECLTRACK_ARG_ATTR(readonly)
4483 else if (isAssumedWriteOnly())
4484 STATS_DECLTRACK_ARG_ATTR(writeonly)
4485 }
4486};
4487
4488struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
4489 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
4490 : AAMemoryBehaviorArgument(IRP) {}
4491
4492 /// See AbstractAttribute::updateImpl(...).
4493 ChangeStatus updateImpl(Attributor &A) override {
4494 // TODO: Once we have call site specific value information we can provide
4495 // call site specific liveness liveness information and then it makes
4496 // sense to specialize attributes for call sites arguments instead of
4497 // redirecting requests to the callee argument.
4498 Argument *Arg = getAssociatedArgument();
4499 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4500 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4501 return clampStateAndIndicateChange(
4502 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05004503 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004504 }
4505
4506 /// See AbstractAttribute::trackStatistics()
4507 void trackStatistics() const override {
4508 if (isAssumedReadNone())
4509 STATS_DECLTRACK_CSARG_ATTR(readnone)
4510 else if (isAssumedReadOnly())
4511 STATS_DECLTRACK_CSARG_ATTR(readonly)
4512 else if (isAssumedWriteOnly())
4513 STATS_DECLTRACK_CSARG_ATTR(writeonly)
4514 }
4515};
4516
4517/// Memory behavior attribute for a call site return position.
4518struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
4519 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
4520 : AAMemoryBehaviorFloating(IRP) {}
4521
4522 /// See AbstractAttribute::manifest(...).
4523 ChangeStatus manifest(Attributor &A) override {
4524 // We do not annotate returned values.
4525 return ChangeStatus::UNCHANGED;
4526 }
4527
4528 /// See AbstractAttribute::trackStatistics()
4529 void trackStatistics() const override {}
4530};
4531
4532/// An AA to represent the memory behavior function attributes.
4533struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
4534 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4535
4536 /// See AbstractAttribute::updateImpl(Attributor &A).
4537 virtual ChangeStatus updateImpl(Attributor &A) override;
4538
4539 /// See AbstractAttribute::manifest(...).
4540 ChangeStatus manifest(Attributor &A) override {
4541 Function &F = cast<Function>(getAnchorValue());
4542 if (isAssumedReadNone()) {
4543 F.removeFnAttr(Attribute::ArgMemOnly);
4544 F.removeFnAttr(Attribute::InaccessibleMemOnly);
4545 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
4546 }
4547 return AAMemoryBehaviorImpl::manifest(A);
4548 }
4549
4550 /// See AbstractAttribute::trackStatistics()
4551 void trackStatistics() const override {
4552 if (isAssumedReadNone())
4553 STATS_DECLTRACK_FN_ATTR(readnone)
4554 else if (isAssumedReadOnly())
4555 STATS_DECLTRACK_FN_ATTR(readonly)
4556 else if (isAssumedWriteOnly())
4557 STATS_DECLTRACK_FN_ATTR(writeonly)
4558 }
4559};
4560
4561/// AAMemoryBehavior attribute for call sites.
4562struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
4563 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4564
4565 /// See AbstractAttribute::initialize(...).
4566 void initialize(Attributor &A) override {
4567 AAMemoryBehaviorImpl::initialize(A);
4568 Function *F = getAssociatedFunction();
4569 if (!F || !F->hasExactDefinition())
4570 indicatePessimisticFixpoint();
4571 }
4572
4573 /// See AbstractAttribute::updateImpl(...).
4574 ChangeStatus updateImpl(Attributor &A) override {
4575 // TODO: Once we have call site specific value information we can provide
4576 // call site specific liveness liveness information and then it makes
4577 // sense to specialize attributes for call sites arguments instead of
4578 // redirecting requests to the callee argument.
4579 Function *F = getAssociatedFunction();
4580 const IRPosition &FnPos = IRPosition::function(*F);
4581 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4582 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05004583 getState(),
4584 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004585 }
4586
4587 /// See AbstractAttribute::trackStatistics()
4588 void trackStatistics() const override {
4589 if (isAssumedReadNone())
4590 STATS_DECLTRACK_CS_ATTR(readnone)
4591 else if (isAssumedReadOnly())
4592 STATS_DECLTRACK_CS_ATTR(readonly)
4593 else if (isAssumedWriteOnly())
4594 STATS_DECLTRACK_CS_ATTR(writeonly)
4595 }
4596};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00004597} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004598
4599ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
4600
4601 // The current assumed state used to determine a change.
4602 auto AssumedState = getAssumed();
4603
4604 auto CheckRWInst = [&](Instruction &I) {
4605 // If the instruction has an own memory behavior state, use it to restrict
4606 // the local state. No further analysis is required as the other memory
4607 // state is as optimistic as it gets.
4608 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
4609 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
4610 *this, IRPosition::callsite_function(ICS));
4611 intersectAssumedBits(MemBehaviorAA.getAssumed());
4612 return !isAtFixpoint();
4613 }
4614
4615 // Remove access kind modifiers if necessary.
4616 if (I.mayReadFromMemory())
4617 removeAssumedBits(NO_READS);
4618 if (I.mayWriteToMemory())
4619 removeAssumedBits(NO_WRITES);
4620 return !isAtFixpoint();
4621 };
4622
4623 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
4624 return indicatePessimisticFixpoint();
4625
4626 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4627 : ChangeStatus::UNCHANGED;
4628}
4629
4630ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
4631
4632 const IRPosition &IRP = getIRPosition();
4633 const IRPosition &FnPos = IRPosition::function_scope(IRP);
4634 AAMemoryBehavior::StateType &S = getState();
4635
4636 // First, check the function scope. We take the known information and we avoid
4637 // work if the assumed information implies the current assumed information for
4638 // this attribute.
4639 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4640 S.addKnownBits(FnMemAA.getKnown());
4641 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
4642 return ChangeStatus::UNCHANGED;
4643
4644 // Make sure the value is not captured (except through "return"), if
4645 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004646 // check the potential aliases introduced by the capture. However, no need
4647 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004648 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004649 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
4650 S.intersectAssumedBits(FnMemAA.getAssumed());
4651 return ChangeStatus::CHANGED;
4652 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004653
4654 // The current assumed state used to determine a change.
4655 auto AssumedState = S.getAssumed();
4656
4657 // Liveness information to exclude dead users.
4658 // TODO: Take the FnPos once we have call site specific liveness information.
4659 const auto &LivenessAA = A.getAAFor<AAIsDead>(
4660 *this, IRPosition::function(*IRP.getAssociatedFunction()));
4661
4662 // Visit and expand uses until all are analyzed or a fixpoint is reached.
4663 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
4664 const Use *U = Uses[i];
4665 Instruction *UserI = cast<Instruction>(U->getUser());
4666 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
4667 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
4668 << "]\n");
4669 if (LivenessAA.isAssumedDead(UserI))
4670 continue;
4671
4672 // Check if the users of UserI should also be visited.
4673 if (followUsersOfUseIn(A, U, UserI))
4674 for (const Use &UserIUse : UserI->uses())
4675 Uses.insert(&UserIUse);
4676
4677 // If UserI might touch memory we analyze the use in detail.
4678 if (UserI->mayReadOrWriteMemory())
4679 analyzeUseIn(A, U, UserI);
4680 }
4681
4682 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4683 : ChangeStatus::UNCHANGED;
4684}
4685
4686bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
4687 const Instruction *UserI) {
4688 // The loaded value is unrelated to the pointer argument, no need to
4689 // follow the users of the load.
4690 if (isa<LoadInst>(UserI))
4691 return false;
4692
4693 // By default we follow all uses assuming UserI might leak information on U,
4694 // we have special handling for call sites operands though.
4695 ImmutableCallSite ICS(UserI);
4696 if (!ICS || !ICS.isArgOperand(U))
4697 return true;
4698
4699 // If the use is a call argument known not to be captured, the users of
4700 // the call do not need to be visited because they have to be unrelated to
4701 // the input. Note that this check is not trivial even though we disallow
4702 // general capturing of the underlying argument. The reason is that the
4703 // call might the argument "through return", which we allow and for which we
4704 // need to check call users.
4705 unsigned ArgNo = ICS.getArgumentNo(U);
4706 const auto &ArgNoCaptureAA =
4707 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
4708 return !ArgNoCaptureAA.isAssumedNoCapture();
4709}
4710
4711void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
4712 const Instruction *UserI) {
4713 assert(UserI->mayReadOrWriteMemory());
4714
4715 switch (UserI->getOpcode()) {
4716 default:
4717 // TODO: Handle all atomics and other side-effect operations we know of.
4718 break;
4719 case Instruction::Load:
4720 // Loads cause the NO_READS property to disappear.
4721 removeAssumedBits(NO_READS);
4722 return;
4723
4724 case Instruction::Store:
4725 // Stores cause the NO_WRITES property to disappear if the use is the
4726 // pointer operand. Note that we do assume that capturing was taken care of
4727 // somewhere else.
4728 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
4729 removeAssumedBits(NO_WRITES);
4730 return;
4731
4732 case Instruction::Call:
4733 case Instruction::CallBr:
4734 case Instruction::Invoke: {
4735 // For call sites we look at the argument memory behavior attribute (this
4736 // could be recursive!) in order to restrict our own state.
4737 ImmutableCallSite ICS(UserI);
4738
4739 // Give up on operand bundles.
4740 if (ICS.isBundleOperand(U)) {
4741 indicatePessimisticFixpoint();
4742 return;
4743 }
4744
4745 // Calling a function does read the function pointer, maybe write it if the
4746 // function is self-modifying.
4747 if (ICS.isCallee(U)) {
4748 removeAssumedBits(NO_READS);
4749 break;
4750 }
4751
4752 // Adjust the possible access behavior based on the information on the
4753 // argument.
4754 unsigned ArgNo = ICS.getArgumentNo(U);
4755 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
4756 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4757 // "assumed" has at most the same bits as the MemBehaviorAA assumed
4758 // and at least "known".
4759 intersectAssumedBits(MemBehaviorAA.getAssumed());
4760 return;
4761 }
4762 };
4763
4764 // Generally, look at the "may-properties" and adjust the assumed state if we
4765 // did not trigger special handling before.
4766 if (UserI->mayReadFromMemory())
4767 removeAssumedBits(NO_READS);
4768 if (UserI->mayWriteToMemory())
4769 removeAssumedBits(NO_WRITES);
4770}
4771
Johannes Doerfertaade7822019-06-05 03:02:24 +00004772/// ----------------------------------------------------------------------------
4773/// Attributor
4774/// ----------------------------------------------------------------------------
4775
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004776bool Attributor::isAssumedDead(const AbstractAttribute &AA,
4777 const AAIsDead *LivenessAA) {
4778 const Instruction *CtxI = AA.getIRPosition().getCtxI();
4779 if (!CtxI)
4780 return false;
4781
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004782 // TODO: Find a good way to utilize fine and coarse grained liveness
4783 // information.
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004784 if (!LivenessAA)
4785 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00004786 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
4787 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00004788
4789 // Don't check liveness for AAIsDead.
4790 if (&AA == LivenessAA)
4791 return false;
4792
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004793 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004794 return false;
4795
Johannes Doerfert19b00432019-08-26 17:48:05 +00004796 // We actually used liveness information so we have to record a dependence.
Johannes Doerfert680f6382019-11-02 02:48:05 -05004797 recordDependence(*LivenessAA, AA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004798
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004799 return true;
4800}
4801
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004802bool Attributor::checkForAllUses(
4803 const function_ref<bool(const Use &, bool &)> &Pred,
4804 const AbstractAttribute &QueryingAA, const Value &V) {
4805 const IRPosition &IRP = QueryingAA.getIRPosition();
4806 SmallVector<const Use *, 16> Worklist;
4807 SmallPtrSet<const Use *, 16> Visited;
4808
4809 for (const Use &U : V.uses())
4810 Worklist.push_back(&U);
4811
4812 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
4813 << " initial uses to check\n");
4814
4815 if (Worklist.empty())
4816 return true;
4817
4818 bool AnyDead = false;
4819 const Function *ScopeFn = IRP.getAnchorScope();
4820 const auto *LivenessAA =
4821 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
4822 /* TrackDependence */ false)
4823 : nullptr;
4824
4825 while (!Worklist.empty()) {
4826 const Use *U = Worklist.pop_back_val();
4827 if (!Visited.insert(U).second)
4828 continue;
4829 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << "\n");
4830 if (Instruction *UserI = dyn_cast<Instruction>(U->getUser()))
4831 if (LivenessAA && LivenessAA->isAssumedDead(UserI)) {
4832 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
4833 << static_cast<const AbstractAttribute &>(*LivenessAA)
4834 << "\n");
4835 AnyDead = true;
4836 continue;
4837 }
4838
4839 bool Follow = false;
4840 if (!Pred(*U, Follow))
4841 return false;
4842 if (!Follow)
4843 continue;
4844 for (const Use &UU : U->getUser()->uses())
4845 Worklist.push_back(&UU);
4846 }
4847
4848 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05004849 recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05004850
4851 return true;
4852}
4853
Johannes Doerfert661db042019-10-07 23:14:58 +00004854bool Attributor::checkForAllCallSites(
4855 const function_ref<bool(AbstractCallSite)> &Pred,
4856 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004857 // We can try to determine information from
4858 // the call sites. However, this is only possible all call sites are known,
4859 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004860 const IRPosition &IRP = QueryingAA.getIRPosition();
4861 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00004862 if (!AssociatedFunction) {
4863 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
4864 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004865 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00004866 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004867
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004868 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
4869 &QueryingAA);
4870}
4871
4872bool Attributor::checkForAllCallSites(
4873 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
4874 bool RequireAllCallSites, const AbstractAttribute *QueryingAA) {
4875 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004876 LLVM_DEBUG(
4877 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004878 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00004879 << " has no internal linkage, hence not all call sites are known\n");
4880 return false;
4881 }
4882
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004883 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00004884 AbstractCallSite ACS(&U);
4885 if (!ACS) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01004886 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00004887 << " has non call site use " << *U.get() << " in "
4888 << *U.getUser() << "\n");
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05004889 // BlockAddress users are allowed.
4890 if (isa<BlockAddress>(U.getUser()))
4891 continue;
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004892 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00004893 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004894
Johannes Doerfert661db042019-10-07 23:14:58 +00004895 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004896 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004897
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004898 const auto *LivenessAA =
4899 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01004900 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004901
4902 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004903 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00004904 // We actually used liveness information so we have to record a
4905 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00004906 if (QueryingAA)
Johannes Doerfert680f6382019-11-02 02:48:05 -05004907 recordDependence(*LivenessAA, *QueryingAA, DepClassTy::OPTIONAL);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004908 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004909 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004910
Johannes Doerfert661db042019-10-07 23:14:58 +00004911 const Use *EffectiveUse =
4912 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
4913 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004914 if (!RequireAllCallSites)
4915 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00004916 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01004917 << " is an invalid use of " << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004918 return false;
4919 }
4920
Johannes Doerfert661db042019-10-07 23:14:58 +00004921 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00004922 continue;
4923
Johannes Doerfert5304b722019-08-14 22:04:28 +00004924 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00004925 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004926 return false;
4927 }
4928
4929 return true;
4930}
4931
Johannes Doerfert14a04932019-08-07 22:27:24 +00004932bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004933 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00004934 &Pred,
4935 const AbstractAttribute &QueryingAA) {
4936
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004937 const IRPosition &IRP = QueryingAA.getIRPosition();
4938 // Since we need to provide return instructions we have to have an exact
4939 // definition.
4940 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004941 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004942 return false;
4943
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004944 // If this is a call site query we use the call site specific return values
4945 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004946 // TODO: use the function scope once we have call site AAReturnedValues.
4947 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004948 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004949 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004950 return false;
4951
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004952 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00004953}
4954
4955bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004956 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00004957 const AbstractAttribute &QueryingAA) {
4958
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004959 const IRPosition &IRP = QueryingAA.getIRPosition();
4960 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004961 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004962 return false;
4963
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004964 // TODO: use the function scope once we have call site AAReturnedValues.
4965 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004966 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004967 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004968 return false;
4969
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004970 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004971 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00004972 return Pred(RV);
4973 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00004974}
4975
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004976static bool
4977checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
4978 const function_ref<bool(Instruction &)> &Pred,
4979 const AAIsDead *LivenessAA, bool &AnyDead,
4980 const ArrayRef<unsigned> &Opcodes) {
4981 for (unsigned Opcode : Opcodes) {
4982 for (Instruction *I : OpcodeInstMap[Opcode]) {
4983 // Skip dead instructions.
4984 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
4985 AnyDead = true;
4986 continue;
4987 }
4988
4989 if (!Pred(*I))
4990 return false;
4991 }
4992 }
4993 return true;
4994}
4995
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004996bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004997 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004998 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004999
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005000 const IRPosition &IRP = QueryingAA.getIRPosition();
5001 // Since we need to provide instructions we have to have an exact definition.
5002 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005003 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005004 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005005
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005006 // TODO: use the function scope once we have call site AAReturnedValues.
5007 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005008 const auto &LivenessAA =
5009 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
5010 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005011
5012 auto &OpcodeInstMap =
5013 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005014 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
5015 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005016 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005017
Johannes Doerfert19b00432019-08-26 17:48:05 +00005018 // If we actually used liveness information so we have to record a dependence.
5019 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005020 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005021
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005022 return true;
5023}
5024
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005025bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005026 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00005027 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005028
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005029 const Function *AssociatedFunction =
5030 QueryingAA.getIRPosition().getAssociatedFunction();
5031 if (!AssociatedFunction)
5032 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005033
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005034 // TODO: use the function scope once we have call site AAReturnedValues.
5035 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
5036 const auto &LivenessAA =
5037 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005038 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005039
5040 for (Instruction *I :
5041 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005042 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00005043 if (LivenessAA.isAssumedDead(I)) {
5044 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005045 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00005046 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005047
5048 if (!Pred(*I))
5049 return false;
5050 }
5051
Johannes Doerfert19b00432019-08-26 17:48:05 +00005052 // If we actually used liveness information so we have to record a dependence.
5053 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005054 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005055
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005056 return true;
5057}
5058
Johannes Doerfert2f622062019-09-04 16:35:20 +00005059ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005060 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
5061 << AllAbstractAttributes.size()
5062 << " abstract attributes.\n");
5063
Stefan Stipanovic53605892019-06-27 11:27:54 +00005064 // Now that all abstract attributes are collected and initialized we start
5065 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00005066
5067 unsigned IterationCounter = 1;
5068
5069 SmallVector<AbstractAttribute *, 64> ChangedAAs;
Johannes Doerfert680f6382019-11-02 02:48:05 -05005070 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005071 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
5072
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005073 bool RecomputeDependences = false;
5074
Johannes Doerfertaade7822019-06-05 03:02:24 +00005075 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005076 // Remember the size to determine new attributes.
5077 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005078 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
5079 << ", Worklist size: " << Worklist.size() << "\n");
5080
Johannes Doerfert680f6382019-11-02 02:48:05 -05005081 // For invalid AAs we can fix dependent AAs that have a required dependence,
5082 // thereby folding long dependence chains in a single step without the need
5083 // to run updates.
5084 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
5085 AbstractAttribute *InvalidAA = InvalidAAs[u];
5086 auto &QuerriedAAs = QueryMap[InvalidAA];
5087 LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has "
5088 << QuerriedAAs.RequiredAAs.size() << "/"
5089 << QuerriedAAs.OptionalAAs.size()
5090 << " required/optional dependences\n");
5091 for (AbstractAttribute *DepOnInvalidAA : QuerriedAAs.RequiredAAs) {
5092 AbstractState &DOIAAState = DepOnInvalidAA->getState();
5093 DOIAAState.indicatePessimisticFixpoint();
5094 ++NumAttributesFixedDueToRequiredDependences;
5095 assert(DOIAAState.isAtFixpoint() && "Expected fixpoint state!");
5096 if (!DOIAAState.isValidState())
5097 InvalidAAs.insert(DepOnInvalidAA);
5098 }
5099 if (!RecomputeDependences)
5100 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
5101 QuerriedAAs.OptionalAAs.end());
5102 }
5103
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005104 // If dependences (=QueryMap) are recomputed we have to look at all abstract
5105 // attributes again, regardless of what changed in the last iteration.
5106 if (RecomputeDependences) {
5107 LLVM_DEBUG(
5108 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
5109 QueryMap.clear();
5110 ChangedAAs.clear();
5111 Worklist.insert(AllAbstractAttributes.begin(),
5112 AllAbstractAttributes.end());
5113 }
5114
Johannes Doerfertaade7822019-06-05 03:02:24 +00005115 // Add all abstract attributes that are potentially dependent on one that
5116 // changed to the work list.
5117 for (AbstractAttribute *ChangedAA : ChangedAAs) {
5118 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05005119 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
5120 QuerriedAAs.OptionalAAs.end());
5121 Worklist.insert(QuerriedAAs.RequiredAAs.begin(),
5122 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00005123 }
5124
Johannes Doerfertb504eb82019-08-26 18:55:47 +00005125 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
5126 << ", Worklist+Dependent size: " << Worklist.size()
5127 << "\n");
5128
Johannes Doerfert680f6382019-11-02 02:48:05 -05005129 // Reset the changed and invalid set.
Johannes Doerfertaade7822019-06-05 03:02:24 +00005130 ChangedAAs.clear();
Johannes Doerfert680f6382019-11-02 02:48:05 -05005131 InvalidAAs.clear();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005132
5133 // Update all abstract attribute in the work list and record the ones that
5134 // changed.
5135 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005136 if (!AA->getState().isAtFixpoint() && !isAssumedDead(*AA, nullptr)) {
5137 QueriedNonFixAA = false;
5138 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005139 ChangedAAs.push_back(AA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05005140 if (!AA->getState().isValidState())
5141 InvalidAAs.insert(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005142 } else if (!QueriedNonFixAA) {
5143 // If the attribute did not query any non-fix information, the state
5144 // will not change and we can indicate that right away.
5145 AA->getState().indicateOptimisticFixpoint();
5146 }
5147 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00005148
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005149 // Check if we recompute the dependences in the next iteration.
5150 RecomputeDependences = (DepRecomputeInterval > 0 &&
5151 IterationCounter % DepRecomputeInterval == 0);
5152
Johannes Doerfert9543f142019-08-23 15:24:57 +00005153 // Add attributes to the changed set if they have been created in the last
5154 // iteration.
5155 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
5156 AllAbstractAttributes.end());
5157
Johannes Doerfertaade7822019-06-05 03:02:24 +00005158 // Reset the work list and repopulate with the changed abstract attributes.
5159 // Note that dependent ones are added above.
5160 Worklist.clear();
5161 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
5162
Johannes Doerfertbf112132019-08-29 01:29:44 +00005163 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
5164 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005165
Johannes Doerfertaade7822019-06-05 03:02:24 +00005166 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
5167 << IterationCounter << "/" << MaxFixpointIterations
5168 << " iterations\n");
5169
Johannes Doerfertbf112132019-08-29 01:29:44 +00005170 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00005171
Johannes Doerfertaade7822019-06-05 03:02:24 +00005172 // Reset abstract arguments not settled in a sound fixpoint by now. This
5173 // happens when we stopped the fixpoint iteration early. Note that only the
5174 // ones marked as "changed" *and* the ones transitively depending on them
5175 // need to be reverted to a pessimistic state. Others might not be in a
5176 // fixpoint state but we can use the optimistic results for them anyway.
5177 SmallPtrSet<AbstractAttribute *, 32> Visited;
5178 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
5179 AbstractAttribute *ChangedAA = ChangedAAs[u];
5180 if (!Visited.insert(ChangedAA).second)
5181 continue;
5182
5183 AbstractState &State = ChangedAA->getState();
5184 if (!State.isAtFixpoint()) {
5185 State.indicatePessimisticFixpoint();
5186
5187 NumAttributesTimedOut++;
5188 }
5189
5190 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05005191 ChangedAAs.append(QuerriedAAs.OptionalAAs.begin(),
5192 QuerriedAAs.OptionalAAs.end());
5193 ChangedAAs.append(QuerriedAAs.RequiredAAs.begin(),
5194 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00005195 }
5196
5197 LLVM_DEBUG({
5198 if (!Visited.empty())
5199 dbgs() << "\n[Attributor] Finalized " << Visited.size()
5200 << " abstract attributes.\n";
5201 });
5202
5203 unsigned NumManifested = 0;
5204 unsigned NumAtFixpoint = 0;
5205 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
5206 for (AbstractAttribute *AA : AllAbstractAttributes) {
5207 AbstractState &State = AA->getState();
5208
5209 // If there is not already a fixpoint reached, we can now take the
5210 // optimistic state. This is correct because we enforced a pessimistic one
5211 // on abstract attributes that were transitively dependent on a changed one
5212 // already above.
5213 if (!State.isAtFixpoint())
5214 State.indicateOptimisticFixpoint();
5215
5216 // If the state is invalid, we do not try to manifest it.
5217 if (!State.isValidState())
5218 continue;
5219
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005220 // Skip dead code.
5221 if (isAssumedDead(*AA, nullptr))
5222 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005223 // Manifest the state and record if we changed the IR.
5224 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00005225 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
5226 AA->trackStatistics();
5227
Johannes Doerfertaade7822019-06-05 03:02:24 +00005228 ManifestChange = ManifestChange | LocalChange;
5229
5230 NumAtFixpoint++;
5231 NumManifested += (LocalChange == ChangeStatus::CHANGED);
5232 }
5233
5234 (void)NumManifested;
5235 (void)NumAtFixpoint;
5236 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
5237 << " arguments while " << NumAtFixpoint
5238 << " were in a valid fixpoint state\n");
5239
Johannes Doerfertaade7822019-06-05 03:02:24 +00005240 NumAttributesManifested += NumManifested;
5241 NumAttributesValidFixpoint += NumAtFixpoint;
5242
Fangrui Songf1826172019-08-20 07:21:43 +00005243 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005244 assert(
5245 NumFinalAAs == AllAbstractAttributes.size() &&
5246 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00005247
5248 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00005249 {
5250 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
5251 << ToBeDeletedFunctions.size() << " functions and "
5252 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005253 << ToBeDeletedInsts.size() << " instructions and "
5254 << ToBeChangedUses.size() << " uses\n");
5255
5256 SmallVector<Instruction *, 32> DeadInsts;
5257 SmallVector<Instruction *, 32> TerminatorsToFold;
5258 SmallVector<Instruction *, 32> UnreachablesToInsert;
5259
5260 for (auto &It : ToBeChangedUses) {
5261 Use *U = It.first;
5262 Value *NewV = It.second;
5263 Value *OldV = U->get();
5264 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
5265 << " instead of " << *OldV << "\n");
5266 U->set(NewV);
5267 if (Instruction *I = dyn_cast<Instruction>(OldV))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005268 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
5269 isInstructionTriviallyDead(I)) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005270 DeadInsts.push_back(I);
5271 }
5272 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
5273 Instruction *UserI = cast<Instruction>(U->getUser());
5274 if (isa<UndefValue>(NewV)) {
5275 UnreachablesToInsert.push_back(UserI);
5276 } else {
5277 TerminatorsToFold.push_back(UserI);
5278 }
5279 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00005280 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005281 for (Instruction *I : UnreachablesToInsert)
5282 changeToUnreachable(I, /* UseLLVMTrap */ false);
5283 for (Instruction *I : TerminatorsToFold)
5284 ConstantFoldTerminator(I->getParent());
5285
5286 for (Instruction *I : ToBeDeletedInsts) {
5287 I->replaceAllUsesWith(UndefValue::get(I->getType()));
5288 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
5289 DeadInsts.push_back(I);
5290 else
5291 I->eraseFromParent();
5292 }
5293
5294 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00005295
Johannes Doerfert2f622062019-09-04 16:35:20 +00005296 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
5297 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
5298 ToBeDeletedBBs.reserve(NumDeadBlocks);
5299 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
Johannes Doerfert5e442a52019-10-30 17:34:59 -05005300 // Actually we do not delete the blocks but squash them into a single
5301 // unreachable but untangling branches that jump here is something we need
5302 // to do in a more generic way.
5303 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
5304 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
5305 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00005306 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00005307
Johannes Doerfert2f622062019-09-04 16:35:20 +00005308 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
5309 for (Function *Fn : ToBeDeletedFunctions) {
5310 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
5311 Fn->eraseFromParent();
5312 STATS_TRACK(AAIsDead, Function);
5313 }
5314
5315 // Identify dead internal functions and delete them. This happens outside
5316 // the other fixpoint analysis as we might treat potentially dead functions
5317 // as live to lower the number of iterations. If they happen to be dead, the
5318 // below fixpoint loop will identify and eliminate them.
5319 SmallVector<Function *, 8> InternalFns;
5320 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00005321 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00005322 InternalFns.push_back(&F);
5323
5324 bool FoundDeadFn = true;
5325 while (FoundDeadFn) {
5326 FoundDeadFn = false;
5327 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
5328 Function *F = InternalFns[u];
5329 if (!F)
5330 continue;
5331
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005332 if (!checkForAllCallSites([](AbstractCallSite ACS) { return false; },
5333 *F, true, nullptr))
Johannes Doerfert2f622062019-09-04 16:35:20 +00005334 continue;
5335
5336 STATS_TRACK(AAIsDead, Function);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005337 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05005338 F->deleteBody();
Johannes Doerfert2f622062019-09-04 16:35:20 +00005339 F->replaceAllUsesWith(UndefValue::get(F->getType()));
5340 F->eraseFromParent();
5341 InternalFns[u] = nullptr;
5342 FoundDeadFn = true;
5343 }
5344 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00005345 }
5346
Johannes Doerfertbf112132019-08-29 01:29:44 +00005347 if (VerifyMaxFixpointIterations &&
5348 IterationCounter != MaxFixpointIterations) {
5349 errs() << "\n[Attributor] Fixpoint iteration done after: "
5350 << IterationCounter << "/" << MaxFixpointIterations
5351 << " iterations\n";
5352 llvm_unreachable("The fixpoint was not reached with exactly the number of "
5353 "specified iterations!");
5354 }
5355
Johannes Doerfertaade7822019-06-05 03:02:24 +00005356 return ManifestChange;
5357}
5358
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005359void Attributor::initializeInformationCache(Function &F) {
5360
5361 // Walk all instructions to find interesting instructions that might be
5362 // queried by abstract attributes during their initialization or update.
5363 // This has to happen before we create attributes.
5364 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
5365 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
5366
5367 for (Instruction &I : instructions(&F)) {
5368 bool IsInterestingOpcode = false;
5369
5370 // To allow easy access to all instructions in a function with a given
5371 // opcode we store them in the InfoCache. As not all opcodes are interesting
5372 // to concrete attributes we only cache the ones that are as identified in
5373 // the following switch.
5374 // Note: There are no concrete attributes now so this is initially empty.
5375 switch (I.getOpcode()) {
5376 default:
5377 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
5378 "New call site/base instruction type needs to be known int the "
5379 "Attributor.");
5380 break;
5381 case Instruction::Load:
5382 // The alignment of a pointer is interesting for loads.
5383 case Instruction::Store:
5384 // The alignment of a pointer is interesting for stores.
5385 case Instruction::Call:
5386 case Instruction::CallBr:
5387 case Instruction::Invoke:
5388 case Instruction::CleanupRet:
5389 case Instruction::CatchSwitch:
5390 case Instruction::Resume:
5391 case Instruction::Ret:
5392 IsInterestingOpcode = true;
5393 }
5394 if (IsInterestingOpcode)
5395 InstOpcodeMap[I.getOpcode()].push_back(&I);
5396 if (I.mayReadOrWriteMemory())
5397 ReadOrWriteInsts.push_back(&I);
5398 }
5399}
5400
Johannes Doerfert12173e62019-10-13 20:25:25 -05005401void Attributor::recordDependence(const AbstractAttribute &FromAA,
Johannes Doerfert680f6382019-11-02 02:48:05 -05005402 const AbstractAttribute &ToAA,
5403 DepClassTy DepClass) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005404 if (FromAA.getState().isAtFixpoint())
5405 return;
5406
Johannes Doerfert680f6382019-11-02 02:48:05 -05005407 if (DepClass == DepClassTy::REQUIRED)
5408 QueryMap[&FromAA].RequiredAAs.insert(
5409 const_cast<AbstractAttribute *>(&ToAA));
5410 else
5411 QueryMap[&FromAA].OptionalAAs.insert(
5412 const_cast<AbstractAttribute *>(&ToAA));
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005413 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05005414}
5415
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005416void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00005417 if (!VisitedFunctions.insert(&F).second)
5418 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05005419 if (F.isDeclaration())
5420 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005421
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005422 IRPosition FPos = IRPosition::function(F);
5423
Johannes Doerfert305b9612019-08-04 18:40:01 +00005424 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00005425 // We need dead instruction detection because we do not want to deal with
5426 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005427 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00005428
5429 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005430 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00005431
Stefan Stipanovic53605892019-06-27 11:27:54 +00005432 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005433 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00005434
Stefan Stipanovic06263672019-07-11 21:37:40 +00005435 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005436 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00005437
Hideto Ueno65bbaf92019-07-12 17:38:51 +00005438 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005439 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00005440
Johannes Doerferte83f3032019-08-05 23:22:05 +00005441 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005442 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00005443
Hideto Ueno63f60662019-09-21 15:13:19 +00005444 // Every function might be "no-recurse".
5445 getOrCreateAAFor<AANoRecurse>(FPos);
5446
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005447 // Every function might be "readnone/readonly/writeonly/...".
5448 getOrCreateAAFor<AAMemoryBehavior>(FPos);
5449
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005450 // Every function might be applicable for Heap-To-Stack conversion.
5451 if (EnableHeapToStack)
5452 getOrCreateAAFor<AAHeapToStack>(FPos);
5453
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00005454 // Return attributes are only appropriate if the return type is non void.
5455 Type *ReturnType = F.getReturnType();
5456 if (!ReturnType->isVoidTy()) {
5457 // Argument attribute "returned" --- Create only one per function even
5458 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005459 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00005460
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005461 IRPosition RetPos = IRPosition::returned(F);
5462
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005463 // Every returned value might be dead.
5464 getOrCreateAAFor<AAIsDead>(RetPos);
5465
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005466 // Every function might be simplified.
5467 getOrCreateAAFor<AAValueSimplify>(RetPos);
5468
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005469 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005470
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005471 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005472 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005473
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005474 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005475 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005476
5477 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005478 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005479
5480 // Every function with pointer return type might be marked
5481 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005482 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00005483 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00005484 }
5485
Hideto Ueno54869ec2019-07-15 06:49:04 +00005486 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005487 IRPosition ArgPos = IRPosition::argument(Arg);
5488
5489 // Every argument might be simplified.
5490 getOrCreateAAFor<AAValueSimplify>(ArgPos);
5491
Hideto Ueno19c07af2019-07-23 08:16:17 +00005492 if (Arg.getType()->isPointerTy()) {
5493 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005494 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005495
Hideto Uenocbab3342019-08-29 05:52:00 +00005496 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005497 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00005498
Hideto Ueno19c07af2019-07-23 08:16:17 +00005499 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005500 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005501
5502 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005503 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005504
5505 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005506 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005507
5508 // Every argument with pointer type might be marked
5509 // "readnone/readonly/writeonly/..."
5510 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005511
5512 // Every argument with pointer type might be marked nofree.
5513 getOrCreateAAFor<AANoFree>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005514 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00005515 }
5516
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005517 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005518 CallSite CS(&I);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005519 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05005520 // Skip declerations except if annotations on their call sites were
5521 // explicitly requested.
5522 if (!AnnotateDeclarationCallSites && Callee->isDeclaration())
5523 return true;
5524
5525 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005526 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
5527
5528 // Call site return values might be dead.
5529 getOrCreateAAFor<AAIsDead>(CSRetPos);
5530 }
5531
5532 for (int i = 0, e = Callee->arg_size(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005533
5534 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
5535
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005536 // Every call site argument might be dead.
5537 getOrCreateAAFor<AAIsDead>(CSArgPos);
5538
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005539 // Call site argument might be simplified.
5540 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
5541
Hideto Ueno54869ec2019-07-15 06:49:04 +00005542 if (!CS.getArgument(i)->getType()->isPointerTy())
5543 continue;
5544
5545 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005546 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00005547
Hideto Uenocbab3342019-08-29 05:52:00 +00005548 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005549 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00005550
Hideto Ueno19c07af2019-07-23 08:16:17 +00005551 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005552 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00005553
5554 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00005555 getOrCreateAAFor<AAAlign>(CSArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005556
5557 // Call site argument attribute "nofree".
5558 getOrCreateAAFor<AANoFree>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00005559 }
5560 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005561 return true;
5562 };
5563
5564 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
5565 bool Success, AnyDead = false;
5566 Success = checkForAllInstructionsImpl(
5567 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
5568 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
5569 (unsigned)Instruction::Call});
5570 (void)Success;
5571 assert(Success && !AnyDead && "Expected the check call to be successful!");
5572
5573 auto LoadStorePred = [&](Instruction &I) -> bool {
5574 if (isa<LoadInst>(I))
5575 getOrCreateAAFor<AAAlign>(
5576 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
5577 else
5578 getOrCreateAAFor<AAAlign>(
5579 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
5580 return true;
5581 };
5582 Success = checkForAllInstructionsImpl(
5583 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
5584 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
5585 (void)Success;
5586 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00005587}
5588
5589/// Helpers to ease debugging through output streams and print calls.
5590///
5591///{
5592raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
5593 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
5594}
5595
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005596raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005597 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005598 case IRPosition::IRP_INVALID:
5599 return OS << "inv";
5600 case IRPosition::IRP_FLOAT:
5601 return OS << "flt";
5602 case IRPosition::IRP_RETURNED:
5603 return OS << "fn_ret";
5604 case IRPosition::IRP_CALL_SITE_RETURNED:
5605 return OS << "cs_ret";
5606 case IRPosition::IRP_FUNCTION:
5607 return OS << "fn";
5608 case IRPosition::IRP_CALL_SITE:
5609 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005610 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00005611 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005612 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00005613 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00005614 }
5615 llvm_unreachable("Unknown attribute position!");
5616}
5617
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005618raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005619 const Value &AV = Pos.getAssociatedValue();
5620 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005621 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
5622}
5623
Johannes Doerfert1a746452019-10-20 22:28:49 -05005624template <typename base_ty, base_ty BestState, base_ty WorstState>
5625raw_ostream &llvm::
5626operator<<(raw_ostream &OS,
5627 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00005628 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
5629 << static_cast<const AbstractState &>(S);
5630}
5631
Johannes Doerfertaade7822019-06-05 03:02:24 +00005632raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
5633 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
5634}
5635
5636raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
5637 AA.print(OS);
5638 return OS;
5639}
5640
5641void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00005642 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
5643 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00005644}
5645///}
5646
5647/// ----------------------------------------------------------------------------
5648/// Pass (Manager) Boilerplate
5649/// ----------------------------------------------------------------------------
5650
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005651static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005652 if (DisableAttributor)
5653 return false;
5654
5655 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
5656 << " functions.\n");
5657
5658 // Create an Attributor and initially empty information cache that is filled
5659 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00005660 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005661 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005662
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005663 for (Function &F : M)
5664 A.initializeInformationCache(F);
5665
Johannes Doerfertaade7822019-06-05 03:02:24 +00005666 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005667 if (F.hasExactDefinition())
5668 NumFnWithExactDefinition++;
5669 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00005670 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005671
Johannes Doerfert2f622062019-09-04 16:35:20 +00005672 // We look at internal functions only on-demand but if any use is not a
5673 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00005674 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00005675 if (llvm::all_of(F.uses(), [](const Use &U) {
5676 return ImmutableCallSite(U.getUser()) &&
5677 ImmutableCallSite(U.getUser()).isCallee(&U);
5678 }))
5679 continue;
5680 }
5681
Johannes Doerfertaade7822019-06-05 03:02:24 +00005682 // Populate the Attributor with abstract attribute opportunities in the
5683 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005684 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005685 }
5686
Johannes Doerfert2f622062019-09-04 16:35:20 +00005687 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005688}
5689
5690PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00005691 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005692 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005693 // FIXME: Think about passes we will preserve and add them here.
5694 return PreservedAnalyses::none();
5695 }
5696 return PreservedAnalyses::all();
5697}
5698
5699namespace {
5700
5701struct AttributorLegacyPass : public ModulePass {
5702 static char ID;
5703
5704 AttributorLegacyPass() : ModulePass(ID) {
5705 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
5706 }
5707
5708 bool runOnModule(Module &M) override {
5709 if (skipModule(M))
5710 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005711
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00005712 AnalysisGetter AG;
5713 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00005714 }
5715
5716 void getAnalysisUsage(AnalysisUsage &AU) const override {
5717 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005718 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005719 }
5720};
5721
5722} // end anonymous namespace
5723
5724Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
5725
5726char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005727
5728const char AAReturnedValues::ID = 0;
5729const char AANoUnwind::ID = 0;
5730const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00005731const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005732const char AANonNull::ID = 0;
5733const char AANoRecurse::ID = 0;
5734const char AAWillReturn::ID = 0;
5735const char AANoAlias::ID = 0;
Pankaj Gode04945c92019-11-22 18:40:47 +05305736const char AAReachability::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005737const char AANoReturn::ID = 0;
5738const char AAIsDead::ID = 0;
5739const char AADereferenceable::ID = 0;
5740const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005741const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005742const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005743const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005744const char AAMemoryBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00005745
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005746// Macro magic to create the static generator function for attributes that
5747// follow the naming scheme.
5748
5749#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
5750 case IRPosition::PK: \
5751 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
5752
5753#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
5754 case IRPosition::PK: \
5755 AA = new CLASS##SUFFIX(IRP); \
5756 break;
5757
5758#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5759 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5760 CLASS *AA = nullptr; \
5761 switch (IRP.getPositionKind()) { \
5762 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5763 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5764 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5765 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5766 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5767 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5768 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5769 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5770 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005771 return *AA; \
5772 }
5773
5774#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5775 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5776 CLASS *AA = nullptr; \
5777 switch (IRP.getPositionKind()) { \
5778 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5779 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
5780 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5781 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5782 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5783 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5784 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5785 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5786 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005787 return *AA; \
5788 }
5789
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005790#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5791 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5792 CLASS *AA = nullptr; \
5793 switch (IRP.getPositionKind()) { \
5794 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5795 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5796 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5797 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5798 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5799 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
5800 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5801 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5802 } \
5803 return *AA; \
5804 }
5805
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005806#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5807 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5808 CLASS *AA = nullptr; \
5809 switch (IRP.getPositionKind()) { \
5810 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5811 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5812 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5813 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5814 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5815 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5816 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5817 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5818 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005819 return *AA; \
5820 }
5821
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005822#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5823 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5824 CLASS *AA = nullptr; \
5825 switch (IRP.getPositionKind()) { \
5826 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5827 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5828 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5829 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5830 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5831 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5832 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5833 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5834 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005835 return *AA; \
5836 }
5837
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005838CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
5839CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005840CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
5841CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
5842CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005843CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
5844
5845CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
5846CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
5847CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
5848CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005849CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005850
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005851CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005852CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005853CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005854
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005855CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
Pankaj Gode04945c92019-11-22 18:40:47 +05305856CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005857
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005858CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
5859
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005860#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005861#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005862#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005863#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005864#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005865#undef SWITCH_PK_CREATE
5866#undef SWITCH_PK_INV
5867
Johannes Doerfertaade7822019-06-05 03:02:24 +00005868INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
5869 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005870INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00005871INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
5872 "Deduce and propagate attributes", false, false)