LLVM  8.0.1
ObjCARCAliasAnalysis.cpp
Go to the documentation of this file.
1 //===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
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.
13 ///
14 /// WARNING: This file knows about certain library functions. It recognizes them
15 /// by name, and hardwires knowledge of their semantics.
16 ///
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.
20 ///
21 /// TODO: Theoretically we could check for dependencies between objc_* calls
22 /// and FMRB_OnlyAccessesArgumentPointees calls or other well-behaved calls.
23 ///
24 //===----------------------------------------------------------------------===//
25 
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/Instruction.h"
30 #include "llvm/IR/Value.h"
31 #include "llvm/InitializePasses.h"
33 #include "llvm/PassSupport.h"
34 
35 #define DEBUG_TYPE "objc-arc-aa"
36 
37 using namespace llvm;
38 using namespace llvm::objcarc;
39 
41  const MemoryLocation &LocB) {
42  if (!EnableARCOpts)
43  return AAResultBase::alias(LocA, LocB);
44 
45  // First, strip off no-ops, including ObjC-specific no-ops, and try making a
46  // precise alias query.
47  const Value *SA = GetRCIdentityRoot(LocA.Ptr);
48  const Value *SB = GetRCIdentityRoot(LocB.Ptr);
49  AliasResult Result =
51  MemoryLocation(SB, LocB.Size, LocB.AATags));
52  if (Result != MayAlias)
53  return Result;
54 
55  // If that failed, climb to the underlying object, including climbing through
56  // ObjC-specific no-ops, and try making an imprecise alias query.
57  const Value *UA = GetUnderlyingObjCPtr(SA, DL);
58  const Value *UB = GetUnderlyingObjCPtr(SB, DL);
59  if (UA != SA || UB != SB) {
61  // We can't use MustAlias or PartialAlias results here because
62  // GetUnderlyingObjCPtr may return an offsetted pointer value.
63  if (Result == NoAlias)
64  return NoAlias;
65  }
66 
67  // If that failed, fail. We don't need to chain here, since that's covered
68  // by the earlier precise query.
69  return MayAlias;
70 }
71 
73  bool OrLocal) {
74  if (!EnableARCOpts)
75  return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
76 
77  // First, strip off no-ops, including ObjC-specific no-ops, and try making
78  // a precise alias query.
79  const Value *S = GetRCIdentityRoot(Loc.Ptr);
81  MemoryLocation(S, Loc.Size, Loc.AATags), OrLocal))
82  return true;
83 
84  // If that failed, climb to the underlying object, including climbing through
85  // ObjC-specific no-ops, and try making an imprecise alias query.
86  const Value *U = GetUnderlyingObjCPtr(S, DL);
87  if (U != S)
89 
90  // If that failed, fail. We don't need to chain here, since that's covered
91  // by the earlier precise query.
92  return false;
93 }
94 
96  if (!EnableARCOpts)
98 
99  switch (GetFunctionClass(F)) {
102  default:
103  break;
104  }
105 
107 }
108 
110  const MemoryLocation &Loc) {
111  if (!EnableARCOpts)
112  return AAResultBase::getModRefInfo(Call, Loc);
113 
114  switch (GetBasicARCInstKind(Call)) {
115  case ARCInstKind::Retain:
123  // These functions don't access any memory visible to the compiler.
124  // Note that this doesn't include objc_retainBlock, because it updates
125  // pointers when it copies block data.
126  return ModRefInfo::NoModRef;
127  default:
128  break;
129  }
130 
131  return AAResultBase::getModRefInfo(Call, Loc);
132 }
133 
135  return ObjCARCAAResult(F.getParent()->getDataLayout());
136 }
137 
138 char ObjCARCAAWrapperPass::ID = 0;
140  "ObjC-ARC-Based Alias Analysis", false, true)
141 
143  return new ObjCARCAAWrapperPass();
144 }
145 
148 }
149 
151  Result.reset(new ObjCARCAAResult(M.getDataLayout()));
152  return false;
153 }
154 
156  Result.reset();
157  return false;
158 }
159 
161  AU.setPreservesAll();
162 }
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal)
The access neither references nor modifies the value stored in memory.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal)
ObjCARCAAResult run(Function &F, FunctionAnalysisManager &AM)
objc_retainedObject, etc.
The two locations do not alias at all.
Definition: AliasAnalysis.h:84
FunctionModRefBehavior getModRefBehavior(const CallBase *Call)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1014
F(f)
could call objc_release
objc_autoreleaseReturnValue
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:371
bool doFinalization(Module &M) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
objc_retainAutoreleasedReturnValue
FunctionModRefBehavior
Summary of how a function affects memory in the program.
bool EnableARCOpts
A handy option to enable/disable all ARC Optimizations.
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
FunctionModRefBehavior getModRefBehavior(const Function *F)
AliasResult
The possible results of an alias query.
Definition: AliasAnalysis.h:78
Represent the analysis usage information of a pass.
ARCInstKind GetFunctionClass(const Function *F)
Determine if F is one of the special known Functions.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known...
This file defines common analysis utilities used by the ObjC ARC Optimizer.
This file declares a simple ARC-aware AliasAnalysis using special knowledge of Objective C to enhance...
This function does not perform any non-local loads or stores to memory.
ARCInstKind GetBasicARCInstKind(const Value *V)
Determine which objc runtime call instruction class V belongs to.
The two locations may or may not alias. This is the least precise result.
Definition: AliasAnalysis.h:86
const Value * Ptr
The address of the start of the location.
Representation for a specific memory location.
ImmutablePass class - This class is used to provide information that does not need to be run...
Definition: Pass.h:256
bool doInitialization(Module &M) override
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
void initializeObjCARCAAWrapperPassPass(PassRegistry &)
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
void setPreservesAll()
Set by analyses that do not transform their input at all.
This is a simple alias analysis implementation that uses knowledge of ARC constructs to answer querie...
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc)
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
const Value * GetUnderlyingObjCPtr(const Value *V, const DataLayout &DL)
This is a wrapper around getUnderlyingObject which also knows how to look through objc_retain and obj...
ObjCARCAAResult(const DataLayout &DL)
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc)
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:566
LLVM Value Representation.
Definition: Value.h:73
Legacy wrapper pass to provide the ObjCARCAAResult object.
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
const Value * GetRCIdentityRoot(const Value *V)
The RCIdentity root of a value V is a dominating value U for which retaining or releasing U is equiva...
A container for analyses that lazily runs them and caches their results.
INITIALIZE_PASS(ObjCARCAAWrapperPass, "objc-arc-aa", "ObjC-ARC-Based Alias Analysis", false, true) ImmutablePass *llvm
ImmutablePass * createObjCARCAAWrapperPass()
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...