1 //===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -*- mode: c++ -*---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file defines a simple ARC-aware AliasAnalysis using special knowledge
11 /// of Objective C to enhance other optimization passes which rely on the Alias
12 /// Analysis infrastructure.
14 /// WARNING: This file knows about certain library functions. It recognizes them
15 /// by name, and hardwires knowledge of their semantics.
17 /// WARNING: This file knows about how certain Objective-C library functions are
18 /// used. Naive LLVM IR transformations which would otherwise be
19 /// behavior-preserving may break these assumptions.
21 //===----------------------------------------------------------------------===//
23 #define DEBUG_TYPE "objc-arc-aa"
25 #include "ObjCARCAliasAnalysis.h"
26 #include "llvm/IR/Instruction.h"
27 #include "llvm/InitializePasses.h"
28 #include "llvm/PassAnalysisSupport.h"
29 #include "llvm/PassSupport.h"
37 using namespace llvm::objcarc;
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)
44 ImmutablePass *llvm::createObjCARCAliasAnalysisPass() {
45 return new ObjCARCAliasAnalysis();
49 ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
51 AliasAnalysis::getAnalysisUsage(AU);
54 AliasAnalysis::AliasResult
55 ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) {
57 return AliasAnalysis::alias(LocA, LocB);
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);
64 AliasAnalysis::alias(Location(SA, LocA.Size, LocA.TBAATag),
65 Location(SB, LocB.Size, LocB.TBAATag));
66 if (Result != MayAlias)
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)
81 // If that failed, fail. We don't need to chain here, since that's covered
82 // by the earlier precise query.
87 ObjCARCAliasAnalysis::pointsToConstantMemory(const Location &Loc,
90 return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
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),
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);
103 return AliasAnalysis::pointsToConstantMemory(Location(U), OrLocal);
105 // If that failed, fail. We don't need to chain here, since that's covered
106 // by the earlier precise query.
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);
116 AliasAnalysis::ModRefBehavior
117 ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
119 return AliasAnalysis::getModRefBehavior(F);
121 switch (GetFunctionClass(F)) {
123 return DoesNotAccessMemory;
128 return AliasAnalysis::getModRefBehavior(F);
131 AliasAnalysis::ModRefResult
132 ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) {
134 return AliasAnalysis::getModRefInfo(CS, Loc);
136 switch (GetBasicInstructionClass(CS.getInstruction())) {
140 case IC_AutoreleaseRV:
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.
153 return AliasAnalysis::getModRefInfo(CS, Loc);
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);