LCOV - code coverage report
Current view: top level - lib/Analysis - ObjCARCAliasAnalysis.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 35 39 89.7 %
Date: 2017-09-14 15:23:50 Functions: 10 12 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : /// \file
      10             : /// This file defines a simple ARC-aware AliasAnalysis using special knowledge
      11             : /// of Objective C to enhance other optimization passes which rely on the Alias
      12             : /// Analysis infrastructure.
      13             : ///
      14             : /// WARNING: This file knows about certain library functions. It recognizes them
      15             : /// by name, and hardwires knowledge of their semantics.
      16             : ///
      17             : /// WARNING: This file knows about how certain Objective-C library functions are
      18             : /// used. Naive LLVM IR transformations which would otherwise be
      19             : /// behavior-preserving may break these assumptions.
      20             : ///
      21             : /// TODO: Theoretically we could check for dependencies between objc_* calls
      22             : /// and FMRB_OnlyAccessesArgumentPointees calls or other well-behaved calls.
      23             : ///
      24             : //===----------------------------------------------------------------------===//
      25             : 
      26             : #include "llvm/Analysis/ObjCARCAliasAnalysis.h"
      27             : #include "llvm/Analysis/ObjCARCAnalysisUtils.h"
      28             : #include "llvm/IR/Function.h"
      29             : #include "llvm/IR/Instruction.h"
      30             : #include "llvm/IR/Value.h"
      31             : #include "llvm/InitializePasses.h"
      32             : #include "llvm/PassAnalysisSupport.h"
      33             : #include "llvm/PassSupport.h"
      34             : 
      35             : #define DEBUG_TYPE "objc-arc-aa"
      36             : 
      37             : using namespace llvm;
      38             : using namespace llvm::objcarc;
      39             : 
      40        1333 : AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA,
      41             :                                    const MemoryLocation &LocB) {
      42        1333 :   if (!EnableARCOpts)
      43             :     return AAResultBase::alias(LocA, LocB);
      44             : 
      45             :   // First, strip off no-ops, including ObjC-specific no-ops, and try making a
      46             :   // precise alias query.
      47        1333 :   const Value *SA = GetRCIdentityRoot(LocA.Ptr);
      48        1333 :   const Value *SB = GetRCIdentityRoot(LocB.Ptr);
      49             :   AliasResult Result =
      50        3999 :       AAResultBase::alias(MemoryLocation(SA, LocA.Size, LocA.AATags),
      51        3999 :                           MemoryLocation(SB, LocB.Size, LocB.AATags));
      52             :   if (Result != MayAlias)
      53             :     return Result;
      54             : 
      55             :   // If that failed, climb to the underlying object, including climbing through
      56             :   // ObjC-specific no-ops, and try making an imprecise alias query.
      57        1333 :   const Value *UA = GetUnderlyingObjCPtr(SA, DL);
      58        1333 :   const Value *UB = GetUnderlyingObjCPtr(SB, DL);
      59             :   if (UA != SA || UB != SB) {
      60             :     Result = AAResultBase::alias(MemoryLocation(UA), MemoryLocation(UB));
      61             :     // We can't use MustAlias or PartialAlias results here because
      62             :     // GetUnderlyingObjCPtr may return an offsetted pointer value.
      63             :     if (Result == NoAlias)
      64             :       return NoAlias;
      65             :   }
      66             : 
      67             :   // If that failed, fail. We don't need to chain here, since that's covered
      68             :   // by the earlier precise query.
      69             :   return MayAlias;
      70             : }
      71             : 
      72        1350 : bool ObjCARCAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
      73             :                                              bool OrLocal) {
      74        1350 :   if (!EnableARCOpts)
      75             :     return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
      76             : 
      77             :   // First, strip off no-ops, including ObjC-specific no-ops, and try making
      78             :   // a precise alias query.
      79        1350 :   const Value *S = GetRCIdentityRoot(Loc.Ptr);
      80        2700 :   if (AAResultBase::pointsToConstantMemory(
      81        2700 :           MemoryLocation(S, Loc.Size, Loc.AATags), OrLocal))
      82             :     return true;
      83             : 
      84             :   // If that failed, climb to the underlying object, including climbing through
      85             :   // ObjC-specific no-ops, and try making an imprecise alias query.
      86        1350 :   const Value *U = GetUnderlyingObjCPtr(S, DL);
      87             :   if (U != S)
      88             :     return AAResultBase::pointsToConstantMemory(MemoryLocation(U), OrLocal);
      89             : 
      90             :   // If that failed, fail. We don't need to chain here, since that's covered
      91             :   // by the earlier precise query.
      92             :   return false;
      93             : }
      94             : 
      95        2189 : FunctionModRefBehavior ObjCARCAAResult::getModRefBehavior(const Function *F) {
      96        2189 :   if (!EnableARCOpts)
      97             :     return AAResultBase::getModRefBehavior(F);
      98             : 
      99        2189 :   switch (GetFunctionClass(F)) {
     100             :   case ARCInstKind::NoopCast:
     101             :     return FMRB_DoesNotAccessMemory;
     102             :   default:
     103             :     break;
     104             :   }
     105             : 
     106        2189 :   return AAResultBase::getModRefBehavior(F);
     107             : }
     108             : 
     109         285 : ModRefInfo ObjCARCAAResult::getModRefInfo(ImmutableCallSite CS,
     110             :                                           const MemoryLocation &Loc) {
     111         285 :   if (!EnableARCOpts)
     112             :     return AAResultBase::getModRefInfo(CS, Loc);
     113             : 
     114         285 :   switch (GetBasicARCInstKind(CS.getInstruction())) {
     115             :   case ARCInstKind::Retain:
     116             :   case ARCInstKind::RetainRV:
     117             :   case ARCInstKind::Autorelease:
     118             :   case ARCInstKind::AutoreleaseRV:
     119             :   case ARCInstKind::NoopCast:
     120             :   case ARCInstKind::AutoreleasepoolPush:
     121             :   case ARCInstKind::FusedRetainAutorelease:
     122             :   case ARCInstKind::FusedRetainAutoreleaseRV:
     123             :     // These functions don't access any memory visible to the compiler.
     124             :     // Note that this doesn't include objc_retainBlock, because it updates
     125             :     // pointers when it copies block data.
     126             :     return MRI_NoModRef;
     127             :   default:
     128             :     break;
     129             :   }
     130             : 
     131         189 :   return AAResultBase::getModRefInfo(CS, Loc);
     132             : }
     133             : 
     134           0 : ObjCARCAAResult ObjCARCAA::run(Function &F, FunctionAnalysisManager &AM) {
     135           0 :   return ObjCARCAAResult(F.getParent()->getDataLayout());
     136             : }
     137             : 
     138             : char ObjCARCAAWrapperPass::ID = 0;
     139      348846 : INITIALIZE_PASS(ObjCARCAAWrapperPass, "objc-arc-aa",
     140             :                 "ObjC-ARC-Based Alias Analysis", false, true)
     141             : 
     142           0 : ImmutablePass *llvm::createObjCARCAAWrapperPass() {
     143           0 :   return new ObjCARCAAWrapperPass();
     144             : }
     145             : 
     146          87 : ObjCARCAAWrapperPass::ObjCARCAAWrapperPass() : ImmutablePass(ID) {
     147          29 :   initializeObjCARCAAWrapperPassPass(*PassRegistry::getPassRegistry());
     148          29 : }
     149             : 
     150          29 : bool ObjCARCAAWrapperPass::doInitialization(Module &M) {
     151          87 :   Result.reset(new ObjCARCAAResult(M.getDataLayout()));
     152          29 :   return false;
     153             : }
     154             : 
     155          29 : bool ObjCARCAAWrapperPass::doFinalization(Module &M) {
     156          58 :   Result.reset();
     157          29 :   return false;
     158             : }
     159             : 
     160          29 : void ObjCARCAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
     161          29 :   AU.setPreservesAll();
     162          29 : }

Generated by: LCOV version 1.13