1//===- ObjCARCUtil.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 several utility functions used by various ARC
11/// optimizations which are IMHO too big to be in a header file.
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#include "ObjCARC.h"
23#include "llvm/IR/Intrinsics.h"
24
25using namespace llvm;
26using namespace llvm::objcarc;
27
28raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
29                                       const InstructionClass Class) {
30  switch (Class) {
31  case IC_Retain:
32    return OS << "IC_Retain";
33  case IC_RetainRV:
34    return OS << "IC_RetainRV";
35  case IC_RetainBlock:
36    return OS << "IC_RetainBlock";
37  case IC_Release:
38    return OS << "IC_Release";
39  case IC_Autorelease:
40    return OS << "IC_Autorelease";
41  case IC_AutoreleaseRV:
42    return OS << "IC_AutoreleaseRV";
43  case IC_AutoreleasepoolPush:
44    return OS << "IC_AutoreleasepoolPush";
45  case IC_AutoreleasepoolPop:
46    return OS << "IC_AutoreleasepoolPop";
47  case IC_NoopCast:
48    return OS << "IC_NoopCast";
49  case IC_FusedRetainAutorelease:
50    return OS << "IC_FusedRetainAutorelease";
51  case IC_FusedRetainAutoreleaseRV:
52    return OS << "IC_FusedRetainAutoreleaseRV";
53  case IC_LoadWeakRetained:
54    return OS << "IC_LoadWeakRetained";
55  case IC_StoreWeak:
56    return OS << "IC_StoreWeak";
57  case IC_InitWeak:
58    return OS << "IC_InitWeak";
59  case IC_LoadWeak:
60    return OS << "IC_LoadWeak";
61  case IC_MoveWeak:
62    return OS << "IC_MoveWeak";
63  case IC_CopyWeak:
64    return OS << "IC_CopyWeak";
65  case IC_DestroyWeak:
66    return OS << "IC_DestroyWeak";
67  case IC_StoreStrong:
68    return OS << "IC_StoreStrong";
69  case IC_CallOrUser:
70    return OS << "IC_CallOrUser";
71  case IC_Call:
72    return OS << "IC_Call";
73  case IC_User:
74    return OS << "IC_User";
75  case IC_IntrinsicUser:
76    return OS << "IC_IntrinsicUser";
77  case IC_None:
78    return OS << "IC_None";
79  }
80  llvm_unreachable("Unknown instruction class!");
81}
82
83InstructionClass llvm::objcarc::GetFunctionClass(const Function *F) {
84  Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
85
86  // No (mandatory) arguments.
87  if (AI == AE)
88    return StringSwitch<InstructionClass>(F->getName())
89      .Case("objc_autoreleasePoolPush",  IC_AutoreleasepoolPush)
90      .Case("clang.arc.use", IC_IntrinsicUser)
91      .Default(IC_CallOrUser);
92
93  // One argument.
94  const Argument *A0 = AI++;
95  if (AI == AE)
96    // Argument is a pointer.
97    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) {
98      Type *ETy = PTy->getElementType();
99      // Argument is i8*.
100      if (ETy->isIntegerTy(8))
101        return StringSwitch<InstructionClass>(F->getName())
102          .Case("objc_retain",                IC_Retain)
103          .Case("objc_retainAutoreleasedReturnValue", IC_RetainRV)
104          .Case("objc_retainBlock",           IC_RetainBlock)
105          .Case("objc_release",               IC_Release)
106          .Case("objc_autorelease",           IC_Autorelease)
107          .Case("objc_autoreleaseReturnValue", IC_AutoreleaseRV)
108          .Case("objc_autoreleasePoolPop",    IC_AutoreleasepoolPop)
109          .Case("objc_retainedObject",        IC_NoopCast)
110          .Case("objc_unretainedObject",      IC_NoopCast)
111          .Case("objc_unretainedPointer",     IC_NoopCast)
112          .Case("objc_retain_autorelease",    IC_FusedRetainAutorelease)
113          .Case("objc_retainAutorelease",     IC_FusedRetainAutorelease)
114          .Case("objc_retainAutoreleaseReturnValue",IC_FusedRetainAutoreleaseRV)
115          .Case("objc_sync_enter", IC_User)
116          .Case("objc_sync_exit", IC_User)
117          .Default(IC_CallOrUser);
118
119      // Argument is i8**
120      if (PointerType *Pte = dyn_cast<PointerType>(ETy))
121        if (Pte->getElementType()->isIntegerTy(8))
122          return StringSwitch<InstructionClass>(F->getName())
123            .Case("objc_loadWeakRetained",      IC_LoadWeakRetained)
124            .Case("objc_loadWeak",              IC_LoadWeak)
125            .Case("objc_destroyWeak",           IC_DestroyWeak)
126            .Default(IC_CallOrUser);
127    }
128
129  // Two arguments, first is i8**.
130  const Argument *A1 = AI++;
131  if (AI == AE)
132    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType()))
133      if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType()))
134        if (Pte->getElementType()->isIntegerTy(8))
135          if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) {
136            Type *ETy1 = PTy1->getElementType();
137            // Second argument is i8*
138            if (ETy1->isIntegerTy(8))
139              return StringSwitch<InstructionClass>(F->getName())
140                .Case("objc_storeWeak",             IC_StoreWeak)
141                .Case("objc_initWeak",              IC_InitWeak)
142                .Case("objc_storeStrong",           IC_StoreStrong)
143                .Default(IC_CallOrUser);
144            // Second argument is i8**.
145            if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
146              if (Pte1->getElementType()->isIntegerTy(8))
147                return StringSwitch<InstructionClass>(F->getName())
148                  .Case("objc_moveWeak",              IC_MoveWeak)
149                  .Case("objc_copyWeak",              IC_CopyWeak)
150                  // Ignore annotation calls. This is important to stop the
151                  // optimizer from treating annotations as uses which would
152                  // make the state of the pointers they are attempting to
153                  // elucidate to be incorrect.
154                  .Case("llvm.arc.annotation.topdown.bbstart", IC_None)
155                  .Case("llvm.arc.annotation.topdown.bbend", IC_None)
156                  .Case("llvm.arc.annotation.bottomup.bbstart", IC_None)
157                  .Case("llvm.arc.annotation.bottomup.bbend", IC_None)
158                  .Default(IC_CallOrUser);
159          }
160
161  // Anything else.
162  return IC_CallOrUser;
163}
164
165/// \brief Determine what kind of construct V is.
166InstructionClass
167llvm::objcarc::GetInstructionClass(const Value *V) {
168  if (const Instruction *I = dyn_cast<Instruction>(V)) {
169    // Any instruction other than bitcast and gep with a pointer operand have a
170    // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
171    // to a subsequent use, rather than using it themselves, in this sense.
172    // As a short cut, several other opcodes are known to have no pointer
173    // operands of interest. And ret is never followed by a release, so it's
174    // not interesting to examine.
175    switch (I->getOpcode()) {
176    case Instruction::Call: {
177      const CallInst *CI = cast<CallInst>(I);
178      // Check for calls to special functions.
179      if (const Function *F = CI->getCalledFunction()) {
180        InstructionClass Class = GetFunctionClass(F);
181        if (Class != IC_CallOrUser)
182          return Class;
183
184        // None of the intrinsic functions do objc_release. For intrinsics, the
185        // only question is whether or not they may be users.
186        switch (F->getIntrinsicID()) {
187        case Intrinsic::returnaddress: case Intrinsic::frameaddress:
188        case Intrinsic::stacksave: case Intrinsic::stackrestore:
189        case Intrinsic::vastart: case Intrinsic::vacopy: case Intrinsic::vaend:
190        case Intrinsic::objectsize: case Intrinsic::prefetch:
191        case Intrinsic::stackprotector:
192        case Intrinsic::eh_return_i32: case Intrinsic::eh_return_i64:
193        case Intrinsic::eh_typeid_for: case Intrinsic::eh_dwarf_cfa:
194        case Intrinsic::eh_sjlj_lsda: case Intrinsic::eh_sjlj_functioncontext:
195        case Intrinsic::init_trampoline: case Intrinsic::adjust_trampoline:
196        case Intrinsic::lifetime_start: case Intrinsic::lifetime_end:
197        case Intrinsic::invariant_start: case Intrinsic::invariant_end:
198        // Don't let dbg info affect our results.
199        case Intrinsic::dbg_declare: case Intrinsic::dbg_value:
200          // Short cut: Some intrinsics obviously don't use ObjC pointers.
201          return IC_None;
202        default:
203          break;
204        }
205      }
206      return GetCallSiteClass(CI);
207    }
208    case Instruction::Invoke:
209      return GetCallSiteClass(cast<InvokeInst>(I));
210    case Instruction::BitCast:
211    case Instruction::GetElementPtr:
212    case Instruction::Select: case Instruction::PHI:
213    case Instruction::Ret: case Instruction::Br:
214    case Instruction::Switch: case Instruction::IndirectBr:
215    case Instruction::Alloca: case Instruction::VAArg:
216    case Instruction::Add: case Instruction::FAdd:
217    case Instruction::Sub: case Instruction::FSub:
218    case Instruction::Mul: case Instruction::FMul:
219    case Instruction::SDiv: case Instruction::UDiv: case Instruction::FDiv:
220    case Instruction::SRem: case Instruction::URem: case Instruction::FRem:
221    case Instruction::Shl: case Instruction::LShr: case Instruction::AShr:
222    case Instruction::And: case Instruction::Or: case Instruction::Xor:
223    case Instruction::SExt: case Instruction::ZExt: case Instruction::Trunc:
224    case Instruction::IntToPtr: case Instruction::FCmp:
225    case Instruction::FPTrunc: case Instruction::FPExt:
226    case Instruction::FPToUI: case Instruction::FPToSI:
227    case Instruction::UIToFP: case Instruction::SIToFP:
228    case Instruction::InsertElement: case Instruction::ExtractElement:
229    case Instruction::ShuffleVector:
230    case Instruction::ExtractValue:
231      break;
232    case Instruction::ICmp:
233      // Comparing a pointer with null, or any other constant, isn't an
234      // interesting use, because we don't care what the pointer points to, or
235      // about the values of any other dynamic reference-counted pointers.
236      if (IsPotentialRetainableObjPtr(I->getOperand(1)))
237        return IC_User;
238      break;
239    default:
240      // For anything else, check all the operands.
241      // Note that this includes both operands of a Store: while the first
242      // operand isn't actually being dereferenced, it is being stored to
243      // memory where we can no longer track who might read it and dereference
244      // it, so we have to consider it potentially used.
245      for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
246           OI != OE; ++OI)
247        if (IsPotentialRetainableObjPtr(*OI))
248          return IC_User;
249    }
250  }
251
252  // Otherwise, it's totally inert for ARC purposes.
253  return IC_None;
254}
255