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