[llvm] r245541 - [ARC] Pull the ObjC ARC components that really serve the role of
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 01:06:03 PDT 2015
Author: chandlerc
Date: Thu Aug 20 03:06:03 2015
New Revision: 245541
URL: http://llvm.org/viewvc/llvm-project?rev=245541&view=rev
Log:
[ARC] Pull the ObjC ARC components that really serve the role of
analyses into LLVM's Analysis library rather than having them in
a Transforms library.
This is motivated by the need to have the core AliasAnalysis
infrastructure be aware of the ObjCARCAliasAnalysis. However, it also
seems like a nice and clean separation. Everything was very easy to move
and this doesn't create much clutter in the analysis library IMO.
Differential Revision: http://reviews.llvm.org/D12133
Added:
llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h
- copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h
llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h
- copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h
llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h
- copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h
llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp
- copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp
llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp
- copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp
llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp
- copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp
Removed:
llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp
llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h
llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp
llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h
Modified:
llvm/trunk/lib/Analysis/Analysis.cpp
llvm/trunk/lib/Analysis/CMakeLists.txt
llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt
llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp
llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h
llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
llvm/trunk/lib/Transforms/ObjCARC/PtrState.h
Copied: llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h?p2=llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h&p1=llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h Thu Aug 20 03:06:03 2015
@@ -1,4 +1,4 @@
-//===- ObjCARCAliasAnalysis.h - ObjC ARC Optimization -*- C++ -*-----------===//
+//===- ObjCARCAliasAnalysis.h - ObjC ARC Alias Analysis ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -20,8 +20,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
+#ifndef LLVM_ANALYSIS_OBJCARCALIASANALYSIS_H
+#define LLVM_ANALYSIS_OBJCARCALIASANALYSIS_H
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Pass.h"
Copied: llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h?p2=llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h&p1=llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h (original)
+++ llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h Thu Aug 20 03:06:03 2015
@@ -1,4 +1,4 @@
-//===- ObjCARC.h - ObjC ARC Optimization --------------*- C++ -*-----------===//
+//===- ObjCARCAnalysisUtils.h - ObjC ARC Analysis Utilities -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
/// \file
-/// This file defines common definitions/declarations used by the ObjC ARC
-/// Optimizer. ARC stands for Automatic Reference Counting and is a system for
-/// managing reference counts for objects in Objective C.
+/// This file defines common analysis utilities used by the ObjC ARC Optimizer.
+/// ARC stands for Automatic Reference Counting and is a system for managing
+/// reference counts for objects in Objective C.
///
/// WARNING: This file knows about certain library functions. It recognizes them
/// by name, and hardwires knowledge of their semantics.
@@ -20,12 +20,13 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
+#ifndef LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
+#define LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/CallSite.h"
@@ -34,7 +35,6 @@
#include "llvm/Pass.h"
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "ARCInstKind.h"
namespace llvm {
class raw_ostream;
@@ -48,7 +48,7 @@ extern bool EnableARCOpts;
/// \brief Test if the given module looks interesting to run ARC optimization
/// on.
-static inline bool ModuleHasARC(const Module &M) {
+inline bool ModuleHasARC(const Module &M) {
return
M.getNamedValue("objc_retain") ||
M.getNamedValue("objc_release") ||
@@ -73,7 +73,7 @@ static inline bool ModuleHasARC(const Mo
/// \brief This is a wrapper around getUnderlyingObject which also knows how to
/// look through objc_retain and objc_autorelease calls, which we know to return
/// their argument verbatim.
-static inline const Value *GetUnderlyingObjCPtr(const Value *V,
+inline const Value *GetUnderlyingObjCPtr(const Value *V,
const DataLayout &DL) {
for (;;) {
V = GetUnderlyingObject(V, DL);
@@ -100,7 +100,7 @@ static inline const Value *GetUnderlying
///
/// Thus this function strips off pointer casts and forwarding calls. *NOTE*
/// This implies that two RCIdentical values must alias.
-static inline const Value *GetRCIdentityRoot(const Value *V) {
+inline const Value *GetRCIdentityRoot(const Value *V) {
for (;;) {
V = V->stripPointerCasts();
if (!IsForwarding(GetBasicARCInstKind(V)))
@@ -114,56 +114,29 @@ static inline const Value *GetRCIdentity
/// casts away the const of the result. For documentation about what an
/// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that
/// function.
-static inline Value *GetRCIdentityRoot(Value *V) {
+inline Value *GetRCIdentityRoot(Value *V) {
return const_cast<Value *>(GetRCIdentityRoot((const Value *)V));
}
/// \brief Assuming the given instruction is one of the special calls such as
/// objc_retain or objc_release, return the RCIdentity root of the argument of
/// the call.
-static inline Value *GetArgRCIdentityRoot(Value *Inst) {
+inline Value *GetArgRCIdentityRoot(Value *Inst) {
return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0));
}
-static inline bool IsNullOrUndef(const Value *V) {
+inline bool IsNullOrUndef(const Value *V) {
return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
}
-static inline bool IsNoopInstruction(const Instruction *I) {
+inline bool IsNoopInstruction(const Instruction *I) {
return isa<BitCastInst>(I) ||
(isa<GetElementPtrInst>(I) &&
cast<GetElementPtrInst>(I)->hasAllZeroIndices());
}
-
-/// \brief Erase the given instruction.
-///
-/// Many ObjC calls return their argument verbatim,
-/// so if it's such a call and the return value has users, replace them with the
-/// argument value.
-///
-static inline void EraseInstruction(Instruction *CI) {
- Value *OldArg = cast<CallInst>(CI)->getArgOperand(0);
-
- bool Unused = CI->use_empty();
-
- if (!Unused) {
- // Replace the return value with the argument.
- assert((IsForwarding(GetBasicARCInstKind(CI)) ||
- (IsNoopOnNull(GetBasicARCInstKind(CI)) &&
- isa<ConstantPointerNull>(OldArg))) &&
- "Can't delete non-forwarding instruction with users!");
- CI->replaceAllUsesWith(OldArg);
- }
-
- CI->eraseFromParent();
-
- if (Unused)
- RecursivelyDeleteTriviallyDeadInstructions(OldArg);
-}
-
/// \brief Test whether the given value is possible a retainable object pointer.
-static inline bool IsPotentialRetainableObjPtr(const Value *Op) {
+inline bool IsPotentialRetainableObjPtr(const Value *Op) {
// Pointers to static or stack storage are not valid retainable object
// pointers.
if (isa<Constant>(Op) || isa<AllocaInst>(Op))
@@ -188,7 +161,7 @@ static inline bool IsPotentialRetainable
return true;
}
-static inline bool IsPotentialRetainableObjPtr(const Value *Op,
+inline bool IsPotentialRetainableObjPtr(const Value *Op,
AliasAnalysis &AA) {
// First make the rudimentary check.
if (!IsPotentialRetainableObjPtr(Op))
@@ -209,7 +182,7 @@ static inline bool IsPotentialRetainable
/// \brief Helper for GetARCInstKind. Determines what kind of construct CS
/// is.
-static inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) {
+inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) {
for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
I != E; ++I)
if (IsPotentialRetainableObjPtr(*I))
@@ -223,7 +196,7 @@ static inline ARCInstKind GetCallSiteCla
///
/// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
/// special knowledge of ObjC conventions.
-static inline bool IsObjCIdentifiedObject(const Value *V) {
+inline bool IsObjCIdentifiedObject(const Value *V) {
// Assume that call results and arguments have their own "provenance".
// Constants (including GlobalVariables) and Allocas are never
// reference-counted.
Copied: llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h?p2=llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h&p1=llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h (original)
+++ llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h Thu Aug 20 03:06:03 2015
@@ -1,4 +1,4 @@
-//===--- ARCInstKind.h - ARC instruction equivalence classes -*- C++ -*----===//
+//===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCINSTKIND_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_ARCINSTKIND_H
+#ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
+#define LLVM_ANALYSIS_OBJCARCINSTKIND_H
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Function.h"
@@ -98,7 +98,7 @@ ARCInstKind GetFunctionClass(const Funct
/// This is similar to GetARCInstKind except that it only detects objc
/// runtime calls. This allows it to be faster.
///
-static inline ARCInstKind GetBasicARCInstKind(const Value *V) {
+inline ARCInstKind GetBasicARCInstKind(const Value *V) {
if (const CallInst *CI = dyn_cast<CallInst>(V)) {
if (const Function *F = CI->getCalledFunction())
return GetFunctionClass(F);
Modified: llvm/trunk/lib/Analysis/Analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Analysis.cpp?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/Analysis.cpp (original)
+++ llvm/trunk/lib/Analysis/Analysis.cpp Thu Aug 20 03:06:03 2015
@@ -61,6 +61,7 @@ void llvm::initializeAnalysis(PassRegist
initializeMemDerefPrinterPass(Registry);
initializeMemoryDependenceAnalysisPass(Registry);
initializeModuleDebugInfoPrinterPass(Registry);
+ initializeObjCARCAliasAnalysisPass(Registry);
initializePostDominatorTreePass(Registry);
initializeRegionInfoPassPass(Registry);
initializeRegionViewerPass(Registry);
Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
+++ llvm/trunk/lib/Analysis/CMakeLists.txt Thu Aug 20 03:06:03 2015
@@ -49,6 +49,9 @@ add_llvm_library(LLVMAnalysis
MemoryLocation.cpp
ModuleDebugInfoPrinter.cpp
NoAliasAnalysis.cpp
+ ObjCARCAliasAnalysis.cpp
+ ObjCARCAnalysisUtils.cpp
+ ObjCARCInstKind.cpp
OrderedBasicBlock.cpp
PHITransAddr.cpp
PostDominators.cpp
Copied: llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp?p2=llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp&p1=llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp Thu Aug 20 03:06:03 2015
@@ -20,8 +20,8 @@
///
//===----------------------------------------------------------------------===//
-#include "ObjCARC.h"
-#include "ObjCARCAliasAnalysis.h"
+#include "llvm/Analysis/ObjCARCAliasAnalysis.h"
+#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Value.h"
Copied: llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp?p2=llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp&p1=llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp (original)
+++ llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp Thu Aug 20 03:06:03 2015
@@ -1,4 +1,4 @@
-//===-- ObjCARC.cpp -------------------------------------------------------===//
+//===- ObjCARCAnalysisUtils.cpp -------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,16 +13,9 @@
//
//===----------------------------------------------------------------------===//
-#include "ObjCARC.h"
-#include "llvm-c/Core.h"
-#include "llvm-c/Initialization.h"
-#include "llvm/InitializePasses.h"
+#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
#include "llvm/Support/CommandLine.h"
-namespace llvm {
- class PassRegistry;
-}
-
using namespace llvm;
using namespace llvm::objcarc;
@@ -33,18 +26,3 @@ EnableARCOptimizations("enable-objc-arc-
cl::desc("enable/disable all ARC Optimizations"),
cl::location(EnableARCOpts),
cl::init(true));
-
-/// initializeObjCARCOptsPasses - Initialize all passes linked into the
-/// ObjCARCOpts library.
-void llvm::initializeObjCARCOpts(PassRegistry &Registry) {
- initializeObjCARCAliasAnalysisPass(Registry);
- initializeObjCARCAPElimPass(Registry);
- initializeObjCARCExpandPass(Registry);
- initializeObjCARCContractPass(Registry);
- initializeObjCARCOptPass(Registry);
- initializePAEvalPass(Registry);
-}
-
-void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R) {
- initializeObjCARCOpts(*unwrap(R));
-}
Copied: llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp?p2=llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp&p1=llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp (original)
+++ llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp Thu Aug 20 03:06:03 2015
@@ -19,7 +19,9 @@
///
//===----------------------------------------------------------------------===//
-#include "ObjCARC.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
+#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Intrinsics.h"
using namespace llvm;
Removed: llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp?rev=245540&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp (removed)
@@ -1,673 +0,0 @@
-//===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file defines several utility functions used by various ARC
-/// optimizations which are IMHO too big to be in a header file.
-///
-/// WARNING: This file knows about certain library functions. It recognizes them
-/// by name, and hardwires knowledge of their semantics.
-///
-/// WARNING: This file knows about how certain Objective-C library functions are
-/// used. Naive LLVM IR transformations which would otherwise be
-/// behavior-preserving may break these assumptions.
-///
-//===----------------------------------------------------------------------===//
-
-#include "ObjCARC.h"
-#include "llvm/IR/Intrinsics.h"
-
-using namespace llvm;
-using namespace llvm::objcarc;
-
-raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
- const ARCInstKind Class) {
- switch (Class) {
- case ARCInstKind::Retain:
- return OS << "ARCInstKind::Retain";
- case ARCInstKind::RetainRV:
- return OS << "ARCInstKind::RetainRV";
- case ARCInstKind::RetainBlock:
- return OS << "ARCInstKind::RetainBlock";
- case ARCInstKind::Release:
- return OS << "ARCInstKind::Release";
- case ARCInstKind::Autorelease:
- return OS << "ARCInstKind::Autorelease";
- case ARCInstKind::AutoreleaseRV:
- return OS << "ARCInstKind::AutoreleaseRV";
- case ARCInstKind::AutoreleasepoolPush:
- return OS << "ARCInstKind::AutoreleasepoolPush";
- case ARCInstKind::AutoreleasepoolPop:
- return OS << "ARCInstKind::AutoreleasepoolPop";
- case ARCInstKind::NoopCast:
- return OS << "ARCInstKind::NoopCast";
- case ARCInstKind::FusedRetainAutorelease:
- return OS << "ARCInstKind::FusedRetainAutorelease";
- case ARCInstKind::FusedRetainAutoreleaseRV:
- return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
- case ARCInstKind::LoadWeakRetained:
- return OS << "ARCInstKind::LoadWeakRetained";
- case ARCInstKind::StoreWeak:
- return OS << "ARCInstKind::StoreWeak";
- case ARCInstKind::InitWeak:
- return OS << "ARCInstKind::InitWeak";
- case ARCInstKind::LoadWeak:
- return OS << "ARCInstKind::LoadWeak";
- case ARCInstKind::MoveWeak:
- return OS << "ARCInstKind::MoveWeak";
- case ARCInstKind::CopyWeak:
- return OS << "ARCInstKind::CopyWeak";
- case ARCInstKind::DestroyWeak:
- return OS << "ARCInstKind::DestroyWeak";
- case ARCInstKind::StoreStrong:
- return OS << "ARCInstKind::StoreStrong";
- case ARCInstKind::CallOrUser:
- return OS << "ARCInstKind::CallOrUser";
- case ARCInstKind::Call:
- return OS << "ARCInstKind::Call";
- case ARCInstKind::User:
- return OS << "ARCInstKind::User";
- case ARCInstKind::IntrinsicUser:
- return OS << "ARCInstKind::IntrinsicUser";
- case ARCInstKind::None:
- return OS << "ARCInstKind::None";
- }
- llvm_unreachable("Unknown instruction class!");
-}
-
-ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) {
- Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
-
- // No (mandatory) arguments.
- if (AI == AE)
- return StringSwitch<ARCInstKind>(F->getName())
- .Case("objc_autoreleasePoolPush", ARCInstKind::AutoreleasepoolPush)
- .Case("clang.arc.use", ARCInstKind::IntrinsicUser)
- .Default(ARCInstKind::CallOrUser);
-
- // One argument.
- const Argument *A0 = AI++;
- if (AI == AE)
- // Argument is a pointer.
- if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) {
- Type *ETy = PTy->getElementType();
- // Argument is i8*.
- if (ETy->isIntegerTy(8))
- return StringSwitch<ARCInstKind>(F->getName())
- .Case("objc_retain", ARCInstKind::Retain)
- .Case("objc_retainAutoreleasedReturnValue", ARCInstKind::RetainRV)
- .Case("objc_retainBlock", ARCInstKind::RetainBlock)
- .Case("objc_release", ARCInstKind::Release)
- .Case("objc_autorelease", ARCInstKind::Autorelease)
- .Case("objc_autoreleaseReturnValue", ARCInstKind::AutoreleaseRV)
- .Case("objc_autoreleasePoolPop", ARCInstKind::AutoreleasepoolPop)
- .Case("objc_retainedObject", ARCInstKind::NoopCast)
- .Case("objc_unretainedObject", ARCInstKind::NoopCast)
- .Case("objc_unretainedPointer", ARCInstKind::NoopCast)
- .Case("objc_retain_autorelease",
- ARCInstKind::FusedRetainAutorelease)
- .Case("objc_retainAutorelease", ARCInstKind::FusedRetainAutorelease)
- .Case("objc_retainAutoreleaseReturnValue",
- ARCInstKind::FusedRetainAutoreleaseRV)
- .Case("objc_sync_enter", ARCInstKind::User)
- .Case("objc_sync_exit", ARCInstKind::User)
- .Default(ARCInstKind::CallOrUser);
-
- // Argument is i8**
- if (PointerType *Pte = dyn_cast<PointerType>(ETy))
- if (Pte->getElementType()->isIntegerTy(8))
- return StringSwitch<ARCInstKind>(F->getName())
- .Case("objc_loadWeakRetained", ARCInstKind::LoadWeakRetained)
- .Case("objc_loadWeak", ARCInstKind::LoadWeak)
- .Case("objc_destroyWeak", ARCInstKind::DestroyWeak)
- .Default(ARCInstKind::CallOrUser);
- }
-
- // Two arguments, first is i8**.
- const Argument *A1 = AI++;
- if (AI == AE)
- if (PointerType *PTy = dyn_cast<PointerType>(A0->getType()))
- if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType()))
- if (Pte->getElementType()->isIntegerTy(8))
- if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) {
- Type *ETy1 = PTy1->getElementType();
- // Second argument is i8*
- if (ETy1->isIntegerTy(8))
- return StringSwitch<ARCInstKind>(F->getName())
- .Case("objc_storeWeak", ARCInstKind::StoreWeak)
- .Case("objc_initWeak", ARCInstKind::InitWeak)
- .Case("objc_storeStrong", ARCInstKind::StoreStrong)
- .Default(ARCInstKind::CallOrUser);
- // Second argument is i8**.
- if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
- if (Pte1->getElementType()->isIntegerTy(8))
- return StringSwitch<ARCInstKind>(F->getName())
- .Case("objc_moveWeak", ARCInstKind::MoveWeak)
- .Case("objc_copyWeak", ARCInstKind::CopyWeak)
- // Ignore annotation calls. This is important to stop the
- // optimizer from treating annotations as uses which would
- // make the state of the pointers they are attempting to
- // elucidate to be incorrect.
- .Case("llvm.arc.annotation.topdown.bbstart",
- ARCInstKind::None)
- .Case("llvm.arc.annotation.topdown.bbend",
- ARCInstKind::None)
- .Case("llvm.arc.annotation.bottomup.bbstart",
- ARCInstKind::None)
- .Case("llvm.arc.annotation.bottomup.bbend",
- ARCInstKind::None)
- .Default(ARCInstKind::CallOrUser);
- }
-
- // Anything else.
- return ARCInstKind::CallOrUser;
-}
-
-// A whitelist of intrinsics that we know do not use objc pointers or decrement
-// ref counts.
-static bool isInertIntrinsic(unsigned ID) {
- // TODO: Make this into a covered switch.
- switch (ID) {
- case Intrinsic::returnaddress:
- case Intrinsic::frameaddress:
- case Intrinsic::stacksave:
- case Intrinsic::stackrestore:
- case Intrinsic::vastart:
- case Intrinsic::vacopy:
- case Intrinsic::vaend:
- case Intrinsic::objectsize:
- case Intrinsic::prefetch:
- case Intrinsic::stackprotector:
- case Intrinsic::eh_return_i32:
- case Intrinsic::eh_return_i64:
- case Intrinsic::eh_typeid_for:
- case Intrinsic::eh_dwarf_cfa:
- case Intrinsic::eh_sjlj_lsda:
- case Intrinsic::eh_sjlj_functioncontext:
- case Intrinsic::init_trampoline:
- case Intrinsic::adjust_trampoline:
- case Intrinsic::lifetime_start:
- case Intrinsic::lifetime_end:
- case Intrinsic::invariant_start:
- case Intrinsic::invariant_end:
- // Don't let dbg info affect our results.
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- // Short cut: Some intrinsics obviously don't use ObjC pointers.
- return true;
- default:
- return false;
- }
-}
-
-// A whitelist of intrinsics that we know do not use objc pointers or decrement
-// ref counts.
-static bool isUseOnlyIntrinsic(unsigned ID) {
- // We are conservative and even though intrinsics are unlikely to touch
- // reference counts, we white list them for safety.
- //
- // TODO: Expand this into a covered switch. There is a lot more here.
- switch (ID) {
- case Intrinsic::memcpy:
- case Intrinsic::memmove:
- case Intrinsic::memset:
- return true;
- default:
- return false;
- }
-}
-
-/// \brief Determine what kind of construct V is.
-ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) {
- if (const Instruction *I = dyn_cast<Instruction>(V)) {
- // Any instruction other than bitcast and gep with a pointer operand have a
- // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
- // to a subsequent use, rather than using it themselves, in this sense.
- // As a short cut, several other opcodes are known to have no pointer
- // operands of interest. And ret is never followed by a release, so it's
- // not interesting to examine.
- switch (I->getOpcode()) {
- case Instruction::Call: {
- const CallInst *CI = cast<CallInst>(I);
- // See if we have a function that we know something about.
- if (const Function *F = CI->getCalledFunction()) {
- ARCInstKind Class = GetFunctionClass(F);
- if (Class != ARCInstKind::CallOrUser)
- return Class;
- Intrinsic::ID ID = F->getIntrinsicID();
- if (isInertIntrinsic(ID))
- return ARCInstKind::None;
- if (isUseOnlyIntrinsic(ID))
- return ARCInstKind::User;
- }
-
- // Otherwise, be conservative.
- return GetCallSiteClass(CI);
- }
- case Instruction::Invoke:
- // Otherwise, be conservative.
- return GetCallSiteClass(cast<InvokeInst>(I));
- case Instruction::BitCast:
- case Instruction::GetElementPtr:
- case Instruction::Select:
- case Instruction::PHI:
- case Instruction::Ret:
- case Instruction::Br:
- case Instruction::Switch:
- case Instruction::IndirectBr:
- case Instruction::Alloca:
- case Instruction::VAArg:
- case Instruction::Add:
- case Instruction::FAdd:
- case Instruction::Sub:
- case Instruction::FSub:
- case Instruction::Mul:
- case Instruction::FMul:
- case Instruction::SDiv:
- case Instruction::UDiv:
- case Instruction::FDiv:
- case Instruction::SRem:
- case Instruction::URem:
- case Instruction::FRem:
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor:
- case Instruction::SExt:
- case Instruction::ZExt:
- case Instruction::Trunc:
- case Instruction::IntToPtr:
- case Instruction::FCmp:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::FPToUI:
- case Instruction::FPToSI:
- case Instruction::UIToFP:
- case Instruction::SIToFP:
- case Instruction::InsertElement:
- case Instruction::ExtractElement:
- case Instruction::ShuffleVector:
- case Instruction::ExtractValue:
- break;
- case Instruction::ICmp:
- // Comparing a pointer with null, or any other constant, isn't an
- // interesting use, because we don't care what the pointer points to, or
- // about the values of any other dynamic reference-counted pointers.
- if (IsPotentialRetainableObjPtr(I->getOperand(1)))
- return ARCInstKind::User;
- break;
- default:
- // For anything else, check all the operands.
- // Note that this includes both operands of a Store: while the first
- // operand isn't actually being dereferenced, it is being stored to
- // memory where we can no longer track who might read it and dereference
- // it, so we have to consider it potentially used.
- for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
- OI != OE; ++OI)
- if (IsPotentialRetainableObjPtr(*OI))
- return ARCInstKind::User;
- }
- }
-
- // Otherwise, it's totally inert for ARC purposes.
- return ARCInstKind::None;
-}
-
-/// \brief Test if the given class is a kind of user.
-bool llvm::objcarc::IsUser(ARCInstKind Class) {
- switch (Class) {
- case ARCInstKind::User:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::IntrinsicUser:
- return true;
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::RetainBlock:
- case ARCInstKind::Release:
- case ARCInstKind::Autorelease:
- case ARCInstKind::AutoreleaseRV:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::AutoreleasepoolPop:
- case ARCInstKind::NoopCast:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::Call:
- case ARCInstKind::None:
- return false;
- }
- llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class is objc_retain or equivalent.
-bool llvm::objcarc::IsRetain(ARCInstKind Class) {
- switch (Class) {
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- return true;
- // I believe we treat retain block as not a retain since it can copy its
- // block.
- case ARCInstKind::RetainBlock:
- case ARCInstKind::Release:
- case ARCInstKind::Autorelease:
- case ARCInstKind::AutoreleaseRV:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::AutoreleasepoolPop:
- case ARCInstKind::NoopCast:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::IntrinsicUser:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::Call:
- case ARCInstKind::User:
- case ARCInstKind::None:
- return false;
- }
- llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class is objc_autorelease or equivalent.
-bool llvm::objcarc::IsAutorelease(ARCInstKind Class) {
- switch (Class) {
- case ARCInstKind::Autorelease:
- case ARCInstKind::AutoreleaseRV:
- return true;
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::RetainBlock:
- case ARCInstKind::Release:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::AutoreleasepoolPop:
- case ARCInstKind::NoopCast:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::IntrinsicUser:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::Call:
- case ARCInstKind::User:
- case ARCInstKind::None:
- return false;
- }
- llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which return their
-/// argument verbatim.
-bool llvm::objcarc::IsForwarding(ARCInstKind Class) {
- switch (Class) {
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::Autorelease:
- case ARCInstKind::AutoreleaseRV:
- case ARCInstKind::NoopCast:
- return true;
- case ARCInstKind::RetainBlock:
- case ARCInstKind::Release:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::AutoreleasepoolPop:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::IntrinsicUser:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::Call:
- case ARCInstKind::User:
- case ARCInstKind::None:
- return false;
- }
- llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which do nothing if
-/// passed a null pointer.
-bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) {
- switch (Class) {
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::Release:
- case ARCInstKind::Autorelease:
- case ARCInstKind::AutoreleaseRV:
- case ARCInstKind::RetainBlock:
- return true;
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::AutoreleasepoolPop:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::IntrinsicUser:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::Call:
- case ARCInstKind::User:
- case ARCInstKind::None:
- case ARCInstKind::NoopCast:
- return false;
- }
- llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which are always safe
-/// to mark with the "tail" keyword.
-bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) {
- // ARCInstKind::RetainBlock may be given a stack argument.
- switch (Class) {
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::AutoreleaseRV:
- return true;
- case ARCInstKind::Release:
- case ARCInstKind::Autorelease:
- case ARCInstKind::RetainBlock:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::AutoreleasepoolPop:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::IntrinsicUser:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::Call:
- case ARCInstKind::User:
- case ARCInstKind::None:
- case ARCInstKind::NoopCast:
- return false;
- }
- llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which are never safe
-/// to mark with the "tail" keyword.
-bool llvm::objcarc::IsNeverTail(ARCInstKind Class) {
- /// It is never safe to tail call objc_autorelease since by tail calling
- /// objc_autorelease: fast autoreleasing causing our object to be potentially
- /// reclaimed from the autorelease pool which violates the semantics of
- /// __autoreleasing types in ARC.
- switch (Class) {
- case ARCInstKind::Autorelease:
- return true;
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::AutoreleaseRV:
- case ARCInstKind::Release:
- case ARCInstKind::RetainBlock:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::AutoreleasepoolPop:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::IntrinsicUser:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::Call:
- case ARCInstKind::User:
- case ARCInstKind::None:
- case ARCInstKind::NoopCast:
- return false;
- }
- llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which are always safe
-/// to mark with the nounwind attribute.
-bool llvm::objcarc::IsNoThrow(ARCInstKind Class) {
- // objc_retainBlock is not nounwind because it calls user copy constructors
- // which could theoretically throw.
- switch (Class) {
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::Release:
- case ARCInstKind::Autorelease:
- case ARCInstKind::AutoreleaseRV:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::AutoreleasepoolPop:
- return true;
- case ARCInstKind::RetainBlock:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::IntrinsicUser:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::Call:
- case ARCInstKind::User:
- case ARCInstKind::None:
- case ARCInstKind::NoopCast:
- return false;
- }
- llvm_unreachable("covered switch isn't covered?");
-}
-
-/// Test whether the given instruction can autorelease any pointer or cause an
-/// autoreleasepool pop.
-///
-/// This means that it *could* interrupt the RV optimization.
-bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) {
- switch (Class) {
- case ARCInstKind::AutoreleasepoolPop:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::Call:
- case ARCInstKind::Autorelease:
- case ARCInstKind::AutoreleaseRV:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- return true;
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::Release:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::RetainBlock:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::IntrinsicUser:
- case ARCInstKind::User:
- case ARCInstKind::None:
- case ARCInstKind::NoopCast:
- return false;
- }
- llvm_unreachable("covered switch isn't covered?");
-}
-
-bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) {
- switch (Kind) {
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::Autorelease:
- case ARCInstKind::AutoreleaseRV:
- case ARCInstKind::NoopCast:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- case ARCInstKind::IntrinsicUser:
- case ARCInstKind::User:
- case ARCInstKind::None:
- return false;
-
- // The cases below are conservative.
-
- // RetainBlock can result in user defined copy constructors being called
- // implying releases may occur.
- case ARCInstKind::RetainBlock:
- case ARCInstKind::Release:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::AutoreleasepoolPop:
- case ARCInstKind::LoadWeakRetained:
- case ARCInstKind::StoreWeak:
- case ARCInstKind::InitWeak:
- case ARCInstKind::LoadWeak:
- case ARCInstKind::MoveWeak:
- case ARCInstKind::CopyWeak:
- case ARCInstKind::DestroyWeak:
- case ARCInstKind::StoreStrong:
- case ARCInstKind::CallOrUser:
- case ARCInstKind::Call:
- return true;
- }
-
- llvm_unreachable("covered switch isn't covered?");
-}
Removed: llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h?rev=245540&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h (removed)
@@ -1,123 +0,0 @@
-//===--- ARCInstKind.h - ARC instruction equivalence classes -*- C++ -*----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCINSTKIND_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_ARCINSTKIND_H
-
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Function.h"
-
-namespace llvm {
-namespace objcarc {
-
-/// \enum ARCInstKind
-///
-/// \brief Equivalence classes of instructions in the ARC Model.
-///
-/// Since we do not have "instructions" to represent ARC concepts in LLVM IR,
-/// we instead operate on equivalence classes of instructions.
-///
-/// TODO: This should be split into two enums: a runtime entry point enum
-/// (possibly united with the ARCRuntimeEntrypoint class) and an enum that deals
-/// with effects of instructions in the ARC model (which would handle the notion
-/// of a User or CallOrUser).
-enum class ARCInstKind {
- Retain, ///< objc_retain
- RetainRV, ///< objc_retainAutoreleasedReturnValue
- RetainBlock, ///< objc_retainBlock
- Release, ///< objc_release
- Autorelease, ///< objc_autorelease
- AutoreleaseRV, ///< objc_autoreleaseReturnValue
- AutoreleasepoolPush, ///< objc_autoreleasePoolPush
- AutoreleasepoolPop, ///< objc_autoreleasePoolPop
- NoopCast, ///< objc_retainedObject, etc.
- FusedRetainAutorelease, ///< objc_retainAutorelease
- FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
- LoadWeakRetained, ///< objc_loadWeakRetained (primitive)
- StoreWeak, ///< objc_storeWeak (primitive)
- InitWeak, ///< objc_initWeak (derived)
- LoadWeak, ///< objc_loadWeak (derived)
- MoveWeak, ///< objc_moveWeak (derived)
- CopyWeak, ///< objc_copyWeak (derived)
- DestroyWeak, ///< objc_destroyWeak (derived)
- StoreStrong, ///< objc_storeStrong (derived)
- IntrinsicUser, ///< clang.arc.use
- CallOrUser, ///< could call objc_release and/or "use" pointers
- Call, ///< could call objc_release
- User, ///< could "use" a pointer
- None ///< anything that is inert from an ARC perspective.
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class);
-
-/// \brief Test if the given class is a kind of user.
-bool IsUser(ARCInstKind Class);
-
-/// \brief Test if the given class is objc_retain or equivalent.
-bool IsRetain(ARCInstKind Class);
-
-/// \brief Test if the given class is objc_autorelease or equivalent.
-bool IsAutorelease(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which return their
-/// argument verbatim.
-bool IsForwarding(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which do nothing if
-/// passed a null pointer.
-bool IsNoopOnNull(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which are always safe
-/// to mark with the "tail" keyword.
-bool IsAlwaysTail(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which are never safe
-/// to mark with the "tail" keyword.
-bool IsNeverTail(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which are always safe
-/// to mark with the nounwind attribute.
-bool IsNoThrow(ARCInstKind Class);
-
-/// Test whether the given instruction can autorelease any pointer or cause an
-/// autoreleasepool pop.
-bool CanInterruptRV(ARCInstKind Class);
-
-/// \brief Determine if F is one of the special known Functions. If it isn't,
-/// return ARCInstKind::CallOrUser.
-ARCInstKind GetFunctionClass(const Function *F);
-
-/// \brief Determine which objc runtime call instruction class V belongs to.
-///
-/// This is similar to GetARCInstKind except that it only detects objc
-/// runtime calls. This allows it to be faster.
-///
-static inline ARCInstKind GetBasicARCInstKind(const Value *V) {
- if (const CallInst *CI = dyn_cast<CallInst>(V)) {
- if (const Function *F = CI->getCalledFunction())
- return GetFunctionClass(F);
- // Otherwise, be conservative.
- return ARCInstKind::CallOrUser;
- }
-
- // Otherwise, be conservative.
- return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User;
-}
-
-/// Map V to its ARCInstKind equivalence class.
-ARCInstKind GetARCInstKind(const Value *V);
-
-/// Returns false if conservatively we can prove that any instruction mapped to
-/// this kind can not decrement ref counts. Returns true otherwise.
-bool CanDecrementRefCount(ARCInstKind Kind);
-
-} // end namespace objcarc
-} // end namespace llvm
-
-#endif
Modified: llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt Thu Aug 20 03:06:03 2015
@@ -3,8 +3,6 @@ add_llvm_library(LLVMObjCARCOpts
ObjCARCOpts.cpp
ObjCARCExpand.cpp
ObjCARCAPElim.cpp
- ObjCARCAliasAnalysis.cpp
- ARCInstKind.cpp
ObjCARCContract.cpp
DependencyAnalysis.cpp
ProvenanceAnalysis.cpp
Modified: llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp Thu Aug 20 03:06:03 2015
@@ -26,14 +26,6 @@ namespace llvm {
using namespace llvm;
using namespace llvm::objcarc;
-/// \brief A handy option to enable/disable all ARC Optimizations.
-bool llvm::objcarc::EnableARCOpts;
-static cl::opt<bool, true>
-EnableARCOptimizations("enable-objc-arc-opts",
- cl::desc("enable/disable all ARC Optimizations"),
- cl::location(EnableARCOpts),
- cl::init(true));
-
/// initializeObjCARCOptsPasses - Initialize all passes linked into the
/// ObjCARCOpts library.
void llvm::initializeObjCARCOpts(PassRegistry &Registry) {
Modified: llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h Thu Aug 20 03:06:03 2015
@@ -26,6 +26,8 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/CallSite.h"
@@ -34,7 +36,6 @@
#include "llvm/Pass.h"
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "ARCInstKind.h"
namespace llvm {
class raw_ostream;
@@ -43,99 +44,6 @@ class raw_ostream;
namespace llvm {
namespace objcarc {
-/// \brief A handy option to enable/disable all ARC Optimizations.
-extern bool EnableARCOpts;
-
-/// \brief Test if the given module looks interesting to run ARC optimization
-/// on.
-static inline bool ModuleHasARC(const Module &M) {
- return
- M.getNamedValue("objc_retain") ||
- M.getNamedValue("objc_release") ||
- M.getNamedValue("objc_autorelease") ||
- M.getNamedValue("objc_retainAutoreleasedReturnValue") ||
- M.getNamedValue("objc_retainBlock") ||
- M.getNamedValue("objc_autoreleaseReturnValue") ||
- M.getNamedValue("objc_autoreleasePoolPush") ||
- M.getNamedValue("objc_loadWeakRetained") ||
- M.getNamedValue("objc_loadWeak") ||
- M.getNamedValue("objc_destroyWeak") ||
- M.getNamedValue("objc_storeWeak") ||
- M.getNamedValue("objc_initWeak") ||
- M.getNamedValue("objc_moveWeak") ||
- M.getNamedValue("objc_copyWeak") ||
- M.getNamedValue("objc_retainedObject") ||
- M.getNamedValue("objc_unretainedObject") ||
- M.getNamedValue("objc_unretainedPointer") ||
- M.getNamedValue("clang.arc.use");
-}
-
-/// \brief This is a wrapper around getUnderlyingObject which also knows how to
-/// look through objc_retain and objc_autorelease calls, which we know to return
-/// their argument verbatim.
-static inline const Value *GetUnderlyingObjCPtr(const Value *V,
- const DataLayout &DL) {
- for (;;) {
- V = GetUnderlyingObject(V, DL);
- if (!IsForwarding(GetBasicARCInstKind(V)))
- break;
- V = cast<CallInst>(V)->getArgOperand(0);
- }
-
- return V;
-}
-
-/// The RCIdentity root of a value \p V is a dominating value U for which
-/// retaining or releasing U is equivalent to retaining or releasing V. In other
-/// words, ARC operations on \p V are equivalent to ARC operations on \p U.
-///
-/// We use this in the ARC optimizer to make it easier to match up ARC
-/// operations by always mapping ARC operations to RCIdentityRoots instead of
-/// pointers themselves.
-///
-/// The two ways that we see RCIdentical values in ObjC are via:
-///
-/// 1. PointerCasts
-/// 2. Forwarding Calls that return their argument verbatim.
-///
-/// Thus this function strips off pointer casts and forwarding calls. *NOTE*
-/// This implies that two RCIdentical values must alias.
-static inline const Value *GetRCIdentityRoot(const Value *V) {
- for (;;) {
- V = V->stripPointerCasts();
- if (!IsForwarding(GetBasicARCInstKind(V)))
- break;
- V = cast<CallInst>(V)->getArgOperand(0);
- }
- return V;
-}
-
-/// Helper which calls const Value *GetRCIdentityRoot(const Value *V) and just
-/// casts away the const of the result. For documentation about what an
-/// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that
-/// function.
-static inline Value *GetRCIdentityRoot(Value *V) {
- return const_cast<Value *>(GetRCIdentityRoot((const Value *)V));
-}
-
-/// \brief Assuming the given instruction is one of the special calls such as
-/// objc_retain or objc_release, return the RCIdentity root of the argument of
-/// the call.
-static inline Value *GetArgRCIdentityRoot(Value *Inst) {
- return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0));
-}
-
-static inline bool IsNullOrUndef(const Value *V) {
- return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
-}
-
-static inline bool IsNoopInstruction(const Instruction *I) {
- return isa<BitCastInst>(I) ||
- (isa<GetElementPtrInst>(I) &&
- cast<GetElementPtrInst>(I)->hasAllZeroIndices());
-}
-
-
/// \brief Erase the given instruction.
///
/// Many ObjC calls return their argument verbatim,
@@ -162,152 +70,6 @@ static inline void EraseInstruction(Inst
RecursivelyDeleteTriviallyDeadInstructions(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.
- 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;
- // Only consider values with pointer types.
- //
- // It seemes intuitive to exclude function pointer types as well, since
- // functions are never retainable object pointers, however clang occasionally
- // bitcasts retainable object pointers to function-pointer type temporarily.
- PointerType *Ty = dyn_cast<PointerType>(Op->getType());
- if (!Ty)
- return false;
- // Conservatively assume anything else is a potential retainable object
- // pointer.
- return true;
-}
-
-static inline bool IsPotentialRetainableObjPtr(const Value *Op,
- AliasAnalysis &AA) {
- // First make the rudimentary check.
- if (!IsPotentialRetainableObjPtr(Op))
- return false;
-
- // Objects in constant memory are not reference-counted.
- if (AA.pointsToConstantMemory(Op))
- return false;
-
- // Pointers in constant memory are not pointing to reference-counted objects.
- if (const LoadInst *LI = dyn_cast<LoadInst>(Op))
- if (AA.pointsToConstantMemory(LI->getPointerOperand()))
- return false;
-
- // Otherwise assume the worst.
- return true;
-}
-
-/// \brief Helper for GetARCInstKind. Determines what kind of construct CS
-/// is.
-static inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) {
- for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
- I != E; ++I)
- if (IsPotentialRetainableObjPtr(*I))
- return CS.onlyReadsMemory() ? ARCInstKind::User : ARCInstKind::CallOrUser;
-
- return CS.onlyReadsMemory() ? ARCInstKind::None : ARCInstKind::Call;
-}
-
-/// \brief Return true if this value refers to a distinct and identifiable
-/// object.
-///
-/// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
-/// special knowledge of ObjC conventions.
-static inline bool IsObjCIdentifiedObject(const Value *V) {
- // Assume that call results and arguments have their own "provenance".
- // Constants (including GlobalVariables) and Allocas are never
- // reference-counted.
- if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
- isa<Argument>(V) || isa<Constant>(V) ||
- isa<AllocaInst>(V))
- return true;
-
- if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
- const Value *Pointer =
- GetRCIdentityRoot(LI->getPointerOperand());
- if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
- // A constant pointer can't be pointing to an object on the heap. It may
- // be reference-counted, but it won't be deleted.
- if (GV->isConstant())
- return true;
- StringRef Name = GV->getName();
- // These special variables are known to hold values which are not
- // reference-counted pointers.
- if (Name.startswith("\01l_objc_msgSend_fixup_"))
- return true;
-
- StringRef Section = GV->getSection();
- if (Section.find("__message_refs") != StringRef::npos ||
- Section.find("__objc_classrefs") != StringRef::npos ||
- Section.find("__objc_superrefs") != StringRef::npos ||
- Section.find("__objc_methname") != StringRef::npos ||
- Section.find("__cstring") != StringRef::npos)
- return true;
- }
- }
-
- return false;
-}
-
-enum class ARCMDKindID {
- ImpreciseRelease,
- CopyOnEscape,
- NoObjCARCExceptions,
-};
-
-/// A cache of MDKinds used by various ARC optimizations.
-class ARCMDKindCache {
- Module *M;
-
- /// The Metadata Kind for clang.imprecise_release metadata.
- llvm::Optional<unsigned> ImpreciseReleaseMDKind;
-
- /// The Metadata Kind for clang.arc.copy_on_escape metadata.
- llvm::Optional<unsigned> CopyOnEscapeMDKind;
-
- /// The Metadata Kind for clang.arc.no_objc_arc_exceptions metadata.
- llvm::Optional<unsigned> NoObjCARCExceptionsMDKind;
-
-public:
- void init(Module *Mod) {
- M = Mod;
- ImpreciseReleaseMDKind = NoneType::None;
- CopyOnEscapeMDKind = NoneType::None;
- NoObjCARCExceptionsMDKind = NoneType::None;
- }
-
- unsigned get(ARCMDKindID ID) {
- switch (ID) {
- case ARCMDKindID::ImpreciseRelease:
- if (!ImpreciseReleaseMDKind)
- ImpreciseReleaseMDKind =
- M->getContext().getMDKindID("clang.imprecise_release");
- return *ImpreciseReleaseMDKind;
- case ARCMDKindID::CopyOnEscape:
- if (!CopyOnEscapeMDKind)
- CopyOnEscapeMDKind =
- M->getContext().getMDKindID("clang.arc.copy_on_escape");
- return *CopyOnEscapeMDKind;
- case ARCMDKindID::NoObjCARCExceptions:
- if (!NoObjCARCExceptionsMDKind)
- NoObjCARCExceptionsMDKind =
- M->getContext().getMDKindID("clang.arc.no_objc_arc_exceptions");
- return *NoObjCARCExceptionsMDKind;
- }
- llvm_unreachable("Covered switch isn't covered?!");
- }
-};
-
} // end namespace objcarc
} // end namespace llvm
Removed: llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp?rev=245540&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp (removed)
@@ -1,162 +0,0 @@
-//===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file defines a simple ARC-aware AliasAnalysis using special knowledge
-/// of Objective C to enhance other optimization passes which rely on the Alias
-/// Analysis infrastructure.
-///
-/// WARNING: This file knows about certain library functions. It recognizes them
-/// by name, and hardwires knowledge of their semantics.
-///
-/// WARNING: This file knows about how certain Objective-C library functions are
-/// used. Naive LLVM IR transformations which would otherwise be
-/// behavior-preserving may break these assumptions.
-///
-//===----------------------------------------------------------------------===//
-
-#include "ObjCARC.h"
-#include "ObjCARCAliasAnalysis.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Value.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/PassAnalysisSupport.h"
-#include "llvm/PassSupport.h"
-
-#define DEBUG_TYPE "objc-arc-aa"
-
-using namespace llvm;
-using namespace llvm::objcarc;
-
-// Register this pass...
-char ObjCARCAliasAnalysis::ID = 0;
-INITIALIZE_AG_PASS(ObjCARCAliasAnalysis, AliasAnalysis, "objc-arc-aa",
- "ObjC-ARC-Based Alias Analysis", false, true, false)
-
-ImmutablePass *llvm::createObjCARCAliasAnalysisPass() {
- return new ObjCARCAliasAnalysis();
-}
-
-bool ObjCARCAliasAnalysis::doInitialization(Module &M) {
- InitializeAliasAnalysis(this, &M.getDataLayout());
- return true;
-}
-
-void ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AliasAnalysis::getAnalysisUsage(AU);
-}
-
-AliasResult ObjCARCAliasAnalysis::alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB) {
- if (!EnableARCOpts)
- return AliasAnalysis::alias(LocA, LocB);
-
- // First, strip off no-ops, including ObjC-specific no-ops, and try making a
- // precise alias query.
- const Value *SA = GetRCIdentityRoot(LocA.Ptr);
- const Value *SB = GetRCIdentityRoot(LocB.Ptr);
- AliasResult Result =
- AliasAnalysis::alias(MemoryLocation(SA, LocA.Size, LocA.AATags),
- MemoryLocation(SB, LocB.Size, LocB.AATags));
- if (Result != MayAlias)
- return Result;
-
- // If that failed, climb to the underlying object, including climbing through
- // ObjC-specific no-ops, and try making an imprecise alias query.
- const Value *UA = GetUnderlyingObjCPtr(SA, *DL);
- const Value *UB = GetUnderlyingObjCPtr(SB, *DL);
- if (UA != SA || UB != SB) {
- Result = AliasAnalysis::alias(MemoryLocation(UA), MemoryLocation(UB));
- // We can't use MustAlias or PartialAlias results here because
- // GetUnderlyingObjCPtr may return an offsetted pointer value.
- if (Result == NoAlias)
- return NoAlias;
- }
-
- // If that failed, fail. We don't need to chain here, since that's covered
- // by the earlier precise query.
- return MayAlias;
-}
-
-bool ObjCARCAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc,
- bool OrLocal) {
- if (!EnableARCOpts)
- return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
-
- // First, strip off no-ops, including ObjC-specific no-ops, and try making
- // a precise alias query.
- const Value *S = GetRCIdentityRoot(Loc.Ptr);
- if (AliasAnalysis::pointsToConstantMemory(
- MemoryLocation(S, Loc.Size, Loc.AATags), OrLocal))
- return true;
-
- // If that failed, climb to the underlying object, including climbing through
- // ObjC-specific no-ops, and try making an imprecise alias query.
- const Value *U = GetUnderlyingObjCPtr(S, *DL);
- if (U != S)
- return AliasAnalysis::pointsToConstantMemory(MemoryLocation(U), OrLocal);
-
- // If that failed, fail. We don't need to chain here, since that's covered
- // by the earlier precise query.
- return false;
-}
-
-FunctionModRefBehavior
-ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
- // We have nothing to do. Just chain to the next AliasAnalysis.
- return AliasAnalysis::getModRefBehavior(CS);
-}
-
-FunctionModRefBehavior
-ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
- if (!EnableARCOpts)
- return AliasAnalysis::getModRefBehavior(F);
-
- switch (GetFunctionClass(F)) {
- case ARCInstKind::NoopCast:
- return FMRB_DoesNotAccessMemory;
- default:
- break;
- }
-
- return AliasAnalysis::getModRefBehavior(F);
-}
-
-ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) {
- if (!EnableARCOpts)
- return AliasAnalysis::getModRefInfo(CS, Loc);
-
- switch (GetBasicARCInstKind(CS.getInstruction())) {
- case ARCInstKind::Retain:
- case ARCInstKind::RetainRV:
- case ARCInstKind::Autorelease:
- case ARCInstKind::AutoreleaseRV:
- case ARCInstKind::NoopCast:
- case ARCInstKind::AutoreleasepoolPush:
- case ARCInstKind::FusedRetainAutorelease:
- case ARCInstKind::FusedRetainAutoreleaseRV:
- // These functions don't access any memory visible to the compiler.
- // Note that this doesn't include objc_retainBlock, because it updates
- // pointers when it copies block data.
- return MRI_NoModRef;
- default:
- break;
- }
-
- return AliasAnalysis::getModRefInfo(CS, Loc);
-}
-
-ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) {
- // TODO: Theoretically we could check for dependencies between objc_* calls
- // and FMRB_OnlyAccessesArgumentPointees calls or other well-behaved calls.
- return AliasAnalysis::getModRefInfo(CS1, CS2);
-}
Removed: llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h?rev=245540&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h (removed)
@@ -1,72 +0,0 @@
-//===- ObjCARCAliasAnalysis.h - ObjC ARC Optimization -*- C++ -*-----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file declares a simple ARC-aware AliasAnalysis using special knowledge
-/// of Objective C to enhance other optimization passes which rely on the Alias
-/// Analysis infrastructure.
-///
-/// WARNING: This file knows about certain library functions. It recognizes them
-/// by name, and hardwires knowledge of their semantics.
-///
-/// WARNING: This file knows about how certain Objective-C library functions are
-/// used. Naive LLVM IR transformations which would otherwise be
-/// behavior-preserving may break these assumptions.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
-
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Pass.h"
-
-namespace llvm {
-namespace objcarc {
-
-/// \brief This is a simple alias analysis implementation that uses knowledge
-/// of ARC constructs to answer queries.
-///
-/// TODO: This class could be generalized to know about other ObjC-specific
-/// tricks. Such as knowing that ivars in the non-fragile ABI are non-aliasing
-/// even though their offsets are dynamic.
-class ObjCARCAliasAnalysis : public ImmutablePass, public AliasAnalysis {
-public:
- static char ID; // Class identification, replacement for typeinfo
- ObjCARCAliasAnalysis() : ImmutablePass(ID) {
- initializeObjCARCAliasAnalysisPass(*PassRegistry::getPassRegistry());
- }
-
-private:
- bool doInitialization(Module &M) override;
-
- /// This method is used when a pass implements an analysis interface through
- /// multiple inheritance. If needed, it should override this to adjust the
- /// this pointer as needed for the specified pass info.
- void *getAdjustedAnalysisPointer(const void *PI) override {
- if (PI == &AliasAnalysis::ID)
- return static_cast<AliasAnalysis *>(this);
- return this;
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- AliasResult alias(const MemoryLocation &LocA,
- const MemoryLocation &LocB) override;
- bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) override;
- FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
- FunctionModRefBehavior getModRefBehavior(const Function *F) override;
- ModRefInfo getModRefInfo(ImmutableCallSite CS,
- const MemoryLocation &Loc) override;
- ModRefInfo getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) override;
-};
-
-} // namespace objcarc
-} // namespace llvm
-
-#endif
Modified: llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp Thu Aug 20 03:06:03 2015
@@ -28,7 +28,6 @@
#include "ARCRuntimeEntryPoints.h"
#include "BlotMapVector.h"
#include "DependencyAnalysis.h"
-#include "ObjCARCAliasAnalysis.h"
#include "ProvenanceAnalysis.h"
#include "PtrState.h"
#include "llvm/ADT/DenseMap.h"
@@ -36,6 +35,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/ObjCARCAliasAnalysis.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
Modified: llvm/trunk/lib/Transforms/ObjCARC/PtrState.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/PtrState.h?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/PtrState.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/PtrState.h Thu Aug 20 03:06:03 2015
@@ -17,8 +17,8 @@
#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H
#define LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H
-#include "ARCInstKind.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/raw_ostream.h"
More information about the llvm-commits
mailing list