Coverage Report

Created: 2018-07-12 09:57

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
Line
Count
Source (jump to first uncovered line)
1
//===- ObjCARCAnalysisUtils.h - ObjC ARC Analysis Utilities -----*- C++ -*-===//
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 common analysis utilities used by the ObjC ARC Optimizer.
11
/// ARC stands for Automatic Reference Counting and is a system for managing
12
/// reference counts for objects in Objective C.
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
//===----------------------------------------------------------------------===//
22
23
#ifndef LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
24
#define LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
25
26
#include "llvm/ADT/Optional.h"
27
#include "llvm/ADT/StringSwitch.h"
28
#include "llvm/Analysis/AliasAnalysis.h"
29
#include "llvm/Analysis/ObjCARCInstKind.h"
30
#include "llvm/Analysis/Passes.h"
31
#include "llvm/Analysis/ValueTracking.h"
32
#include "llvm/IR/CallSite.h"
33
#include "llvm/IR/Constants.h"
34
#include "llvm/IR/InstIterator.h"
35
#include "llvm/IR/LLVMContext.h"
36
#include "llvm/IR/Module.h"
37
#include "llvm/IR/ValueHandle.h"
38
#include "llvm/Pass.h"
39
40
namespace llvm {
41
class raw_ostream;
42
}
43
44
namespace llvm {
45
namespace objcarc {
46
47
/// A handy option to enable/disable all ARC Optimizations.
48
extern bool EnableARCOpts;
49
50
/// Test if the given module looks interesting to run ARC optimization
51
/// on.
52
12.1k
inline bool ModuleHasARC(const Module &M) {
53
12.1k
  return
54
12.1k
    M.getNamedValue("objc_retain") ||
55
12.1k
    
M.getNamedValue("objc_release")12.1k
||
56
12.1k
    
M.getNamedValue("objc_autorelease")12.1k
||
57
12.1k
    
M.getNamedValue("objc_retainAutoreleasedReturnValue")12.1k
||
58
12.1k
    
M.getNamedValue("objc_unsafeClaimAutoreleasedReturnValue")12.1k
||
59
12.1k
    
M.getNamedValue("objc_retainBlock")12.1k
||
60
12.1k
    
M.getNamedValue("objc_autoreleaseReturnValue")12.1k
||
61
12.1k
    
M.getNamedValue("objc_autoreleasePoolPush")12.1k
||
62
12.1k
    
M.getNamedValue("objc_loadWeakRetained")12.1k
||
63
12.1k
    
M.getNamedValue("objc_loadWeak")12.1k
||
64
12.1k
    
M.getNamedValue("objc_destroyWeak")12.1k
||
65
12.1k
    
M.getNamedValue("objc_storeWeak")12.1k
||
66
12.1k
    
M.getNamedValue("objc_initWeak")12.1k
||
67
12.1k
    
M.getNamedValue("objc_moveWeak")12.1k
||
68
12.1k
    
M.getNamedValue("objc_copyWeak")12.1k
||
69
12.1k
    
M.getNamedValue("objc_retainedObject")12.1k
||
70
12.1k
    
M.getNamedValue("objc_unretainedObject")12.1k
||
71
12.1k
    
M.getNamedValue("objc_unretainedPointer")12.1k
||
72
12.1k
    
M.getNamedValue("clang.arc.use")12.1k
;
73
12.1k
}
74
75
/// This is a wrapper around getUnderlyingObject which also knows how to
76
/// look through objc_retain and objc_autorelease calls, which we know to return
77
/// their argument verbatim.
78
inline const Value *GetUnderlyingObjCPtr(const Value *V,
79
4.45k
                                                const DataLayout &DL) {
80
4.51k
  for (;;) {
81
4.51k
    V = GetUnderlyingObject(V, DL);
82
4.51k
    if (!IsForwarding(GetBasicARCInstKind(V)))
83
4.45k
      break;
84
59
    V = cast<CallInst>(V)->getArgOperand(0);
85
59
  }
86
4.45k
87
4.45k
  return V;
88
4.45k
}
89
90
/// A wrapper for GetUnderlyingObjCPtr used for results memoization.
91
inline const Value *
92
GetUnderlyingObjCPtrCached(const Value *V, const DataLayout &DL,
93
2.77k
                           DenseMap<const Value *, WeakTrackingVH> &Cache) {
94
2.77k
  if (auto InCache = Cache.lookup(V))
95
2.24k
    return InCache;
96
522
97
522
  const Value *Computed = GetUnderlyingObjCPtr(V, DL);
98
522
  Cache[V] = const_cast<Value *>(Computed);
99
522
  return Computed;
100
522
}
101
102
/// The RCIdentity root of a value \p V is a dominating value U for which
103
/// retaining or releasing U is equivalent to retaining or releasing V. In other
104
/// words, ARC operations on \p V are equivalent to ARC operations on \p U.
105
///
106
/// We use this in the ARC optimizer to make it easier to match up ARC
107
/// operations by always mapping ARC operations to RCIdentityRoots instead of
108
/// pointers themselves.
109
///
110
/// The two ways that we see RCIdentical values in ObjC are via:
111
///
112
///   1. PointerCasts
113
///   2. Forwarding Calls that return their argument verbatim.
114
///
115
/// Thus this function strips off pointer casts and forwarding calls. *NOTE*
116
/// This implies that two RCIdentical values must alias.
117
6.82k
inline const Value *GetRCIdentityRoot(const Value *V) {
118
7.29k
  for (;;) {
119
7.29k
    V = V->stripPointerCasts();
120
7.29k
    if (!IsForwarding(GetBasicARCInstKind(V)))
121
6.82k
      break;
122
474
    V = cast<CallInst>(V)->getArgOperand(0);
123
474
  }
124
6.82k
  return V;
125
6.82k
}
126
127
/// Helper which calls const Value *GetRCIdentityRoot(const Value *V) and just
128
/// casts away the const of the result. For documentation about what an
129
/// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that
130
/// function.
131
2.52k
inline Value *GetRCIdentityRoot(Value *V) {
132
2.52k
  return const_cast<Value *>(GetRCIdentityRoot((const Value *)V));
133
2.52k
}
134
135
/// Assuming the given instruction is one of the special calls such as
136
/// objc_retain or objc_release, return the RCIdentity root of the argument of
137
/// the call.
138
2.40k
inline Value *GetArgRCIdentityRoot(Value *Inst) {
139
2.40k
  return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0));
140
2.40k
}
141
142
857
inline bool IsNullOrUndef(const Value *V) {
143
857
  return isa<ConstantPointerNull>(V) || 
isa<UndefValue>(V)803
;
144
857
}
145
146
70
inline bool IsNoopInstruction(const Instruction *I) {
147
70
  return isa<BitCastInst>(I) ||
148
70
    
(56
isa<GetElementPtrInst>(I)56
&&
149
56
     
cast<GetElementPtrInst>(I)->hasAllZeroIndices()0
);
150
70
}
151
152
/// Test whether the given value is possible a retainable object pointer.
153
4.16k
inline bool IsPotentialRetainableObjPtr(const Value *Op) {
154
4.16k
  // Pointers to static or stack storage are not valid retainable object
155
4.16k
  // pointers.
156
4.16k
  if (isa<Constant>(Op) || 
isa<AllocaInst>(Op)2.42k
)
157
1.84k
    return false;
158
2.32k
  // Special arguments can not be a valid retainable object pointer.
159
2.32k
  if (const Argument *Arg = dyn_cast<Argument>(Op))
160
575
    if (Arg->hasByValAttr() ||
161
575
        Arg->hasInAllocaAttr() ||
162
575
        Arg->hasNestAttr() ||
163
575
        Arg->hasStructRetAttr())
164
0
      return false;
165
2.32k
  // Only consider values with pointer types.
166
2.32k
  //
167
2.32k
  // It seemes intuitive to exclude function pointer types as well, since
168
2.32k
  // functions are never retainable object pointers, however clang occasionally
169
2.32k
  // bitcasts retainable object pointers to function-pointer type temporarily.
170
2.32k
  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
171
2.32k
  if (!Ty)
172
134
    return false;
173
2.18k
  // Conservatively assume anything else is a potential retainable object
174
2.18k
  // pointer.
175
2.18k
  return true;
176
2.18k
}
177
178
inline bool IsPotentialRetainableObjPtr(const Value *Op,
179
1.05k
                                               AliasAnalysis &AA) {
180
1.05k
  // First make the rudimentary check.
181
1.05k
  if (!IsPotentialRetainableObjPtr(Op))
182
125
    return false;
183
934
184
934
  // Objects in constant memory are not reference-counted.
185
934
  if (AA.pointsToConstantMemory(Op))
186
0
    return false;
187
934
188
934
  // Pointers in constant memory are not pointing to reference-counted objects.
189
934
  if (const LoadInst *LI = dyn_cast<LoadInst>(Op))
190
206
    if (AA.pointsToConstantMemory(LI->getPointerOperand()))
191
17
      return false;
192
917
193
917
  // Otherwise assume the worst.
194
917
  return true;
195
917
}
196
197
/// Helper for GetARCInstKind. Determines what kind of construct CS
198
/// is.
199
1.10k
inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) {
200
1.10k
  for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
201
2.12k
       I != E; 
++I1.01k
)
202
1.53k
    if (IsPotentialRetainableObjPtr(*I))
203
520
      return CS.onlyReadsMemory() ? 
ARCInstKind::User1
:
ARCInstKind::CallOrUser519
;
204
1.10k
205
1.10k
  
return CS.onlyReadsMemory() 585
?
ARCInstKind::None0
:
ARCInstKind::Call585
;
206
1.10k
}
207
208
/// Return true if this value refers to a distinct and identifiable
209
/// object.
210
///
211
/// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
212
/// special knowledge of ObjC conventions.
213
1.29k
inline bool IsObjCIdentifiedObject(const Value *V) {
214
1.29k
  // Assume that call results and arguments have their own "provenance".
215
1.29k
  // Constants (including GlobalVariables) and Allocas are never
216
1.29k
  // reference-counted.
217
1.29k
  if (isa<CallInst>(V) || 
isa<InvokeInst>(V)980
||
218
1.29k
      
isa<Argument>(V)974
||
isa<Constant>(V)744
||
219
1.29k
      
isa<AllocaInst>(V)618
)
220
707
    return true;
221
586
222
586
  if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
223
420
    const Value *Pointer =
224
420
      GetRCIdentityRoot(LI->getPointerOperand());
225
420
    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
226
264
      // A constant pointer can't be pointing to an object on the heap. It may
227
264
      // be reference-counted, but it won't be deleted.
228
264
      if (GV->isConstant())
229
4
        return true;
230
260
      StringRef Name = GV->getName();
231
260
      // These special variables are known to hold values which are not
232
260
      // reference-counted pointers.
233
260
      if (Name.startswith("\01l_objc_msgSend_fixup_"))
234
18
        return true;
235
242
236
242
      StringRef Section = GV->getSection();
237
242
      if (Section.find("__message_refs") != StringRef::npos ||
238
242
          
Section.find("__objc_classrefs") != StringRef::npos224
||
239
242
          
Section.find("__objc_superrefs") != StringRef::npos159
||
240
242
          
Section.find("__objc_methname") != StringRef::npos141
||
241
242
          
Section.find("__cstring") != StringRef::npos123
)
242
137
        return true;
243
427
    }
244
420
  }
245
427
246
427
  return false;
247
427
}
248
249
enum class ARCMDKindID {
250
  ImpreciseRelease,
251
  CopyOnEscape,
252
  NoObjCARCExceptions,
253
};
254
255
/// A cache of MDKinds used by various ARC optimizations.
256
class ARCMDKindCache {
257
  Module *M;
258
259
  /// The Metadata Kind for clang.imprecise_release metadata.
260
  llvm::Optional<unsigned> ImpreciseReleaseMDKind;
261
262
  /// The Metadata Kind for clang.arc.copy_on_escape metadata.
263
  llvm::Optional<unsigned> CopyOnEscapeMDKind;
264
265
  /// The Metadata Kind for clang.arc.no_objc_arc_exceptions metadata.
266
  llvm::Optional<unsigned> NoObjCARCExceptionsMDKind;
267
268
public:
269
30
  void init(Module *Mod) {
270
30
    M = Mod;
271
30
    ImpreciseReleaseMDKind = NoneType::None;
272
30
    CopyOnEscapeMDKind = NoneType::None;
273
30
    NoObjCARCExceptionsMDKind = NoneType::None;
274
30
  }
275
276
1.16k
  unsigned get(ARCMDKindID ID) {
277
1.16k
    switch (ID) {
278
1.16k
    case ARCMDKindID::ImpreciseRelease:
279
973
      if (!ImpreciseReleaseMDKind)
280
27
        ImpreciseReleaseMDKind =
281
27
            M->getContext().getMDKindID("clang.imprecise_release");
282
973
      return *ImpreciseReleaseMDKind;
283
1.16k
    case ARCMDKindID::CopyOnEscape:
284
0
      if (!CopyOnEscapeMDKind)
285
0
        CopyOnEscapeMDKind =
286
0
            M->getContext().getMDKindID("clang.arc.copy_on_escape");
287
0
      return *CopyOnEscapeMDKind;
288
1.16k
    case ARCMDKindID::NoObjCARCExceptions:
289
195
      if (!NoObjCARCExceptionsMDKind)
290
24
        NoObjCARCExceptionsMDKind =
291
24
            M->getContext().getMDKindID("clang.arc.no_objc_arc_exceptions");
292
195
      return *NoObjCARCExceptionsMDKind;
293
0
    }
294
0
    llvm_unreachable("Covered switch isn't covered?!");
295
0
  }
296
};
297
298
} // end namespace objcarc
299
} // end namespace llvm
300
301
#endif