llvm.org GIT mirror llvm / 6086847
Refactor ObjCARCAliasAnalysis into its own file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173662 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Gottesman 7 years ago
5 changed file(s) with 352 addition(s) and 283 deletion(s). Raw diff Collapse all Expand all
22 ObjCARCOpts.cpp
33 ObjCARCExpand.cpp
44 ObjCARCAPElim.cpp
5 ObjCARCAliasAnalysis.cpp
56 )
67
78 add_dependencies(LLVMObjCARCOpts intrinsics_gen)
2525 #include "llvm/ADT/StringSwitch.h"
2626 #include "llvm/Analysis/AliasAnalysis.h"
2727 #include "llvm/Analysis/Passes.h"
28 #include "llvm/Analysis/ValueTracking.h"
2829 #include "llvm/IR/Module.h"
2930 #include "llvm/Pass.h"
3031 #include "llvm/Support/Debug.h"
144145 llvm_unreachable("Unknown instruction class!");
145146 }
146147
148 /// \brief Test if the given class is objc_retain or equivalent.
149 static inline bool IsRetain(InstructionClass Class) {
150 return Class == IC_Retain ||
151 Class == IC_RetainRV;
152 }
153
154 /// \brief Test if the given class is objc_autorelease or equivalent.
155 static inline bool IsAutorelease(InstructionClass Class) {
156 return Class == IC_Autorelease ||
157 Class == IC_AutoreleaseRV;
158 }
159
160 /// \brief Test if the given class represents instructions which return their
161 /// argument verbatim.
162 static inline bool IsForwarding(InstructionClass Class) {
163 // objc_retainBlock technically doesn't always return its argument
164 // verbatim, but it doesn't matter for our purposes here.
165 return Class == IC_Retain ||
166 Class == IC_RetainRV ||
167 Class == IC_Autorelease ||
168 Class == IC_AutoreleaseRV ||
169 Class == IC_RetainBlock ||
170 Class == IC_NoopCast;
171 }
172
173 /// \brief Test if the given class represents instructions which do nothing if
174 /// passed a null pointer.
175 static inline bool IsNoopOnNull(InstructionClass Class) {
176 return Class == IC_Retain ||
177 Class == IC_RetainRV ||
178 Class == IC_Release ||
179 Class == IC_Autorelease ||
180 Class == IC_AutoreleaseRV ||
181 Class == IC_RetainBlock;
182 }
183
184 /// \brief Test if the given class represents instructions which are always safe
185 /// to mark with the "tail" keyword.
186 static inline bool IsAlwaysTail(InstructionClass Class) {
187 // IC_RetainBlock may be given a stack argument.
188 return Class == IC_Retain ||
189 Class == IC_RetainRV ||
190 Class == IC_AutoreleaseRV;
191 }
192
193 /// \brief Test if the given class represents instructions which are never safe
194 /// to mark with the "tail" keyword.
195 static inline bool IsNeverTail(InstructionClass Class) {
196 /// It is never safe to tail call objc_autorelease since by tail calling
197 /// objc_autorelease, we also tail call -[NSObject autorelease] which supports
198 /// fast autoreleasing causing our object to be potentially reclaimed from the
199 /// autorelease pool which violates the semantics of __autoreleasing types in
200 /// ARC.
201 return Class == IC_Autorelease;
202 }
203
204 /// \brief Test if the given class represents instructions which are always safe
205 /// to mark with the nounwind attribute.
206 static inline bool IsNoThrow(InstructionClass Class) {
207 // objc_retainBlock is not nounwind because it calls user copy constructors
208 // which could theoretically throw.
209 return Class == IC_Retain ||
210 Class == IC_RetainRV ||
211 Class == IC_Release ||
212 Class == IC_Autorelease ||
213 Class == IC_AutoreleaseRV ||
214 Class == IC_AutoreleasepoolPush ||
215 Class == IC_AutoreleasepoolPop;
216 }
147217
148218 /// \brief Determine if F is one of the special known Functions. If it isn't,
149219 /// return IC_CallOrUser.
150 static inline InstructionClass GetFunctionClass(const Function *F) {
220 static InstructionClass GetFunctionClass(const Function *F)
221 LLVM_ATTRIBUTE_USED;
222 static InstructionClass GetFunctionClass(const Function *F) {
151223 Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
152224
153225 // No arguments.
235307 return isa(V) ? IC_CallOrUser : IC_User;
236308 }
237309
310
311 /// \brief This is a wrapper around getUnderlyingObject which also knows how to
312 /// look through objc_retain and objc_autorelease calls, which we know to return
313 /// their argument verbatim.
314 static inline const Value *GetUnderlyingObjCPtr(const Value *V) {
315 for (;;) {
316 V = GetUnderlyingObject(V);
317 if (!IsForwarding(GetBasicInstructionClass(V)))
318 break;
319 V = cast(V)->getArgOperand(0);
320 }
321
322 return V;
323 }
324
325 /// \brief This is a wrapper around Value::stripPointerCasts which also knows
326 /// how to look through objc_retain and objc_autorelease calls, which we know to
327 /// return their argument verbatim.
328 static inline const Value *StripPointerCastsAndObjCCalls(const Value *V) {
329 for (;;) {
330 V = V->stripPointerCasts();
331 if (!IsForwarding(GetBasicInstructionClass(V)))
332 break;
333 V = cast(V)->getArgOperand(0);
334 }
335 return V;
336 }
337
338 /// \brief This is a wrapper around Value::stripPointerCasts which also knows
339 /// how to look through objc_retain and objc_autorelease calls, which we know to
340 /// return their argument verbatim.
341 static inline Value *StripPointerCastsAndObjCCalls(Value *V) {
342 for (;;) {
343 V = V->stripPointerCasts();
344 if (!IsForwarding(GetBasicInstructionClass(V)))
345 break;
346 V = cast(V)->getArgOperand(0);
347 }
348 return V;
349 }
350
351
238352 } // end namespace objcarc
239353 } // end namespace llvm
240354
0 //===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -*- mode: c++ -*---===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file defines a simple ARC-aware AliasAnalysis using special knowledge
10 /// of Objective C to enhance other optimization passes which rely on the Alias
11 /// Analysis infrastructure.
12 ///
13 /// WARNING: This file knows about certain library functions. It recognizes them
14 /// by name, and hardwires knowledge of their semantics.
15 ///
16 /// WARNING: This file knows about how certain Objective-C library functions are
17 /// used. Naive LLVM IR transformations which would otherwise be
18 /// behavior-preserving may break these assumptions.
19 ///
20 //===----------------------------------------------------------------------===//
21
22 #define DEBUG_TYPE "objc-arc-aa"
23 #include "ObjCARC.h"
24 #include "ObjCARCAliasAnalysis.h"
25
26 #include "llvm/IR/Instruction.h"
27 #include "llvm/InitializePasses.h"
28 #include "llvm/PassAnalysisSupport.h"
29 #include "llvm/PassSupport.h"
30
31 namespace llvm {
32 class Function;
33 class Value;
34 }
35
36 using namespace llvm;
37 using namespace llvm::objcarc;
38
39 // Register this pass...
40 char ObjCARCAliasAnalysis::ID = 0;
41 INITIALIZE_AG_PASS(ObjCARCAliasAnalysis, AliasAnalysis, "objc-arc-aa",
42 "ObjC-ARC-Based Alias Analysis", false, true, false)
43
44 ImmutablePass *llvm::createObjCARCAliasAnalysisPass() {
45 return new ObjCARCAliasAnalysis();
46 }
47
48 void
49 ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
50 AU.setPreservesAll();
51 AliasAnalysis::getAnalysisUsage(AU);
52 }
53
54 AliasAnalysis::AliasResult
55 ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) {
56 if (!EnableARCOpts)
57 return AliasAnalysis::alias(LocA, LocB);
58
59 // First, strip off no-ops, including ObjC-specific no-ops, and try making a
60 // precise alias query.
61 const Value *SA = StripPointerCastsAndObjCCalls(LocA.Ptr);
62 const Value *SB = StripPointerCastsAndObjCCalls(LocB.Ptr);
63 AliasResult Result =
64 AliasAnalysis::alias(Location(SA, LocA.Size, LocA.TBAATag),
65 Location(SB, LocB.Size, LocB.TBAATag));
66 if (Result != MayAlias)
67 return Result;
68
69 // If that failed, climb to the underlying object, including climbing through
70 // ObjC-specific no-ops, and try making an imprecise alias query.
71 const Value *UA = GetUnderlyingObjCPtr(SA);
72 const Value *UB = GetUnderlyingObjCPtr(SB);
73 if (UA != SA || UB != SB) {
74 Result = AliasAnalysis::alias(Location(UA), Location(UB));
75 // We can't use MustAlias or PartialAlias results here because
76 // GetUnderlyingObjCPtr may return an offsetted pointer value.
77 if (Result == NoAlias)
78 return NoAlias;
79 }
80
81 // If that failed, fail. We don't need to chain here, since that's covered
82 // by the earlier precise query.
83 return MayAlias;
84 }
85
86 bool
87 ObjCARCAliasAnalysis::pointsToConstantMemory(const Location &Loc,
88 bool OrLocal) {
89 if (!EnableARCOpts)
90 return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
91
92 // First, strip off no-ops, including ObjC-specific no-ops, and try making
93 // a precise alias query.
94 const Value *S = StripPointerCastsAndObjCCalls(Loc.Ptr);
95 if (AliasAnalysis::pointsToConstantMemory(Location(S, Loc.Size, Loc.TBAATag),
96 OrLocal))
97 return true;
98
99 // If that failed, climb to the underlying object, including climbing through
100 // ObjC-specific no-ops, and try making an imprecise alias query.
101 const Value *U = GetUnderlyingObjCPtr(S);
102 if (U != S)
103 return AliasAnalysis::pointsToConstantMemory(Location(U), OrLocal);
104
105 // If that failed, fail. We don't need to chain here, since that's covered
106 // by the earlier precise query.
107 return false;
108 }
109
110 AliasAnalysis::ModRefBehavior
111 ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
112 // We have nothing to do. Just chain to the next AliasAnalysis.
113 return AliasAnalysis::getModRefBehavior(CS);
114 }
115
116 AliasAnalysis::ModRefBehavior
117 ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
118 if (!EnableARCOpts)
119 return AliasAnalysis::getModRefBehavior(F);
120
121 switch (GetFunctionClass(F)) {
122 case IC_NoopCast:
123 return DoesNotAccessMemory;
124 default:
125 break;
126 }
127
128 return AliasAnalysis::getModRefBehavior(F);
129 }
130
131 AliasAnalysis::ModRefResult
132 ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) {
133 if (!EnableARCOpts)
134 return AliasAnalysis::getModRefInfo(CS, Loc);
135
136 switch (GetBasicInstructionClass(CS.getInstruction())) {
137 case IC_Retain:
138 case IC_RetainRV:
139 case IC_Autorelease:
140 case IC_AutoreleaseRV:
141 case IC_NoopCast:
142 case IC_AutoreleasepoolPush:
143 case IC_FusedRetainAutorelease:
144 case IC_FusedRetainAutoreleaseRV:
145 // These functions don't access any memory visible to the compiler.
146 // Note that this doesn't include objc_retainBlock, because it updates
147 // pointers when it copies block data.
148 return NoModRef;
149 default:
150 break;
151 }
152
153 return AliasAnalysis::getModRefInfo(CS, Loc);
154 }
155
156 AliasAnalysis::ModRefResult
157 ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
158 ImmutableCallSite CS2) {
159 // TODO: Theoretically we could check for dependencies between objc_* calls
160 // and OnlyAccessesArgumentPointees calls or other well-behaved calls.
161 return AliasAnalysis::getModRefInfo(CS1, CS2);
162 }
163
0 //===- ObjCARCAliasAnalysis.h - ObjC ARC Optimization -*- mode: c++ -*-----===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file declares a simple ARC-aware AliasAnalysis using special knowledge
10 /// of Objective C to enhance other optimization passes which rely on the Alias
11 /// Analysis infrastructure.
12 ///
13 /// WARNING: This file knows about certain library functions. It recognizes them
14 /// by name, and hardwires knowledge of their semantics.
15 ///
16 /// WARNING: This file knows about how certain Objective-C library functions are
17 /// used. Naive LLVM IR transformations which would otherwise be
18 /// behavior-preserving may break these assumptions.
19 ///
20 //===----------------------------------------------------------------------===//
21
22 #ifndef LLVM_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
23 #define LLVM_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
24
25 namespace llvm {
26 namespace objcarc {
27
28 /// \brief This is a simple alias analysis implementation that uses knowledge
29 /// of ARC constructs to answer queries.
30 ///
31 /// TODO: This class could be generalized to know about other ObjC-specific
32 /// tricks. Such as knowing that ivars in the non-fragile ABI are non-aliasing
33 /// even though their offsets are dynamic.
34 class ObjCARCAliasAnalysis : public ImmutablePass,
35 public AliasAnalysis {
36 public:
37 static char ID; // Class identification, replacement for typeinfo
38 ObjCARCAliasAnalysis() : ImmutablePass(ID) {
39 initializeObjCARCAliasAnalysisPass(*PassRegistry::getPassRegistry());
40 }
41
42 private:
43 virtual void initializePass() {
44 InitializeAliasAnalysis(this);
45 }
46
47 /// This method is used when a pass implements an analysis interface through
48 /// multiple inheritance. If needed, it should override this to adjust the
49 /// this pointer as needed for the specified pass info.
50 virtual void *getAdjustedAnalysisPointer(const void *PI) {
51 if (PI == &AliasAnalysis::ID)
52 return static_cast(this);
53 return this;
54 }
55
56 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
57 virtual AliasResult alias(const Location &LocA, const Location &LocB);
58 virtual bool pointsToConstantMemory(const Location &Loc, bool OrLocal);
59 virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
60 virtual ModRefBehavior getModRefBehavior(const Function *F);
61 virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
62 const Location &Loc);
63 virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
64 ImmutableCallSite CS2);
65 };
66
67 } // namespace objcarc
68 } // namespace llvm
69
70 #endif // LLVM_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
2929
3030 #define DEBUG_TYPE "objc-arc-opts"
3131 #include "ObjCARC.h"
32 #include "ObjCARCAliasAnalysis.h"
3233
3334 #include "llvm/ADT/DenseMap.h"
3435 #include "llvm/ADT/SmallPtrSet.h"
130131 /// \defgroup ARCUtilities Utility declarations/definitions specific to ARC.
131132 /// @{
132133
133 #include "llvm/Analysis/ValueTracking.h"
134134 #include "llvm/IR/Intrinsics.h"
135135 #include "llvm/Support/CallSite.h"
136136 #include "llvm/Transforms/Utils/Local.h"
259259 return IC_None;
260260 }
261261
262 /// \brief Test if the given class is objc_retain or equivalent.
263 static bool IsRetain(InstructionClass Class) {
264 return Class == IC_Retain ||
265 Class == IC_RetainRV;
266 }
267
268 /// \brief Test if the given class is objc_autorelease or equivalent.
269 static bool IsAutorelease(InstructionClass Class) {
270 return Class == IC_Autorelease ||
271 Class == IC_AutoreleaseRV;
272 }
273
274 /// \brief Test if the given class represents instructions which return their
275 /// argument verbatim.
276 static bool IsForwarding(InstructionClass Class) {
277 // objc_retainBlock technically doesn't always return its argument
278 // verbatim, but it doesn't matter for our purposes here.
279 return Class == IC_Retain ||
280 Class == IC_RetainRV ||
281 Class == IC_Autorelease ||
282 Class == IC_AutoreleaseRV ||
283 Class == IC_RetainBlock ||
284 Class == IC_NoopCast;
285 }
286
287 /// \brief Test if the given class represents instructions which do nothing if
288 /// passed a null pointer.
289 static bool IsNoopOnNull(InstructionClass Class) {
290 return Class == IC_Retain ||
291 Class == IC_RetainRV ||
292 Class == IC_Release ||
293 Class == IC_Autorelease ||
294 Class == IC_AutoreleaseRV ||
295 Class == IC_RetainBlock;
296 }
297
298 /// \brief Test if the given class represents instructions which are always safe
299 /// to mark with the "tail" keyword.
300 static bool IsAlwaysTail(InstructionClass Class) {
301 // IC_RetainBlock may be given a stack argument.
302 return Class == IC_Retain ||
303 Class == IC_RetainRV ||
304 Class == IC_AutoreleaseRV;
305 }
306
307 /// \brief Test if the given class represents instructions which are never safe
308 /// to mark with the "tail" keyword.
309 static bool IsNeverTail(InstructionClass Class) {
310 /// It is never safe to tail call objc_autorelease since by tail calling
311 /// objc_autorelease, we also tail call -[NSObject autorelease] which supports
312 /// fast autoreleasing causing our object to be potentially reclaimed from the
313 /// autorelease pool which violates the semantics of __autoreleasing types in
314 /// ARC.
315 return Class == IC_Autorelease;
316 }
317
318 /// \brief Test if the given class represents instructions which are always safe
319 /// to mark with the nounwind attribute.
320 static bool IsNoThrow(InstructionClass Class) {
321 // objc_retainBlock is not nounwind because it calls user copy constructors
322 // which could theoretically throw.
323 return Class == IC_Retain ||
324 Class == IC_RetainRV ||
325 Class == IC_Release ||
326 Class == IC_Autorelease ||
327 Class == IC_AutoreleaseRV ||
328 Class == IC_AutoreleasepoolPush ||
329 Class == IC_AutoreleasepoolPop;
330 }
331
332262 /// \brief Erase the given instruction.
333263 ///
334264 /// Many ObjC calls return their argument verbatim,
351281
352282 if (Unused)
353283 RecursivelyDeleteTriviallyDeadInstructions(OldArg);
354 }
355
356 /// \brief This is a wrapper around getUnderlyingObject which also knows how to
357 /// look through objc_retain and objc_autorelease calls, which we know to return
358 /// their argument verbatim.
359 static const Value *GetUnderlyingObjCPtr(const Value *V) {
360 for (;;) {
361 V = GetUnderlyingObject(V);
362 if (!IsForwarding(GetBasicInstructionClass(V)))
363 break;
364 V = cast(V)->getArgOperand(0);
365 }
366
367 return V;
368 }
369
370 /// \brief This is a wrapper around Value::stripPointerCasts which also knows
371 /// how to look through objc_retain and objc_autorelease calls, which we know to
372 /// return their argument verbatim.
373 static const Value *StripPointerCastsAndObjCCalls(const Value *V) {
374 for (;;) {
375 V = V->stripPointerCasts();
376 if (!IsForwarding(GetBasicInstructionClass(V)))
377 break;
378 V = cast(V)->getArgOperand(0);
379 }
380 return V;
381 }
382
383 /// \brief This is a wrapper around Value::stripPointerCasts which also knows
384 /// how to look through objc_retain and objc_autorelease calls, which we know to
385 /// return their argument verbatim.
386 static Value *StripPointerCastsAndObjCCalls(Value *V) {
387 for (;;) {
388 V = V->stripPointerCasts();
389 if (!IsForwarding(GetBasicInstructionClass(V)))
390 break;
391 V = cast(V)->getArgOperand(0);
392 }
393 return V;
394284 }
395285
396286 /// \brief Assuming the given instruction is one of the special calls such as
548438 // No escapes found.
549439 DEBUG(dbgs() << "DoesObjCBlockEscape: Block does not escape.\n");
550440 return false;
551 }
552
553 /// @}
554 ///
555 /// \defgroup ARCAA Extends alias analysis using ObjC specific knowledge.
556 /// @{
557
558 namespace {
559 /// \brief This is a simple alias analysis implementation that uses knowledge
560 /// of ARC constructs to answer queries.
561 ///
562 /// TODO: This class could be generalized to know about other ObjC-specific
563 /// tricks. Such as knowing that ivars in the non-fragile ABI are non-aliasing
564 /// even though their offsets are dynamic.
565 class ObjCARCAliasAnalysis : public ImmutablePass,
566 public AliasAnalysis {
567 public:
568 static char ID; // Class identification, replacement for typeinfo
569 ObjCARCAliasAnalysis() : ImmutablePass(ID) {
570 initializeObjCARCAliasAnalysisPass(*PassRegistry::getPassRegistry());
571 }
572
573 private:
574 virtual void initializePass() {
575 InitializeAliasAnalysis(this);
576 }
577
578 /// This method is used when a pass implements an analysis interface through
579 /// multiple inheritance. If needed, it should override this to adjust the
580 /// this pointer as needed for the specified pass info.
581 virtual void *getAdjustedAnalysisPointer(const void *PI) {
582 if (PI == &AliasAnalysis::ID)
583 return static_cast(this);
584 return this;
585 }
586
587 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
588 virtual AliasResult alias(const Location &LocA, const Location &LocB);
589 virtual bool pointsToConstantMemory(const Location &Loc, bool OrLocal);
590 virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
591 virtual ModRefBehavior getModRefBehavior(const Function *F);
592 virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
593 const Location &Loc);
594 virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
595 ImmutableCallSite CS2);
596 };
597 } // End of anonymous namespace
598
599 // Register this pass...
600 char ObjCARCAliasAnalysis::ID = 0;
601 INITIALIZE_AG_PASS(ObjCARCAliasAnalysis, AliasAnalysis, "objc-arc-aa",
602 "ObjC-ARC-Based Alias Analysis", false, true, false)
603
604 ImmutablePass *llvm::createObjCARCAliasAnalysisPass() {
605 return new ObjCARCAliasAnalysis();
606 }
607
608 void
609 ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
610 AU.setPreservesAll();
611 AliasAnalysis::getAnalysisUsage(AU);
612 }
613
614 AliasAnalysis::AliasResult
615 ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) {
616 if (!EnableARCOpts)
617 return AliasAnalysis::alias(LocA, LocB);
618
619 // First, strip off no-ops, including ObjC-specific no-ops, and try making a
620 // precise alias query.
621 const Value *SA = StripPointerCastsAndObjCCalls(LocA.Ptr);
622 const Value *SB = StripPointerCastsAndObjCCalls(LocB.Ptr);
623 AliasResult Result =
624 AliasAnalysis::alias(Location(SA, LocA.Size, LocA.TBAATag),
625 Location(SB, LocB.Size, LocB.TBAATag));
626 if (Result != MayAlias)
627 return Result;
628
629 // If that failed, climb to the underlying object, including climbing through
630 // ObjC-specific no-ops, and try making an imprecise alias query.
631 const Value *UA = GetUnderlyingObjCPtr(SA);
632 const Value *UB = GetUnderlyingObjCPtr(SB);
633 if (UA != SA || UB != SB) {
634 Result = AliasAnalysis::alias(Location(UA), Location(UB));
635 // We can't use MustAlias or PartialAlias results here because
636 // GetUnderlyingObjCPtr may return an offsetted pointer value.
637 if (Result == NoAlias)
638 return NoAlias;
639 }
640
641 // If that failed, fail. We don't need to chain here, since that's covered
642 // by the earlier precise query.
643 return MayAlias;
644 }
645
646 bool
647 ObjCARCAliasAnalysis::pointsToConstantMemory(const Location &Loc,
648 bool OrLocal) {
649 if (!EnableARCOpts)
650 return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
651
652 // First, strip off no-ops, including ObjC-specific no-ops, and try making
653 // a precise alias query.
654 const Value *S = StripPointerCastsAndObjCCalls(Loc.Ptr);
655 if (AliasAnalysis::pointsToConstantMemory(Location(S, Loc.Size, Loc.TBAATag),
656 OrLocal))
657 return true;
658
659 // If that failed, climb to the underlying object, including climbing through
660 // ObjC-specific no-ops, and try making an imprecise alias query.
661 const Value *U = GetUnderlyingObjCPtr(S);
662 if (U != S)
663 return AliasAnalysis::pointsToConstantMemory(Location(U), OrLocal);
664
665 // If that failed, fail. We don't need to chain here, since that's covered
666 // by the earlier precise query.
667 return false;
668 }
669
670 AliasAnalysis::ModRefBehavior
671 ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
672 // We have nothing to do. Just chain to the next AliasAnalysis.
673 return AliasAnalysis::getModRefBehavior(CS);
674 }
675
676 AliasAnalysis::ModRefBehavior
677 ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
678 if (!EnableARCOpts)
679 return AliasAnalysis::getModRefBehavior(F);
680
681 switch (GetFunctionClass(F)) {
682 case IC_NoopCast:
683 return DoesNotAccessMemory;
684 default:
685 break;
686 }
687
688 return AliasAnalysis::getModRefBehavior(F);
689 }
690
691 AliasAnalysis::ModRefResult
692 ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) {
693 if (!EnableARCOpts)
694 return AliasAnalysis::getModRefInfo(CS, Loc);
695
696 switch (GetBasicInstructionClass(CS.getInstruction())) {
697 case IC_Retain:
698 case IC_RetainRV:
699 case IC_Autorelease:
700 case IC_AutoreleaseRV:
701 case IC_NoopCast:
702 case IC_AutoreleasepoolPush:
703 case IC_FusedRetainAutorelease:
704 case IC_FusedRetainAutoreleaseRV:
705 // These functions don't access any memory visible to the compiler.
706 // Note that this doesn't include objc_retainBlock, because it updates
707 // pointers when it copies block data.
708 return NoModRef;
709 default:
710 break;
711 }
712
713 return AliasAnalysis::getModRefInfo(CS, Loc);
714 }
715
716 AliasAnalysis::ModRefResult
717 ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
718 ImmutableCallSite CS2) {
719 // TODO: Theoretically we could check for dependencies between objc_* calls
720 // and OnlyAccessesArgumentPointees calls or other well-behaved calls.
721 return AliasAnalysis::getModRefInfo(CS1, CS2);
722441 }
723442
724443 /// @}