-//===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -*- mode: c++ -*---===//
+//===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -------------------===//
//
// The LLVM Compiler Infrastructure
//
///
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "objc-arc-aa"
#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"
-namespace llvm {
- class Function;
- class Value;
-}
+#define DEBUG_TYPE "objc-arc-aa"
using namespace llvm;
using namespace llvm::objcarc;
return new ObjCARCAliasAnalysis();
}
-void
-ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
+bool ObjCARCAliasAnalysis::doInitialization(Module &M) {
+ InitializeAliasAnalysis(this, &M.getDataLayout());
+ return true;
+}
+
+void ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AliasAnalysis::getAnalysisUsage(AU);
}
-AliasAnalysis::AliasResult
-ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) {
+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 = StripPointerCastsAndObjCCalls(LocA.Ptr);
- const Value *SB = StripPointerCastsAndObjCCalls(LocB.Ptr);
+ const Value *SA = GetRCIdentityRoot(LocA.Ptr);
+ const Value *SB = GetRCIdentityRoot(LocB.Ptr);
AliasResult Result =
- AliasAnalysis::alias(Location(SA, LocA.Size, LocA.TBAATag),
- Location(SB, LocB.Size, LocB.TBAATag));
+ 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);
- const Value *UB = GetUnderlyingObjCPtr(SB);
+ const Value *UA = GetUnderlyingObjCPtr(SA, *DL);
+ const Value *UB = GetUnderlyingObjCPtr(SB, *DL);
if (UA != SA || UB != SB) {
- Result = AliasAnalysis::alias(Location(UA), Location(UB));
+ 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 MayAlias;
}
-bool
-ObjCARCAliasAnalysis::pointsToConstantMemory(const Location &Loc,
- bool OrLocal) {
+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 = StripPointerCastsAndObjCCalls(Loc.Ptr);
- if (AliasAnalysis::pointsToConstantMemory(Location(S, Loc.Size, Loc.TBAATag),
- OrLocal))
+ 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);
+ const Value *U = GetUnderlyingObjCPtr(S, *DL);
if (U != S)
- return AliasAnalysis::pointsToConstantMemory(Location(U), OrLocal);
+ 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;
}
-AliasAnalysis::ModRefBehavior
+FunctionModRefBehavior
ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
// We have nothing to do. Just chain to the next AliasAnalysis.
return AliasAnalysis::getModRefBehavior(CS);
}
-AliasAnalysis::ModRefBehavior
+FunctionModRefBehavior
ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
if (!EnableARCOpts)
return AliasAnalysis::getModRefBehavior(F);
switch (GetFunctionClass(F)) {
- case IC_NoopCast:
- return DoesNotAccessMemory;
+ case ARCInstKind::NoopCast:
+ return FMRB_DoesNotAccessMemory;
default:
break;
}
return AliasAnalysis::getModRefBehavior(F);
}
-AliasAnalysis::ModRefResult
-ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) {
+ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
+ const MemoryLocation &Loc) {
if (!EnableARCOpts)
return AliasAnalysis::getModRefInfo(CS, Loc);
- switch (GetBasicInstructionClass(CS.getInstruction())) {
- case IC_Retain:
- case IC_RetainRV:
- case IC_Autorelease:
- case IC_AutoreleaseRV:
- case IC_NoopCast:
- case IC_AutoreleasepoolPush:
- case IC_FusedRetainAutorelease:
- case IC_FusedRetainAutoreleaseRV:
+ 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 NoModRef;
+ return MRI_NoModRef;
default:
break;
}
return AliasAnalysis::getModRefInfo(CS, Loc);
}
-AliasAnalysis::ModRefResult
-ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) {
+ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) {
// TODO: Theoretically we could check for dependencies between objc_* calls
- // and OnlyAccessesArgumentPointees calls or other well-behaved calls.
+ // and FMRB_OnlyAccessesArgumentPointees calls or other well-behaved calls.
return AliasAnalysis::getModRefInfo(CS1, CS2);
}
-