Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Analysis/ObjCARCInstKind.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===//
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 several utility functions used by various ARC
10
/// optimizations which are IMHO too big to be in a header file.
11
///
12
/// WARNING: This file knows about certain library functions. It recognizes them
13
/// by name, and hardwires knowledge of their semantics.
14
///
15
/// WARNING: This file knows about how certain Objective-C library functions are
16
/// used. Naive LLVM IR transformations which would otherwise be
17
/// behavior-preserving may break these assumptions.
18
///
19
//===----------------------------------------------------------------------===//
20
21
#include "llvm/Analysis/ObjCARCInstKind.h"
22
#include "llvm/ADT/StringSwitch.h"
23
#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
24
#include "llvm/IR/Intrinsics.h"
25
26
using namespace llvm;
27
using namespace llvm::objcarc;
28
29
raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
30
0
                                       const ARCInstKind Class) {
31
0
  switch (Class) {
32
0
  case ARCInstKind::Retain:
33
0
    return OS << "ARCInstKind::Retain";
34
0
  case ARCInstKind::RetainRV:
35
0
    return OS << "ARCInstKind::RetainRV";
36
0
  case ARCInstKind::ClaimRV:
37
0
    return OS << "ARCInstKind::ClaimRV";
38
0
  case ARCInstKind::RetainBlock:
39
0
    return OS << "ARCInstKind::RetainBlock";
40
0
  case ARCInstKind::Release:
41
0
    return OS << "ARCInstKind::Release";
42
0
  case ARCInstKind::Autorelease:
43
0
    return OS << "ARCInstKind::Autorelease";
44
0
  case ARCInstKind::AutoreleaseRV:
45
0
    return OS << "ARCInstKind::AutoreleaseRV";
46
0
  case ARCInstKind::AutoreleasepoolPush:
47
0
    return OS << "ARCInstKind::AutoreleasepoolPush";
48
0
  case ARCInstKind::AutoreleasepoolPop:
49
0
    return OS << "ARCInstKind::AutoreleasepoolPop";
50
0
  case ARCInstKind::NoopCast:
51
0
    return OS << "ARCInstKind::NoopCast";
52
0
  case ARCInstKind::FusedRetainAutorelease:
53
0
    return OS << "ARCInstKind::FusedRetainAutorelease";
54
0
  case ARCInstKind::FusedRetainAutoreleaseRV:
55
0
    return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
56
0
  case ARCInstKind::LoadWeakRetained:
57
0
    return OS << "ARCInstKind::LoadWeakRetained";
58
0
  case ARCInstKind::StoreWeak:
59
0
    return OS << "ARCInstKind::StoreWeak";
60
0
  case ARCInstKind::InitWeak:
61
0
    return OS << "ARCInstKind::InitWeak";
62
0
  case ARCInstKind::LoadWeak:
63
0
    return OS << "ARCInstKind::LoadWeak";
64
0
  case ARCInstKind::MoveWeak:
65
0
    return OS << "ARCInstKind::MoveWeak";
66
0
  case ARCInstKind::CopyWeak:
67
0
    return OS << "ARCInstKind::CopyWeak";
68
0
  case ARCInstKind::DestroyWeak:
69
0
    return OS << "ARCInstKind::DestroyWeak";
70
0
  case ARCInstKind::StoreStrong:
71
0
    return OS << "ARCInstKind::StoreStrong";
72
0
  case ARCInstKind::CallOrUser:
73
0
    return OS << "ARCInstKind::CallOrUser";
74
0
  case ARCInstKind::Call:
75
0
    return OS << "ARCInstKind::Call";
76
0
  case ARCInstKind::User:
77
0
    return OS << "ARCInstKind::User";
78
0
  case ARCInstKind::IntrinsicUser:
79
0
    return OS << "ARCInstKind::IntrinsicUser";
80
0
  case ARCInstKind::None:
81
0
    return OS << "ARCInstKind::None";
82
0
  }
83
0
  llvm_unreachable("Unknown instruction class!");
84
0
}
85
86
11.9k
ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) {
87
11.9k
88
11.9k
  Intrinsic::ID ID = F->getIntrinsicID();
89
11.9k
  switch (ID) {
90
11.9k
  default:
91
5.35k
    return ARCInstKind::CallOrUser;
92
11.9k
  case Intrinsic::objc_autorelease:
93
95
    return ARCInstKind::Autorelease;
94
11.9k
  case Intrinsic::objc_autoreleasePoolPop:
95
22
    return ARCInstKind::AutoreleasepoolPop;
96
11.9k
  case Intrinsic::objc_autoreleasePoolPush:
97
36
    return ARCInstKind::AutoreleasepoolPush;
98
11.9k
  case Intrinsic::objc_autoreleaseReturnValue:
99
90
    return ARCInstKind::AutoreleaseRV;
100
11.9k
  case Intrinsic::objc_copyWeak:
101
62
    return ARCInstKind::CopyWeak;
102
11.9k
  case Intrinsic::objc_destroyWeak:
103
235
    return ARCInstKind::DestroyWeak;
104
11.9k
  case Intrinsic::objc_initWeak:
105
110
    return ARCInstKind::InitWeak;
106
11.9k
  case Intrinsic::objc_loadWeak:
107
36
    return ARCInstKind::LoadWeak;
108
11.9k
  case Intrinsic::objc_loadWeakRetained:
109
23
    return ARCInstKind::LoadWeakRetained;
110
11.9k
  case Intrinsic::objc_moveWeak:
111
4
    return ARCInstKind::MoveWeak;
112
11.9k
  case Intrinsic::objc_release:
113
2.72k
    return ARCInstKind::Release;
114
11.9k
  case Intrinsic::objc_retain:
115
2.06k
    return ARCInstKind::Retain;
116
11.9k
  case Intrinsic::objc_retainAutorelease:
117
2
    return ARCInstKind::FusedRetainAutorelease;
118
11.9k
  case Intrinsic::objc_retainAutoreleaseReturnValue:
119
1
    return ARCInstKind::FusedRetainAutoreleaseRV;
120
11.9k
  case Intrinsic::objc_retainAutoreleasedReturnValue:
121
434
    return ARCInstKind::RetainRV;
122
11.9k
  case Intrinsic::objc_retainBlock:
123
519
    return ARCInstKind::RetainBlock;
124
11.9k
  case Intrinsic::objc_storeStrong:
125
3
    return ARCInstKind::StoreStrong;
126
11.9k
  case Intrinsic::objc_storeWeak:
127
22
    return ARCInstKind::StoreWeak;
128
11.9k
  case Intrinsic::objc_clang_arc_use:
129
51
    return ARCInstKind::IntrinsicUser;
130
11.9k
  case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
131
10
    return ARCInstKind::ClaimRV;
132
11.9k
  case Intrinsic::objc_retainedObject:
133
1
    return ARCInstKind::NoopCast;
134
11.9k
  case Intrinsic::objc_unretainedObject:
135
2
    return ARCInstKind::NoopCast;
136
11.9k
  case Intrinsic::objc_unretainedPointer:
137
1
    return ARCInstKind::NoopCast;
138
11.9k
  case Intrinsic::objc_retain_autorelease:
139
0
    return ARCInstKind::FusedRetainAutorelease;
140
11.9k
  case Intrinsic::objc_sync_enter:
141
7
    return ARCInstKind::User;
142
11.9k
  case Intrinsic::objc_sync_exit:
143
5
    return ARCInstKind::User;
144
11.9k
  case Intrinsic::objc_arc_annotation_topdown_bbstart:
145
0
  case Intrinsic::objc_arc_annotation_topdown_bbend:
146
0
  case Intrinsic::objc_arc_annotation_bottomup_bbstart:
147
0
  case Intrinsic::objc_arc_annotation_bottomup_bbend:
148
0
    // Ignore annotation calls. This is important to stop the
149
0
    // optimizer from treating annotations as uses which would
150
0
    // make the state of the pointers they are attempting to
151
0
    // elucidate to be incorrect.
152
0
    return ARCInstKind::None;
153
11.9k
  }
154
11.9k
}
155
156
// A whitelist of intrinsics that we know do not use objc pointers or decrement
157
// ref counts.
158
696
static bool isInertIntrinsic(unsigned ID) {
159
696
  // TODO: Make this into a covered switch.
160
696
  switch (ID) {
161
696
  case Intrinsic::returnaddress:
162
44
  case Intrinsic::addressofreturnaddress:
163
44
  case Intrinsic::frameaddress:
164
44
  case Intrinsic::stacksave:
165
44
  case Intrinsic::stackrestore:
166
44
  case Intrinsic::vastart:
167
44
  case Intrinsic::vacopy:
168
44
  case Intrinsic::vaend:
169
44
  case Intrinsic::objectsize:
170
44
  case Intrinsic::prefetch:
171
44
  case Intrinsic::stackprotector:
172
44
  case Intrinsic::eh_return_i32:
173
44
  case Intrinsic::eh_return_i64:
174
44
  case Intrinsic::eh_typeid_for:
175
44
  case Intrinsic::eh_dwarf_cfa:
176
44
  case Intrinsic::eh_sjlj_lsda:
177
44
  case Intrinsic::eh_sjlj_functioncontext:
178
44
  case Intrinsic::init_trampoline:
179
44
  case Intrinsic::adjust_trampoline:
180
44
  case Intrinsic::lifetime_start:
181
44
  case Intrinsic::lifetime_end:
182
44
  case Intrinsic::invariant_start:
183
44
  case Intrinsic::invariant_end:
184
44
  // Don't let dbg info affect our results.
185
44
  case Intrinsic::dbg_declare:
186
44
  case Intrinsic::dbg_value:
187
44
  case Intrinsic::dbg_label:
188
44
    // Short cut: Some intrinsics obviously don't use ObjC pointers.
189
44
    return true;
190
652
  default:
191
652
    return false;
192
696
  }
193
696
}
194
195
// A whitelist of intrinsics that we know do not use objc pointers or decrement
196
// ref counts.
197
652
static bool isUseOnlyIntrinsic(unsigned ID) {
198
652
  // We are conservative and even though intrinsics are unlikely to touch
199
652
  // reference counts, we white list them for safety.
200
652
  //
201
652
  // TODO: Expand this into a covered switch. There is a lot more here.
202
652
  switch (ID) {
203
652
  case Intrinsic::memcpy:
204
42
  case Intrinsic::memmove:
205
42
  case Intrinsic::memset:
206
42
    return true;
207
610
  default:
208
610
    return false;
209
652
  }
210
652
}
211
212
/// Determine what kind of construct V is.
213
8.96k
ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) {
214
8.96k
  if (const Instruction *I = dyn_cast<Instruction>(V)) {
215
8.96k
    // Any instruction other than bitcast and gep with a pointer operand have a
216
8.96k
    // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
217
8.96k
    // to a subsequent use, rather than using it themselves, in this sense.
218
8.96k
    // As a short cut, several other opcodes are known to have no pointer
219
8.96k
    // operands of interest. And ret is never followed by a release, so it's
220
8.96k
    // not interesting to examine.
221
8.96k
    switch (I->getOpcode()) {
222
8.96k
    case Instruction::Call: {
223
2.49k
      const CallInst *CI = cast<CallInst>(I);
224
2.49k
      // See if we have a function that we know something about.
225
2.49k
      if (const Function *F = CI->getCalledFunction()) {
226
2.37k
        ARCInstKind Class = GetFunctionClass(F);
227
2.37k
        if (Class != ARCInstKind::CallOrUser)
228
1.67k
          return Class;
229
696
        Intrinsic::ID ID = F->getIntrinsicID();
230
696
        if (isInertIntrinsic(ID))
231
44
          return ARCInstKind::None;
232
652
        if (isUseOnlyIntrinsic(ID))
233
42
          return ARCInstKind::User;
234
734
      }
235
734
236
734
      // Otherwise, be conservative.
237
734
      return GetCallSiteClass(CI);
238
734
    }
239
734
    case Instruction::Invoke:
240
480
      // Otherwise, be conservative.
241
480
      return GetCallSiteClass(cast<InvokeInst>(I));
242
4.01k
    case Instruction::BitCast:
243
4.01k
    case Instruction::GetElementPtr:
244
4.01k
    case Instruction::Select:
245
4.01k
    case Instruction::PHI:
246
4.01k
    case Instruction::Ret:
247
4.01k
    case Instruction::Br:
248
4.01k
    case Instruction::Switch:
249
4.01k
    case Instruction::IndirectBr:
250
4.01k
    case Instruction::Alloca:
251
4.01k
    case Instruction::VAArg:
252
4.01k
    case Instruction::Add:
253
4.01k
    case Instruction::FAdd:
254
4.01k
    case Instruction::Sub:
255
4.01k
    case Instruction::FSub:
256
4.01k
    case Instruction::Mul:
257
4.01k
    case Instruction::FMul:
258
4.01k
    case Instruction::SDiv:
259
4.01k
    case Instruction::UDiv:
260
4.01k
    case Instruction::FDiv:
261
4.01k
    case Instruction::SRem:
262
4.01k
    case Instruction::URem:
263
4.01k
    case Instruction::FRem:
264
4.01k
    case Instruction::Shl:
265
4.01k
    case Instruction::LShr:
266
4.01k
    case Instruction::AShr:
267
4.01k
    case Instruction::And:
268
4.01k
    case Instruction::Or:
269
4.01k
    case Instruction::Xor:
270
4.01k
    case Instruction::SExt:
271
4.01k
    case Instruction::ZExt:
272
4.01k
    case Instruction::Trunc:
273
4.01k
    case Instruction::IntToPtr:
274
4.01k
    case Instruction::FCmp:
275
4.01k
    case Instruction::FPTrunc:
276
4.01k
    case Instruction::FPExt:
277
4.01k
    case Instruction::FPToUI:
278
4.01k
    case Instruction::FPToSI:
279
4.01k
    case Instruction::UIToFP:
280
4.01k
    case Instruction::SIToFP:
281
4.01k
    case Instruction::InsertElement:
282
4.01k
    case Instruction::ExtractElement:
283
4.01k
    case Instruction::ShuffleVector:
284
4.01k
    case Instruction::ExtractValue:
285
4.01k
      break;
286
4.01k
    case Instruction::ICmp:
287
267
      // Comparing a pointer with null, or any other constant, isn't an
288
267
      // interesting use, because we don't care what the pointer points to, or
289
267
      // about the values of any other dynamic reference-counted pointers.
290
267
      if (IsPotentialRetainableObjPtr(I->getOperand(1)))
291
23
        return ARCInstKind::User;
292
244
      break;
293
1.70k
    default:
294
1.70k
      // For anything else, check all the operands.
295
1.70k
      // Note that this includes both operands of a Store: while the first
296
1.70k
      // operand isn't actually being dereferenced, it is being stored to
297
1.70k
      // memory where we can no longer track who might read it and dereference
298
1.70k
      // it, so we have to consider it potentially used.
299
1.70k
      for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
300
2.50k
           OI != OE; 
++OI800
)
301
1.76k
        if (IsPotentialRetainableObjPtr(*OI))
302
969
          return ARCInstKind::User;
303
8.96k
    }
304
8.96k
  }
305
8.96k
306
8.96k
  // Otherwise, it's totally inert for ARC purposes.
307
8.96k
  
return ARCInstKind::None4.99k
;
308
8.96k
}
309
310
/// Test if the given class is a kind of user.
311
47
bool llvm::objcarc::IsUser(ARCInstKind Class) {
312
47
  switch (Class) {
313
47
  case ARCInstKind::User:
314
16
  case ARCInstKind::CallOrUser:
315
16
  case ARCInstKind::IntrinsicUser:
316
16
    return true;
317
31
  case ARCInstKind::Retain:
318
31
  case ARCInstKind::RetainRV:
319
31
  case ARCInstKind::RetainBlock:
320
31
  case ARCInstKind::Release:
321
31
  case ARCInstKind::Autorelease:
322
31
  case ARCInstKind::AutoreleaseRV:
323
31
  case ARCInstKind::AutoreleasepoolPush:
324
31
  case ARCInstKind::AutoreleasepoolPop:
325
31
  case ARCInstKind::NoopCast:
326
31
  case ARCInstKind::FusedRetainAutorelease:
327
31
  case ARCInstKind::FusedRetainAutoreleaseRV:
328
31
  case ARCInstKind::LoadWeakRetained:
329
31
  case ARCInstKind::StoreWeak:
330
31
  case ARCInstKind::InitWeak:
331
31
  case ARCInstKind::LoadWeak:
332
31
  case ARCInstKind::MoveWeak:
333
31
  case ARCInstKind::CopyWeak:
334
31
  case ARCInstKind::DestroyWeak:
335
31
  case ARCInstKind::StoreStrong:
336
31
  case ARCInstKind::Call:
337
31
  case ARCInstKind::None:
338
31
  case ARCInstKind::ClaimRV:
339
31
    return false;
340
0
  }
341
0
  llvm_unreachable("covered switch isn't covered?");
342
0
}
343
344
/// Test if the given class is objc_retain or equivalent.
345
46
bool llvm::objcarc::IsRetain(ARCInstKind Class) {
346
46
  switch (Class) {
347
46
  case ARCInstKind::Retain:
348
13
  case ARCInstKind::RetainRV:
349
13
    return true;
350
13
  // I believe we treat retain block as not a retain since it can copy its
351
13
  // block.
352
33
  case ARCInstKind::RetainBlock:
353
33
  case ARCInstKind::Release:
354
33
  case ARCInstKind::Autorelease:
355
33
  case ARCInstKind::AutoreleaseRV:
356
33
  case ARCInstKind::AutoreleasepoolPush:
357
33
  case ARCInstKind::AutoreleasepoolPop:
358
33
  case ARCInstKind::NoopCast:
359
33
  case ARCInstKind::FusedRetainAutorelease:
360
33
  case ARCInstKind::FusedRetainAutoreleaseRV:
361
33
  case ARCInstKind::LoadWeakRetained:
362
33
  case ARCInstKind::StoreWeak:
363
33
  case ARCInstKind::InitWeak:
364
33
  case ARCInstKind::LoadWeak:
365
33
  case ARCInstKind::MoveWeak:
366
33
  case ARCInstKind::CopyWeak:
367
33
  case ARCInstKind::DestroyWeak:
368
33
  case ARCInstKind::StoreStrong:
369
33
  case ARCInstKind::IntrinsicUser:
370
33
  case ARCInstKind::CallOrUser:
371
33
  case ARCInstKind::Call:
372
33
  case ARCInstKind::User:
373
33
  case ARCInstKind::None:
374
33
  case ARCInstKind::ClaimRV:
375
33
    return false;
376
0
  }
377
0
  llvm_unreachable("covered switch isn't covered?");
378
0
}
379
380
/// Test if the given class is objc_autorelease or equivalent.
381
4.62k
bool llvm::objcarc::IsAutorelease(ARCInstKind Class) {
382
4.62k
  switch (Class) {
383
4.62k
  case ARCInstKind::Autorelease:
384
81
  case ARCInstKind::AutoreleaseRV:
385
81
    return true;
386
4.54k
  case ARCInstKind::Retain:
387
4.54k
  case ARCInstKind::RetainRV:
388
4.54k
  case ARCInstKind::ClaimRV:
389
4.54k
  case ARCInstKind::RetainBlock:
390
4.54k
  case ARCInstKind::Release:
391
4.54k
  case ARCInstKind::AutoreleasepoolPush:
392
4.54k
  case ARCInstKind::AutoreleasepoolPop:
393
4.54k
  case ARCInstKind::NoopCast:
394
4.54k
  case ARCInstKind::FusedRetainAutorelease:
395
4.54k
  case ARCInstKind::FusedRetainAutoreleaseRV:
396
4.54k
  case ARCInstKind::LoadWeakRetained:
397
4.54k
  case ARCInstKind::StoreWeak:
398
4.54k
  case ARCInstKind::InitWeak:
399
4.54k
  case ARCInstKind::LoadWeak:
400
4.54k
  case ARCInstKind::MoveWeak:
401
4.54k
  case ARCInstKind::CopyWeak:
402
4.54k
  case ARCInstKind::DestroyWeak:
403
4.54k
  case ARCInstKind::StoreStrong:
404
4.54k
  case ARCInstKind::IntrinsicUser:
405
4.54k
  case ARCInstKind::CallOrUser:
406
4.54k
  case ARCInstKind::Call:
407
4.54k
  case ARCInstKind::User:
408
4.54k
  case ARCInstKind::None:
409
4.54k
    return false;
410
0
  }
411
0
  llvm_unreachable("covered switch isn't covered?");
412
0
}
413
414
/// Test if the given class represents instructions which return their
415
/// argument verbatim.
416
17.1k
bool llvm::objcarc::IsForwarding(ARCInstKind Class) {
417
17.1k
  switch (Class) {
418
17.1k
  case ARCInstKind::Retain:
419
552
  case ARCInstKind::RetainRV:
420
552
  case ARCInstKind::ClaimRV:
421
552
  case ARCInstKind::Autorelease:
422
552
  case ARCInstKind::AutoreleaseRV:
423
552
  case ARCInstKind::NoopCast:
424
552
    return true;
425
16.5k
  case ARCInstKind::RetainBlock:
426
16.5k
  case ARCInstKind::Release:
427
16.5k
  case ARCInstKind::AutoreleasepoolPush:
428
16.5k
  case ARCInstKind::AutoreleasepoolPop:
429
16.5k
  case ARCInstKind::FusedRetainAutorelease:
430
16.5k
  case ARCInstKind::FusedRetainAutoreleaseRV:
431
16.5k
  case ARCInstKind::LoadWeakRetained:
432
16.5k
  case ARCInstKind::StoreWeak:
433
16.5k
  case ARCInstKind::InitWeak:
434
16.5k
  case ARCInstKind::LoadWeak:
435
16.5k
  case ARCInstKind::MoveWeak:
436
16.5k
  case ARCInstKind::CopyWeak:
437
16.5k
  case ARCInstKind::DestroyWeak:
438
16.5k
  case ARCInstKind::StoreStrong:
439
16.5k
  case ARCInstKind::IntrinsicUser:
440
16.5k
  case ARCInstKind::CallOrUser:
441
16.5k
  case ARCInstKind::Call:
442
16.5k
  case ARCInstKind::User:
443
16.5k
  case ARCInstKind::None:
444
16.5k
    return false;
445
0
  }
446
0
  llvm_unreachable("covered switch isn't covered?");
447
0
}
448
449
/// Test if the given class represents instructions which do nothing if
450
/// passed a null pointer.
451
4.59k
bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) {
452
4.59k
  switch (Class) {
453
4.59k
  case ARCInstKind::Retain:
454
836
  case ARCInstKind::RetainRV:
455
836
  case ARCInstKind::ClaimRV:
456
836
  case ARCInstKind::Release:
457
836
  case ARCInstKind::Autorelease:
458
836
  case ARCInstKind::AutoreleaseRV:
459
836
  case ARCInstKind::RetainBlock:
460
836
    return true;
461
3.75k
  case ARCInstKind::AutoreleasepoolPush:
462
3.75k
  case ARCInstKind::AutoreleasepoolPop:
463
3.75k
  case ARCInstKind::FusedRetainAutorelease:
464
3.75k
  case ARCInstKind::FusedRetainAutoreleaseRV:
465
3.75k
  case ARCInstKind::LoadWeakRetained:
466
3.75k
  case ARCInstKind::StoreWeak:
467
3.75k
  case ARCInstKind::InitWeak:
468
3.75k
  case ARCInstKind::LoadWeak:
469
3.75k
  case ARCInstKind::MoveWeak:
470
3.75k
  case ARCInstKind::CopyWeak:
471
3.75k
  case ARCInstKind::DestroyWeak:
472
3.75k
  case ARCInstKind::StoreStrong:
473
3.75k
  case ARCInstKind::IntrinsicUser:
474
3.75k
  case ARCInstKind::CallOrUser:
475
3.75k
  case ARCInstKind::Call:
476
3.75k
  case ARCInstKind::User:
477
3.75k
  case ARCInstKind::None:
478
3.75k
  case ARCInstKind::NoopCast:
479
3.75k
    return false;
480
0
  }
481
0
  llvm_unreachable("covered switch isn't covered?");
482
0
}
483
484
/// Test if the given class represents instructions which do nothing if
485
/// passed a global variable.
486
4.62k
bool llvm::objcarc::IsNoopOnGlobal(ARCInstKind Class) {
487
4.62k
  switch (Class) {
488
4.62k
  case ARCInstKind::Retain:
489
845
  case ARCInstKind::RetainRV:
490
845
  case ARCInstKind::ClaimRV:
491
845
  case ARCInstKind::Release:
492
845
  case ARCInstKind::Autorelease:
493
845
  case ARCInstKind::AutoreleaseRV:
494
845
  case ARCInstKind::RetainBlock:
495
845
  case ARCInstKind::FusedRetainAutorelease:
496
845
  case ARCInstKind::FusedRetainAutoreleaseRV:
497
845
    return true;
498
3.78k
  case ARCInstKind::AutoreleasepoolPush:
499
3.78k
  case ARCInstKind::AutoreleasepoolPop:
500
3.78k
  case ARCInstKind::LoadWeakRetained:
501
3.78k
  case ARCInstKind::StoreWeak:
502
3.78k
  case ARCInstKind::InitWeak:
503
3.78k
  case ARCInstKind::LoadWeak:
504
3.78k
  case ARCInstKind::MoveWeak:
505
3.78k
  case ARCInstKind::CopyWeak:
506
3.78k
  case ARCInstKind::DestroyWeak:
507
3.78k
  case ARCInstKind::StoreStrong:
508
3.78k
  case ARCInstKind::IntrinsicUser:
509
3.78k
  case ARCInstKind::CallOrUser:
510
3.78k
  case ARCInstKind::Call:
511
3.78k
  case ARCInstKind::User:
512
3.78k
  case ARCInstKind::None:
513
3.78k
  case ARCInstKind::NoopCast:
514
3.78k
    return false;
515
0
  }
516
0
  llvm_unreachable("covered switch isn't covered?");
517
0
}
518
519
/// Test if the given class represents instructions which are always safe
520
/// to mark with the "tail" keyword.
521
4.59k
bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) {
522
4.59k
  // ARCInstKind::RetainBlock may be given a stack argument.
523
4.59k
  switch (Class) {
524
4.59k
  case ARCInstKind::Retain:
525
388
  case ARCInstKind::RetainRV:
526
388
  case ARCInstKind::ClaimRV:
527
388
  case ARCInstKind::AutoreleaseRV:
528
388
    return true;
529
4.20k
  case ARCInstKind::Release:
530
4.20k
  case ARCInstKind::Autorelease:
531
4.20k
  case ARCInstKind::RetainBlock:
532
4.20k
  case ARCInstKind::AutoreleasepoolPush:
533
4.20k
  case ARCInstKind::AutoreleasepoolPop:
534
4.20k
  case ARCInstKind::FusedRetainAutorelease:
535
4.20k
  case ARCInstKind::FusedRetainAutoreleaseRV:
536
4.20k
  case ARCInstKind::LoadWeakRetained:
537
4.20k
  case ARCInstKind::StoreWeak:
538
4.20k
  case ARCInstKind::InitWeak:
539
4.20k
  case ARCInstKind::LoadWeak:
540
4.20k
  case ARCInstKind::MoveWeak:
541
4.20k
  case ARCInstKind::CopyWeak:
542
4.20k
  case ARCInstKind::DestroyWeak:
543
4.20k
  case ARCInstKind::StoreStrong:
544
4.20k
  case ARCInstKind::IntrinsicUser:
545
4.20k
  case ARCInstKind::CallOrUser:
546
4.20k
  case ARCInstKind::Call:
547
4.20k
  case ARCInstKind::User:
548
4.20k
  case ARCInstKind::None:
549
4.20k
  case ARCInstKind::NoopCast:
550
4.20k
    return false;
551
0
  }
552
0
  llvm_unreachable("covered switch isn't covered?");
553
0
}
554
555
/// Test if the given class represents instructions which are never safe
556
/// to mark with the "tail" keyword.
557
4.59k
bool llvm::objcarc::IsNeverTail(ARCInstKind Class) {
558
4.59k
  /// It is never safe to tail call objc_autorelease since by tail calling
559
4.59k
  /// objc_autorelease: fast autoreleasing causing our object to be potentially
560
4.59k
  /// reclaimed from the autorelease pool which violates the semantics of
561
4.59k
  /// __autoreleasing types in ARC.
562
4.59k
  switch (Class) {
563
4.59k
  case ARCInstKind::Autorelease:
564
33
    return true;
565
4.59k
  case ARCInstKind::Retain:
566
4.56k
  case ARCInstKind::RetainRV:
567
4.56k
  case ARCInstKind::ClaimRV:
568
4.56k
  case ARCInstKind::AutoreleaseRV:
569
4.56k
  case ARCInstKind::Release:
570
4.56k
  case ARCInstKind::RetainBlock:
571
4.56k
  case ARCInstKind::AutoreleasepoolPush:
572
4.56k
  case ARCInstKind::AutoreleasepoolPop:
573
4.56k
  case ARCInstKind::FusedRetainAutorelease:
574
4.56k
  case ARCInstKind::FusedRetainAutoreleaseRV:
575
4.56k
  case ARCInstKind::LoadWeakRetained:
576
4.56k
  case ARCInstKind::StoreWeak:
577
4.56k
  case ARCInstKind::InitWeak:
578
4.56k
  case ARCInstKind::LoadWeak:
579
4.56k
  case ARCInstKind::MoveWeak:
580
4.56k
  case ARCInstKind::CopyWeak:
581
4.56k
  case ARCInstKind::DestroyWeak:
582
4.56k
  case ARCInstKind::StoreStrong:
583
4.56k
  case ARCInstKind::IntrinsicUser:
584
4.56k
  case ARCInstKind::CallOrUser:
585
4.56k
  case ARCInstKind::Call:
586
4.56k
  case ARCInstKind::User:
587
4.56k
  case ARCInstKind::None:
588
4.56k
  case ARCInstKind::NoopCast:
589
4.56k
    return false;
590
0
  }
591
0
  llvm_unreachable("covered switch isn't covered?");
592
0
}
593
594
/// Test if the given class represents instructions which are always safe
595
/// to mark with the nounwind attribute.
596
4.59k
bool llvm::objcarc::IsNoThrow(ARCInstKind Class) {
597
4.59k
  // objc_retainBlock is not nounwind because it calls user copy constructors
598
4.59k
  // which could theoretically throw.
599
4.59k
  switch (Class) {
600
4.59k
  case ARCInstKind::Retain:
601
830
  case ARCInstKind::RetainRV:
602
830
  case ARCInstKind::ClaimRV:
603
830
  case ARCInstKind::Release:
604
830
  case ARCInstKind::Autorelease:
605
830
  case ARCInstKind::AutoreleaseRV:
606
830
  case ARCInstKind::AutoreleasepoolPush:
607
830
  case ARCInstKind::AutoreleasepoolPop:
608
830
    return true;
609
3.76k
  case ARCInstKind::RetainBlock:
610
3.76k
  case ARCInstKind::FusedRetainAutorelease:
611
3.76k
  case ARCInstKind::FusedRetainAutoreleaseRV:
612
3.76k
  case ARCInstKind::LoadWeakRetained:
613
3.76k
  case ARCInstKind::StoreWeak:
614
3.76k
  case ARCInstKind::InitWeak:
615
3.76k
  case ARCInstKind::LoadWeak:
616
3.76k
  case ARCInstKind::MoveWeak:
617
3.76k
  case ARCInstKind::CopyWeak:
618
3.76k
  case ARCInstKind::DestroyWeak:
619
3.76k
  case ARCInstKind::StoreStrong:
620
3.76k
  case ARCInstKind::IntrinsicUser:
621
3.76k
  case ARCInstKind::CallOrUser:
622
3.76k
  case ARCInstKind::Call:
623
3.76k
  case ARCInstKind::User:
624
3.76k
  case ARCInstKind::None:
625
3.76k
  case ARCInstKind::NoopCast:
626
3.76k
    return false;
627
0
  }
628
0
  llvm_unreachable("covered switch isn't covered?");
629
0
}
630
631
/// Test whether the given instruction can autorelease any pointer or cause an
632
/// autoreleasepool pop.
633
///
634
/// This means that it *could* interrupt the RV optimization.
635
4
bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) {
636
4
  switch (Class) {
637
4
  case ARCInstKind::AutoreleasepoolPop:
638
1
  case ARCInstKind::CallOrUser:
639
1
  case ARCInstKind::Call:
640
1
  case ARCInstKind::Autorelease:
641
1
  case ARCInstKind::AutoreleaseRV:
642
1
  case ARCInstKind::FusedRetainAutorelease:
643
1
  case ARCInstKind::FusedRetainAutoreleaseRV:
644
1
    return true;
645
3
  case ARCInstKind::Retain:
646
3
  case ARCInstKind::RetainRV:
647
3
  case ARCInstKind::ClaimRV:
648
3
  case ARCInstKind::Release:
649
3
  case ARCInstKind::AutoreleasepoolPush:
650
3
  case ARCInstKind::RetainBlock:
651
3
  case ARCInstKind::LoadWeakRetained:
652
3
  case ARCInstKind::StoreWeak:
653
3
  case ARCInstKind::InitWeak:
654
3
  case ARCInstKind::LoadWeak:
655
3
  case ARCInstKind::MoveWeak:
656
3
  case ARCInstKind::CopyWeak:
657
3
  case ARCInstKind::DestroyWeak:
658
3
  case ARCInstKind::StoreStrong:
659
3
  case ARCInstKind::IntrinsicUser:
660
3
  case ARCInstKind::User:
661
3
  case ARCInstKind::None:
662
3
  case ARCInstKind::NoopCast:
663
3
    return false;
664
0
  }
665
0
  llvm_unreachable("covered switch isn't covered?");
666
0
}
667
668
39
bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) {
669
39
  switch (Kind) {
670
39
  case ARCInstKind::Retain:
671
32
  case ARCInstKind::RetainRV:
672
32
  case ARCInstKind::Autorelease:
673
32
  case ARCInstKind::AutoreleaseRV:
674
32
  case ARCInstKind::NoopCast:
675
32
  case ARCInstKind::FusedRetainAutorelease:
676
32
  case ARCInstKind::FusedRetainAutoreleaseRV:
677
32
  case ARCInstKind::IntrinsicUser:
678
32
  case ARCInstKind::User:
679
32
  case ARCInstKind::None:
680
32
    return false;
681
32
682
32
  // The cases below are conservative.
683
32
684
32
  // RetainBlock can result in user defined copy constructors being called
685
32
  // implying releases may occur.
686
32
  case ARCInstKind::RetainBlock:
687
7
  case ARCInstKind::Release:
688
7
  case ARCInstKind::AutoreleasepoolPush:
689
7
  case ARCInstKind::AutoreleasepoolPop:
690
7
  case ARCInstKind::LoadWeakRetained:
691
7
  case ARCInstKind::StoreWeak:
692
7
  case ARCInstKind::InitWeak:
693
7
  case ARCInstKind::LoadWeak:
694
7
  case ARCInstKind::MoveWeak:
695
7
  case ARCInstKind::CopyWeak:
696
7
  case ARCInstKind::DestroyWeak:
697
7
  case ARCInstKind::StoreStrong:
698
7
  case ARCInstKind::CallOrUser:
699
7
  case ARCInstKind::Call:
700
7
  case ARCInstKind::ClaimRV:
701
7
    return true;
702
0
  }
703
0
704
0
  llvm_unreachable("covered switch isn't covered?");
705
0
}