Coverage Report

Created: 2019-07-24 05:18

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