1023d2bbbbedc6ed991b11381a987673133be2c81Michael Gottesman//===- ObjCARC.h - ObjC ARC Optimization --------------*- C++ -*-----------===//
26504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman//
36504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman//                     The LLVM Compiler Infrastructure
46504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman//
56504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman// This file is distributed under the University of Illinois Open Source
66504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman// License. See LICENSE.TXT for details.
76504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman//
86504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman//===----------------------------------------------------------------------===//
96504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// \file
106504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// This file defines common definitions/declarations used by the ObjC ARC
116504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// Optimizer. ARC stands for Automatic Reference Counting and is a system for
126504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// managing reference counts for objects in Objective C.
136504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman///
146504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// WARNING: This file knows about certain library functions. It recognizes them
156504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// by name, and hardwires knowledge of their semantics.
166504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman///
176504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// WARNING: This file knows about how certain Objective-C library functions are
186504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// used. Naive LLVM IR transformations which would otherwise be
196504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// behavior-preserving may break these assumptions.
206504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman///
216504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman//===----------------------------------------------------------------------===//
226504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
236504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#ifndef LLVM_TRANSFORMS_SCALAR_OBJCARC_H
246504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#define LLVM_TRANSFORMS_SCALAR_OBJCARC_H
256504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
266504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#include "llvm/ADT/StringSwitch.h"
276504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#include "llvm/Analysis/AliasAnalysis.h"
286504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#include "llvm/Analysis/Passes.h"
296086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman#include "llvm/Analysis/ValueTracking.h"
306504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#include "llvm/IR/Module.h"
316504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#include "llvm/Pass.h"
323a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/Support/CallSite.h"
336504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#include "llvm/Support/InstIterator.h"
346504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#include "llvm/Transforms/ObjCARC.h"
353a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/Transforms/Utils/Local.h"
366504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
376504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmannamespace llvm {
389ab758b9bc2fe51af6dabbdeb30f4a2e600bdcd0Michael Gottesmanclass raw_ostream;
399ab758b9bc2fe51af6dabbdeb30f4a2e600bdcd0Michael Gottesman}
409ab758b9bc2fe51af6dabbdeb30f4a2e600bdcd0Michael Gottesman
419ab758b9bc2fe51af6dabbdeb30f4a2e600bdcd0Michael Gottesmannamespace llvm {
426504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmannamespace objcarc {
436504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
446504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// \brief A handy option to enable/disable all ARC Optimizations.
456504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanextern bool EnableARCOpts;
466504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
476504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// \brief Test if the given module looks interesting to run ARC optimization
486504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// on.
496504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanstatic inline bool ModuleHasARC(const Module &M) {
506504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  return
516504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_retain") ||
526504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_release") ||
536504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_autorelease") ||
546504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_retainAutoreleasedReturnValue") ||
556504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_retainBlock") ||
566504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_autoreleaseReturnValue") ||
576504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_autoreleasePoolPush") ||
586504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_loadWeakRetained") ||
596504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_loadWeak") ||
606504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_destroyWeak") ||
616504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_storeWeak") ||
626504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_initWeak") ||
636504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_moveWeak") ||
646504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_copyWeak") ||
656504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_retainedObject") ||
666504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    M.getNamedValue("objc_unretainedObject") ||
673e9f3a0389488701bd1cb5c778d0e785c827d790Michael Gottesman    M.getNamedValue("objc_unretainedPointer") ||
683e9f3a0389488701bd1cb5c778d0e785c827d790Michael Gottesman    M.getNamedValue("clang.arc.use");
696504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman}
706504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
716504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// \enum InstructionClass
726504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// \brief A simple classification for instructions.
736504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanenum InstructionClass {
746504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_Retain,              ///< objc_retain
756504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_RetainRV,            ///< objc_retainAutoreleasedReturnValue
766504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_RetainBlock,         ///< objc_retainBlock
776504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_Release,             ///< objc_release
786504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_Autorelease,         ///< objc_autorelease
796504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_AutoreleaseRV,       ///< objc_autoreleaseReturnValue
806504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_AutoreleasepoolPush, ///< objc_autoreleasePoolPush
816504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_AutoreleasepoolPop,  ///< objc_autoreleasePoolPop
826504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_NoopCast,            ///< objc_retainedObject, etc.
836504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_FusedRetainAutorelease, ///< objc_retainAutorelease
846504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
856504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_LoadWeakRetained,    ///< objc_loadWeakRetained (primitive)
866504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_StoreWeak,           ///< objc_storeWeak (primitive)
876504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_InitWeak,            ///< objc_initWeak (derived)
886504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_LoadWeak,            ///< objc_loadWeak (derived)
896504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_MoveWeak,            ///< objc_moveWeak (derived)
906504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_CopyWeak,            ///< objc_copyWeak (derived)
916504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_DestroyWeak,         ///< objc_destroyWeak (derived)
926504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_StoreStrong,         ///< objc_storeStrong (derived)
931f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall  IC_IntrinsicUser,       ///< clang.arc.use
946504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_CallOrUser,          ///< could call objc_release and/or "use" pointers
956504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_Call,                ///< could call objc_release
966504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_User,                ///< could "use" a pointer
976504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  IC_None                 ///< anything else
986504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman};
996504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
10064437ead05db4f5d28e697058180ae575c3cf75bMichael Gottesmanraw_ostream &operator<<(raw_ostream &OS, const InstructionClass Class);
1016504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
1021f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall/// \brief Test if the given class is a kind of user.
1031f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCallinline static bool IsUser(InstructionClass Class) {
1041f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall  return Class == IC_User ||
1051f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall         Class == IC_CallOrUser ||
1061f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall         Class == IC_IntrinsicUser;
1071f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall}
1081f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall
1096086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief Test if the given class is objc_retain or equivalent.
1106086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline bool IsRetain(InstructionClass Class) {
1116086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return Class == IC_Retain ||
1126086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_RetainRV;
1136086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
1146086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
1156086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief Test if the given class is objc_autorelease or equivalent.
1166086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline bool IsAutorelease(InstructionClass Class) {
1176086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return Class == IC_Autorelease ||
1186086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_AutoreleaseRV;
1196086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
1206086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
1216086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief Test if the given class represents instructions which return their
1226086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// argument verbatim.
1236086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline bool IsForwarding(InstructionClass Class) {
1246086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return Class == IC_Retain ||
1256086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_RetainRV ||
1266086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_Autorelease ||
1276086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_AutoreleaseRV ||
1286086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_NoopCast;
1296086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
1306086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
1316086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief Test if the given class represents instructions which do nothing if
1326086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// passed a null pointer.
1336086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline bool IsNoopOnNull(InstructionClass Class) {
1346086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return Class == IC_Retain ||
1356086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_RetainRV ||
1366086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_Release ||
1376086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_Autorelease ||
1386086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_AutoreleaseRV ||
1396086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_RetainBlock;
1406086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
1416086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
1426086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief Test if the given class represents instructions which are always safe
1436086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// to mark with the "tail" keyword.
1446086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline bool IsAlwaysTail(InstructionClass Class) {
1456086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  // IC_RetainBlock may be given a stack argument.
1466086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return Class == IC_Retain ||
1476086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_RetainRV ||
1486086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_AutoreleaseRV;
1496086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
1506086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
1516086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief Test if the given class represents instructions which are never safe
1526086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// to mark with the "tail" keyword.
1536086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline bool IsNeverTail(InstructionClass Class) {
1546086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  /// It is never safe to tail call objc_autorelease since by tail calling
1556086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  /// objc_autorelease, we also tail call -[NSObject autorelease] which supports
1566086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  /// fast autoreleasing causing our object to be potentially reclaimed from the
1576086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  /// autorelease pool which violates the semantics of __autoreleasing types in
1586086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  /// ARC.
1596086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return Class == IC_Autorelease;
1606086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
1616086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
1626086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief Test if the given class represents instructions which are always safe
1636086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// to mark with the nounwind attribute.
1646086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline bool IsNoThrow(InstructionClass Class) {
1656086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  // objc_retainBlock is not nounwind because it calls user copy constructors
1666086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  // which could theoretically throw.
1676086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return Class == IC_Retain ||
1686086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_RetainRV ||
1696086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_Release ||
1706086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_Autorelease ||
1716086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_AutoreleaseRV ||
1726086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_AutoreleasepoolPush ||
1736086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman         Class == IC_AutoreleasepoolPop;
1746086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
1756504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
1763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// Test whether the given instruction can autorelease any pointer or cause an
1773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// autoreleasepool pop.
1783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanstatic inline bool
1793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanCanInterruptRV(InstructionClass Class) {
1803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  switch (Class) {
1813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  case IC_AutoreleasepoolPop:
1823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  case IC_CallOrUser:
1833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  case IC_Call:
1843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  case IC_Autorelease:
1853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  case IC_AutoreleaseRV:
1863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  case IC_FusedRetainAutorelease:
1873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  case IC_FusedRetainAutoreleaseRV:
1883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    return true;
1893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  default:
1903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    return false;
1913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  }
1923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
1933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
1946504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// \brief Determine if F is one of the special known Functions.  If it isn't,
1956504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// return IC_CallOrUser.
19664437ead05db4f5d28e697058180ae575c3cf75bMichael GottesmanInstructionClass GetFunctionClass(const Function *F);
1976504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
1986504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// \brief Determine which objc runtime call instruction class V belongs to.
1996504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman///
2006504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// This is similar to GetInstructionClass except that it only detects objc
2016504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// runtime calls. This allows it to be faster.
2026504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman///
2036504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanstatic inline InstructionClass GetBasicInstructionClass(const Value *V) {
2046504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  if (const CallInst *CI = dyn_cast<CallInst>(V)) {
2056504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    if (const Function *F = CI->getCalledFunction())
2066504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman      return GetFunctionClass(F);
2076504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    // Otherwise, be conservative.
2086504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman    return IC_CallOrUser;
2096504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  }
2106504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
2116504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  // Otherwise, be conservative.
2126504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman  return isa<InvokeInst>(V) ? IC_CallOrUser : IC_User;
2136504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman}
2146504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
2153a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// \brief Determine what kind of construct V is.
2163a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanInstructionClass GetInstructionClass(const Value *V);
2176086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
2186086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief This is a wrapper around getUnderlyingObject which also knows how to
2196086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// look through objc_retain and objc_autorelease calls, which we know to return
2206086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// their argument verbatim.
2216086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline const Value *GetUnderlyingObjCPtr(const Value *V) {
2226086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  for (;;) {
2236086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman    V = GetUnderlyingObject(V);
2246086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman    if (!IsForwarding(GetBasicInstructionClass(V)))
2256086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman      break;
2266086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman    V = cast<CallInst>(V)->getArgOperand(0);
2276086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  }
2286086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
2296086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return V;
2306086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
2316086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
2326086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief This is a wrapper around Value::stripPointerCasts which also knows
2336086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// how to look through objc_retain and objc_autorelease calls, which we know to
2346086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// return their argument verbatim.
2356086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline const Value *StripPointerCastsAndObjCCalls(const Value *V) {
2366086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  for (;;) {
2376086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman    V = V->stripPointerCasts();
2386086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman    if (!IsForwarding(GetBasicInstructionClass(V)))
2396086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman      break;
2406086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman    V = cast<CallInst>(V)->getArgOperand(0);
2416086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  }
2426086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return V;
2436086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
2446086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
2456086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \brief This is a wrapper around Value::stripPointerCasts which also knows
2466086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// how to look through objc_retain and objc_autorelease calls, which we know to
2476086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// return their argument verbatim.
2486086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanstatic inline Value *StripPointerCastsAndObjCCalls(Value *V) {
2496086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  for (;;) {
2506086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman    V = V->stripPointerCasts();
2516086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman    if (!IsForwarding(GetBasicInstructionClass(V)))
2526086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman      break;
2536086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman    V = cast<CallInst>(V)->getArgOperand(0);
2546086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  }
2556086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman  return V;
2566086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman}
2576086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
2583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// \brief Assuming the given instruction is one of the special calls such as
2593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// objc_retain or objc_release, return the argument value, stripped of no-op
2603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// casts and forwarding calls.
2613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanstatic inline Value *GetObjCArg(Value *Inst) {
2623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  return StripPointerCastsAndObjCCalls(cast<CallInst>(Inst)->getArgOperand(0));
2633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
2643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
265f0a15d88afce23453ff55894400035014ad46a15Michael Gottesmanstatic inline bool IsNullOrUndef(const Value *V) {
2663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
2673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
2683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
269f0a15d88afce23453ff55894400035014ad46a15Michael Gottesmanstatic inline bool IsNoopInstruction(const Instruction *I) {
2703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  return isa<BitCastInst>(I) ||
2713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    (isa<GetElementPtrInst>(I) &&
2723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman     cast<GetElementPtrInst>(I)->hasAllZeroIndices());
2733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
2743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
2753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
2763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// \brief Erase the given instruction.
2773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman///
2783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// Many ObjC calls return their argument verbatim,
2793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// so if it's such a call and the return value has users, replace them with the
2803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// argument value.
2813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman///
2823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanstatic inline void EraseInstruction(Instruction *CI) {
2833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Value *OldArg = cast<CallInst>(CI)->getArgOperand(0);
2843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
2853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  bool Unused = CI->use_empty();
2863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
2873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (!Unused) {
2883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    // Replace the return value with the argument.
289a75b293e4fa702d3e233839dc347ebf565be2d4dMichael Gottesman    assert((IsForwarding(GetBasicInstructionClass(CI)) ||
290a75b293e4fa702d3e233839dc347ebf565be2d4dMichael Gottesman            (IsNoopOnNull(GetBasicInstructionClass(CI)) &&
291a75b293e4fa702d3e233839dc347ebf565be2d4dMichael Gottesman             isa<ConstantPointerNull>(OldArg))) &&
2923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman           "Can't delete non-forwarding instruction with users!");
2933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    CI->replaceAllUsesWith(OldArg);
2943a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  }
2953a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
2963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  CI->eraseFromParent();
2973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
2983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (Unused)
2993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    RecursivelyDeleteTriviallyDeadInstructions(OldArg);
3003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
3013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// \brief Test whether the given value is possible a retainable object pointer.
3033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanstatic inline bool IsPotentialRetainableObjPtr(const Value *Op) {
3043dcfdab267f157aeb0e6aed896f7acdeb11481baMichael Gottesman  // Pointers to static or stack storage are not valid retainable object
3053dcfdab267f157aeb0e6aed896f7acdeb11481baMichael Gottesman  // pointers.
3063a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (isa<Constant>(Op) || isa<AllocaInst>(Op))
3073a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    return false;
3083a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // Special arguments can not be a valid retainable object pointer.
3093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (const Argument *Arg = dyn_cast<Argument>(Op))
3103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    if (Arg->hasByValAttr() ||
3113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        Arg->hasNestAttr() ||
3123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        Arg->hasStructRetAttr())
3133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      return false;
3143a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // Only consider values with pointer types.
3153a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  //
3163a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // It seemes intuitive to exclude function pointer types as well, since
3173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // functions are never retainable object pointers, however clang occasionally
3183a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // bitcasts retainable object pointers to function-pointer type temporarily.
3193a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
3203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (!Ty)
3213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    return false;
3223dcfdab267f157aeb0e6aed896f7acdeb11481baMichael Gottesman  // Conservatively assume anything else is a potential retainable object
3233dcfdab267f157aeb0e6aed896f7acdeb11481baMichael Gottesman  // pointer.
3243a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  return true;
3253a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
3263a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3273a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanstatic inline bool IsPotentialRetainableObjPtr(const Value *Op,
3283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                                               AliasAnalysis &AA) {
3293a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // First make the rudimentary check.
3303a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (!IsPotentialRetainableObjPtr(Op))
3313a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    return false;
3323a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3333a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // Objects in constant memory are not reference-counted.
3343a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (AA.pointsToConstantMemory(Op))
3353a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    return false;
3363a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3373a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // Pointers in constant memory are not pointing to reference-counted objects.
3383a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (const LoadInst *LI = dyn_cast<LoadInst>(Op))
3393a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    if (AA.pointsToConstantMemory(LI->getPointerOperand()))
3403a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      return false;
3413a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3423a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // Otherwise assume the worst.
3433a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  return true;
3443a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
3453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// \brief Helper for GetInstructionClass. Determines what kind of construct CS
3473a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// is.
3483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanstatic inline InstructionClass GetCallSiteClass(ImmutableCallSite CS) {
3493a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
3503a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman       I != E; ++I)
3513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    if (IsPotentialRetainableObjPtr(*I))
3523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      return CS.onlyReadsMemory() ? IC_User : IC_CallOrUser;
3533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  return CS.onlyReadsMemory() ? IC_None : IC_Call;
3553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
3563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// \brief Return true if this value refers to a distinct and identifiable
3583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// object.
3593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman///
3603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
3613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// special knowledge of ObjC conventions.
3623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanstatic inline bool IsObjCIdentifiedObject(const Value *V) {
3633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // Assume that call results and arguments have their own "provenance".
3643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // Constants (including GlobalVariables) and Allocas are never
3653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // reference-counted.
3663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
3673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      isa<Argument>(V) || isa<Constant>(V) ||
3683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      isa<AllocaInst>(V))
3693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    return true;
3703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
3723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    const Value *Pointer =
3733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      StripPointerCastsAndObjCCalls(LI->getPointerOperand());
3743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
3753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // A constant pointer can't be pointing to an object on the heap. It may
3763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // be reference-counted, but it won't be deleted.
3773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      if (GV->isConstant())
3783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        return true;
3793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      StringRef Name = GV->getName();
3803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // These special variables are known to hold values which are not
3813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // reference-counted pointers.
3823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      if (Name.startswith("\01L_OBJC_SELECTOR_REFERENCES_") ||
3833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          Name.startswith("\01L_OBJC_CLASSLIST_REFERENCES_") ||
3843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          Name.startswith("\01L_OBJC_CLASSLIST_SUP_REFS_$_") ||
3853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          Name.startswith("\01L_OBJC_METH_VAR_NAME_") ||
3863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          Name.startswith("\01l_objc_msgSend_fixup_"))
3873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        return true;
3883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    }
3893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  }
3903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  return false;
3923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
3936086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman
3946504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman} // end namespace objcarc
3956504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman} // end namespace llvm
3966504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman
3976504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#endif // LLVM_TRANSFORMS_SCALAR_OBJCARC_H
398