Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Transforms/ObjCARC/ObjCARC.h
Line
Count
Source (jump to first uncovered line)
1
//===- ObjCARC.h - ObjC ARC Optimization --------------*- 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 definitions/declarations used by the ObjC ARC
10
/// Optimizer. ARC stands for Automatic Reference Counting and is a system for
11
/// managing 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_TRANSFORMS_OBJCARC_OBJCARC_H
23
#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
24
25
#include "llvm/ADT/StringSwitch.h"
26
#include "llvm/Analysis/AliasAnalysis.h"
27
#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
28
#include "llvm/Analysis/ObjCARCInstKind.h"
29
#include "llvm/Analysis/Passes.h"
30
#include "llvm/Transforms/Utils/Local.h"
31
#include "llvm/Analysis/ValueTracking.h"
32
#include "llvm/IR/CallSite.h"
33
#include "llvm/IR/InstIterator.h"
34
#include "llvm/IR/Module.h"
35
#include "llvm/Pass.h"
36
#include "llvm/Transforms/ObjCARC.h"
37
38
namespace llvm {
39
class raw_ostream;
40
}
41
42
namespace llvm {
43
namespace objcarc {
44
45
/// Erase the given instruction.
46
///
47
/// Many ObjC calls return their argument verbatim,
48
/// so if it's such a call and the return value has users, replace them with the
49
/// argument value.
50
///
51
356
static inline void EraseInstruction(Instruction *CI) {
52
356
  Value *OldArg = cast<CallInst>(CI)->getArgOperand(0);
53
356
54
356
  bool Unused = CI->use_empty();
55
356
56
356
  if (!Unused) {
57
38
    // Replace the return value with the argument.
58
38
    assert((IsForwarding(GetBasicARCInstKind(CI)) ||
59
38
            (IsNoopOnNull(GetBasicARCInstKind(CI)) &&
60
38
             IsNullOrUndef(OldArg->stripPointerCasts()))) &&
61
38
           "Can't delete non-forwarding instruction with users!");
62
38
    CI->replaceAllUsesWith(OldArg);
63
38
  }
64
356
65
356
  CI->eraseFromParent();
66
356
67
356
  if (Unused)
68
318
    RecursivelyDeleteTriviallyDeadInstructions(OldArg);
69
356
}
ObjCARCOpts.cpp:llvm::objcarc::EraseInstruction(llvm::Instruction*)
Line
Count
Source
51
341
static inline void EraseInstruction(Instruction *CI) {
52
341
  Value *OldArg = cast<CallInst>(CI)->getArgOperand(0);
53
341
54
341
  bool Unused = CI->use_empty();
55
341
56
341
  if (!Unused) {
57
33
    // Replace the return value with the argument.
58
33
    assert((IsForwarding(GetBasicARCInstKind(CI)) ||
59
33
            (IsNoopOnNull(GetBasicARCInstKind(CI)) &&
60
33
             IsNullOrUndef(OldArg->stripPointerCasts()))) &&
61
33
           "Can't delete non-forwarding instruction with users!");
62
33
    CI->replaceAllUsesWith(OldArg);
63
33
  }
64
341
65
341
  CI->eraseFromParent();
66
341
67
341
  if (Unused)
68
308
    RecursivelyDeleteTriviallyDeadInstructions(OldArg);
69
341
}
Unexecuted instantiation: ObjCARCExpand.cpp:llvm::objcarc::EraseInstruction(llvm::Instruction*)
Unexecuted instantiation: ObjCARCAPElim.cpp:llvm::objcarc::EraseInstruction(llvm::Instruction*)
ObjCARCContract.cpp:llvm::objcarc::EraseInstruction(llvm::Instruction*)
Line
Count
Source
51
15
static inline void EraseInstruction(Instruction *CI) {
52
15
  Value *OldArg = cast<CallInst>(CI)->getArgOperand(0);
53
15
54
15
  bool Unused = CI->use_empty();
55
15
56
15
  if (!Unused) {
57
5
    // Replace the return value with the argument.
58
5
    assert((IsForwarding(GetBasicARCInstKind(CI)) ||
59
5
            (IsNoopOnNull(GetBasicARCInstKind(CI)) &&
60
5
             IsNullOrUndef(OldArg->stripPointerCasts()))) &&
61
5
           "Can't delete non-forwarding instruction with users!");
62
5
    CI->replaceAllUsesWith(OldArg);
63
5
  }
64
15
65
15
  CI->eraseFromParent();
66
15
67
15
  if (Unused)
68
10
    RecursivelyDeleteTriviallyDeadInstructions(OldArg);
69
15
}
Unexecuted instantiation: DependencyAnalysis.cpp:llvm::objcarc::EraseInstruction(llvm::Instruction*)
Unexecuted instantiation: PtrState.cpp:llvm::objcarc::EraseInstruction(llvm::Instruction*)
Unexecuted instantiation: ObjCARC.cpp:llvm::objcarc::EraseInstruction(llvm::Instruction*)
70
71
/// If Inst is a ReturnRV and its operand is a call or invoke, return the
72
/// operand. Otherwise return null.
73
static inline const Instruction *getreturnRVOperand(const Instruction &Inst,
74
356
                                                    ARCInstKind Class) {
75
356
  if (Class != ARCInstKind::RetainRV)
76
350
    return nullptr;
77
6
78
6
  const auto *Opnd = Inst.getOperand(0)->stripPointerCasts();
79
6
  if (const auto *C = dyn_cast<CallInst>(Opnd))
80
2
    return C;
81
4
  return dyn_cast<InvokeInst>(Opnd);
82
4
}
Unexecuted instantiation: ObjCARCOpts.cpp:llvm::objcarc::getreturnRVOperand(llvm::Instruction const&, llvm::objcarc::ARCInstKind)
Unexecuted instantiation: ObjCARCExpand.cpp:llvm::objcarc::getreturnRVOperand(llvm::Instruction const&, llvm::objcarc::ARCInstKind)
Unexecuted instantiation: ObjCARCAPElim.cpp:llvm::objcarc::getreturnRVOperand(llvm::Instruction const&, llvm::objcarc::ARCInstKind)
Unexecuted instantiation: ObjCARCContract.cpp:llvm::objcarc::getreturnRVOperand(llvm::Instruction const&, llvm::objcarc::ARCInstKind)
Unexecuted instantiation: DependencyAnalysis.cpp:llvm::objcarc::getreturnRVOperand(llvm::Instruction const&, llvm::objcarc::ARCInstKind)
PtrState.cpp:llvm::objcarc::getreturnRVOperand(llvm::Instruction const&, llvm::objcarc::ARCInstKind)
Line
Count
Source
74
356
                                                    ARCInstKind Class) {
75
356
  if (Class != ARCInstKind::RetainRV)
76
350
    return nullptr;
77
6
78
6
  const auto *Opnd = Inst.getOperand(0)->stripPointerCasts();
79
6
  if (const auto *C = dyn_cast<CallInst>(Opnd))
80
2
    return C;
81
4
  return dyn_cast<InvokeInst>(Opnd);
82
4
}
Unexecuted instantiation: ObjCARC.cpp:llvm::objcarc::getreturnRVOperand(llvm::Instruction const&, llvm::objcarc::ARCInstKind)
83
84
/// Return the list of PHI nodes that are equivalent to PN.
85
template<class PHINodeTy, class VectorTy>
86
9
void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList) {
87
9
  auto *BB = PN.getParent();
88
13
  for (auto &P : BB->phis()) {
89
13
    if (&P == &PN) // Do not add PN to the list.
90
9
      continue;
91
4
    unsigned I = 0, E = PN.getNumIncomingValues();
92
10
    for (; I < E; 
++I6
) {
93
6
      auto *BB = PN.getIncomingBlock(I);
94
6
      auto *PNOpnd = PN.getIncomingValue(I)->stripPointerCasts();
95
6
      auto *POpnd = P.getIncomingValueForBlock(BB)->stripPointerCasts();
96
6
      if (PNOpnd != POpnd)
97
0
        break;
98
6
    }
99
4
    if (I == E)
100
4
      PHIList.push_back(&P);
101
4
  }
102
9
}
void llvm::objcarc::getEquivalentPHIs<llvm::PHINode const, llvm::SmallVector<llvm::Value const*, 2u> >(llvm::PHINode const&, llvm::SmallVector<llvm::Value const*, 2u>&)
Line
Count
Source
86
7
void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList) {
87
7
  auto *BB = PN.getParent();
88
10
  for (auto &P : BB->phis()) {
89
10
    if (&P == &PN) // Do not add PN to the list.
90
7
      continue;
91
3
    unsigned I = 0, E = PN.getNumIncomingValues();
92
7
    for (; I < E; 
++I4
) {
93
4
      auto *BB = PN.getIncomingBlock(I);
94
4
      auto *PNOpnd = PN.getIncomingValue(I)->stripPointerCasts();
95
4
      auto *POpnd = P.getIncomingValueForBlock(BB)->stripPointerCasts();
96
4
      if (PNOpnd != POpnd)
97
0
        break;
98
4
    }
99
3
    if (I == E)
100
3
      PHIList.push_back(&P);
101
3
  }
102
7
}
void llvm::objcarc::getEquivalentPHIs<llvm::PHINode, llvm::SmallVector<llvm::Value*, 1u> >(llvm::PHINode&, llvm::SmallVector<llvm::Value*, 1u>&)
Line
Count
Source
86
2
void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList) {
87
2
  auto *BB = PN.getParent();
88
3
  for (auto &P : BB->phis()) {
89
3
    if (&P == &PN) // Do not add PN to the list.
90
2
      continue;
91
1
    unsigned I = 0, E = PN.getNumIncomingValues();
92
3
    for (; I < E; 
++I2
) {
93
2
      auto *BB = PN.getIncomingBlock(I);
94
2
      auto *PNOpnd = PN.getIncomingValue(I)->stripPointerCasts();
95
2
      auto *POpnd = P.getIncomingValueForBlock(BB)->stripPointerCasts();
96
2
      if (PNOpnd != POpnd)
97
0
        break;
98
2
    }
99
1
    if (I == E)
100
1
      PHIList.push_back(&P);
101
1
  }
102
2
}
103
104
} // end namespace objcarc
105
} // end namespace llvm
106
107
#endif