-//===- ObjCARC.h - ObjC ARC Optimization --------------*- mode: c++ -*-----===//
+//===- ObjCARC.h - ObjC ARC Optimization --------------*- C++ -*-----------===//
//
// The LLVM Compiler Infrastructure
//
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_SCALAR_OBJCARC_H
-#define LLVM_TRANSFORMS_SCALAR_OBJCARC_H
+#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
+#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/InstIterator.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Utils/Local.h"
+namespace llvm {
+class raw_ostream;
+}
+
namespace llvm {
namespace objcarc {
M.getNamedValue("objc_copyWeak") ||
M.getNamedValue("objc_retainedObject") ||
M.getNamedValue("objc_unretainedObject") ||
- M.getNamedValue("objc_unretainedPointer");
+ M.getNamedValue("objc_unretainedPointer") ||
+ M.getNamedValue("clang.arc.use");
}
/// \enum InstructionClass
IC_CopyWeak, ///< objc_copyWeak (derived)
IC_DestroyWeak, ///< objc_destroyWeak (derived)
IC_StoreStrong, ///< objc_storeStrong (derived)
+ IC_IntrinsicUser, ///< clang.arc.use
IC_CallOrUser, ///< could call objc_release and/or "use" pointers
IC_Call, ///< could call objc_release
IC_User, ///< could "use" a pointer
raw_ostream &operator<<(raw_ostream &OS, const InstructionClass Class);
+/// \brief Test if the given class is a kind of user.
+inline static bool IsUser(InstructionClass Class) {
+ return Class == IC_User ||
+ Class == IC_CallOrUser ||
+ Class == IC_IntrinsicUser;
+}
+
/// \brief Test if the given class is objc_retain or equivalent.
static inline bool IsRetain(InstructionClass Class) {
return Class == IC_Retain ||
/// \brief Test if the given class represents instructions which return their
/// argument verbatim.
static inline bool IsForwarding(InstructionClass Class) {
- // objc_retainBlock technically doesn't always return its argument
- // verbatim, but it doesn't matter for our purposes here.
return Class == IC_Retain ||
Class == IC_RetainRV ||
Class == IC_Autorelease ||
Class == IC_AutoreleaseRV ||
- Class == IC_RetainBlock ||
Class == IC_NoopCast;
}
return StripPointerCastsAndObjCCalls(cast<CallInst>(Inst)->getArgOperand(0));
}
-static inline bool isNullOrUndef(const Value *V) {
+static inline bool IsNullOrUndef(const Value *V) {
return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
}
-static inline bool isNoopInstruction(const Instruction *I) {
+static inline bool IsNoopInstruction(const Instruction *I) {
return isa<BitCastInst>(I) ||
(isa<GetElementPtrInst>(I) &&
cast<GetElementPtrInst>(I)->hasAllZeroIndices());
if (!Unused) {
// Replace the return value with the argument.
- assert(IsForwarding(GetBasicInstructionClass(CI)) &&
+ assert((IsForwarding(GetBasicInstructionClass(CI)) ||
+ (IsNoopOnNull(GetBasicInstructionClass(CI)) &&
+ isa<ConstantPointerNull>(OldArg))) &&
"Can't delete non-forwarding instruction with users!");
CI->replaceAllUsesWith(OldArg);
}
/// \brief Test whether the given value is possible a retainable object pointer.
static inline bool IsPotentialRetainableObjPtr(const Value *Op) {
- // Pointers to static or stack storage are not valid retainable object pointers.
+ // Pointers to static or stack storage are not valid retainable object
+ // pointers.
if (isa<Constant>(Op) || isa<AllocaInst>(Op))
return false;
// Special arguments can not be a valid retainable object pointer.
if (const Argument *Arg = dyn_cast<Argument>(Op))
if (Arg->hasByValAttr() ||
+ Arg->hasInAllocaAttr() ||
Arg->hasNestAttr() ||
Arg->hasStructRetAttr())
return false;
PointerType *Ty = dyn_cast<PointerType>(Op->getType());
if (!Ty)
return false;
- // Conservatively assume anything else is a potential retainable object pointer.
+ // Conservatively assume anything else is a potential retainable object
+ // pointer.
return true;
}
} // end namespace objcarc
} // end namespace llvm
-#endif // LLVM_TRANSFORMS_SCALAR_OBJCARC_H
+#endif