blob: 654f2084be4b4603d9288a342f3be18e949568ad [file] [log] [blame]
Johannes Doerfertaade7822019-06-05 03:02:24 +00001//===- Attributor.cpp - Module-wide attribute deduction -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements an inter procedural pass that deduces and/or propagating
10// attributes. This is done in an abstract interpretation style fixpoint
11// iteration. See the Attributor.h file comment and the class descriptions in
12// that file for more information.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Transforms/IPO/Attributor.h"
17
Hideto Ueno11d37102019-07-17 15:15:43 +000018#include "llvm/ADT/DepthFirstIterator.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000019#include "llvm/ADT/STLExtras.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000020#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/Statistic.h"
Stefan Stipanovic69ebb022019-07-22 19:36:27 +000023#include "llvm/Analysis/CaptureTracking.h"
Johannes Doerfert924d2132019-08-05 21:34:45 +000024#include "llvm/Analysis/EHPersonalities.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000025#include "llvm/Analysis/GlobalsModRef.h"
Hideto Ueno19c07af2019-07-23 08:16:17 +000026#include "llvm/Analysis/Loads.h"
Stefan Stipanovic431141c2019-09-15 21:47:41 +000027#include "llvm/Analysis/MemoryBuiltins.h"
Hideto Ueno54869ec2019-07-15 06:49:04 +000028#include "llvm/Analysis/ValueTracking.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000029#include "llvm/IR/Argument.h"
30#include "llvm/IR/Attributes.h"
Hideto Ueno11d37102019-07-17 15:15:43 +000031#include "llvm/IR/CFG.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000032#include "llvm/IR/InstIterator.h"
Stefan Stipanovic06263672019-07-11 21:37:40 +000033#include "llvm/IR/IntrinsicInst.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000034#include "llvm/Support/CommandLine.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/raw_ostream.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000037#include "llvm/Transforms/Utils/BasicBlockUtils.h"
38#include "llvm/Transforms/Utils/Local.h"
39
Johannes Doerfertaade7822019-06-05 03:02:24 +000040#include <cassert>
41
42using namespace llvm;
43
44#define DEBUG_TYPE "attributor"
45
46STATISTIC(NumFnWithExactDefinition,
47 "Number of function with exact definitions");
48STATISTIC(NumFnWithoutExactDefinition,
49 "Number of function without exact definitions");
50STATISTIC(NumAttributesTimedOut,
51 "Number of abstract attributes timed out before fixpoint");
52STATISTIC(NumAttributesValidFixpoint,
53 "Number of abstract attributes in a valid fixpoint state");
54STATISTIC(NumAttributesManifested,
55 "Number of abstract attributes manifested in IR");
56
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000057// Some helper macros to deal with statistics tracking.
58//
59// Usage:
60// For simple IR attribute tracking overload trackStatistics in the abstract
Johannes Doerfert17b578b2019-08-14 21:46:25 +000061// attribute and choose the right STATS_DECLTRACK_********* macro,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000062// e.g.,:
63// void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +000064// STATS_DECLTRACK_ARG_ATTR(returned)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000065// }
66// If there is a single "increment" side one can use the macro
Johannes Doerfert17b578b2019-08-14 21:46:25 +000067// STATS_DECLTRACK with a custom message. If there are multiple increment
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000068// sides, STATS_DECL and STATS_TRACK can also be used separatly.
69//
70#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
71 ("Number of " #TYPE " marked '" #NAME "'")
72#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
Johannes Doerferta7a3b3a2019-09-04 19:01:08 +000073#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
74#define STATS_DECL(NAME, TYPE, MSG) \
75 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000076#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
Johannes Doerfert17b578b2019-08-14 21:46:25 +000077#define STATS_DECLTRACK(NAME, TYPE, MSG) \
Johannes Doerfert169af992019-08-20 06:09:56 +000078 { \
79 STATS_DECL(NAME, TYPE, MSG) \
80 STATS_TRACK(NAME, TYPE) \
81 }
Johannes Doerfert17b578b2019-08-14 21:46:25 +000082#define STATS_DECLTRACK_ARG_ATTR(NAME) \
83 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
84#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
85 STATS_DECLTRACK(NAME, CSArguments, \
86 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
87#define STATS_DECLTRACK_FN_ATTR(NAME) \
88 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
89#define STATS_DECLTRACK_CS_ATTR(NAME) \
90 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
91#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
92 STATS_DECLTRACK(NAME, FunctionReturn, \
Johannes Doerfert2db85282019-08-21 20:56:56 +000093 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
Johannes Doerfert17b578b2019-08-14 21:46:25 +000094#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
95 STATS_DECLTRACK(NAME, CSReturn, \
96 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
97#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
98 STATS_DECLTRACK(NAME, Floating, \
99 ("Number of floating values known to be '" #NAME "'"))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000100
Johannes Doerfertaade7822019-06-05 03:02:24 +0000101// TODO: Determine a good default value.
102//
103// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
104// (when run with the first 5 abstract attributes). The results also indicate
105// that we never reach 32 iterations but always find a fixpoint sooner.
106//
107// This will become more evolved once we perform two interleaved fixpoint
108// iterations: bottom-up and top-down.
109static cl::opt<unsigned>
110 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
111 cl::desc("Maximal number of fixpoint iterations."),
112 cl::init(32));
Johannes Doerfertb504eb82019-08-26 18:55:47 +0000113static cl::opt<bool> VerifyMaxFixpointIterations(
114 "attributor-max-iterations-verify", cl::Hidden,
115 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
116 cl::init(false));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000117
118static cl::opt<bool> DisableAttributor(
119 "attributor-disable", cl::Hidden,
120 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +0000121 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000122
Johannes Doerfert7516a5e2019-09-03 20:37:24 +0000123static cl::opt<bool> ManifestInternal(
124 "attributor-manifest-internal", cl::Hidden,
125 cl::desc("Manifest Attributor internal string attributes."),
126 cl::init(false));
127
Johannes Doerfertaade7822019-06-05 03:02:24 +0000128static cl::opt<bool> VerifyAttributor(
129 "attributor-verify", cl::Hidden,
130 cl::desc("Verify the Attributor deduction and "
131 "manifestation of attributes -- may issue false-positive errors"),
132 cl::init(false));
133
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000134static cl::opt<unsigned> DepRecInterval(
135 "attributor-dependence-recompute-interval", cl::Hidden,
136 cl::desc("Number of iterations until dependences are recomputed."),
137 cl::init(4));
138
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000139static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
140 cl::init(true), cl::Hidden);
141
142static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size",
143 cl::init(128), cl::Hidden);
144
Johannes Doerfertaade7822019-06-05 03:02:24 +0000145/// Logic operators for the change status enum class.
146///
147///{
148ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
149 return l == ChangeStatus::CHANGED ? l : r;
150}
151ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
152 return l == ChangeStatus::UNCHANGED ? l : r;
153}
154///}
155
Johannes Doerfertdef99282019-08-14 21:29:37 +0000156/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000157/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000158/// with the "returned" attribute. Once we cannot look through the value any
159/// further, the callback \p VisitValueCB is invoked and passed the current
160/// value, the \p State, and a flag to indicate if we stripped anything. To
161/// limit how much effort is invested, we will never visit more values than
162/// specified by \p MaxValues.
163template <typename AAType, typename StateTy>
164bool genericValueTraversal(
165 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000166 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000167 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000168
Johannes Doerfertdef99282019-08-14 21:29:37 +0000169 const AAIsDead *LivenessAA = nullptr;
170 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000171 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000172 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
173 /* TrackDependence */ false);
174 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000175
176 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000177 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000178 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000179 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000180
181 int Iteration = 0;
182 do {
183 Value *V = Worklist.pop_back_val();
184
185 // Check if we should process the current value. To prevent endless
186 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000187 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000188 continue;
189
190 // Make sure we limit the compile time for complex expressions.
191 if (Iteration++ >= MaxValues)
192 return false;
193
194 // Explicitly look through calls with a "returned" attribute if we do
195 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000196 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000197 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000198 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000199 } else {
200 CallSite CS(V);
201 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000202 for (Argument &Arg : CS.getCalledFunction()->args())
203 if (Arg.hasReturnedAttr()) {
204 NewV = CS.getArgOperand(Arg.getArgNo());
205 break;
206 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000207 }
208 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000209 if (NewV && NewV != V) {
210 Worklist.push_back(NewV);
211 continue;
212 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000213
214 // Look through select instructions, visit both potential values.
215 if (auto *SI = dyn_cast<SelectInst>(V)) {
216 Worklist.push_back(SI->getTrueValue());
217 Worklist.push_back(SI->getFalseValue());
218 continue;
219 }
220
Johannes Doerfertdef99282019-08-14 21:29:37 +0000221 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000222 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000223 assert(LivenessAA &&
224 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000225 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
226 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000227 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000228 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000229 continue;
230 }
231 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000232 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000233 continue;
234 }
235
236 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000237 if (!VisitValueCB(*V, State, Iteration > 1))
238 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000239 } while (!Worklist.empty());
240
Johannes Doerfert19b00432019-08-26 17:48:05 +0000241 // If we actually used liveness information so we have to record a dependence.
242 if (AnyDead)
243 A.recordDependence(*LivenessAA, QueryingAA);
244
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000245 // All values have been visited.
246 return true;
247}
248
Johannes Doerfertaade7822019-06-05 03:02:24 +0000249/// Return true if \p New is equal or worse than \p Old.
250static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
251 if (!Old.isIntAttribute())
252 return true;
253
254 return Old.getValueAsInt() >= New.getValueAsInt();
255}
256
257/// Return true if the information provided by \p Attr was added to the
258/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000259/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000260static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000261 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000262
263 if (Attr.isEnumAttribute()) {
264 Attribute::AttrKind Kind = Attr.getKindAsEnum();
265 if (Attrs.hasAttribute(AttrIdx, Kind))
266 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
267 return false;
268 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
269 return true;
270 }
271 if (Attr.isStringAttribute()) {
272 StringRef Kind = Attr.getKindAsString();
273 if (Attrs.hasAttribute(AttrIdx, Kind))
274 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
275 return false;
276 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
277 return true;
278 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000279 if (Attr.isIntAttribute()) {
280 Attribute::AttrKind Kind = Attr.getKindAsEnum();
281 if (Attrs.hasAttribute(AttrIdx, Kind))
282 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
283 return false;
284 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
285 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
286 return true;
287 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000288
289 llvm_unreachable("Expected enum or string attribute!");
290}
291
Johannes Doerfertece81902019-08-12 22:05:53 +0000292ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000293 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
294 if (getState().isAtFixpoint())
295 return HasChanged;
296
297 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
298
Johannes Doerfertece81902019-08-12 22:05:53 +0000299 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000300
301 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
302 << "\n");
303
304 return HasChanged;
305}
306
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000307ChangeStatus
308IRAttributeManifest::manifestAttrs(Attributor &A, IRPosition &IRP,
309 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000310 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000311 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000312
Johannes Doerfertaade7822019-06-05 03:02:24 +0000313 // In the following some generic code that will manifest attributes in
314 // DeducedAttrs if they improve the current IR. Due to the different
315 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000316
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000317 AttributeList Attrs;
318 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000319 case IRPosition::IRP_INVALID:
320 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000321 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000322 case IRPosition::IRP_ARGUMENT:
323 case IRPosition::IRP_FUNCTION:
324 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000325 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000326 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000327 case IRPosition::IRP_CALL_SITE:
328 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000329 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000330 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000331 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000332 }
333
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000334 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000335 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000336 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000337 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000338 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000339
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000340 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000341 }
342
343 if (HasChanged == ChangeStatus::UNCHANGED)
344 return HasChanged;
345
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000346 switch (PK) {
347 case IRPosition::IRP_ARGUMENT:
348 case IRPosition::IRP_FUNCTION:
349 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000350 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000351 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000352 case IRPosition::IRP_CALL_SITE:
353 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000354 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000355 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000356 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000357 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000358 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000359 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000360 }
361
362 return HasChanged;
363}
364
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000365const IRPosition IRPosition::EmptyKey(255);
366const IRPosition IRPosition::TombstoneKey(256);
367
368SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
369 IRPositions.emplace_back(IRP);
370
371 ImmutableCallSite ICS(&IRP.getAnchorValue());
372 switch (IRP.getPositionKind()) {
373 case IRPosition::IRP_INVALID:
374 case IRPosition::IRP_FLOAT:
375 case IRPosition::IRP_FUNCTION:
376 return;
377 case IRPosition::IRP_ARGUMENT:
378 case IRPosition::IRP_RETURNED:
379 IRPositions.emplace_back(
380 IRPosition::function(*IRP.getAssociatedFunction()));
381 return;
382 case IRPosition::IRP_CALL_SITE:
383 assert(ICS && "Expected call site!");
384 // TODO: We need to look at the operand bundles similar to the redirection
385 // in CallBase.
386 if (!ICS.hasOperandBundles())
387 if (const Function *Callee = ICS.getCalledFunction())
388 IRPositions.emplace_back(IRPosition::function(*Callee));
389 return;
390 case IRPosition::IRP_CALL_SITE_RETURNED:
391 assert(ICS && "Expected call site!");
392 // TODO: We need to look at the operand bundles similar to the redirection
393 // in CallBase.
394 if (!ICS.hasOperandBundles()) {
395 if (const Function *Callee = ICS.getCalledFunction()) {
396 IRPositions.emplace_back(IRPosition::returned(*Callee));
397 IRPositions.emplace_back(IRPosition::function(*Callee));
398 }
399 }
400 IRPositions.emplace_back(
401 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
402 return;
403 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
404 int ArgNo = IRP.getArgNo();
405 assert(ICS && ArgNo >= 0 && "Expected call site!");
406 // TODO: We need to look at the operand bundles similar to the redirection
407 // in CallBase.
408 if (!ICS.hasOperandBundles()) {
409 const Function *Callee = ICS.getCalledFunction();
410 if (Callee && Callee->arg_size() > unsigned(ArgNo))
411 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
412 if (Callee)
413 IRPositions.emplace_back(IRPosition::function(*Callee));
414 }
415 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
416 return;
417 }
418 }
419}
420
421bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs) const {
422 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this))
423 for (Attribute::AttrKind AK : AKs)
424 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
425 return true;
426 return false;
427}
428
429void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
430 SmallVectorImpl<Attribute> &Attrs) const {
431 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this))
432 for (Attribute::AttrKind AK : AKs) {
433 const Attribute &Attr = EquivIRP.getAttr(AK);
434 if (Attr.getKindAsEnum() == AK)
435 Attrs.push_back(Attr);
436 }
437}
438
439void IRPosition::verify() {
440 switch (KindOrArgNo) {
441 default:
442 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
443 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
444 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000445 if (isa<Argument>(AnchorVal)) {
446 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000447 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000448 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
449 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000450 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000451 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000452 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000453 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
454 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000455 "Associated value mismatch!");
456 }
457 break;
458 case IRP_INVALID:
459 assert(!AnchorVal && "Expected no value for an invalid position!");
460 break;
461 case IRP_FLOAT:
462 assert((!isa<CallBase>(&getAssociatedValue()) &&
463 !isa<Argument>(&getAssociatedValue())) &&
464 "Expected specialized kind for call base and argument values!");
465 break;
466 case IRP_RETURNED:
467 assert(isa<Function>(AnchorVal) &&
468 "Expected function for a 'returned' position!");
469 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
470 break;
471 case IRP_CALL_SITE_RETURNED:
472 assert((isa<CallBase>(AnchorVal)) &&
473 "Expected call base for 'call site returned' position!");
474 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
475 break;
476 case IRP_CALL_SITE:
477 assert((isa<CallBase>(AnchorVal)) &&
478 "Expected call base for 'call site function' position!");
479 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
480 break;
481 case IRP_FUNCTION:
482 assert(isa<Function>(AnchorVal) &&
483 "Expected function for a 'function' position!");
484 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
485 break;
486 }
487}
488
Johannes Doerfert234eda52019-08-16 19:51:23 +0000489/// Helper functions to clamp a state \p S of type \p StateType with the
490/// information in \p R and indicate/return if \p S did change (as-in update is
491/// required to be run again).
492///
493///{
494template <typename StateType>
495ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R);
496
497template <>
498ChangeStatus clampStateAndIndicateChange<IntegerState>(IntegerState &S,
499 const IntegerState &R) {
500 auto Assumed = S.getAssumed();
501 S ^= R;
502 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
503 : ChangeStatus::CHANGED;
504}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000505
506template <>
507ChangeStatus clampStateAndIndicateChange<BooleanState>(BooleanState &S,
508 const BooleanState &R) {
509 return clampStateAndIndicateChange<IntegerState>(S, R);
510}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000511///}
512
513/// Clamp the information known for all returned values of a function
514/// (identified by \p QueryingAA) into \p S.
515template <typename AAType, typename StateType = typename AAType::StateType>
516static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
517 StateType &S) {
518 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
519 << static_cast<const AbstractAttribute &>(QueryingAA)
520 << " into " << S << "\n");
521
522 assert((QueryingAA.getIRPosition().getPositionKind() ==
523 IRPosition::IRP_RETURNED ||
524 QueryingAA.getIRPosition().getPositionKind() ==
525 IRPosition::IRP_CALL_SITE_RETURNED) &&
526 "Can only clamp returned value states for a function returned or call "
527 "site returned position!");
528
529 // Use an optional state as there might not be any return values and we want
530 // to join (IntegerState::operator&) the state of all there are.
531 Optional<StateType> T;
532
533 // Callback for each possibly returned value.
534 auto CheckReturnValue = [&](Value &RV) -> bool {
535 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000536 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
537 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
538 << " @ " << RVPos << "\n");
539 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000540 if (T.hasValue())
541 *T &= AAS;
542 else
543 T = AAS;
544 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
545 << "\n");
546 return T->isValidState();
547 };
548
549 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
550 S.indicatePessimisticFixpoint();
551 else if (T.hasValue())
552 S ^= *T;
553}
554
555/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000556template <typename AAType, typename Base,
557 typename StateType = typename AAType::StateType>
558struct AAReturnedFromReturnedValues : public Base {
559 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000560
561 /// See AbstractAttribute::updateImpl(...).
562 ChangeStatus updateImpl(Attributor &A) override {
563 StateType S;
564 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000565 // TODO: If we know we visited all returned values, thus no are assumed
566 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000567 return clampStateAndIndicateChange<StateType>(this->getState(), S);
568 }
569};
570
571/// Clamp the information known at all call sites for a given argument
572/// (identified by \p QueryingAA) into \p S.
573template <typename AAType, typename StateType = typename AAType::StateType>
574static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
575 StateType &S) {
576 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
577 << static_cast<const AbstractAttribute &>(QueryingAA)
578 << " into " << S << "\n");
579
580 assert(QueryingAA.getIRPosition().getPositionKind() ==
581 IRPosition::IRP_ARGUMENT &&
582 "Can only clamp call site argument states for an argument position!");
583
584 // Use an optional state as there might not be any return values and we want
585 // to join (IntegerState::operator&) the state of all there are.
586 Optional<StateType> T;
587
588 // The argument number which is also the call site argument number.
589 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
590
591 auto CallSiteCheck = [&](CallSite CS) {
592 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000593 const AAType &AA = A.getAAFor<AAType>(QueryingAA, CSArgPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000594 LLVM_DEBUG(dbgs() << "[Attributor] CS: " << *CS.getInstruction()
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000595 << " AA: " << AA.getAsStr() << " @" << CSArgPos << "\n");
596 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000597 if (T.hasValue())
598 *T &= AAS;
599 else
600 T = AAS;
601 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
602 << "\n");
603 return T->isValidState();
604 };
605
606 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true))
607 S.indicatePessimisticFixpoint();
608 else if (T.hasValue())
609 S ^= *T;
610}
611
612/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000613template <typename AAType, typename Base,
614 typename StateType = typename AAType::StateType>
615struct AAArgumentFromCallSiteArguments : public Base {
616 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000617
618 /// See AbstractAttribute::updateImpl(...).
619 ChangeStatus updateImpl(Attributor &A) override {
620 StateType S;
621 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000622 // TODO: If we know we visited all incoming values, thus no are assumed
623 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000624 return clampStateAndIndicateChange<StateType>(this->getState(), S);
625 }
626};
627
628/// Helper class for generic replication: function returned -> cs returned.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000629template <typename AAType, typename Base>
630struct AACallSiteReturnedFromReturned : public Base {
631 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000632
633 /// See AbstractAttribute::updateImpl(...).
634 ChangeStatus updateImpl(Attributor &A) override {
635 assert(this->getIRPosition().getPositionKind() ==
636 IRPosition::IRP_CALL_SITE_RETURNED &&
637 "Can only wrap function returned positions for call site returned "
638 "positions!");
639 auto &S = this->getState();
640
641 const Function *AssociatedFunction =
642 this->getIRPosition().getAssociatedFunction();
643 if (!AssociatedFunction)
644 return S.indicatePessimisticFixpoint();
645
646 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000647 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000648 return clampStateAndIndicateChange(
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000649 S, static_cast<const typename AAType::StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000650 }
651};
652
Stefan Stipanovic53605892019-06-27 11:27:54 +0000653/// -----------------------NoUnwind Function Attribute--------------------------
654
Johannes Doerfert344d0382019-08-07 22:34:26 +0000655struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000656 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000657
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000658 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000659 return getAssumed() ? "nounwind" : "may-unwind";
660 }
661
662 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000663 ChangeStatus updateImpl(Attributor &A) override {
664 auto Opcodes = {
665 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
666 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
667 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
668
669 auto CheckForNoUnwind = [&](Instruction &I) {
670 if (!I.mayThrow())
671 return true;
672
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000673 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
674 const auto &NoUnwindAA =
675 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
676 return NoUnwindAA.isAssumedNoUnwind();
677 }
678 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000679 };
680
681 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
682 return indicatePessimisticFixpoint();
683
684 return ChangeStatus::UNCHANGED;
685 }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000686};
687
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000688struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000689 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000690
691 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000692 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000693};
694
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000695/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000696struct AANoUnwindCallSite final : AANoUnwindImpl {
697 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
698
699 /// See AbstractAttribute::initialize(...).
700 void initialize(Attributor &A) override {
701 AANoUnwindImpl::initialize(A);
702 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000703 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000704 indicatePessimisticFixpoint();
705 }
706
707 /// See AbstractAttribute::updateImpl(...).
708 ChangeStatus updateImpl(Attributor &A) override {
709 // TODO: Once we have call site specific value information we can provide
710 // call site specific liveness information and then it makes
711 // sense to specialize attributes for call sites arguments instead of
712 // redirecting requests to the callee argument.
713 Function *F = getAssociatedFunction();
714 const IRPosition &FnPos = IRPosition::function(*F);
715 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
716 return clampStateAndIndicateChange(
717 getState(),
718 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
719 }
720
721 /// See AbstractAttribute::trackStatistics()
722 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
723};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000724
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000725/// --------------------- Function Return Values -------------------------------
726
727/// "Attribute" that collects all potential returned values and the return
728/// instructions that they arise from.
729///
730/// If there is a unique returned value R, the manifest method will:
731/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +0000732class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000733
734 /// Mapping of values potentially returned by the associated function to the
735 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +0000736 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000737
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000738 /// Mapping to remember the number of returned values for a call site such
739 /// that we can avoid updates if nothing changed.
740 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
741
742 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +0000743 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000744
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000745 /// State flags
746 ///
747 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000748 bool IsFixed = false;
749 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000750 ///}
751
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000752public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000753 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000754
755 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +0000756 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000757 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000758 IsFixed = false;
759 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000760 ReturnedValues.clear();
761
Johannes Doerfertdef99282019-08-14 21:29:37 +0000762 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000763 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000764 indicatePessimisticFixpoint();
765 return;
766 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000767
768 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000769 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000770
771 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000772 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000773 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000774 auto &ReturnInstSet = ReturnedValues[&Arg];
775 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
776 ReturnInstSet.insert(cast<ReturnInst>(RI));
777
778 indicateOptimisticFixpoint();
779 return;
780 }
781 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000782
783 if (!F->hasExactDefinition())
784 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000785 }
786
787 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000788 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000789
790 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000791 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000792
793 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000794 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000795
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000796 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +0000797 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000798
Johannes Doerfertdef99282019-08-14 21:29:37 +0000799 llvm::iterator_range<iterator> returned_values() override {
800 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
801 }
802
803 llvm::iterator_range<const_iterator> returned_values() const override {
804 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
805 }
806
Johannes Doerfert695089e2019-08-23 15:23:49 +0000807 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000808 return UnresolvedCalls;
809 }
810
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000811 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000812 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000813 return isValidState() ? ReturnedValues.size() : -1;
814 }
815
816 /// Return an assumed unique return value if a single candidate is found. If
817 /// there cannot be one, return a nullptr. If it is not clear yet, return the
818 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000819 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000820
Johannes Doerfert14a04932019-08-07 22:27:24 +0000821 /// See AbstractState::checkForAllReturnedValues(...).
822 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +0000823 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +0000824 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000825
826 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000827 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000828
829 /// See AbstractState::isAtFixpoint().
830 bool isAtFixpoint() const override { return IsFixed; }
831
832 /// See AbstractState::isValidState().
833 bool isValidState() const override { return IsValidState; }
834
835 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000836 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000837 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000838 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000839 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000840
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000841 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000842 IsFixed = true;
843 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000844 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000845 }
846};
847
848ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
849 ChangeStatus Changed = ChangeStatus::UNCHANGED;
850
851 // Bookkeeping.
852 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000853 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
854 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000855
856 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000857 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000858
859 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
860 return Changed;
861
862 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000863 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
864 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000865
Johannes Doerfert23400e612019-08-23 17:41:37 +0000866 // Callback to replace the uses of CB with the constant C.
867 auto ReplaceCallSiteUsersWith = [](CallBase &CB, Constant &C) {
868 if (CB.getNumUses() == 0)
869 return ChangeStatus::UNCHANGED;
870 CB.replaceAllUsesWith(&C);
871 return ChangeStatus::CHANGED;
872 };
873
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000874 // If the assumed unique return value is an argument, annotate it.
875 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000876 getIRPosition() = IRPosition::argument(*UniqueRVArg);
Johannes Doerfert23400e612019-08-23 17:41:37 +0000877 Changed = IRAttribute::manifest(A);
878 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
879 // We can replace the returned value with the unique returned constant.
880 Value &AnchorValue = getAnchorValue();
881 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
882 for (const Use &U : F->uses())
883 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +0000884 if (CB->isCallee(&U)) {
885 Constant *RVCCast =
886 ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
887 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
888 }
Johannes Doerfert23400e612019-08-23 17:41:37 +0000889 } else {
890 assert(isa<CallBase>(AnchorValue) &&
891 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +0000892 Constant *RVCCast =
893 ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
894 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +0000895 }
896 if (Changed == ChangeStatus::CHANGED)
897 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
898 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000899 }
900
901 return Changed;
902}
903
904const std::string AAReturnedValuesImpl::getAsStr() const {
905 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +0000906 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +0000907 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000908}
909
Johannes Doerfert14a04932019-08-07 22:27:24 +0000910Optional<Value *>
911AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
912 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000913 // undef values that can also be present, it is assumed to be the actual
914 // return value and forwarded to the caller of this method. If there are
915 // multiple, a nullptr is returned indicating there cannot be a unique
916 // returned value.
917 Optional<Value *> UniqueRV;
918
Johannes Doerfert14a04932019-08-07 22:27:24 +0000919 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000920 // If we found a second returned value and neither the current nor the saved
921 // one is an undef, there is no unique returned value. Undefs are special
922 // since we can pretend they have any value.
923 if (UniqueRV.hasValue() && UniqueRV != &RV &&
924 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
925 UniqueRV = nullptr;
926 return false;
927 }
928
929 // Do not overwrite a value with an undef.
930 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
931 UniqueRV = &RV;
932
933 return true;
934 };
935
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000936 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000937 UniqueRV = nullptr;
938
939 return UniqueRV;
940}
941
Johannes Doerfert14a04932019-08-07 22:27:24 +0000942bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +0000943 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +0000944 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000945 if (!isValidState())
946 return false;
947
948 // Check all returned values but ignore call sites as long as we have not
949 // encountered an overdefined one during an update.
950 for (auto &It : ReturnedValues) {
951 Value *RV = It.first;
952
Johannes Doerfertdef99282019-08-14 21:29:37 +0000953 CallBase *CB = dyn_cast<CallBase>(RV);
954 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000955 continue;
956
Johannes Doerfert695089e2019-08-23 15:23:49 +0000957 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000958 return false;
959 }
960
961 return true;
962}
963
Johannes Doerfertece81902019-08-12 22:05:53 +0000964ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000965 size_t NumUnresolvedCalls = UnresolvedCalls.size();
966 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000967
Johannes Doerfertdef99282019-08-14 21:29:37 +0000968 // State used in the value traversals starting in returned values.
969 struct RVState {
970 // The map in which we collect return values -> return instrs.
971 decltype(ReturnedValues) &RetValsMap;
972 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +0000973 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000974 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +0000975 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000976 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000977
Johannes Doerfertdef99282019-08-14 21:29:37 +0000978 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000979 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000980 auto Size = RVS.RetValsMap[&Val].size();
981 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
982 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
983 RVS.Changed |= Inserted;
984 LLVM_DEBUG({
985 if (Inserted)
986 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
987 << " => " << RVS.RetInsts.size() << "\n";
988 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000989 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000990 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000991
Johannes Doerfertdef99282019-08-14 21:29:37 +0000992 // Helper method to invoke the generic value traversal.
993 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
994 IRPosition RetValPos = IRPosition::value(RV);
995 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
996 RVS, VisitValueCB);
997 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +0000998
Johannes Doerfertdef99282019-08-14 21:29:37 +0000999 // Callback for all "return intructions" live in the associated function.
1000 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1001 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001002 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001003 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001004 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1005 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001006
Johannes Doerfertdef99282019-08-14 21:29:37 +00001007 // Start by discovering returned values from all live returned instructions in
1008 // the associated function.
1009 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1010 return indicatePessimisticFixpoint();
1011
1012 // Once returned values "directly" present in the code are handled we try to
1013 // resolve returned calls.
1014 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001015 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001016 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1017 << " by #" << It.second.size() << " RIs\n");
1018 CallBase *CB = dyn_cast<CallBase>(It.first);
1019 if (!CB || UnresolvedCalls.count(CB))
1020 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001021
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001022 if (!CB->getCalledFunction()) {
1023 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1024 << "\n");
1025 UnresolvedCalls.insert(CB);
1026 continue;
1027 }
1028
1029 // TODO: use the function scope once we have call site AAReturnedValues.
1030 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1031 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001032 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
1033 << static_cast<const AbstractAttribute &>(RetValAA)
1034 << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001035
1036 // Skip dead ends, thus if we do not know anything about the returned
1037 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001038 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001039 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1040 << "\n");
1041 UnresolvedCalls.insert(CB);
1042 continue;
1043 }
1044
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001045 // Do not try to learn partial information. If the callee has unresolved
1046 // return values we will treat the call as unresolved/opaque.
1047 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1048 if (!RetValAAUnresolvedCalls.empty()) {
1049 UnresolvedCalls.insert(CB);
1050 continue;
1051 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001052
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001053 // Now check if we can track transitively returned values. If possible, thus
1054 // if all return value can be represented in the current scope, do so.
1055 bool Unresolved = false;
1056 for (auto &RetValAAIt : RetValAA.returned_values()) {
1057 Value *RetVal = RetValAAIt.first;
1058 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1059 isa<Constant>(RetVal))
1060 continue;
1061 // Anything that did not fit in the above categories cannot be resolved,
1062 // mark the call as unresolved.
1063 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1064 "cannot be translated: "
1065 << *RetVal << "\n");
1066 UnresolvedCalls.insert(CB);
1067 Unresolved = true;
1068 break;
1069 }
1070
1071 if (Unresolved)
1072 continue;
1073
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001074 // Now track transitively returned values.
1075 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1076 if (NumRetAA == RetValAA.getNumReturnValues()) {
1077 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1078 "changed since it was seen last\n");
1079 continue;
1080 }
1081 NumRetAA = RetValAA.getNumReturnValues();
1082
Johannes Doerfertdef99282019-08-14 21:29:37 +00001083 for (auto &RetValAAIt : RetValAA.returned_values()) {
1084 Value *RetVal = RetValAAIt.first;
1085 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1086 // Arguments are mapped to call site operands and we begin the traversal
1087 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001088 bool Unused = false;
1089 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001090 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1091 continue;
1092 } else if (isa<CallBase>(RetVal)) {
1093 // Call sites are resolved by the callee attribute over time, no need to
1094 // do anything for us.
1095 continue;
1096 } else if (isa<Constant>(RetVal)) {
1097 // Constants are valid everywhere, we can simply take them.
1098 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1099 continue;
1100 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001101 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001102 }
1103
Johannes Doerfertdef99282019-08-14 21:29:37 +00001104 // To avoid modifications to the ReturnedValues map while we iterate over it
1105 // we kept record of potential new entries in a copy map, NewRVsMap.
1106 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001107 assert(!It.second.empty() && "Entry does not add anything.");
1108 auto &ReturnInsts = ReturnedValues[It.first];
1109 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001110 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001111 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1112 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001113 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001114 }
1115 }
1116
Johannes Doerfertdef99282019-08-14 21:29:37 +00001117 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1118 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001119}
1120
Johannes Doerfertdef99282019-08-14 21:29:37 +00001121struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1122 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1123
1124 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001125 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001126};
1127
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001128/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001129struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1130 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1131
1132 /// See AbstractAttribute::initialize(...).
1133 void initialize(Attributor &A) override {
1134 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001135 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001136 // sense to specialize attributes for call sites instead of
1137 // redirecting requests to the callee.
1138 llvm_unreachable("Abstract attributes for returned values are not "
1139 "supported for call sites yet!");
1140 }
1141
1142 /// See AbstractAttribute::updateImpl(...).
1143 ChangeStatus updateImpl(Attributor &A) override {
1144 return indicatePessimisticFixpoint();
1145 }
1146
1147 /// See AbstractAttribute::trackStatistics()
1148 void trackStatistics() const override {}
1149};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001150
Stefan Stipanovic06263672019-07-11 21:37:40 +00001151/// ------------------------ NoSync Function Attribute -------------------------
1152
Johannes Doerfert344d0382019-08-07 22:34:26 +00001153struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001154 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001155
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001156 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001157 return getAssumed() ? "nosync" : "may-sync";
1158 }
1159
1160 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001161 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001162
Stefan Stipanovic06263672019-07-11 21:37:40 +00001163 /// Helper function used to determine whether an instruction is non-relaxed
1164 /// atomic. In other words, if an atomic instruction does not have unordered
1165 /// or monotonic ordering
1166 static bool isNonRelaxedAtomic(Instruction *I);
1167
1168 /// Helper function used to determine whether an instruction is volatile.
1169 static bool isVolatile(Instruction *I);
1170
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001171 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1172 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001173 static bool isNoSyncIntrinsic(Instruction *I);
1174};
1175
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001176bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001177 if (!I->isAtomic())
1178 return false;
1179
1180 AtomicOrdering Ordering;
1181 switch (I->getOpcode()) {
1182 case Instruction::AtomicRMW:
1183 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1184 break;
1185 case Instruction::Store:
1186 Ordering = cast<StoreInst>(I)->getOrdering();
1187 break;
1188 case Instruction::Load:
1189 Ordering = cast<LoadInst>(I)->getOrdering();
1190 break;
1191 case Instruction::Fence: {
1192 auto *FI = cast<FenceInst>(I);
1193 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1194 return false;
1195 Ordering = FI->getOrdering();
1196 break;
1197 }
1198 case Instruction::AtomicCmpXchg: {
1199 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1200 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1201 // Only if both are relaxed, than it can be treated as relaxed.
1202 // Otherwise it is non-relaxed.
1203 if (Success != AtomicOrdering::Unordered &&
1204 Success != AtomicOrdering::Monotonic)
1205 return true;
1206 if (Failure != AtomicOrdering::Unordered &&
1207 Failure != AtomicOrdering::Monotonic)
1208 return true;
1209 return false;
1210 }
1211 default:
1212 llvm_unreachable(
1213 "New atomic operations need to be known in the attributor.");
1214 }
1215
1216 // Relaxed.
1217 if (Ordering == AtomicOrdering::Unordered ||
1218 Ordering == AtomicOrdering::Monotonic)
1219 return false;
1220 return true;
1221}
1222
1223/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1224/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001225bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001226 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1227 switch (II->getIntrinsicID()) {
1228 /// Element wise atomic memory intrinsics are can only be unordered,
1229 /// therefore nosync.
1230 case Intrinsic::memset_element_unordered_atomic:
1231 case Intrinsic::memmove_element_unordered_atomic:
1232 case Intrinsic::memcpy_element_unordered_atomic:
1233 return true;
1234 case Intrinsic::memset:
1235 case Intrinsic::memmove:
1236 case Intrinsic::memcpy:
1237 if (!cast<MemIntrinsic>(II)->isVolatile())
1238 return true;
1239 return false;
1240 default:
1241 return false;
1242 }
1243 }
1244 return false;
1245}
1246
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001247bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001248 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1249 "Calls should not be checked here");
1250
1251 switch (I->getOpcode()) {
1252 case Instruction::AtomicRMW:
1253 return cast<AtomicRMWInst>(I)->isVolatile();
1254 case Instruction::Store:
1255 return cast<StoreInst>(I)->isVolatile();
1256 case Instruction::Load:
1257 return cast<LoadInst>(I)->isVolatile();
1258 case Instruction::AtomicCmpXchg:
1259 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1260 default:
1261 return false;
1262 }
1263}
1264
Johannes Doerfertece81902019-08-12 22:05:53 +00001265ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001266
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001267 auto CheckRWInstForNoSync = [&](Instruction &I) {
1268 /// We are looking for volatile instructions or Non-Relaxed atomics.
1269 /// FIXME: We should ipmrove the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001270
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001271 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1272 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001273
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001274 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1275 if (ICS.hasFnAttr(Attribute::NoSync))
1276 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001277
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001278 const auto &NoSyncAA =
1279 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1280 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001281 return true;
1282 return false;
1283 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001284
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001285 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1286 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001287
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001288 return false;
1289 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001290
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001291 auto CheckForNoSync = [&](Instruction &I) {
1292 // At this point we handled all read/write effects and they are all
1293 // nosync, so they can be skipped.
1294 if (I.mayReadOrWriteMemory())
1295 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001296
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001297 // non-convergent and readnone imply nosync.
1298 return !ImmutableCallSite(&I).isConvergent();
1299 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001300
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001301 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1302 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001303 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001304
Stefan Stipanovic06263672019-07-11 21:37:40 +00001305 return ChangeStatus::UNCHANGED;
1306}
1307
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001308struct AANoSyncFunction final : public AANoSyncImpl {
1309 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1310
1311 /// See AbstractAttribute::trackStatistics()
1312 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1313};
1314
1315/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001316struct AANoSyncCallSite final : AANoSyncImpl {
1317 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1318
1319 /// See AbstractAttribute::initialize(...).
1320 void initialize(Attributor &A) override {
1321 AANoSyncImpl::initialize(A);
1322 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001323 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001324 indicatePessimisticFixpoint();
1325 }
1326
1327 /// See AbstractAttribute::updateImpl(...).
1328 ChangeStatus updateImpl(Attributor &A) override {
1329 // TODO: Once we have call site specific value information we can provide
1330 // call site specific liveness information and then it makes
1331 // sense to specialize attributes for call sites arguments instead of
1332 // redirecting requests to the callee argument.
1333 Function *F = getAssociatedFunction();
1334 const IRPosition &FnPos = IRPosition::function(*F);
1335 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1336 return clampStateAndIndicateChange(
1337 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1338 }
1339
1340 /// See AbstractAttribute::trackStatistics()
1341 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1342};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001343
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001344/// ------------------------ No-Free Attributes ----------------------------
1345
Johannes Doerfert344d0382019-08-07 22:34:26 +00001346struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001347 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001348
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001349 /// See AbstractAttribute::updateImpl(...).
1350 ChangeStatus updateImpl(Attributor &A) override {
1351 auto CheckForNoFree = [&](Instruction &I) {
1352 ImmutableCallSite ICS(&I);
1353 if (ICS.hasFnAttr(Attribute::NoFree))
1354 return true;
1355
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001356 const auto &NoFreeAA =
1357 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1358 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001359 };
1360
1361 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1362 return indicatePessimisticFixpoint();
1363 return ChangeStatus::UNCHANGED;
1364 }
1365
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001366 /// See AbstractAttribute::getAsStr().
1367 const std::string getAsStr() const override {
1368 return getAssumed() ? "nofree" : "may-free";
1369 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001370};
1371
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001372struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001373 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001374
1375 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001376 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001377};
1378
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001379/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001380struct AANoFreeCallSite final : AANoFreeImpl {
1381 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1382
1383 /// See AbstractAttribute::initialize(...).
1384 void initialize(Attributor &A) override {
1385 AANoFreeImpl::initialize(A);
1386 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001387 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001388 indicatePessimisticFixpoint();
1389 }
1390
1391 /// See AbstractAttribute::updateImpl(...).
1392 ChangeStatus updateImpl(Attributor &A) override {
1393 // TODO: Once we have call site specific value information we can provide
1394 // call site specific liveness information and then it makes
1395 // sense to specialize attributes for call sites arguments instead of
1396 // redirecting requests to the callee argument.
1397 Function *F = getAssociatedFunction();
1398 const IRPosition &FnPos = IRPosition::function(*F);
1399 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1400 return clampStateAndIndicateChange(
1401 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1402 }
1403
1404 /// See AbstractAttribute::trackStatistics()
1405 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1406};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001407
Hideto Ueno54869ec2019-07-15 06:49:04 +00001408/// ------------------------ NonNull Argument Attribute ------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00001409struct AANonNullImpl : AANonNull {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001410 AANonNullImpl(const IRPosition &IRP) : AANonNull(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001411
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001412 /// See AbstractAttribute::initialize(...).
1413 void initialize(Attributor &A) override {
1414 if (hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
1415 indicateOptimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001416 else
1417 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001418 }
1419
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001420 /// See AbstractAttribute::getAsStr().
1421 const std::string getAsStr() const override {
1422 return getAssumed() ? "nonnull" : "may-null";
1423 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001424};
1425
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001426/// NonNull attribute for a floating value.
1427struct AANonNullFloating : AANonNullImpl {
1428 AANonNullFloating(const IRPosition &IRP) : AANonNullImpl(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001429
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001430 /// See AbstractAttribute::initialize(...).
1431 void initialize(Attributor &A) override {
1432 AANonNullImpl::initialize(A);
Hideto Ueno54869ec2019-07-15 06:49:04 +00001433
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001434 if (isAtFixpoint())
1435 return;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001436
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001437 const IRPosition &IRP = getIRPosition();
1438 const Value &V = IRP.getAssociatedValue();
1439 const DataLayout &DL = A.getDataLayout();
Hideto Ueno54869ec2019-07-15 06:49:04 +00001440
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001441 // TODO: This context sensitive query should be removed once we can do
1442 // context sensitive queries in the genericValueTraversal below.
1443 if (isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, IRP.getCtxI(),
1444 /* TODO: DT */ nullptr))
1445 indicateOptimisticFixpoint();
1446 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001447
1448 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001449 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001450 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001451
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001452 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
1453 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001454 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1455 if (!Stripped && this == &AA) {
1456 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr,
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001457 /* TODO: CtxI */ nullptr,
1458 /* TODO: DT */ nullptr))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001459 T.indicatePessimisticFixpoint();
1460 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001461 // Use abstract attribute information.
1462 const AANonNull::StateType &NS =
1463 static_cast<const AANonNull::StateType &>(AA.getState());
1464 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001465 }
1466 return T.isValidState();
1467 };
1468
1469 StateType T;
1470 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
1471 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001472 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001473
1474 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001475 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001476
1477 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001478 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001479};
1480
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001481/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001482struct AANonNullReturned final
1483 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001484 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001485 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001486
1487 /// See AbstractAttribute::trackStatistics()
1488 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
1489};
1490
Hideto Ueno54869ec2019-07-15 06:49:04 +00001491/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001492struct AANonNullArgument final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001493 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001494 AANonNullArgument(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001495 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001496
1497 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001498 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001499};
1500
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001501struct AANonNullCallSiteArgument final : AANonNullFloating {
1502 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001503
1504 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00001505 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001506};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001507
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001508/// NonNull attribute for a call site return position.
1509struct AANonNullCallSiteReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001510 : AACallSiteReturnedFromReturned<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001511 AANonNullCallSiteReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001512 : AACallSiteReturnedFromReturned<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001513
1514 /// See AbstractAttribute::trackStatistics()
1515 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
1516};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001517
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001518/// ------------------------ No-Recurse Attributes ----------------------------
1519
1520struct AANoRecurseImpl : public AANoRecurse {
1521 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
1522
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001523 /// See AbstractAttribute::getAsStr()
1524 const std::string getAsStr() const override {
1525 return getAssumed() ? "norecurse" : "may-recurse";
1526 }
1527};
1528
1529struct AANoRecurseFunction final : AANoRecurseImpl {
1530 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1531
1532 /// See AbstractAttribute::updateImpl(...).
1533 ChangeStatus updateImpl(Attributor &A) override {
1534 // TODO: Implement this.
1535 return indicatePessimisticFixpoint();
1536 }
1537
1538 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
1539};
1540
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001541/// NoRecurse attribute deduction for a call sites.
1542struct AANoRecurseCallSite final : AANoRecurseImpl {
1543 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1544
1545 /// See AbstractAttribute::initialize(...).
1546 void initialize(Attributor &A) override {
1547 AANoRecurseImpl::initialize(A);
1548 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001549 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001550 indicatePessimisticFixpoint();
1551 }
1552
1553 /// See AbstractAttribute::updateImpl(...).
1554 ChangeStatus updateImpl(Attributor &A) override {
1555 // TODO: Once we have call site specific value information we can provide
1556 // call site specific liveness information and then it makes
1557 // sense to specialize attributes for call sites arguments instead of
1558 // redirecting requests to the callee argument.
1559 Function *F = getAssociatedFunction();
1560 const IRPosition &FnPos = IRPosition::function(*F);
1561 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
1562 return clampStateAndIndicateChange(
1563 getState(),
1564 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
1565 }
1566
1567 /// See AbstractAttribute::trackStatistics()
1568 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
1569};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001570
Hideto Ueno11d37102019-07-17 15:15:43 +00001571/// ------------------------ Will-Return Attributes ----------------------------
1572
Hideto Ueno11d37102019-07-17 15:15:43 +00001573// Helper function that checks whether a function has any cycle.
1574// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001575static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00001576 SmallPtrSet<BasicBlock *, 32> Visited;
1577
1578 // Traverse BB by dfs and check whether successor is already visited.
1579 for (BasicBlock *BB : depth_first(&F)) {
1580 Visited.insert(BB);
1581 for (auto *SuccBB : successors(BB)) {
1582 if (Visited.count(SuccBB))
1583 return true;
1584 }
1585 }
1586 return false;
1587}
1588
1589// Helper function that checks the function have a loop which might become an
1590// endless loop
1591// FIXME: Any cycle is regarded as endless loop for now.
1592// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001593static bool containsPossiblyEndlessLoop(Function *F) {
1594 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00001595}
1596
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001597struct AAWillReturnImpl : public AAWillReturn {
1598 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00001599
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001600 /// See AbstractAttribute::initialize(...).
1601 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001602 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00001603
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001604 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001605 if (containsPossiblyEndlessLoop(F))
1606 indicatePessimisticFixpoint();
1607 }
Hideto Ueno11d37102019-07-17 15:15:43 +00001608
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001609 /// See AbstractAttribute::updateImpl(...).
1610 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001611 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001612 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
1613 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
1614 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001615 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001616 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001617 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001618 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
1619 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001620 };
1621
1622 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
1623 return indicatePessimisticFixpoint();
1624
1625 return ChangeStatus::UNCHANGED;
1626 }
1627
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001628 /// See AbstractAttribute::getAsStr()
1629 const std::string getAsStr() const override {
1630 return getAssumed() ? "willreturn" : "may-noreturn";
1631 }
1632};
1633
1634struct AAWillReturnFunction final : AAWillReturnImpl {
1635 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1636
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001637 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001638 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001639};
Hideto Ueno11d37102019-07-17 15:15:43 +00001640
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001641/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001642struct AAWillReturnCallSite final : AAWillReturnImpl {
1643 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1644
1645 /// See AbstractAttribute::initialize(...).
1646 void initialize(Attributor &A) override {
1647 AAWillReturnImpl::initialize(A);
1648 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001649 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001650 indicatePessimisticFixpoint();
1651 }
1652
1653 /// See AbstractAttribute::updateImpl(...).
1654 ChangeStatus updateImpl(Attributor &A) override {
1655 // TODO: Once we have call site specific value information we can provide
1656 // call site specific liveness information and then it makes
1657 // sense to specialize attributes for call sites arguments instead of
1658 // redirecting requests to the callee argument.
1659 Function *F = getAssociatedFunction();
1660 const IRPosition &FnPos = IRPosition::function(*F);
1661 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
1662 return clampStateAndIndicateChange(
1663 getState(),
1664 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
1665 }
1666
1667 /// See AbstractAttribute::trackStatistics()
1668 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
1669};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001670
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001671/// ------------------------ NoAlias Argument Attribute ------------------------
1672
Johannes Doerfert344d0382019-08-07 22:34:26 +00001673struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001674 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001675
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001676 const std::string getAsStr() const override {
1677 return getAssumed() ? "noalias" : "may-alias";
1678 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001679};
1680
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001681/// NoAlias attribute for a floating value.
1682struct AANoAliasFloating final : AANoAliasImpl {
1683 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1684
Hideto Uenocbab3342019-08-29 05:52:00 +00001685 /// See AbstractAttribute::initialize(...).
1686 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001687 AANoAliasImpl::initialize(A);
1688 if (isa<AllocaInst>(getAnchorValue()))
1689 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001690 }
1691
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001692 /// See AbstractAttribute::updateImpl(...).
1693 ChangeStatus updateImpl(Attributor &A) override {
1694 // TODO: Implement this.
1695 return indicatePessimisticFixpoint();
1696 }
1697
1698 /// See AbstractAttribute::trackStatistics()
1699 void trackStatistics() const override {
1700 STATS_DECLTRACK_FLOATING_ATTR(noalias)
1701 }
1702};
1703
1704/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00001705struct AANoAliasArgument final
1706 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
1707 AANoAliasArgument(const IRPosition &IRP)
1708 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001709
1710 /// See AbstractAttribute::trackStatistics()
1711 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
1712};
1713
1714struct AANoAliasCallSiteArgument final : AANoAliasImpl {
1715 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1716
Hideto Uenocbab3342019-08-29 05:52:00 +00001717 /// See AbstractAttribute::initialize(...).
1718 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00001719 // See callsite argument attribute and callee argument attribute.
1720 ImmutableCallSite ICS(&getAnchorValue());
1721 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
1722 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001723 }
1724
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001725 /// See AbstractAttribute::updateImpl(...).
1726 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001727 // We can deduce "noalias" if the following conditions hold.
1728 // (i) Associated value is assumed to be noalias in the definition.
1729 // (ii) Associated value is assumed to be no-capture in all the uses
1730 // possibly executed before this callsite.
1731 // (iii) There is no other pointer argument which could alias with the
1732 // value.
1733
1734 const Value &V = getAssociatedValue();
1735 const IRPosition IRP = IRPosition::value(V);
1736
1737 // (i) Check whether noalias holds in the definition.
1738
1739 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
1740
1741 if (!NoAliasAA.isAssumedNoAlias())
1742 return indicatePessimisticFixpoint();
1743
1744 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
1745 << " is assumed NoAlias in the definition\n");
1746
1747 // (ii) Check whether the value is captured in the scope using AANoCapture.
1748 // FIXME: This is conservative though, it is better to look at CFG and
1749 // check only uses possibly executed before this callsite.
1750
1751 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
1752 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned())
1753 return indicatePessimisticFixpoint();
1754
1755 // (iii) Check there is no other pointer argument which could alias with the
1756 // value.
1757 ImmutableCallSite ICS(&getAnchorValue());
1758 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
1759 if (getArgNo() == (int)i)
1760 continue;
1761 const Value *ArgOp = ICS.getArgOperand(i);
1762 if (!ArgOp->getType()->isPointerTy())
1763 continue;
1764
Hideto Ueno30d86f12019-09-17 06:53:27 +00001765 if (const Function *F = getAnchorScope()) {
1766 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
1767 LLVM_DEBUG(dbgs()
1768 << "[Attributor][NoAliasCSArg] Check alias between "
1769 "callsite arguments "
1770 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
1771 << getAssociatedValue() << " " << *ArgOp << "\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001772
Hideto Ueno30d86f12019-09-17 06:53:27 +00001773 if (AAR->isNoAlias(&getAssociatedValue(), ArgOp))
1774 continue;
1775 }
1776 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001777 return indicatePessimisticFixpoint();
1778 }
1779
1780 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001781 }
1782
1783 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00001784 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001785};
1786
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001787/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00001788struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001789 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001790
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001791 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001792 virtual ChangeStatus updateImpl(Attributor &A) override {
1793
1794 auto CheckReturnValue = [&](Value &RV) -> bool {
1795 if (Constant *C = dyn_cast<Constant>(&RV))
1796 if (C->isNullValue() || isa<UndefValue>(C))
1797 return true;
1798
1799 /// For now, we can only deduce noalias if we have call sites.
1800 /// FIXME: add more support.
1801 ImmutableCallSite ICS(&RV);
1802 if (!ICS)
1803 return false;
1804
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00001805 const IRPosition &RVPos = IRPosition::value(RV);
1806 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001807 if (!NoAliasAA.isAssumedNoAlias())
1808 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001809
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00001810 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
1811 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001812 };
1813
1814 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
1815 return indicatePessimisticFixpoint();
1816
1817 return ChangeStatus::UNCHANGED;
1818 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001819
1820 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001821 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001822};
1823
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001824/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001825struct AANoAliasCallSiteReturned final : AANoAliasImpl {
1826 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1827
1828 /// See AbstractAttribute::initialize(...).
1829 void initialize(Attributor &A) override {
1830 AANoAliasImpl::initialize(A);
1831 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001832 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001833 indicatePessimisticFixpoint();
1834 }
1835
1836 /// See AbstractAttribute::updateImpl(...).
1837 ChangeStatus updateImpl(Attributor &A) override {
1838 // TODO: Once we have call site specific value information we can provide
1839 // call site specific liveness information and then it makes
1840 // sense to specialize attributes for call sites arguments instead of
1841 // redirecting requests to the callee argument.
1842 Function *F = getAssociatedFunction();
1843 const IRPosition &FnPos = IRPosition::returned(*F);
1844 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
1845 return clampStateAndIndicateChange(
1846 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
1847 }
1848
1849 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00001850 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001851};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001852
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001853/// -------------------AAIsDead Function Attribute-----------------------
1854
Johannes Doerfert344d0382019-08-07 22:34:26 +00001855struct AAIsDeadImpl : public AAIsDead {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001856 AAIsDeadImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001857
Johannes Doerfertece81902019-08-12 22:05:53 +00001858 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001859 const Function *F = getAssociatedFunction();
Johannes Doerfert97fd5822019-09-04 16:26:20 +00001860 if (F && !F->isDeclaration())
1861 exploreFromEntry(A, F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00001862 }
1863
1864 void exploreFromEntry(Attributor &A, const Function *F) {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001865 ToBeExploredPaths.insert(&(F->getEntryBlock().front()));
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00001866
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001867 for (size_t i = 0; i < ToBeExploredPaths.size(); ++i)
Johannes Doerfert4361da22019-08-04 18:38:53 +00001868 if (const Instruction *NextNoReturnI =
1869 findNextNoReturn(A, ToBeExploredPaths[i]))
1870 NoReturnCalls.insert(NextNoReturnI);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00001871
1872 // Mark the block live after we looked for no-return instructions.
1873 assumeLive(A, F->getEntryBlock());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001874 }
1875
Johannes Doerfert4361da22019-08-04 18:38:53 +00001876 /// Find the next assumed noreturn instruction in the block of \p I starting
1877 /// from, thus including, \p I.
1878 ///
1879 /// The caller is responsible to monitor the ToBeExploredPaths set as new
1880 /// instructions discovered in other basic block will be placed in there.
1881 ///
1882 /// \returns The next assumed noreturn instructions in the block of \p I
1883 /// starting from, thus including, \p I.
1884 const Instruction *findNextNoReturn(Attributor &A, const Instruction *I);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001885
Johannes Doerfertbeb51502019-08-07 22:36:15 +00001886 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001887 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00001888 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001889 std::to_string(getAssociatedFunction()->size()) + "][#NRI " +
Johannes Doerfertbeb51502019-08-07 22:36:15 +00001890 std::to_string(NoReturnCalls.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001891 }
1892
1893 /// See AbstractAttribute::manifest(...).
1894 ChangeStatus manifest(Attributor &A) override {
1895 assert(getState().isValidState() &&
1896 "Attempted to manifest an invalid state!");
1897
1898 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00001899 Function &F = *getAssociatedFunction();
1900
1901 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00001902 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00001903 return ChangeStatus::CHANGED;
1904 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00001905
Johannes Doerfertbeb51502019-08-07 22:36:15 +00001906 // Flag to determine if we can change an invoke to a call assuming the
1907 // callee is nounwind. This is not possible if the personality of the
1908 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00001909 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001910
Johannes Doerfert4361da22019-08-04 18:38:53 +00001911 for (const Instruction *NRC : NoReturnCalls) {
1912 Instruction *I = const_cast<Instruction *>(NRC);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001913 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00001914 Instruction *SplitPos = I->getNextNode();
Johannes Doerfertd4108052019-08-21 20:56:41 +00001915 // TODO: mark stuff before unreachable instructions as dead.
1916 if (isa_and_nonnull<UnreachableInst>(SplitPos))
1917 continue;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001918
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001919 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00001920 // If we keep the invoke the split position is at the beginning of the
1921 // normal desitination block (it invokes a noreturn function after all).
1922 BasicBlock *NormalDestBB = II->getNormalDest();
1923 SplitPos = &NormalDestBB->front();
1924
Johannes Doerfert4361da22019-08-04 18:38:53 +00001925 /// Invoke is replaced with a call and unreachable is placed after it if
1926 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
1927 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00001928 if (Invoke2CallAllowed) {
Michael Liaoa99086d2019-08-20 21:02:31 +00001929 if (II->getCalledFunction()) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001930 const IRPosition &IPos = IRPosition::callsite_function(*II);
1931 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
1932 if (AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert924d2132019-08-05 21:34:45 +00001933 LLVM_DEBUG(dbgs()
1934 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00001935 // We do not need an invoke (II) but instead want a call followed
1936 // by an unreachable. However, we do not remove II as other
1937 // abstract attributes might have it cached as part of their
1938 // results. Given that we modify the CFG anyway, we simply keep II
1939 // around but in a new dead block. To avoid II being live through
1940 // a different edge we have to ensure the block we place it in is
1941 // only reached from the current block of II and then not reached
1942 // at all when we insert the unreachable.
1943 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
1944 CallInst *CI = createCallMatchingInvoke(II);
1945 CI->insertBefore(II);
1946 CI->takeName(II);
1947 II->replaceAllUsesWith(CI);
1948 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00001949 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001950 }
1951 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00001952
Johannes Doerfert7ab52532019-09-04 20:34:52 +00001953 if (SplitPos == &NormalDestBB->front()) {
1954 // If this is an invoke of a noreturn function the edge to the normal
1955 // destination block is dead but not necessarily the block itself.
1956 // TODO: We need to move to an edge based system during deduction and
1957 // also manifest.
1958 assert(!NormalDestBB->isLandingPad() &&
1959 "Expected the normal destination not to be a landingpad!");
1960 BasicBlock *SplitBB =
1961 SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
1962 // The split block is live even if it contains only an unreachable
1963 // instruction at the end.
1964 assumeLive(A, *SplitBB);
1965 SplitPos = SplitBB->getTerminator();
1966 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001967 }
1968
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00001969 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00001970 SplitBlock(BB, SplitPos);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001971 changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
1972 HasChanged = ChangeStatus::CHANGED;
1973 }
1974
Johannes Doerfertb19cd272019-09-03 20:42:16 +00001975 for (BasicBlock &BB : F)
1976 if (!AssumedLiveBlocks.count(&BB))
1977 A.deleteAfterManifest(BB);
1978
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001979 return HasChanged;
1980 }
1981
1982 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001983 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001984
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001985 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00001986 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001987 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001988 "BB must be in the same anchor scope function.");
1989
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001990 if (!getAssumed())
1991 return false;
1992 return !AssumedLiveBlocks.count(BB);
1993 }
1994
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001995 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00001996 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001997 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001998 }
1999
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002000 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002001 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002002 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002003 "Instruction must be in the same anchor scope function.");
2004
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002005 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002006 return false;
2007
2008 // If it is not in AssumedLiveBlocks then it for sure dead.
2009 // Otherwise, it can still be after noreturn call in a live block.
2010 if (!AssumedLiveBlocks.count(I->getParent()))
2011 return true;
2012
2013 // If it is not after a noreturn call, than it is live.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002014 return isAfterNoReturn(I);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002015 }
2016
2017 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002018 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002019 return getKnown() && isAssumedDead(I);
2020 }
2021
2022 /// Check if instruction is after noreturn call, in other words, assumed dead.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002023 bool isAfterNoReturn(const Instruction *I) const;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002024
Johannes Doerfert924d2132019-08-05 21:34:45 +00002025 /// Determine if \p F might catch asynchronous exceptions.
2026 static bool mayCatchAsynchronousExceptions(const Function &F) {
2027 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2028 }
2029
Johannes Doerfert2f622062019-09-04 16:35:20 +00002030 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2031 /// that internal function called from \p BB should now be looked at.
2032 void assumeLive(Attributor &A, const BasicBlock &BB) {
2033 if (!AssumedLiveBlocks.insert(&BB).second)
2034 return;
2035
2036 // We assume that all of BB is (probably) live now and if there are calls to
2037 // internal functions we will assume that those are now live as well. This
2038 // is a performance optimization for blocks with calls to a lot of internal
2039 // functions. It can however cause dead functions to be treated as live.
2040 for (const Instruction &I : BB)
2041 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
2042 if (const Function *F = ICS.getCalledFunction())
2043 if (F->hasInternalLinkage())
2044 A.markLiveInternalFunction(*F);
2045 }
2046
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002047 /// Collection of to be explored paths.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002048 SmallSetVector<const Instruction *, 8> ToBeExploredPaths;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002049
2050 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002051 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002052
2053 /// Collection of calls with noreturn attribute, assumed or knwon.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002054 SmallSetVector<const Instruction *, 4> NoReturnCalls;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002055};
2056
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002057struct AAIsDeadFunction final : public AAIsDeadImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002058 AAIsDeadFunction(const IRPosition &IRP) : AAIsDeadImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002059
2060 /// See AbstractAttribute::trackStatistics()
2061 void trackStatistics() const override {
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002062 STATS_DECL(PartiallyDeadBlocks, Function,
2063 "Number of basic blocks classified as partially dead");
2064 BUILD_STAT_NAME(PartiallyDeadBlocks, Function) += NoReturnCalls.size();
2065 }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002066};
2067
2068bool AAIsDeadImpl::isAfterNoReturn(const Instruction *I) const {
Johannes Doerfert4361da22019-08-04 18:38:53 +00002069 const Instruction *PrevI = I->getPrevNode();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002070 while (PrevI) {
2071 if (NoReturnCalls.count(PrevI))
2072 return true;
2073 PrevI = PrevI->getPrevNode();
2074 }
2075 return false;
2076}
2077
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002078const Instruction *AAIsDeadImpl::findNextNoReturn(Attributor &A,
2079 const Instruction *I) {
Johannes Doerfert4361da22019-08-04 18:38:53 +00002080 const BasicBlock *BB = I->getParent();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002081 const Function &F = *BB->getParent();
2082
2083 // Flag to determine if we can change an invoke to a call assuming the callee
2084 // is nounwind. This is not possible if the personality of the function allows
2085 // to catch asynchronous exceptions.
2086 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002087
2088 // TODO: We should have a function that determines if an "edge" is dead.
2089 // Edges could be from an instruction to the next or from a terminator
2090 // to the successor. For now, we need to special case the unwind block
2091 // of InvokeInst below.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002092
2093 while (I) {
2094 ImmutableCallSite ICS(I);
2095
2096 if (ICS) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002097 const IRPosition &IPos = IRPosition::callsite_function(ICS);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002098 // Regarless of the no-return property of an invoke instruction we only
2099 // learn that the regular successor is not reachable through this
2100 // instruction but the unwind block might still be.
2101 if (auto *Invoke = dyn_cast<InvokeInst>(I)) {
2102 // Use nounwind to justify the unwind block is dead as well.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002103 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2104 if (!Invoke2CallAllowed || !AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002105 assumeLive(A, *Invoke->getUnwindDest());
Johannes Doerfert4361da22019-08-04 18:38:53 +00002106 ToBeExploredPaths.insert(&Invoke->getUnwindDest()->front());
2107 }
2108 }
2109
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002110 const auto &NoReturnAA = A.getAAFor<AANoReturn>(*this, IPos);
2111 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert4361da22019-08-04 18:38:53 +00002112 return I;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002113 }
2114
2115 I = I->getNextNode();
2116 }
2117
2118 // get new paths (reachable blocks).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002119 for (const BasicBlock *SuccBB : successors(BB)) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002120 assumeLive(A, *SuccBB);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002121 ToBeExploredPaths.insert(&SuccBB->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002122 }
2123
Johannes Doerfert4361da22019-08-04 18:38:53 +00002124 // No noreturn instruction found.
2125 return nullptr;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002126}
2127
Johannes Doerfertece81902019-08-12 22:05:53 +00002128ChangeStatus AAIsDeadImpl::updateImpl(Attributor &A) {
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002129 ChangeStatus Status = ChangeStatus::UNCHANGED;
2130
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002131 // Temporary collection to iterate over existing noreturn instructions. This
2132 // will alow easier modification of NoReturnCalls collection
Johannes Doerfert4361da22019-08-04 18:38:53 +00002133 SmallVector<const Instruction *, 8> NoReturnChanged;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002134
Johannes Doerfert4361da22019-08-04 18:38:53 +00002135 for (const Instruction *I : NoReturnCalls)
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002136 NoReturnChanged.push_back(I);
2137
Johannes Doerfert4361da22019-08-04 18:38:53 +00002138 for (const Instruction *I : NoReturnChanged) {
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002139 size_t Size = ToBeExploredPaths.size();
2140
Johannes Doerfert4361da22019-08-04 18:38:53 +00002141 const Instruction *NextNoReturnI = findNextNoReturn(A, I);
2142 if (NextNoReturnI != I) {
2143 Status = ChangeStatus::CHANGED;
2144 NoReturnCalls.remove(I);
2145 if (NextNoReturnI)
2146 NoReturnCalls.insert(NextNoReturnI);
2147 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002148
Johannes Doerfert4361da22019-08-04 18:38:53 +00002149 // Explore new paths.
2150 while (Size != ToBeExploredPaths.size()) {
2151 Status = ChangeStatus::CHANGED;
2152 if (const Instruction *NextNoReturnI =
2153 findNextNoReturn(A, ToBeExploredPaths[Size++]))
2154 NoReturnCalls.insert(NextNoReturnI);
2155 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002156 }
2157
Johannes Doerfertdef99282019-08-14 21:29:37 +00002158 LLVM_DEBUG(dbgs() << "[AAIsDead] AssumedLiveBlocks: "
2159 << AssumedLiveBlocks.size() << " Total number of blocks: "
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002160 << getAssociatedFunction()->size() << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002161
Johannes Doerfertd6207812019-08-07 22:32:38 +00002162 // If we know everything is live there is no need to query for liveness.
2163 if (NoReturnCalls.empty() &&
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002164 getAssociatedFunction()->size() == AssumedLiveBlocks.size()) {
Johannes Doerfertd6207812019-08-07 22:32:38 +00002165 // Indicating a pessimistic fixpoint will cause the state to be "invalid"
2166 // which will cause the Attributor to not return the AAIsDead on request,
2167 // which will prevent us from querying isAssumedDead().
2168 indicatePessimisticFixpoint();
2169 assert(!isValidState() && "Expected an invalid state!");
Johannes Doerfert62a9c1d2019-08-29 01:26:58 +00002170 Status = ChangeStatus::CHANGED;
Johannes Doerfertd6207812019-08-07 22:32:38 +00002171 }
2172
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002173 return Status;
2174}
2175
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002176/// Liveness information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002177struct AAIsDeadCallSite final : AAIsDeadImpl {
2178 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadImpl(IRP) {}
2179
2180 /// See AbstractAttribute::initialize(...).
2181 void initialize(Attributor &A) override {
2182 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002183 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002184 // sense to specialize attributes for call sites instead of
2185 // redirecting requests to the callee.
2186 llvm_unreachable("Abstract attributes for liveness are not "
2187 "supported for call sites yet!");
2188 }
2189
2190 /// See AbstractAttribute::updateImpl(...).
2191 ChangeStatus updateImpl(Attributor &A) override {
2192 return indicatePessimisticFixpoint();
2193 }
2194
2195 /// See AbstractAttribute::trackStatistics()
2196 void trackStatistics() const override {}
2197};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002198
Hideto Ueno19c07af2019-07-23 08:16:17 +00002199/// -------------------- Dereferenceable Argument Attribute --------------------
2200
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002201template <>
2202ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
2203 const DerefState &R) {
2204 ChangeStatus CS0 = clampStateAndIndicateChange<IntegerState>(
2205 S.DerefBytesState, R.DerefBytesState);
2206 ChangeStatus CS1 =
2207 clampStateAndIndicateChange<IntegerState>(S.GlobalState, R.GlobalState);
2208 return CS0 | CS1;
2209}
2210
Hideto Ueno70576ca2019-08-22 14:18:29 +00002211struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002212 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00002213 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00002214
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002215 void initialize(Attributor &A) override {
2216 SmallVector<Attribute, 4> Attrs;
2217 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
2218 Attrs);
2219 for (const Attribute &Attr : Attrs)
2220 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
2221
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002222 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002223
2224 const IRPosition &IRP = this->getIRPosition();
2225 bool IsFnInterface = IRP.isFnInterfaceKind();
2226 const Function *FnScope = IRP.getAnchorScope();
2227 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
2228 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002229 }
2230
Hideto Ueno19c07af2019-07-23 08:16:17 +00002231 /// See AbstractAttribute::getState()
2232 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00002233 StateType &getState() override { return *this; }
2234 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002235 /// }
2236
Johannes Doerferteccdf082019-08-05 23:35:12 +00002237 void getDeducedAttributes(LLVMContext &Ctx,
2238 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002239 // TODO: Add *_globally support
2240 if (isAssumedNonNull())
2241 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
2242 Ctx, getAssumedDereferenceableBytes()));
2243 else
2244 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
2245 Ctx, getAssumedDereferenceableBytes()));
2246 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002247
2248 /// See AbstractAttribute::getAsStr().
2249 const std::string getAsStr() const override {
2250 if (!getAssumedDereferenceableBytes())
2251 return "unknown-dereferenceable";
2252 return std::string("dereferenceable") +
2253 (isAssumedNonNull() ? "" : "_or_null") +
2254 (isAssumedGlobal() ? "_globally" : "") + "<" +
2255 std::to_string(getKnownDereferenceableBytes()) + "-" +
2256 std::to_string(getAssumedDereferenceableBytes()) + ">";
2257 }
2258};
2259
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002260/// Dereferenceable attribute for a floating value.
2261struct AADereferenceableFloating : AADereferenceableImpl {
2262 AADereferenceableFloating(const IRPosition &IRP)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002263 : AADereferenceableImpl(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00002264
2265 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002266 ChangeStatus updateImpl(Attributor &A) override {
2267 const DataLayout &DL = A.getDataLayout();
2268
2269 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
2270 unsigned IdxWidth =
2271 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
2272 APInt Offset(IdxWidth, 0);
2273 const Value *Base =
2274 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
2275
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002276 const auto &AA =
2277 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002278 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002279 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002280 // Use IR information if we did not strip anything.
2281 // TODO: track globally.
2282 bool CanBeNull;
2283 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
2284 T.GlobalState.indicatePessimisticFixpoint();
2285 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002286 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002287 DerefBytes = DS.DerefBytesState.getAssumed();
2288 T.GlobalState &= DS.GlobalState;
2289 }
2290
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002291 // For now we do not try to "increase" dereferenceability due to negative
2292 // indices as we first have to come up with code to deal with loops and
2293 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00002294 int64_t OffsetSExt = Offset.getSExtValue();
2295 if (OffsetSExt < 0)
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002296 Offset = 0;
2297
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002298 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00002299 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002300
Johannes Doerfert785fad32019-08-23 17:29:23 +00002301 if (this == &AA) {
2302 if (!Stripped) {
2303 // If nothing was stripped IR information is all we got.
2304 T.takeKnownDerefBytesMaximum(
2305 std::max(int64_t(0), DerefBytes - OffsetSExt));
2306 T.indicatePessimisticFixpoint();
2307 } else if (OffsetSExt > 0) {
2308 // If something was stripped but there is circular reasoning we look
2309 // for the offset. If it is positive we basically decrease the
2310 // dereferenceable bytes in a circluar loop now, which will simply
2311 // drive them down to the known value in a very slow way which we
2312 // can accelerate.
2313 T.indicatePessimisticFixpoint();
2314 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002315 }
2316
2317 return T.isValidState();
2318 };
2319
2320 DerefState T;
2321 if (!genericValueTraversal<AADereferenceable, DerefState>(
2322 A, getIRPosition(), *this, T, VisitValueCB))
2323 return indicatePessimisticFixpoint();
2324
2325 return clampStateAndIndicateChange(getState(), T);
2326 }
2327
2328 /// See AbstractAttribute::trackStatistics()
2329 void trackStatistics() const override {
2330 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
2331 }
2332};
2333
2334/// Dereferenceable attribute for a return value.
2335struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002336 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2337 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002338 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002339 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2340 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002341
2342 /// See AbstractAttribute::trackStatistics()
2343 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002344 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002345 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002346};
2347
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002348/// Dereferenceable attribute for an argument
2349struct AADereferenceableArgument final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002350 : AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl,
2351 DerefState> {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002352 AADereferenceableArgument(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002353 : AAArgumentFromCallSiteArguments<AADereferenceable,
2354 AADereferenceableImpl, DerefState>(
2355 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002356
2357 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002358 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00002359 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
2360 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002361};
2362
Hideto Ueno19c07af2019-07-23 08:16:17 +00002363/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002364struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002365 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002366 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002367
2368 /// See AbstractAttribute::trackStatistics()
2369 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002370 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002371 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002372};
2373
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002374/// Dereferenceable attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002375struct AADereferenceableCallSiteReturned final : AADereferenceableImpl {
2376 AADereferenceableCallSiteReturned(const IRPosition &IRP)
2377 : AADereferenceableImpl(IRP) {}
2378
2379 /// See AbstractAttribute::initialize(...).
2380 void initialize(Attributor &A) override {
2381 AADereferenceableImpl::initialize(A);
2382 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002383 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002384 indicatePessimisticFixpoint();
2385 }
2386
2387 /// See AbstractAttribute::updateImpl(...).
2388 ChangeStatus updateImpl(Attributor &A) override {
2389 // TODO: Once we have call site specific value information we can provide
2390 // call site specific liveness information and then it makes
2391 // sense to specialize attributes for call sites arguments instead of
2392 // redirecting requests to the callee argument.
2393 Function *F = getAssociatedFunction();
2394 const IRPosition &FnPos = IRPosition::returned(*F);
2395 auto &FnAA = A.getAAFor<AADereferenceable>(*this, FnPos);
2396 return clampStateAndIndicateChange(
2397 getState(), static_cast<const DerefState &>(FnAA.getState()));
2398 }
2399
2400 /// See AbstractAttribute::trackStatistics()
2401 void trackStatistics() const override {
2402 STATS_DECLTRACK_CS_ATTR(dereferenceable);
2403 }
2404};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002405
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002406// ------------------------ Align Argument Attribute ------------------------
2407
Johannes Doerfert344d0382019-08-07 22:34:26 +00002408struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002409 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002410
2411 // Max alignemnt value allowed in IR
2412 static const unsigned MAX_ALIGN = 1U << 29;
2413
Johannes Doerfert234eda52019-08-16 19:51:23 +00002414 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002415 void initialize(Attributor &A) override {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002416 takeAssumedMinimum(MAX_ALIGN);
2417
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002418 SmallVector<Attribute, 4> Attrs;
2419 getAttrs({Attribute::Alignment}, Attrs);
2420 for (const Attribute &Attr : Attrs)
2421 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00002422
2423 if (getIRPosition().isFnInterfaceKind() &&
2424 (!getAssociatedFunction() ||
2425 !getAssociatedFunction()->hasExactDefinition()))
2426 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002427 }
2428
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002429 /// See AbstractAttribute::manifest(...).
2430 ChangeStatus manifest(Attributor &A) override {
2431 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2432
2433 // Check for users that allow alignment annotations.
2434 Value &AnchorVal = getIRPosition().getAnchorValue();
2435 for (const Use &U : AnchorVal.uses()) {
2436 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
2437 if (SI->getPointerOperand() == &AnchorVal)
2438 if (SI->getAlignment() < getAssumedAlign()) {
2439 STATS_DECLTRACK(AAAlign, Store,
2440 "Number of times alignemnt added to a store");
2441 SI->setAlignment(getAssumedAlign());
2442 Changed = ChangeStatus::CHANGED;
2443 }
2444 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
2445 if (LI->getPointerOperand() == &AnchorVal)
2446 if (LI->getAlignment() < getAssumedAlign()) {
2447 LI->setAlignment(getAssumedAlign());
2448 STATS_DECLTRACK(AAAlign, Load,
2449 "Number of times alignemnt added to a load");
2450 Changed = ChangeStatus::CHANGED;
2451 }
2452 }
2453 }
2454
Johannes Doerfert81df4522019-08-30 15:22:28 +00002455 return AAAlign::manifest(A) | Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002456 }
2457
Johannes Doerfert81df4522019-08-30 15:22:28 +00002458 // TODO: Provide a helper to determine the implied ABI alignment and check in
2459 // the existing manifest method and a new one for AAAlignImpl that value
2460 // to avoid making the alignment explicit if it did not improve.
2461
2462 /// See AbstractAttribute::getDeducedAttributes
2463 virtual void
2464 getDeducedAttributes(LLVMContext &Ctx,
2465 SmallVectorImpl<Attribute> &Attrs) const override {
2466 if (getAssumedAlign() > 1)
2467 Attrs.emplace_back(Attribute::getWithAlignment(Ctx, getAssumedAlign()));
2468 }
2469
2470 /// See AbstractAttribute::getAsStr().
2471 const std::string getAsStr() const override {
2472 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
2473 "-" + std::to_string(getAssumedAlign()) + ">")
2474 : "unknown-align";
2475 }
2476};
2477
2478/// Align attribute for a floating value.
2479struct AAAlignFloating : AAAlignImpl {
2480 AAAlignFloating(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2481
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002482 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00002483 ChangeStatus updateImpl(Attributor &A) override {
2484 const DataLayout &DL = A.getDataLayout();
2485
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002486 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
2487 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002488 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
2489 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002490 // Use only IR information if we did not strip anything.
2491 T.takeKnownMaximum(V.getPointerAlignment(DL));
2492 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002493 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002494 // Use abstract attribute information.
2495 const AAAlign::StateType &DS =
2496 static_cast<const AAAlign::StateType &>(AA.getState());
2497 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00002498 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002499 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002500 };
2501
2502 StateType T;
2503 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
2504 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002505 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002506
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00002507 // TODO: If we know we visited all incoming values, thus no are assumed
2508 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00002509 return clampStateAndIndicateChange(getState(), T);
2510 }
2511
2512 /// See AbstractAttribute::trackStatistics()
2513 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
2514};
2515
2516/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002517struct AAAlignReturned final
2518 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002519 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002520 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002521
2522 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002523 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002524};
2525
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002526/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002527struct AAAlignArgument final
2528 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002529 AAAlignArgument(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002530 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002531
2532 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00002533 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002534};
2535
Johannes Doerfert234eda52019-08-16 19:51:23 +00002536struct AAAlignCallSiteArgument final : AAAlignFloating {
2537 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002538
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002539 /// See AbstractAttribute::manifest(...).
2540 ChangeStatus manifest(Attributor &A) override {
2541 return AAAlignImpl::manifest(A);
2542 }
2543
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002544 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002545 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002546};
2547
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002548/// Align attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002549struct AAAlignCallSiteReturned final : AAAlignImpl {
2550 AAAlignCallSiteReturned(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2551
2552 /// See AbstractAttribute::initialize(...).
2553 void initialize(Attributor &A) override {
2554 AAAlignImpl::initialize(A);
2555 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002556 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002557 indicatePessimisticFixpoint();
2558 }
2559
2560 /// See AbstractAttribute::updateImpl(...).
2561 ChangeStatus updateImpl(Attributor &A) override {
2562 // TODO: Once we have call site specific value information we can provide
2563 // call site specific liveness information and then it makes
2564 // sense to specialize attributes for call sites arguments instead of
2565 // redirecting requests to the callee argument.
2566 Function *F = getAssociatedFunction();
2567 const IRPosition &FnPos = IRPosition::returned(*F);
2568 auto &FnAA = A.getAAFor<AAAlign>(*this, FnPos);
2569 return clampStateAndIndicateChange(
2570 getState(), static_cast<const AAAlign::StateType &>(FnAA.getState()));
2571 }
2572
2573 /// See AbstractAttribute::trackStatistics()
2574 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
2575};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002576
Johannes Doerferte83f3032019-08-05 23:22:05 +00002577/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00002578struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002579 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00002580
Johannes Doerferte83f3032019-08-05 23:22:05 +00002581 /// See AbstractAttribute::getAsStr().
2582 const std::string getAsStr() const override {
2583 return getAssumed() ? "noreturn" : "may-return";
2584 }
2585
Johannes Doerferte83f3032019-08-05 23:22:05 +00002586 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00002587 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00002588 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002589 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00002590 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00002591 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00002592 return ChangeStatus::UNCHANGED;
2593 }
2594};
2595
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002596struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002597 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002598
2599 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002600 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002601};
2602
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002603/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002604struct AANoReturnCallSite final : AANoReturnImpl {
2605 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
2606
2607 /// See AbstractAttribute::initialize(...).
2608 void initialize(Attributor &A) override {
2609 AANoReturnImpl::initialize(A);
2610 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002611 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002612 indicatePessimisticFixpoint();
2613 }
2614
2615 /// See AbstractAttribute::updateImpl(...).
2616 ChangeStatus updateImpl(Attributor &A) override {
2617 // TODO: Once we have call site specific value information we can provide
2618 // call site specific liveness information and then it makes
2619 // sense to specialize attributes for call sites arguments instead of
2620 // redirecting requests to the callee argument.
2621 Function *F = getAssociatedFunction();
2622 const IRPosition &FnPos = IRPosition::function(*F);
2623 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
2624 return clampStateAndIndicateChange(
2625 getState(),
2626 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
2627 }
2628
2629 /// See AbstractAttribute::trackStatistics()
2630 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
2631};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002632
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002633/// ----------------------- Variable Capturing ---------------------------------
2634
2635/// A class to hold the state of for no-capture attributes.
2636struct AANoCaptureImpl : public AANoCapture {
2637 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
2638
2639 /// See AbstractAttribute::initialize(...).
2640 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002641 AANoCapture::initialize(A);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002642
2643 const IRPosition &IRP = getIRPosition();
2644 const Function *F =
2645 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
2646
2647 // Check what state the associated function can actually capture.
2648 if (F)
2649 determineFunctionCaptureCapabilities(*F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002650 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002651 indicatePessimisticFixpoint();
2652 }
2653
2654 /// See AbstractAttribute::updateImpl(...).
2655 ChangeStatus updateImpl(Attributor &A) override;
2656
2657 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
2658 virtual void
2659 getDeducedAttributes(LLVMContext &Ctx,
2660 SmallVectorImpl<Attribute> &Attrs) const override {
2661 if (!isAssumedNoCaptureMaybeReturned())
2662 return;
2663
Hideto Ueno37367642019-09-11 06:52:11 +00002664 if (getArgNo() >= 0) {
2665 if (isAssumedNoCapture())
2666 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
2667 else if (ManifestInternal)
2668 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
2669 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002670 }
2671
2672 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
2673 /// depending on the ability of the function associated with \p IRP to capture
2674 /// state in memory and through "returning/throwing", respectively.
2675 static void determineFunctionCaptureCapabilities(const Function &F,
2676 IntegerState &State) {
2677 // TODO: Once we have memory behavior attributes we should use them here.
2678
2679 // If we know we cannot communicate or write to memory, we do not care about
2680 // ptr2int anymore.
2681 if (F.onlyReadsMemory() && F.doesNotThrow() &&
2682 F.getReturnType()->isVoidTy()) {
2683 State.addKnownBits(NO_CAPTURE);
2684 return;
2685 }
2686
2687 // A function cannot capture state in memory if it only reads memory, it can
2688 // however return/throw state and the state might be influenced by the
2689 // pointer value, e.g., loading from a returned pointer might reveal a bit.
2690 if (F.onlyReadsMemory())
2691 State.addKnownBits(NOT_CAPTURED_IN_MEM);
2692
2693 // A function cannot communicate state back if it does not through
2694 // exceptions and doesn not return values.
2695 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
2696 State.addKnownBits(NOT_CAPTURED_IN_RET);
2697 }
2698
2699 /// See AbstractState::getAsStr().
2700 const std::string getAsStr() const override {
2701 if (isKnownNoCapture())
2702 return "known not-captured";
2703 if (isAssumedNoCapture())
2704 return "assumed not-captured";
2705 if (isKnownNoCaptureMaybeReturned())
2706 return "known not-captured-maybe-returned";
2707 if (isAssumedNoCaptureMaybeReturned())
2708 return "assumed not-captured-maybe-returned";
2709 return "assumed-captured";
2710 }
2711};
2712
2713/// Attributor-aware capture tracker.
2714struct AACaptureUseTracker final : public CaptureTracker {
2715
2716 /// Create a capture tracker that can lookup in-flight abstract attributes
2717 /// through the Attributor \p A.
2718 ///
2719 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
2720 /// search is stopped. If a use leads to a return instruction,
2721 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
2722 /// If a use leads to a ptr2int which may capture the value,
2723 /// \p CapturedInInteger is set. If a use is found that is currently assumed
2724 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
2725 /// set. All values in \p PotentialCopies are later tracked as well. For every
2726 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
2727 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
2728 /// conservatively set to true.
2729 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
2730 const AAIsDead &IsDeadAA, IntegerState &State,
2731 SmallVectorImpl<const Value *> &PotentialCopies,
2732 unsigned &RemainingUsesToExplore)
2733 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
2734 PotentialCopies(PotentialCopies),
2735 RemainingUsesToExplore(RemainingUsesToExplore) {}
2736
2737 /// Determine if \p V maybe captured. *Also updates the state!*
2738 bool valueMayBeCaptured(const Value *V) {
2739 if (V->getType()->isPointerTy()) {
2740 PointerMayBeCaptured(V, this);
2741 } else {
2742 State.indicatePessimisticFixpoint();
2743 }
2744 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
2745 }
2746
2747 /// See CaptureTracker::tooManyUses().
2748 void tooManyUses() override {
2749 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
2750 }
2751
2752 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
2753 if (CaptureTracker::isDereferenceableOrNull(O, DL))
2754 return true;
2755 const auto &DerefAA =
2756 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
2757 return DerefAA.getAssumedDereferenceableBytes();
2758 }
2759
2760 /// See CaptureTracker::captured(...).
2761 bool captured(const Use *U) override {
2762 Instruction *UInst = cast<Instruction>(U->getUser());
2763 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
2764 << "\n");
2765
2766 // Because we may reuse the tracker multiple times we keep track of the
2767 // number of explored uses ourselves as well.
2768 if (RemainingUsesToExplore-- == 0) {
2769 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
2770 return isCapturedIn(/* Memory */ true, /* Integer */ true,
2771 /* Return */ true);
2772 }
2773
2774 // Deal with ptr2int by following uses.
2775 if (isa<PtrToIntInst>(UInst)) {
2776 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
2777 return valueMayBeCaptured(UInst);
2778 }
2779
2780 // Explicitly catch return instructions.
2781 if (isa<ReturnInst>(UInst))
2782 return isCapturedIn(/* Memory */ false, /* Integer */ false,
2783 /* Return */ true);
2784
2785 // For now we only use special logic for call sites. However, the tracker
2786 // itself knows about a lot of other non-capturing cases already.
2787 CallSite CS(UInst);
2788 if (!CS || !CS.isArgOperand(U))
2789 return isCapturedIn(/* Memory */ true, /* Integer */ true,
2790 /* Return */ true);
2791
2792 unsigned ArgNo = CS.getArgumentNo(U);
2793 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
2794 // If we have a abstract no-capture attribute for the argument we can use
2795 // it to justify a non-capture attribute here. This allows recursion!
2796 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
2797 if (ArgNoCaptureAA.isAssumedNoCapture())
2798 return isCapturedIn(/* Memory */ false, /* Integer */ false,
2799 /* Return */ false);
2800 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2801 addPotentialCopy(CS);
2802 return isCapturedIn(/* Memory */ false, /* Integer */ false,
2803 /* Return */ false);
2804 }
2805
2806 // Lastly, we could not find a reason no-capture can be assumed so we don't.
2807 return isCapturedIn(/* Memory */ true, /* Integer */ true,
2808 /* Return */ true);
2809 }
2810
2811 /// Register \p CS as potential copy of the value we are checking.
2812 void addPotentialCopy(CallSite CS) {
2813 PotentialCopies.push_back(CS.getInstruction());
2814 }
2815
2816 /// See CaptureTracker::shouldExplore(...).
2817 bool shouldExplore(const Use *U) override {
2818 // Check liveness.
2819 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
2820 }
2821
2822 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
2823 /// \p CapturedInRet, then return the appropriate value for use in the
2824 /// CaptureTracker::captured() interface.
2825 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
2826 bool CapturedInRet) {
2827 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
2828 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
2829 if (CapturedInMem)
2830 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
2831 if (CapturedInInt)
2832 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
2833 if (CapturedInRet)
2834 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
2835 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
2836 }
2837
2838private:
2839 /// The attributor providing in-flight abstract attributes.
2840 Attributor &A;
2841
2842 /// The abstract attribute currently updated.
2843 AANoCapture &NoCaptureAA;
2844
2845 /// The abstract liveness state.
2846 const AAIsDead &IsDeadAA;
2847
2848 /// The state currently updated.
2849 IntegerState &State;
2850
2851 /// Set of potential copies of the tracked value.
2852 SmallVectorImpl<const Value *> &PotentialCopies;
2853
2854 /// Global counter to limit the number of explored uses.
2855 unsigned &RemainingUsesToExplore;
2856};
2857
2858ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
2859 const IRPosition &IRP = getIRPosition();
2860 const Value *V =
2861 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
2862 if (!V)
2863 return indicatePessimisticFixpoint();
2864
2865 const Function *F =
2866 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
2867 assert(F && "Expected a function!");
2868 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(*F));
2869
2870 AANoCapture::StateType T;
2871 // TODO: Once we have memory behavior attributes we should use them here
2872 // similar to the reasoning in
2873 // AANoCaptureImpl::determineFunctionCaptureCapabilities(...).
2874
2875 // TODO: Use the AAReturnedValues to learn if the argument can return or
2876 // not.
2877
2878 // Use the CaptureTracker interface and logic with the specialized tracker,
2879 // defined in AACaptureUseTracker, that can look at in-flight abstract
2880 // attributes and directly updates the assumed state.
2881 SmallVector<const Value *, 4> PotentialCopies;
2882 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
2883 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
2884 RemainingUsesToExplore);
2885
2886 // Check all potential copies of the associated value until we can assume
2887 // none will be captured or we have to assume at least one might be.
2888 unsigned Idx = 0;
2889 PotentialCopies.push_back(V);
2890 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
2891 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
2892
2893 AAAlign::StateType &S = getState();
2894 auto Assumed = S.getAssumed();
2895 S.intersectAssumedBits(T.getAssumed());
2896 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
2897 : ChangeStatus::CHANGED;
2898}
2899
2900/// NoCapture attribute for function arguments.
2901struct AANoCaptureArgument final : AANoCaptureImpl {
2902 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
2903
2904 /// See AbstractAttribute::trackStatistics()
2905 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
2906};
2907
2908/// NoCapture attribute for call site arguments.
2909struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
2910 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
2911
2912 /// See AbstractAttribute::updateImpl(...).
2913 ChangeStatus updateImpl(Attributor &A) override {
2914 // TODO: Once we have call site specific value information we can provide
2915 // call site specific liveness information and then it makes
2916 // sense to specialize attributes for call sites arguments instead of
2917 // redirecting requests to the callee argument.
2918 Argument *Arg = getAssociatedArgument();
2919 if (!Arg)
2920 return indicatePessimisticFixpoint();
2921 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2922 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
2923 return clampStateAndIndicateChange(
2924 getState(),
2925 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
2926 }
2927
2928 /// See AbstractAttribute::trackStatistics()
2929 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
2930};
2931
2932/// NoCapture attribute for floating values.
2933struct AANoCaptureFloating final : AANoCaptureImpl {
2934 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
2935
2936 /// See AbstractAttribute::trackStatistics()
2937 void trackStatistics() const override {
2938 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
2939 }
2940};
2941
2942/// NoCapture attribute for function return value.
2943struct AANoCaptureReturned final : AANoCaptureImpl {
2944 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
2945 llvm_unreachable("NoCapture is not applicable to function returns!");
2946 }
2947
2948 /// See AbstractAttribute::initialize(...).
2949 void initialize(Attributor &A) override {
2950 llvm_unreachable("NoCapture is not applicable to function returns!");
2951 }
2952
2953 /// See AbstractAttribute::updateImpl(...).
2954 ChangeStatus updateImpl(Attributor &A) override {
2955 llvm_unreachable("NoCapture is not applicable to function returns!");
2956 }
2957
2958 /// See AbstractAttribute::trackStatistics()
2959 void trackStatistics() const override {}
2960};
2961
2962/// NoCapture attribute deduction for a call site return value.
2963struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
2964 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
2965
2966 /// See AbstractAttribute::trackStatistics()
2967 void trackStatistics() const override {
2968 STATS_DECLTRACK_CSRET_ATTR(nocapture)
2969 }
2970};
2971
Hideto Uenof2b9dc42019-09-07 07:03:05 +00002972/// ------------------ Value Simplify Attribute ----------------------------
2973struct AAValueSimplifyImpl : AAValueSimplify {
2974 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
2975
2976 /// See AbstractAttribute::getAsStr().
2977 const std::string getAsStr() const override {
2978 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
2979 : "not-simple";
2980 }
2981
2982 /// See AbstractAttribute::trackStatistics()
2983 void trackStatistics() const override {}
2984
2985 /// See AAValueSimplify::getAssumedSimplifiedValue()
2986 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
2987 if (!getAssumed())
2988 return const_cast<Value *>(&getAssociatedValue());
2989 return SimplifiedAssociatedValue;
2990 }
2991 void initialize(Attributor &A) override {}
2992
2993 /// Helper function for querying AAValueSimplify and updating candicate.
2994 /// \param QueryingValue Value trying to unify with SimplifiedValue
2995 /// \param AccumulatedSimplifiedValue Current simplification result.
2996 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
2997 Value &QueryingValue,
2998 Optional<Value *> &AccumulatedSimplifiedValue) {
2999 // FIXME: Add a typecast support.
3000
3001 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
3002 QueryingAA, IRPosition::value(QueryingValue));
3003
3004 Optional<Value *> QueryingValueSimplified =
3005 ValueSimpifyAA.getAssumedSimplifiedValue(A);
3006
3007 if (!QueryingValueSimplified.hasValue())
3008 return true;
3009
3010 if (!QueryingValueSimplified.getValue())
3011 return false;
3012
3013 Value &QueryingValueSimplifiedUnwrapped =
3014 *QueryingValueSimplified.getValue();
3015
3016 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
3017 return true;
3018
3019 if (AccumulatedSimplifiedValue.hasValue())
3020 return AccumulatedSimplifiedValue == QueryingValueSimplified;
3021
3022 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
3023 << " is assumed to be "
3024 << QueryingValueSimplifiedUnwrapped << "\n");
3025
3026 AccumulatedSimplifiedValue = QueryingValueSimplified;
3027 return true;
3028 }
3029
3030 /// See AbstractAttribute::manifest(...).
3031 ChangeStatus manifest(Attributor &A) override {
3032 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3033
3034 if (!SimplifiedAssociatedValue.hasValue() ||
3035 !SimplifiedAssociatedValue.getValue())
3036 return Changed;
3037
3038 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
3039 // We can replace the AssociatedValue with the constant.
3040 Value &V = getAssociatedValue();
3041 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
3042 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
3043 << "\n");
3044 V.replaceAllUsesWith(C);
3045 Changed = ChangeStatus::CHANGED;
3046 }
3047 }
3048
3049 return Changed | AAValueSimplify::manifest(A);
3050 }
3051
3052protected:
3053 // An assumed simplified value. Initially, it is set to Optional::None, which
3054 // means that the value is not clear under current assumption. If in the
3055 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
3056 // returns orignal associated value.
3057 Optional<Value *> SimplifiedAssociatedValue;
3058};
3059
3060struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
3061 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3062
3063 /// See AbstractAttribute::updateImpl(...).
3064 ChangeStatus updateImpl(Attributor &A) override {
3065 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3066
3067 auto PredForCallSite = [&](CallSite CS) {
3068 return checkAndUpdate(A, *this, *CS.getArgOperand(getArgNo()),
3069 SimplifiedAssociatedValue);
3070 };
3071
3072 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
3073 return indicatePessimisticFixpoint();
3074
3075 // If a candicate was found in this update, return CHANGED.
3076 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3077 ? ChangeStatus::UNCHANGED
3078 : ChangeStatus ::CHANGED;
3079 }
3080
3081 /// See AbstractAttribute::trackStatistics()
3082 void trackStatistics() const override {
3083 STATS_DECLTRACK_ARG_ATTR(value_simplify)
3084 }
3085};
3086
3087struct AAValueSimplifyReturned : AAValueSimplifyImpl {
3088 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3089
3090 /// See AbstractAttribute::updateImpl(...).
3091 ChangeStatus updateImpl(Attributor &A) override {
3092 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3093
3094 auto PredForReturned = [&](Value &V) {
3095 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3096 };
3097
3098 if (!A.checkForAllReturnedValues(PredForReturned, *this))
3099 return indicatePessimisticFixpoint();
3100
3101 // If a candicate was found in this update, return CHANGED.
3102 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3103 ? ChangeStatus::UNCHANGED
3104 : ChangeStatus ::CHANGED;
3105 }
3106 /// See AbstractAttribute::trackStatistics()
3107 void trackStatistics() const override {
3108 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
3109 }
3110};
3111
3112struct AAValueSimplifyFloating : AAValueSimplifyImpl {
3113 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3114
3115 /// See AbstractAttribute::initialize(...).
3116 void initialize(Attributor &A) override {
3117 Value &V = getAnchorValue();
3118
3119 // TODO: add other stuffs
3120 if (isa<Constant>(V) || isa<UndefValue>(V))
3121 indicatePessimisticFixpoint();
3122 }
3123
3124 /// See AbstractAttribute::updateImpl(...).
3125 ChangeStatus updateImpl(Attributor &A) override {
3126 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3127
3128 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
3129 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
3130 if (!Stripped && this == &AA) {
3131 // TODO: Look the instruction and check recursively.
3132 LLVM_DEBUG(
3133 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
3134 << V << "\n");
3135 indicatePessimisticFixpoint();
3136 return false;
3137 }
3138 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3139 };
3140
3141 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
3142 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
3143 VisitValueCB))
3144 return indicatePessimisticFixpoint();
3145
3146 // If a candicate was found in this update, return CHANGED.
3147
3148 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3149 ? ChangeStatus::UNCHANGED
3150 : ChangeStatus ::CHANGED;
3151 }
3152
3153 /// See AbstractAttribute::trackStatistics()
3154 void trackStatistics() const override {
3155 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
3156 }
3157};
3158
3159struct AAValueSimplifyFunction : AAValueSimplifyImpl {
3160 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3161
3162 /// See AbstractAttribute::initialize(...).
3163 void initialize(Attributor &A) override {
3164 SimplifiedAssociatedValue = &getAnchorValue();
3165 indicateOptimisticFixpoint();
3166 }
3167 /// See AbstractAttribute::initialize(...).
3168 ChangeStatus updateImpl(Attributor &A) override {
3169 llvm_unreachable(
3170 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
3171 }
3172 /// See AbstractAttribute::trackStatistics()
3173 void trackStatistics() const override {
3174 STATS_DECLTRACK_FN_ATTR(value_simplify)
3175 }
3176};
3177
3178struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
3179 AAValueSimplifyCallSite(const IRPosition &IRP)
3180 : AAValueSimplifyFunction(IRP) {}
3181 /// See AbstractAttribute::trackStatistics()
3182 void trackStatistics() const override {
3183 STATS_DECLTRACK_CS_ATTR(value_simplify)
3184 }
3185};
3186
3187struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
3188 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
3189 : AAValueSimplifyReturned(IRP) {}
3190
3191 void trackStatistics() const override {
3192 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
3193 }
3194};
3195struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
3196 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
3197 : AAValueSimplifyFloating(IRP) {}
3198
3199 void trackStatistics() const override {
3200 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
3201 }
3202};
3203
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003204/// ----------------------- Heap-To-Stack Conversion ---------------------------
3205struct AAHeapToStackImpl : public AAHeapToStack {
3206 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
3207
3208 const std::string getAsStr() const override {
3209 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
3210 }
3211
3212 ChangeStatus manifest(Attributor &A) override {
3213 assert(getState().isValidState() &&
3214 "Attempted to manifest an invalid state!");
3215
3216 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
3217 Function *F = getAssociatedFunction();
3218 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3219
3220 for (Instruction *MallocCall : MallocCalls) {
3221 // This malloc cannot be replaced.
3222 if (BadMallocCalls.count(MallocCall))
3223 continue;
3224
3225 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
3226 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
3227 A.deleteAfterManifest(*FreeCall);
3228 HasChanged = ChangeStatus::CHANGED;
3229 }
3230
3231 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
3232 << "\n");
3233
3234 Constant *Size;
3235 if (isCallocLikeFn(MallocCall, TLI)) {
3236 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
3237 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
3238 APInt TotalSize = SizeT->getValue() * Num->getValue();
3239 Size =
3240 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
3241 } else {
3242 Size = cast<ConstantInt>(MallocCall->getOperand(0));
3243 }
3244
3245 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
3246 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
3247 Size, "", MallocCall->getNextNode());
3248
3249 if (AI->getType() != MallocCall->getType())
3250 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
3251 AI->getNextNode());
3252
3253 MallocCall->replaceAllUsesWith(AI);
3254
3255 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
3256 auto *NBB = II->getNormalDest();
3257 BranchInst::Create(NBB, MallocCall->getParent());
3258 A.deleteAfterManifest(*MallocCall);
3259 } else {
3260 A.deleteAfterManifest(*MallocCall);
3261 }
3262
3263 if (isCallocLikeFn(MallocCall, TLI)) {
3264 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
3265 AI->getNextNode());
3266 Value *Ops[] = {
3267 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
3268 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
3269
3270 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
3271 Module *M = F->getParent();
3272 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
3273 CallInst::Create(Fn, Ops, "", BI->getNextNode());
3274 }
3275 HasChanged = ChangeStatus::CHANGED;
3276 }
3277
3278 return HasChanged;
3279 }
3280
3281 /// Collection of all malloc calls in a function.
3282 SmallSetVector<Instruction *, 4> MallocCalls;
3283
3284 /// Collection of malloc calls that cannot be converted.
3285 DenseSet<const Instruction *> BadMallocCalls;
3286
3287 /// A map for each malloc call to the set of associated free calls.
3288 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
3289
3290 ChangeStatus updateImpl(Attributor &A) override;
3291};
3292
3293ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
3294 const Function *F = getAssociatedFunction();
3295 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3296
3297 auto UsesCheck = [&](Instruction &I) {
3298 SmallPtrSet<const Use *, 8> Visited;
3299 SmallVector<const Use *, 8> Worklist;
3300
3301 for (Use &U : I.uses())
3302 Worklist.push_back(&U);
3303
3304 while (!Worklist.empty()) {
3305 const Use *U = Worklist.pop_back_val();
3306 if (!Visited.insert(U).second)
3307 continue;
3308
3309 auto *UserI = U->getUser();
3310
3311 if (isa<LoadInst>(UserI) || isa<StoreInst>(UserI))
3312 continue;
3313
3314 // NOTE: Right now, if a function that has malloc pointer as an argument
3315 // frees memory, we assume that the malloc pointer is freed.
3316
3317 // TODO: Add nofree callsite argument attribute to indicate that pointer
3318 // argument is not freed.
3319 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3320 if (!CB->isArgOperand(U))
3321 continue;
3322
3323 if (CB->isLifetimeStartOrEnd())
3324 continue;
3325
3326 // Record malloc.
3327 if (isFreeCall(UserI, TLI)) {
3328 FreesForMalloc[&I].insert(
3329 cast<Instruction>(const_cast<User *>(UserI)));
3330 continue;
3331 }
3332
3333 // If a function does not free memory we are fine
3334 const auto &NoFreeAA =
3335 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(*CB));
3336
3337 unsigned ArgNo = U - CB->arg_begin();
3338 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
3339 *this, IRPosition::callsite_argument(*CB, ArgNo));
3340
3341 if (!NoCaptureAA.isAssumedNoCapture() || !NoFreeAA.isAssumedNoFree()) {
3342 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
3343 return false;
3344 }
3345 continue;
3346 }
3347
3348 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI)) {
3349 for (Use &U : UserI->uses())
3350 Worklist.push_back(&U);
3351 continue;
3352 }
3353
3354 // Unknown user.
3355 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
3356 return false;
3357 }
3358 return true;
3359 };
3360
3361 auto MallocCallocCheck = [&](Instruction &I) {
3362 if (isMallocLikeFn(&I, TLI)) {
3363 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
3364 if (!Size->getValue().sle(MaxHeapToStackSize))
3365 return true;
3366 } else if (isCallocLikeFn(&I, TLI)) {
3367 bool Overflow = false;
3368 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
3369 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
3370 if (!(Size->getValue().umul_ov(Num->getValue(), Overflow))
3371 .sle(MaxHeapToStackSize))
3372 if (!Overflow)
3373 return true;
3374 } else {
3375 BadMallocCalls.insert(&I);
3376 return true;
3377 }
3378
3379 if (BadMallocCalls.count(&I))
3380 return true;
3381
3382 if (UsesCheck(I))
3383 MallocCalls.insert(&I);
3384 else
3385 BadMallocCalls.insert(&I);
3386 return true;
3387 };
3388
3389 size_t NumBadMallocs = BadMallocCalls.size();
3390
3391 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
3392
3393 if (NumBadMallocs != BadMallocCalls.size())
3394 return ChangeStatus::CHANGED;
3395
3396 return ChangeStatus::UNCHANGED;
3397}
3398
3399struct AAHeapToStackFunction final : public AAHeapToStackImpl {
3400 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
3401
3402 /// See AbstractAttribute::trackStatistics()
3403 void trackStatistics() const override {
3404 STATS_DECL(MallocCalls, Function,
3405 "Number of MallocCalls converted to allocas");
3406 BUILD_STAT_NAME(MallocCalls, Function) += MallocCalls.size();
3407 }
3408};
3409
Johannes Doerfertaade7822019-06-05 03:02:24 +00003410/// ----------------------------------------------------------------------------
3411/// Attributor
3412/// ----------------------------------------------------------------------------
3413
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00003414bool Attributor::isAssumedDead(const AbstractAttribute &AA,
3415 const AAIsDead *LivenessAA) {
3416 const Instruction *CtxI = AA.getIRPosition().getCtxI();
3417 if (!CtxI)
3418 return false;
3419
3420 if (!LivenessAA)
3421 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00003422 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
3423 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003424
3425 // Don't check liveness for AAIsDead.
3426 if (&AA == LivenessAA)
3427 return false;
3428
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003429 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00003430 return false;
3431
Johannes Doerfert19b00432019-08-26 17:48:05 +00003432 // We actually used liveness information so we have to record a dependence.
3433 recordDependence(*LivenessAA, AA);
3434
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00003435 return true;
3436}
3437
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003438bool Attributor::checkForAllCallSites(const function_ref<bool(CallSite)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00003439 const AbstractAttribute &QueryingAA,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003440 bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00003441 // We can try to determine information from
3442 // the call sites. However, this is only possible all call sites are known,
3443 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003444 const IRPosition &IRP = QueryingAA.getIRPosition();
3445 const Function *AssociatedFunction = IRP.getAssociatedFunction();
3446 if (!AssociatedFunction)
3447 return false;
3448
3449 if (RequireAllCallSites && !AssociatedFunction->hasInternalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00003450 LLVM_DEBUG(
3451 dbgs()
Johannes Doerfert5304b722019-08-14 22:04:28 +00003452 << "[Attributor] Function " << AssociatedFunction->getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00003453 << " has no internal linkage, hence not all call sites are known\n");
3454 return false;
3455 }
3456
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003457 for (const Use &U : AssociatedFunction->uses()) {
Johannes Doerfertd98f9752019-08-21 21:48:56 +00003458 Instruction *I = dyn_cast<Instruction>(U.getUser());
3459 // TODO: Deal with abstract call sites here.
3460 if (!I)
3461 return false;
3462
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003463 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003464
Johannes Doerfert19b00432019-08-26 17:48:05 +00003465 const auto &LivenessAA = getAAFor<AAIsDead>(
3466 QueryingAA, IRPosition::function(*Caller), /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003467
3468 // Skip dead calls.
Johannes Doerfert19b00432019-08-26 17:48:05 +00003469 if (LivenessAA.isAssumedDead(I)) {
3470 // We actually used liveness information so we have to record a
3471 // dependence.
3472 recordDependence(LivenessAA, QueryingAA);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003473 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00003474 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00003475
3476 CallSite CS(U.getUser());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003477 if (!CS || !CS.isCallee(&U)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00003478 if (!RequireAllCallSites)
3479 continue;
3480
Johannes Doerfert5304b722019-08-14 22:04:28 +00003481 LLVM_DEBUG(dbgs() << "[Attributor] User " << *U.getUser()
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003482 << " is an invalid use of "
3483 << AssociatedFunction->getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00003484 return false;
3485 }
3486
3487 if (Pred(CS))
3488 continue;
3489
Johannes Doerfert5304b722019-08-14 22:04:28 +00003490 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Hideto Ueno54869ec2019-07-15 06:49:04 +00003491 << *CS.getInstruction() << "\n");
3492 return false;
3493 }
3494
3495 return true;
3496}
3497
Johannes Doerfert14a04932019-08-07 22:27:24 +00003498bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00003499 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00003500 &Pred,
3501 const AbstractAttribute &QueryingAA) {
3502
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003503 const IRPosition &IRP = QueryingAA.getIRPosition();
3504 // Since we need to provide return instructions we have to have an exact
3505 // definition.
3506 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003507 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00003508 return false;
3509
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003510 // If this is a call site query we use the call site specific return values
3511 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003512 // TODO: use the function scope once we have call site AAReturnedValues.
3513 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003514 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003515 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003516 return false;
3517
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003518 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00003519}
3520
3521bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003522 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00003523 const AbstractAttribute &QueryingAA) {
3524
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003525 const IRPosition &IRP = QueryingAA.getIRPosition();
3526 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003527 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00003528 return false;
3529
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003530 // TODO: use the function scope once we have call site AAReturnedValues.
3531 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003532 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003533 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003534 return false;
3535
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003536 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00003537 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00003538 return Pred(RV);
3539 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00003540}
3541
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00003542static bool
3543checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
3544 const function_ref<bool(Instruction &)> &Pred,
3545 const AAIsDead *LivenessAA, bool &AnyDead,
3546 const ArrayRef<unsigned> &Opcodes) {
3547 for (unsigned Opcode : Opcodes) {
3548 for (Instruction *I : OpcodeInstMap[Opcode]) {
3549 // Skip dead instructions.
3550 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
3551 AnyDead = true;
3552 continue;
3553 }
3554
3555 if (!Pred(*I))
3556 return false;
3557 }
3558 }
3559 return true;
3560}
3561
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003562bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003563 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00003564 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003565
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003566 const IRPosition &IRP = QueryingAA.getIRPosition();
3567 // Since we need to provide instructions we have to have an exact definition.
3568 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003569 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003570 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003571
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003572 // TODO: use the function scope once we have call site AAReturnedValues.
3573 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00003574 const auto &LivenessAA =
3575 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
3576 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003577
3578 auto &OpcodeInstMap =
3579 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00003580 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead, Opcodes))
3581 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003582
Johannes Doerfert19b00432019-08-26 17:48:05 +00003583 // If we actually used liveness information so we have to record a dependence.
3584 if (AnyDead)
3585 recordDependence(LivenessAA, QueryingAA);
3586
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003587 return true;
3588}
3589
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00003590bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003591 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00003592 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00003593
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003594 const Function *AssociatedFunction =
3595 QueryingAA.getIRPosition().getAssociatedFunction();
3596 if (!AssociatedFunction)
3597 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00003598
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003599 // TODO: use the function scope once we have call site AAReturnedValues.
3600 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
3601 const auto &LivenessAA =
3602 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00003603 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003604
3605 for (Instruction *I :
3606 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00003607 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00003608 if (LivenessAA.isAssumedDead(I)) {
3609 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00003610 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00003611 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00003612
3613 if (!Pred(*I))
3614 return false;
3615 }
3616
Johannes Doerfert19b00432019-08-26 17:48:05 +00003617 // If we actually used liveness information so we have to record a dependence.
3618 if (AnyDead)
3619 recordDependence(LivenessAA, QueryingAA);
3620
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00003621 return true;
3622}
3623
Johannes Doerfert2f622062019-09-04 16:35:20 +00003624ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00003625 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
3626 << AllAbstractAttributes.size()
3627 << " abstract attributes.\n");
3628
Stefan Stipanovic53605892019-06-27 11:27:54 +00003629 // Now that all abstract attributes are collected and initialized we start
3630 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00003631
3632 unsigned IterationCounter = 1;
3633
3634 SmallVector<AbstractAttribute *, 64> ChangedAAs;
3635 SetVector<AbstractAttribute *> Worklist;
3636 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
3637
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00003638 bool RecomputeDependences = false;
3639
Johannes Doerfertaade7822019-06-05 03:02:24 +00003640 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003641 // Remember the size to determine new attributes.
3642 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00003643 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
3644 << ", Worklist size: " << Worklist.size() << "\n");
3645
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00003646 // If dependences (=QueryMap) are recomputed we have to look at all abstract
3647 // attributes again, regardless of what changed in the last iteration.
3648 if (RecomputeDependences) {
3649 LLVM_DEBUG(
3650 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
3651 QueryMap.clear();
3652 ChangedAAs.clear();
3653 Worklist.insert(AllAbstractAttributes.begin(),
3654 AllAbstractAttributes.end());
3655 }
3656
Johannes Doerfertaade7822019-06-05 03:02:24 +00003657 // Add all abstract attributes that are potentially dependent on one that
3658 // changed to the work list.
3659 for (AbstractAttribute *ChangedAA : ChangedAAs) {
3660 auto &QuerriedAAs = QueryMap[ChangedAA];
3661 Worklist.insert(QuerriedAAs.begin(), QuerriedAAs.end());
3662 }
3663
Johannes Doerfertb504eb82019-08-26 18:55:47 +00003664 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
3665 << ", Worklist+Dependent size: " << Worklist.size()
3666 << "\n");
3667
Johannes Doerfertaade7822019-06-05 03:02:24 +00003668 // Reset the changed set.
3669 ChangedAAs.clear();
3670
3671 // Update all abstract attribute in the work list and record the ones that
3672 // changed.
3673 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00003674 if (!isAssumedDead(*AA, nullptr))
3675 if (AA->update(*this) == ChangeStatus::CHANGED)
3676 ChangedAAs.push_back(AA);
Johannes Doerfertaade7822019-06-05 03:02:24 +00003677
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00003678 // Check if we recompute the dependences in the next iteration.
3679 RecomputeDependences = (DepRecomputeInterval > 0 &&
3680 IterationCounter % DepRecomputeInterval == 0);
3681
Johannes Doerfert9543f142019-08-23 15:24:57 +00003682 // Add attributes to the changed set if they have been created in the last
3683 // iteration.
3684 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
3685 AllAbstractAttributes.end());
3686
Johannes Doerfertaade7822019-06-05 03:02:24 +00003687 // Reset the work list and repopulate with the changed abstract attributes.
3688 // Note that dependent ones are added above.
3689 Worklist.clear();
3690 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
3691
Johannes Doerfertbf112132019-08-29 01:29:44 +00003692 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
3693 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00003694
Johannes Doerfertaade7822019-06-05 03:02:24 +00003695 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
3696 << IterationCounter << "/" << MaxFixpointIterations
3697 << " iterations\n");
3698
Johannes Doerfertbf112132019-08-29 01:29:44 +00003699 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00003700
Johannes Doerfertaade7822019-06-05 03:02:24 +00003701 bool FinishedAtFixpoint = Worklist.empty();
3702
3703 // Reset abstract arguments not settled in a sound fixpoint by now. This
3704 // happens when we stopped the fixpoint iteration early. Note that only the
3705 // ones marked as "changed" *and* the ones transitively depending on them
3706 // need to be reverted to a pessimistic state. Others might not be in a
3707 // fixpoint state but we can use the optimistic results for them anyway.
3708 SmallPtrSet<AbstractAttribute *, 32> Visited;
3709 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
3710 AbstractAttribute *ChangedAA = ChangedAAs[u];
3711 if (!Visited.insert(ChangedAA).second)
3712 continue;
3713
3714 AbstractState &State = ChangedAA->getState();
3715 if (!State.isAtFixpoint()) {
3716 State.indicatePessimisticFixpoint();
3717
3718 NumAttributesTimedOut++;
3719 }
3720
3721 auto &QuerriedAAs = QueryMap[ChangedAA];
3722 ChangedAAs.append(QuerriedAAs.begin(), QuerriedAAs.end());
3723 }
3724
3725 LLVM_DEBUG({
3726 if (!Visited.empty())
3727 dbgs() << "\n[Attributor] Finalized " << Visited.size()
3728 << " abstract attributes.\n";
3729 });
3730
3731 unsigned NumManifested = 0;
3732 unsigned NumAtFixpoint = 0;
3733 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
3734 for (AbstractAttribute *AA : AllAbstractAttributes) {
3735 AbstractState &State = AA->getState();
3736
3737 // If there is not already a fixpoint reached, we can now take the
3738 // optimistic state. This is correct because we enforced a pessimistic one
3739 // on abstract attributes that were transitively dependent on a changed one
3740 // already above.
3741 if (!State.isAtFixpoint())
3742 State.indicateOptimisticFixpoint();
3743
3744 // If the state is invalid, we do not try to manifest it.
3745 if (!State.isValidState())
3746 continue;
3747
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00003748 // Skip dead code.
3749 if (isAssumedDead(*AA, nullptr))
3750 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00003751 // Manifest the state and record if we changed the IR.
3752 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003753 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
3754 AA->trackStatistics();
3755
Johannes Doerfertaade7822019-06-05 03:02:24 +00003756 ManifestChange = ManifestChange | LocalChange;
3757
3758 NumAtFixpoint++;
3759 NumManifested += (LocalChange == ChangeStatus::CHANGED);
3760 }
3761
3762 (void)NumManifested;
3763 (void)NumAtFixpoint;
3764 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
3765 << " arguments while " << NumAtFixpoint
3766 << " were in a valid fixpoint state\n");
3767
3768 // If verification is requested, we finished this run at a fixpoint, and the
3769 // IR was changed, we re-run the whole fixpoint analysis, starting at
3770 // re-initialization of the arguments. This re-run should not result in an IR
3771 // change. Though, the (virtual) state of attributes at the end of the re-run
3772 // might be more optimistic than the known state or the IR state if the better
3773 // state cannot be manifested.
3774 if (VerifyAttributor && FinishedAtFixpoint &&
3775 ManifestChange == ChangeStatus::CHANGED) {
3776 VerifyAttributor = false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003777 ChangeStatus VerifyStatus = run(M);
Johannes Doerfertaade7822019-06-05 03:02:24 +00003778 if (VerifyStatus != ChangeStatus::UNCHANGED)
3779 llvm_unreachable(
3780 "Attributor verification failed, re-run did result in an IR change "
3781 "even after a fixpoint was reached in the original run. (False "
3782 "positives possible!)");
3783 VerifyAttributor = true;
3784 }
3785
3786 NumAttributesManifested += NumManifested;
3787 NumAttributesValidFixpoint += NumAtFixpoint;
3788
Fangrui Songf1826172019-08-20 07:21:43 +00003789 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003790 assert(
3791 NumFinalAAs == AllAbstractAttributes.size() &&
3792 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00003793
3794 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00003795 {
3796 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
3797 << ToBeDeletedFunctions.size() << " functions and "
3798 << ToBeDeletedBlocks.size() << " blocks and "
3799 << ToBeDeletedInsts.size() << " instructions\n");
3800 for (Instruction *I : ToBeDeletedInsts) {
3801 if (!I->use_empty())
3802 I->replaceAllUsesWith(UndefValue::get(I->getType()));
3803 I->eraseFromParent();
3804 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003805
Johannes Doerfert2f622062019-09-04 16:35:20 +00003806 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
3807 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
3808 ToBeDeletedBBs.reserve(NumDeadBlocks);
3809 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
3810 DeleteDeadBlocks(ToBeDeletedBBs);
3811 STATS_DECLTRACK(AAIsDead, BasicBlock,
3812 "Number of dead basic blocks deleted.");
3813 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003814
Johannes Doerfert2f622062019-09-04 16:35:20 +00003815 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
3816 for (Function *Fn : ToBeDeletedFunctions) {
3817 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
3818 Fn->eraseFromParent();
3819 STATS_TRACK(AAIsDead, Function);
3820 }
3821
3822 // Identify dead internal functions and delete them. This happens outside
3823 // the other fixpoint analysis as we might treat potentially dead functions
3824 // as live to lower the number of iterations. If they happen to be dead, the
3825 // below fixpoint loop will identify and eliminate them.
3826 SmallVector<Function *, 8> InternalFns;
3827 for (Function &F : M)
3828 if (F.hasInternalLinkage())
3829 InternalFns.push_back(&F);
3830
3831 bool FoundDeadFn = true;
3832 while (FoundDeadFn) {
3833 FoundDeadFn = false;
3834 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
3835 Function *F = InternalFns[u];
3836 if (!F)
3837 continue;
3838
3839 const auto *LivenessAA =
3840 lookupAAFor<AAIsDead>(IRPosition::function(*F));
3841 if (LivenessAA &&
3842 !checkForAllCallSites([](CallSite CS) { return false; },
3843 *LivenessAA, true))
3844 continue;
3845
3846 STATS_TRACK(AAIsDead, Function);
3847 F->replaceAllUsesWith(UndefValue::get(F->getType()));
3848 F->eraseFromParent();
3849 InternalFns[u] = nullptr;
3850 FoundDeadFn = true;
3851 }
3852 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00003853 }
3854
Johannes Doerfertbf112132019-08-29 01:29:44 +00003855 if (VerifyMaxFixpointIterations &&
3856 IterationCounter != MaxFixpointIterations) {
3857 errs() << "\n[Attributor] Fixpoint iteration done after: "
3858 << IterationCounter << "/" << MaxFixpointIterations
3859 << " iterations\n";
3860 llvm_unreachable("The fixpoint was not reached with exactly the number of "
3861 "specified iterations!");
3862 }
3863
Johannes Doerfertaade7822019-06-05 03:02:24 +00003864 return ManifestChange;
3865}
3866
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00003867void Attributor::initializeInformationCache(Function &F) {
3868
3869 // Walk all instructions to find interesting instructions that might be
3870 // queried by abstract attributes during their initialization or update.
3871 // This has to happen before we create attributes.
3872 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
3873 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
3874
3875 for (Instruction &I : instructions(&F)) {
3876 bool IsInterestingOpcode = false;
3877
3878 // To allow easy access to all instructions in a function with a given
3879 // opcode we store them in the InfoCache. As not all opcodes are interesting
3880 // to concrete attributes we only cache the ones that are as identified in
3881 // the following switch.
3882 // Note: There are no concrete attributes now so this is initially empty.
3883 switch (I.getOpcode()) {
3884 default:
3885 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
3886 "New call site/base instruction type needs to be known int the "
3887 "Attributor.");
3888 break;
3889 case Instruction::Load:
3890 // The alignment of a pointer is interesting for loads.
3891 case Instruction::Store:
3892 // The alignment of a pointer is interesting for stores.
3893 case Instruction::Call:
3894 case Instruction::CallBr:
3895 case Instruction::Invoke:
3896 case Instruction::CleanupRet:
3897 case Instruction::CatchSwitch:
3898 case Instruction::Resume:
3899 case Instruction::Ret:
3900 IsInterestingOpcode = true;
3901 }
3902 if (IsInterestingOpcode)
3903 InstOpcodeMap[I.getOpcode()].push_back(&I);
3904 if (I.mayReadOrWriteMemory())
3905 ReadOrWriteInsts.push_back(&I);
3906 }
3907}
3908
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00003909void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00003910 if (!VisitedFunctions.insert(&F).second)
3911 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00003912
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003913 IRPosition FPos = IRPosition::function(F);
3914
Johannes Doerfert305b9612019-08-04 18:40:01 +00003915 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00003916 // We need dead instruction detection because we do not want to deal with
3917 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003918 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00003919
3920 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003921 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00003922
Stefan Stipanovic53605892019-06-27 11:27:54 +00003923 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003924 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00003925
Stefan Stipanovic06263672019-07-11 21:37:40 +00003926 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003927 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00003928
Hideto Ueno65bbaf92019-07-12 17:38:51 +00003929 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003930 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00003931
Johannes Doerferte83f3032019-08-05 23:22:05 +00003932 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003933 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00003934
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003935 // Every function might be applicable for Heap-To-Stack conversion.
3936 if (EnableHeapToStack)
3937 getOrCreateAAFor<AAHeapToStack>(FPos);
3938
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00003939 // Return attributes are only appropriate if the return type is non void.
3940 Type *ReturnType = F.getReturnType();
3941 if (!ReturnType->isVoidTy()) {
3942 // Argument attribute "returned" --- Create only one per function even
3943 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003944 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00003945
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003946 IRPosition RetPos = IRPosition::returned(F);
3947
3948 // Every function might be simplified.
3949 getOrCreateAAFor<AAValueSimplify>(RetPos);
3950
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00003951 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003952
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003953 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003954 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003955
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00003956 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003957 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00003958
3959 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003960 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00003961
3962 // Every function with pointer return type might be marked
3963 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003964 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00003965 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00003966 }
3967
Hideto Ueno54869ec2019-07-15 06:49:04 +00003968 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003969 IRPosition ArgPos = IRPosition::argument(Arg);
3970
3971 // Every argument might be simplified.
3972 getOrCreateAAFor<AAValueSimplify>(ArgPos);
3973
Hideto Ueno19c07af2019-07-23 08:16:17 +00003974 if (Arg.getType()->isPointerTy()) {
3975 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003976 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00003977
Hideto Uenocbab3342019-08-29 05:52:00 +00003978 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003979 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00003980
Hideto Ueno19c07af2019-07-23 08:16:17 +00003981 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003982 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003983
3984 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003985 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003986
3987 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003988 getOrCreateAAFor<AANoCapture>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00003989 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00003990 }
3991
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00003992 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00003993 CallSite CS(&I);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00003994 if (CS.getCalledFunction()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00003995 for (int i = 0, e = CS.getCalledFunction()->arg_size(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003996
3997 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
3998
3999 // Call site argument might be simplified.
4000 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
4001
Hideto Ueno54869ec2019-07-15 06:49:04 +00004002 if (!CS.getArgument(i)->getType()->isPointerTy())
4003 continue;
4004
4005 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004006 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004007
Hideto Uenocbab3342019-08-29 05:52:00 +00004008 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004009 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00004010
Hideto Ueno19c07af2019-07-23 08:16:17 +00004011 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004012 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004013
4014 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004015 getOrCreateAAFor<AAAlign>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00004016 }
4017 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004018 return true;
4019 };
4020
4021 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
4022 bool Success, AnyDead = false;
4023 Success = checkForAllInstructionsImpl(
4024 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
4025 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
4026 (unsigned)Instruction::Call});
4027 (void)Success;
4028 assert(Success && !AnyDead && "Expected the check call to be successful!");
4029
4030 auto LoadStorePred = [&](Instruction &I) -> bool {
4031 if (isa<LoadInst>(I))
4032 getOrCreateAAFor<AAAlign>(
4033 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
4034 else
4035 getOrCreateAAFor<AAAlign>(
4036 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
4037 return true;
4038 };
4039 Success = checkForAllInstructionsImpl(
4040 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
4041 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
4042 (void)Success;
4043 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00004044}
4045
4046/// Helpers to ease debugging through output streams and print calls.
4047///
4048///{
4049raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
4050 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
4051}
4052
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004053raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004054 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004055 case IRPosition::IRP_INVALID:
4056 return OS << "inv";
4057 case IRPosition::IRP_FLOAT:
4058 return OS << "flt";
4059 case IRPosition::IRP_RETURNED:
4060 return OS << "fn_ret";
4061 case IRPosition::IRP_CALL_SITE_RETURNED:
4062 return OS << "cs_ret";
4063 case IRPosition::IRP_FUNCTION:
4064 return OS << "fn";
4065 case IRPosition::IRP_CALL_SITE:
4066 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004067 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00004068 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004069 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00004070 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00004071 }
4072 llvm_unreachable("Unknown attribute position!");
4073}
4074
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004075raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004076 const Value &AV = Pos.getAssociatedValue();
4077 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004078 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
4079}
4080
Johannes Doerfertacc80792019-08-12 22:07:34 +00004081raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerState &S) {
4082 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
4083 << static_cast<const AbstractState &>(S);
4084}
4085
Johannes Doerfertaade7822019-06-05 03:02:24 +00004086raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
4087 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
4088}
4089
4090raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
4091 AA.print(OS);
4092 return OS;
4093}
4094
4095void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004096 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
4097 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00004098}
4099///}
4100
4101/// ----------------------------------------------------------------------------
4102/// Pass (Manager) Boilerplate
4103/// ----------------------------------------------------------------------------
4104
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004105static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004106 if (DisableAttributor)
4107 return false;
4108
4109 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
4110 << " functions.\n");
4111
4112 // Create an Attributor and initially empty information cache that is filled
4113 // while we identify default attribute opportunities.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004114 InformationCache InfoCache(M.getDataLayout(), AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004115 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004116
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004117 for (Function &F : M)
4118 A.initializeInformationCache(F);
4119
Johannes Doerfertaade7822019-06-05 03:02:24 +00004120 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004121 if (F.hasExactDefinition())
4122 NumFnWithExactDefinition++;
4123 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00004124 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004125
4126 // For now we ignore naked and optnone functions.
4127 if (F.hasFnAttribute(Attribute::Naked) ||
4128 F.hasFnAttribute(Attribute::OptimizeNone))
4129 continue;
4130
Johannes Doerfert2f622062019-09-04 16:35:20 +00004131 // We look at internal functions only on-demand but if any use is not a
4132 // direct call, we have to do it eagerly.
4133 if (F.hasInternalLinkage()) {
4134 if (llvm::all_of(F.uses(), [](const Use &U) {
4135 return ImmutableCallSite(U.getUser()) &&
4136 ImmutableCallSite(U.getUser()).isCallee(&U);
4137 }))
4138 continue;
4139 }
4140
Johannes Doerfertaade7822019-06-05 03:02:24 +00004141 // Populate the Attributor with abstract attribute opportunities in the
4142 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004143 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004144 }
4145
Johannes Doerfert2f622062019-09-04 16:35:20 +00004146 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004147}
4148
4149PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004150 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
4151
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004152 AnalysisGetter AG(FAM);
4153 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004154 // FIXME: Think about passes we will preserve and add them here.
4155 return PreservedAnalyses::none();
4156 }
4157 return PreservedAnalyses::all();
4158}
4159
4160namespace {
4161
4162struct AttributorLegacyPass : public ModulePass {
4163 static char ID;
4164
4165 AttributorLegacyPass() : ModulePass(ID) {
4166 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
4167 }
4168
4169 bool runOnModule(Module &M) override {
4170 if (skipModule(M))
4171 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004172
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004173 AnalysisGetter AG;
4174 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004175 }
4176
4177 void getAnalysisUsage(AnalysisUsage &AU) const override {
4178 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004179 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004180 }
4181};
4182
4183} // end anonymous namespace
4184
4185Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
4186
4187char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00004188
4189const char AAReturnedValues::ID = 0;
4190const char AANoUnwind::ID = 0;
4191const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00004192const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00004193const char AANonNull::ID = 0;
4194const char AANoRecurse::ID = 0;
4195const char AAWillReturn::ID = 0;
4196const char AANoAlias::ID = 0;
4197const char AANoReturn::ID = 0;
4198const char AAIsDead::ID = 0;
4199const char AADereferenceable::ID = 0;
4200const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004201const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004202const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004203const char AAHeapToStack::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00004204
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004205// Macro magic to create the static generator function for attributes that
4206// follow the naming scheme.
4207
4208#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
4209 case IRPosition::PK: \
4210 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
4211
4212#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
4213 case IRPosition::PK: \
4214 AA = new CLASS##SUFFIX(IRP); \
4215 break;
4216
4217#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4218 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4219 CLASS *AA = nullptr; \
4220 switch (IRP.getPositionKind()) { \
4221 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4222 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
4223 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
4224 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
4225 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
4226 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
4227 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4228 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
4229 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004230 return *AA; \
4231 }
4232
4233#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4234 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4235 CLASS *AA = nullptr; \
4236 switch (IRP.getPositionKind()) { \
4237 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4238 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
4239 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
4240 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
4241 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
4242 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
4243 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
4244 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
4245 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004246 return *AA; \
4247 }
4248
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004249#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4250 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4251 CLASS *AA = nullptr; \
4252 switch (IRP.getPositionKind()) { \
4253 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4254 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4255 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
4256 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
4257 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
4258 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
4259 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
4260 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
4261 } \
4262 return *AA; \
4263 }
4264
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004265#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4266 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4267 CLASS *AA = nullptr; \
4268 switch (IRP.getPositionKind()) { \
4269 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4270 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
4271 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
4272 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
4273 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
4274 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
4275 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
4276 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4277 } \
4278 AA->initialize(A); \
4279 return *AA; \
4280 }
4281
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004282CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
4283CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
4284CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
4285CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
4286CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
4287CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
4288CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
4289CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
4290
4291CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
4292CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
4293CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
4294CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004295CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004296
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004297CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
4298
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004299CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
4300
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004301#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
4302#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004303#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004304#undef SWITCH_PK_CREATE
4305#undef SWITCH_PK_INV
4306
Johannes Doerfertaade7822019-06-05 03:02:24 +00004307INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
4308 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004309INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00004310INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
4311 "Deduce and propagate attributes", false, false)