Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Transforms/ObjCARC/ObjCARCExpand.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ObjCARCExpand.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 ObjC ARC optimizations. ARC stands for Automatic
11
/// Reference Counting and is a system for managing reference counts for objects
12
/// in Objective C.
13
///
14
/// This specific file deals with early optimizations which perform certain
15
/// cleanup operations.
16
///
17
/// WARNING: This file knows about certain library functions. It recognizes them
18
/// by name, and hardwires knowledge of their semantics.
19
///
20
/// WARNING: This file knows about how certain Objective-C library functions are
21
/// used. Naive LLVM IR transformations which would otherwise be
22
/// behavior-preserving may break these assumptions.
23
///
24
//===----------------------------------------------------------------------===//
25
26
#include "ObjCARC.h"
27
#include "llvm/IR/Function.h"
28
#include "llvm/IR/InstIterator.h"
29
#include "llvm/IR/Instruction.h"
30
#include "llvm/IR/Instructions.h"
31
#include "llvm/IR/Value.h"
32
#include "llvm/Pass.h"
33
#include "llvm/PassAnalysisSupport.h"
34
#include "llvm/PassRegistry.h"
35
#include "llvm/PassSupport.h"
36
#include "llvm/Support/Casting.h"
37
#include "llvm/Support/Debug.h"
38
#include "llvm/Support/raw_ostream.h"
39
40
#define DEBUG_TYPE "objc-arc-expand"
41
42
namespace llvm {
43
  class Module;
44
}
45
46
using namespace llvm;
47
using namespace llvm::objcarc;
48
49
namespace {
50
  /// \brief Early ARC transformations.
51
  class ObjCARCExpand : public FunctionPass {
52
    void getAnalysisUsage(AnalysisUsage &AU) const override;
53
    bool doInitialization(Module &M) override;
54
    bool runOnFunction(Function &F) override;
55
56
    /// A flag indicating whether this optimization pass should run.
57
    bool Run;
58
59
  public:
60
    static char ID;
61
6
    ObjCARCExpand() : FunctionPass(ID) {
62
6
      initializeObjCARCExpandPass(*PassRegistry::getPassRegistry());
63
6
    }
64
  };
65
}
66
67
char ObjCARCExpand::ID = 0;
68
INITIALIZE_PASS(ObjCARCExpand,
69
                "objc-arc-expand", "ObjC ARC expansion", false, false)
70
71
4
Pass *llvm::createObjCARCExpandPass() {
72
4
  return new ObjCARCExpand();
73
4
}
74
75
6
void ObjCARCExpand::getAnalysisUsage(AnalysisUsage &AU) const {
76
6
  AU.setPreservesCFG();
77
6
}
78
79
6
bool ObjCARCExpand::doInitialization(Module &M) {
80
6
  Run = ModuleHasARC(M);
81
6
  return false;
82
6
}
83
84
31
bool ObjCARCExpand::runOnFunction(Function &F) {
85
31
  if (!EnableARCOpts)
86
0
    return false;
87
31
88
31
  // If nothing in the Module uses ARC, don't do anything.
89
31
  
if (31
!Run31
)
90
0
    return false;
91
31
92
31
  bool Changed = false;
93
31
94
31
  DEBUG(dbgs() << "ObjCARCExpand: Visiting Function: " << F.getName() << "\n");
95
31
96
674
  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); 
I != E674
;
++I643
) {
97
643
    Instruction *Inst = &*I;
98
643
99
643
    DEBUG(dbgs() << "ObjCARCExpand: Visiting: " << *Inst << "\n");
100
643
101
643
    switch (GetBasicARCInstKind(Inst)) {
102
24
    case ARCInstKind::Retain:
103
24
    case ARCInstKind::RetainRV:
104
24
    case ARCInstKind::Autorelease:
105
24
    case ARCInstKind::AutoreleaseRV:
106
24
    case ARCInstKind::FusedRetainAutorelease:
107
24
    case ARCInstKind::FusedRetainAutoreleaseRV: {
108
24
      // These calls return their argument verbatim, as a low-level
109
24
      // optimization. However, this makes high-level optimizations
110
24
      // harder. Undo any uses of this optimization that the front-end
111
24
      // emitted here. We'll redo them in the contract pass.
112
24
      Changed = true;
113
24
      Value *Value = cast<CallInst>(Inst)->getArgOperand(0);
114
24
      DEBUG(dbgs() << "ObjCARCExpand: Old = " << *Inst << "\n"
115
24
                      "               New = " << *Value << "\n");
116
24
      Inst->replaceAllUsesWith(Value);
117
24
      break;
118
24
    }
119
619
    default:
120
619
      break;
121
643
    }
122
643
  }
123
31
124
31
  
DEBUG31
(dbgs() << "ObjCARCExpand: Finished List.\n\n");
125
31
126
31
  return Changed;
127
31
}