1023d2bbbbedc6ed991b11381a987673133be2c81Michael Gottesman//===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -------------------===// 26086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman// 36086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman// The LLVM Compiler Infrastructure 46086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman// 56086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman// This file is distributed under the University of Illinois Open Source 66086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman// License. See LICENSE.TXT for details. 76086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman// 86086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman//===----------------------------------------------------------------------===// 96086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// \file 106086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// This file defines a simple ARC-aware AliasAnalysis using special knowledge 116086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// of Objective C to enhance other optimization passes which rely on the Alias 126086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// Analysis infrastructure. 136086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// 146086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// WARNING: This file knows about certain library functions. It recognizes them 156086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// by name, and hardwires knowledge of their semantics. 166086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// 176086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// WARNING: This file knows about how certain Objective-C library functions are 186086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// used. Naive LLVM IR transformations which would otherwise be 196086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// behavior-preserving may break these assumptions. 206086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman/// 216086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman//===----------------------------------------------------------------------===// 226086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 236086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman#include "ObjCARC.h" 246086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman#include "ObjCARCAliasAnalysis.h" 256086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman#include "llvm/IR/Instruction.h" 266086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman#include "llvm/InitializePasses.h" 276086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman#include "llvm/PassAnalysisSupport.h" 286086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman#include "llvm/PassSupport.h" 296086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "objc-arc-aa" 31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 326086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmannamespace llvm { 336086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman class Function; 346086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman class Value; 356086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman} 366086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 376086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanusing namespace llvm; 386086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanusing namespace llvm::objcarc; 396086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 406086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman// Register this pass... 416086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanchar ObjCARCAliasAnalysis::ID = 0; 426086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanINITIALIZE_AG_PASS(ObjCARCAliasAnalysis, AliasAnalysis, "objc-arc-aa", 436086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman "ObjC-ARC-Based Alias Analysis", false, true, false) 446086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 456086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanImmutablePass *llvm::createObjCARCAliasAnalysisPass() { 466086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return new ObjCARCAliasAnalysis(); 476086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman} 486086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 496086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanvoid 506086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { 516086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman AU.setPreservesAll(); 526086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman AliasAnalysis::getAnalysisUsage(AU); 536086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman} 546086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 556086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanAliasAnalysis::AliasResult 566086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) { 576086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman if (!EnableARCOpts) 586086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return AliasAnalysis::alias(LocA, LocB); 596086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 606086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // First, strip off no-ops, including ObjC-specific no-ops, and try making a 616086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // precise alias query. 626086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman const Value *SA = StripPointerCastsAndObjCCalls(LocA.Ptr); 636086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman const Value *SB = StripPointerCastsAndObjCCalls(LocB.Ptr); 646086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman AliasResult Result = 656086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman AliasAnalysis::alias(Location(SA, LocA.Size, LocA.TBAATag), 666086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman Location(SB, LocB.Size, LocB.TBAATag)); 676086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman if (Result != MayAlias) 686086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return Result; 696086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 706086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // If that failed, climb to the underlying object, including climbing through 716086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // ObjC-specific no-ops, and try making an imprecise alias query. 726086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman const Value *UA = GetUnderlyingObjCPtr(SA); 736086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman const Value *UB = GetUnderlyingObjCPtr(SB); 746086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman if (UA != SA || UB != SB) { 756086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman Result = AliasAnalysis::alias(Location(UA), Location(UB)); 766086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // We can't use MustAlias or PartialAlias results here because 776086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // GetUnderlyingObjCPtr may return an offsetted pointer value. 786086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman if (Result == NoAlias) 796086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return NoAlias; 806086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman } 816086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 826086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // If that failed, fail. We don't need to chain here, since that's covered 836086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // by the earlier precise query. 846086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return MayAlias; 856086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman} 866086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 876086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesmanbool 886086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanObjCARCAliasAnalysis::pointsToConstantMemory(const Location &Loc, 896086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman bool OrLocal) { 906086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman if (!EnableARCOpts) 916086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); 926086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 936086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // First, strip off no-ops, including ObjC-specific no-ops, and try making 946086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // a precise alias query. 956086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman const Value *S = StripPointerCastsAndObjCCalls(Loc.Ptr); 966086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman if (AliasAnalysis::pointsToConstantMemory(Location(S, Loc.Size, Loc.TBAATag), 976086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman OrLocal)) 986086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return true; 996086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1006086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // If that failed, climb to the underlying object, including climbing through 1016086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // ObjC-specific no-ops, and try making an imprecise alias query. 1026086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman const Value *U = GetUnderlyingObjCPtr(S); 1036086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman if (U != S) 1046086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return AliasAnalysis::pointsToConstantMemory(Location(U), OrLocal); 1056086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1066086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // If that failed, fail. We don't need to chain here, since that's covered 1076086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // by the earlier precise query. 1086086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return false; 1096086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman} 1106086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1116086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanAliasAnalysis::ModRefBehavior 1126086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { 1136086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // We have nothing to do. Just chain to the next AliasAnalysis. 1146086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return AliasAnalysis::getModRefBehavior(CS); 1156086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman} 1166086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1176086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanAliasAnalysis::ModRefBehavior 1186086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanObjCARCAliasAnalysis::getModRefBehavior(const Function *F) { 1196086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman if (!EnableARCOpts) 1206086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return AliasAnalysis::getModRefBehavior(F); 1216086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1226086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman switch (GetFunctionClass(F)) { 1236086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman case IC_NoopCast: 1246086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return DoesNotAccessMemory; 1256086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman default: 1266086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman break; 1276086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman } 1286086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1296086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return AliasAnalysis::getModRefBehavior(F); 1306086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman} 1316086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1326086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanAliasAnalysis::ModRefResult 1336086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) { 1346086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman if (!EnableARCOpts) 1356086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return AliasAnalysis::getModRefInfo(CS, Loc); 1366086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1376086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman switch (GetBasicInstructionClass(CS.getInstruction())) { 1386086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman case IC_Retain: 1396086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman case IC_RetainRV: 1406086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman case IC_Autorelease: 1416086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman case IC_AutoreleaseRV: 1426086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman case IC_NoopCast: 1436086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman case IC_AutoreleasepoolPush: 1446086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman case IC_FusedRetainAutorelease: 1456086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman case IC_FusedRetainAutoreleaseRV: 1466086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // These functions don't access any memory visible to the compiler. 1476086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // Note that this doesn't include objc_retainBlock, because it updates 1486086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // pointers when it copies block data. 1496086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return NoModRef; 1506086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman default: 1516086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman break; 1526086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman } 1536086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1546086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return AliasAnalysis::getModRefInfo(CS, Loc); 1556086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman} 1566086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman 1576086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanAliasAnalysis::ModRefResult 1586086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael GottesmanObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1, 1596086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman ImmutableCallSite CS2) { 1606086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // TODO: Theoretically we could check for dependencies between objc_* calls 1616086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman // and OnlyAccessesArgumentPointees calls or other well-behaved calls. 1626086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman return AliasAnalysis::getModRefInfo(CS1, CS2); 1636086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman} 164