LLVM API Documentation

ObjCARCAliasAnalysis.cpp
Go to the documentation of this file.
00001 //===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 /// \file
00010 /// This file defines a simple ARC-aware AliasAnalysis using special knowledge
00011 /// of Objective C to enhance other optimization passes which rely on the Alias
00012 /// Analysis infrastructure.
00013 ///
00014 /// WARNING: This file knows about certain library functions. It recognizes them
00015 /// by name, and hardwires knowledge of their semantics.
00016 ///
00017 /// WARNING: This file knows about how certain Objective-C library functions are
00018 /// used. Naive LLVM IR transformations which would otherwise be
00019 /// behavior-preserving may break these assumptions.
00020 ///
00021 //===----------------------------------------------------------------------===//
00022 
00023 #define DEBUG_TYPE "objc-arc-aa"
00024 #include "ObjCARC.h"
00025 #include "ObjCARCAliasAnalysis.h"
00026 #include "llvm/IR/Instruction.h"
00027 #include "llvm/InitializePasses.h"
00028 #include "llvm/PassAnalysisSupport.h"
00029 #include "llvm/PassSupport.h"
00030 
00031 namespace llvm {
00032   class Function;
00033   class Value;
00034 }
00035 
00036 using namespace llvm;
00037 using namespace llvm::objcarc;
00038 
00039 // Register this pass...
00040 char ObjCARCAliasAnalysis::ID = 0;
00041 INITIALIZE_AG_PASS(ObjCARCAliasAnalysis, AliasAnalysis, "objc-arc-aa",
00042                    "ObjC-ARC-Based Alias Analysis", false, true, false)
00043 
00044 ImmutablePass *llvm::createObjCARCAliasAnalysisPass() {
00045   return new ObjCARCAliasAnalysis();
00046 }
00047 
00048 void
00049 ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
00050   AU.setPreservesAll();
00051   AliasAnalysis::getAnalysisUsage(AU);
00052 }
00053 
00054 AliasAnalysis::AliasResult
00055 ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) {
00056   if (!EnableARCOpts)
00057     return AliasAnalysis::alias(LocA, LocB);
00058 
00059   // First, strip off no-ops, including ObjC-specific no-ops, and try making a
00060   // precise alias query.
00061   const Value *SA = StripPointerCastsAndObjCCalls(LocA.Ptr);
00062   const Value *SB = StripPointerCastsAndObjCCalls(LocB.Ptr);
00063   AliasResult Result =
00064     AliasAnalysis::alias(Location(SA, LocA.Size, LocA.TBAATag),
00065                          Location(SB, LocB.Size, LocB.TBAATag));
00066   if (Result != MayAlias)
00067     return Result;
00068 
00069   // If that failed, climb to the underlying object, including climbing through
00070   // ObjC-specific no-ops, and try making an imprecise alias query.
00071   const Value *UA = GetUnderlyingObjCPtr(SA);
00072   const Value *UB = GetUnderlyingObjCPtr(SB);
00073   if (UA != SA || UB != SB) {
00074     Result = AliasAnalysis::alias(Location(UA), Location(UB));
00075     // We can't use MustAlias or PartialAlias results here because
00076     // GetUnderlyingObjCPtr may return an offsetted pointer value.
00077     if (Result == NoAlias)
00078       return NoAlias;
00079   }
00080 
00081   // If that failed, fail. We don't need to chain here, since that's covered
00082   // by the earlier precise query.
00083   return MayAlias;
00084 }
00085 
00086 bool
00087 ObjCARCAliasAnalysis::pointsToConstantMemory(const Location &Loc,
00088                                              bool OrLocal) {
00089   if (!EnableARCOpts)
00090     return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
00091 
00092   // First, strip off no-ops, including ObjC-specific no-ops, and try making
00093   // a precise alias query.
00094   const Value *S = StripPointerCastsAndObjCCalls(Loc.Ptr);
00095   if (AliasAnalysis::pointsToConstantMemory(Location(S, Loc.Size, Loc.TBAATag),
00096                                             OrLocal))
00097     return true;
00098 
00099   // If that failed, climb to the underlying object, including climbing through
00100   // ObjC-specific no-ops, and try making an imprecise alias query.
00101   const Value *U = GetUnderlyingObjCPtr(S);
00102   if (U != S)
00103     return AliasAnalysis::pointsToConstantMemory(Location(U), OrLocal);
00104 
00105   // If that failed, fail. We don't need to chain here, since that's covered
00106   // by the earlier precise query.
00107   return false;
00108 }
00109 
00110 AliasAnalysis::ModRefBehavior
00111 ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
00112   // We have nothing to do. Just chain to the next AliasAnalysis.
00113   return AliasAnalysis::getModRefBehavior(CS);
00114 }
00115 
00116 AliasAnalysis::ModRefBehavior
00117 ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
00118   if (!EnableARCOpts)
00119     return AliasAnalysis::getModRefBehavior(F);
00120 
00121   switch (GetFunctionClass(F)) {
00122   case IC_NoopCast:
00123     return DoesNotAccessMemory;
00124   default:
00125     break;
00126   }
00127 
00128   return AliasAnalysis::getModRefBehavior(F);
00129 }
00130 
00131 AliasAnalysis::ModRefResult
00132 ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) {
00133   if (!EnableARCOpts)
00134     return AliasAnalysis::getModRefInfo(CS, Loc);
00135 
00136   switch (GetBasicInstructionClass(CS.getInstruction())) {
00137   case IC_Retain:
00138   case IC_RetainRV:
00139   case IC_Autorelease:
00140   case IC_AutoreleaseRV:
00141   case IC_NoopCast:
00142   case IC_AutoreleasepoolPush:
00143   case IC_FusedRetainAutorelease:
00144   case IC_FusedRetainAutoreleaseRV:
00145     // These functions don't access any memory visible to the compiler.
00146     // Note that this doesn't include objc_retainBlock, because it updates
00147     // pointers when it copies block data.
00148     return NoModRef;
00149   default:
00150     break;
00151   }
00152 
00153   return AliasAnalysis::getModRefInfo(CS, Loc);
00154 }
00155 
00156 AliasAnalysis::ModRefResult
00157 ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
00158                                     ImmutableCallSite CS2) {
00159   // TODO: Theoretically we could check for dependencies between objc_* calls
00160   // and OnlyAccessesArgumentPointees calls or other well-behaved calls.
00161   return AliasAnalysis::getModRefInfo(CS1, CS2);
00162 }