forked from OSchip/llvm-project
				
			Created ObjCARCUtil.cpp for functions which in my humble opinion are too large to static inline and place in a header file such as ObjCARC.h.
llvm-svn: 173666
This commit is contained in:
		
							parent
							
								
									d269a3e281
								
							
						
					
					
						commit
						5ed40afe17
					
				| 
						 | 
				
			
			@ -4,6 +4,7 @@ add_llvm_library(LLVMObjCARCOpts
 | 
			
		|||
  ObjCARCExpand.cpp
 | 
			
		||||
  ObjCARCAPElim.cpp
 | 
			
		||||
  ObjCARCAliasAnalysis.cpp
 | 
			
		||||
  ObjCARCUtil.cpp
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
add_dependencies(LLVMObjCARCOpts intrinsics_gen)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,60 +91,7 @@ enum InstructionClass {
 | 
			
		|||
  IC_None                 ///< anything else
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static raw_ostream &operator<<(raw_ostream &OS, const InstructionClass Class)
 | 
			
		||||
  LLVM_ATTRIBUTE_USED;
 | 
			
		||||
 | 
			
		||||
static raw_ostream &operator<<(raw_ostream &OS, const InstructionClass Class) {
 | 
			
		||||
  switch (Class) {
 | 
			
		||||
  case IC_Retain:
 | 
			
		||||
    return OS << "IC_Retain";
 | 
			
		||||
  case IC_RetainRV:
 | 
			
		||||
    return OS << "IC_RetainRV";
 | 
			
		||||
  case IC_RetainBlock:
 | 
			
		||||
    return OS << "IC_RetainBlock";
 | 
			
		||||
  case IC_Release:
 | 
			
		||||
    return OS << "IC_Release";
 | 
			
		||||
  case IC_Autorelease:
 | 
			
		||||
    return OS << "IC_Autorelease";
 | 
			
		||||
  case IC_AutoreleaseRV:
 | 
			
		||||
    return OS << "IC_AutoreleaseRV";
 | 
			
		||||
  case IC_AutoreleasepoolPush:
 | 
			
		||||
    return OS << "IC_AutoreleasepoolPush";
 | 
			
		||||
  case IC_AutoreleasepoolPop:
 | 
			
		||||
    return OS << "IC_AutoreleasepoolPop";
 | 
			
		||||
  case IC_NoopCast:
 | 
			
		||||
    return OS << "IC_NoopCast";
 | 
			
		||||
  case IC_FusedRetainAutorelease:
 | 
			
		||||
    return OS << "IC_FusedRetainAutorelease";
 | 
			
		||||
  case IC_FusedRetainAutoreleaseRV:
 | 
			
		||||
    return OS << "IC_FusedRetainAutoreleaseRV";
 | 
			
		||||
  case IC_LoadWeakRetained:
 | 
			
		||||
    return OS << "IC_LoadWeakRetained";
 | 
			
		||||
  case IC_StoreWeak:
 | 
			
		||||
    return OS << "IC_StoreWeak";
 | 
			
		||||
  case IC_InitWeak:
 | 
			
		||||
    return OS << "IC_InitWeak";
 | 
			
		||||
  case IC_LoadWeak:
 | 
			
		||||
    return OS << "IC_LoadWeak";
 | 
			
		||||
  case IC_MoveWeak:
 | 
			
		||||
    return OS << "IC_MoveWeak";
 | 
			
		||||
  case IC_CopyWeak:
 | 
			
		||||
    return OS << "IC_CopyWeak";
 | 
			
		||||
  case IC_DestroyWeak:
 | 
			
		||||
    return OS << "IC_DestroyWeak";
 | 
			
		||||
  case IC_StoreStrong:
 | 
			
		||||
    return OS << "IC_StoreStrong";
 | 
			
		||||
  case IC_CallOrUser:
 | 
			
		||||
    return OS << "IC_CallOrUser";
 | 
			
		||||
  case IC_Call:
 | 
			
		||||
    return OS << "IC_Call";
 | 
			
		||||
  case IC_User:
 | 
			
		||||
    return OS << "IC_User";
 | 
			
		||||
  case IC_None:
 | 
			
		||||
    return OS << "IC_None";
 | 
			
		||||
  }
 | 
			
		||||
  llvm_unreachable("Unknown instruction class!");
 | 
			
		||||
}
 | 
			
		||||
raw_ostream &operator<<(raw_ostream &OS, const InstructionClass Class);
 | 
			
		||||
 | 
			
		||||
/// \brief Test if the given class is objc_retain or equivalent.
 | 
			
		||||
static inline bool IsRetain(InstructionClass Class) {
 | 
			
		||||
| 
						 | 
				
			
			@ -218,78 +165,7 @@ static inline bool IsNoThrow(InstructionClass Class) {
 | 
			
		|||
 | 
			
		||||
/// \brief Determine if F is one of the special known Functions.  If it isn't,
 | 
			
		||||
/// return IC_CallOrUser.
 | 
			
		||||
static InstructionClass GetFunctionClass(const Function *F)
 | 
			
		||||
  LLVM_ATTRIBUTE_USED;
 | 
			
		||||
static InstructionClass GetFunctionClass(const Function *F) {
 | 
			
		||||
  Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
 | 
			
		||||
 | 
			
		||||
  // No arguments.
 | 
			
		||||
  if (AI == AE)
 | 
			
		||||
    return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
      .Case("objc_autoreleasePoolPush",  IC_AutoreleasepoolPush)
 | 
			
		||||
      .Default(IC_CallOrUser);
 | 
			
		||||
 | 
			
		||||
  // One argument.
 | 
			
		||||
  const Argument *A0 = AI++;
 | 
			
		||||
  if (AI == AE)
 | 
			
		||||
    // Argument is a pointer.
 | 
			
		||||
    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) {
 | 
			
		||||
      Type *ETy = PTy->getElementType();
 | 
			
		||||
      // Argument is i8*.
 | 
			
		||||
      if (ETy->isIntegerTy(8))
 | 
			
		||||
        return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
          .Case("objc_retain",                IC_Retain)
 | 
			
		||||
          .Case("objc_retainAutoreleasedReturnValue", IC_RetainRV)
 | 
			
		||||
          .Case("objc_retainBlock",           IC_RetainBlock)
 | 
			
		||||
          .Case("objc_release",               IC_Release)
 | 
			
		||||
          .Case("objc_autorelease",           IC_Autorelease)
 | 
			
		||||
          .Case("objc_autoreleaseReturnValue", IC_AutoreleaseRV)
 | 
			
		||||
          .Case("objc_autoreleasePoolPop",    IC_AutoreleasepoolPop)
 | 
			
		||||
          .Case("objc_retainedObject",        IC_NoopCast)
 | 
			
		||||
          .Case("objc_unretainedObject",      IC_NoopCast)
 | 
			
		||||
          .Case("objc_unretainedPointer",     IC_NoopCast)
 | 
			
		||||
          .Case("objc_retain_autorelease",    IC_FusedRetainAutorelease)
 | 
			
		||||
          .Case("objc_retainAutorelease",     IC_FusedRetainAutorelease)
 | 
			
		||||
          .Case("objc_retainAutoreleaseReturnValue",IC_FusedRetainAutoreleaseRV)
 | 
			
		||||
          .Default(IC_CallOrUser);
 | 
			
		||||
 | 
			
		||||
      // Argument is i8**
 | 
			
		||||
      if (PointerType *Pte = dyn_cast<PointerType>(ETy))
 | 
			
		||||
        if (Pte->getElementType()->isIntegerTy(8))
 | 
			
		||||
          return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
            .Case("objc_loadWeakRetained",      IC_LoadWeakRetained)
 | 
			
		||||
            .Case("objc_loadWeak",              IC_LoadWeak)
 | 
			
		||||
            .Case("objc_destroyWeak",           IC_DestroyWeak)
 | 
			
		||||
            .Default(IC_CallOrUser);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  // Two arguments, first is i8**.
 | 
			
		||||
  const Argument *A1 = AI++;
 | 
			
		||||
  if (AI == AE)
 | 
			
		||||
    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType()))
 | 
			
		||||
      if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType()))
 | 
			
		||||
        if (Pte->getElementType()->isIntegerTy(8))
 | 
			
		||||
          if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) {
 | 
			
		||||
            Type *ETy1 = PTy1->getElementType();
 | 
			
		||||
            // Second argument is i8*
 | 
			
		||||
            if (ETy1->isIntegerTy(8))
 | 
			
		||||
              return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
                     .Case("objc_storeWeak",             IC_StoreWeak)
 | 
			
		||||
                     .Case("objc_initWeak",              IC_InitWeak)
 | 
			
		||||
                     .Case("objc_storeStrong",           IC_StoreStrong)
 | 
			
		||||
                     .Default(IC_CallOrUser);
 | 
			
		||||
            // Second argument is i8**.
 | 
			
		||||
            if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
 | 
			
		||||
              if (Pte1->getElementType()->isIntegerTy(8))
 | 
			
		||||
                return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
                       .Case("objc_moveWeak",              IC_MoveWeak)
 | 
			
		||||
                       .Case("objc_copyWeak",              IC_CopyWeak)
 | 
			
		||||
                       .Default(IC_CallOrUser);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
  // Anything else.
 | 
			
		||||
  return IC_CallOrUser;
 | 
			
		||||
}
 | 
			
		||||
InstructionClass GetFunctionClass(const Function *F);
 | 
			
		||||
 | 
			
		||||
/// \brief Determine which objc runtime call instruction class V belongs to.
 | 
			
		||||
///
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,149 @@
 | 
			
		|||
//===- ObjCARCUtil.h - ObjC ARC Optimization ----------*- mode: c++ -*-----===//
 | 
			
		||||
//
 | 
			
		||||
//                     The LLVM Compiler Infrastructure
 | 
			
		||||
//
 | 
			
		||||
// This file is distributed under the University of Illinois Open Source
 | 
			
		||||
// License. See LICENSE.TXT for details.
 | 
			
		||||
//
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
/// \file
 | 
			
		||||
/// This file defines several utility functions used by various ARC
 | 
			
		||||
/// optimizations which are IMHO too big to be in a header file.
 | 
			
		||||
///
 | 
			
		||||
/// WARNING: This file knows about certain library functions. It recognizes them
 | 
			
		||||
/// by name, and hardwires knowledge of their semantics.
 | 
			
		||||
///
 | 
			
		||||
/// WARNING: This file knows about how certain Objective-C library functions are
 | 
			
		||||
/// used. Naive LLVM IR transformations which would otherwise be
 | 
			
		||||
/// behavior-preserving may break these assumptions.
 | 
			
		||||
///
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
#include "ObjCARC.h"
 | 
			
		||||
 | 
			
		||||
using namespace llvm;
 | 
			
		||||
using namespace llvm::objcarc;
 | 
			
		||||
 | 
			
		||||
raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
 | 
			
		||||
                                       const InstructionClass Class) {
 | 
			
		||||
  switch (Class) {
 | 
			
		||||
  case IC_Retain:
 | 
			
		||||
    return OS << "IC_Retain";
 | 
			
		||||
  case IC_RetainRV:
 | 
			
		||||
    return OS << "IC_RetainRV";
 | 
			
		||||
  case IC_RetainBlock:
 | 
			
		||||
    return OS << "IC_RetainBlock";
 | 
			
		||||
  case IC_Release:
 | 
			
		||||
    return OS << "IC_Release";
 | 
			
		||||
  case IC_Autorelease:
 | 
			
		||||
    return OS << "IC_Autorelease";
 | 
			
		||||
  case IC_AutoreleaseRV:
 | 
			
		||||
    return OS << "IC_AutoreleaseRV";
 | 
			
		||||
  case IC_AutoreleasepoolPush:
 | 
			
		||||
    return OS << "IC_AutoreleasepoolPush";
 | 
			
		||||
  case IC_AutoreleasepoolPop:
 | 
			
		||||
    return OS << "IC_AutoreleasepoolPop";
 | 
			
		||||
  case IC_NoopCast:
 | 
			
		||||
    return OS << "IC_NoopCast";
 | 
			
		||||
  case IC_FusedRetainAutorelease:
 | 
			
		||||
    return OS << "IC_FusedRetainAutorelease";
 | 
			
		||||
  case IC_FusedRetainAutoreleaseRV:
 | 
			
		||||
    return OS << "IC_FusedRetainAutoreleaseRV";
 | 
			
		||||
  case IC_LoadWeakRetained:
 | 
			
		||||
    return OS << "IC_LoadWeakRetained";
 | 
			
		||||
  case IC_StoreWeak:
 | 
			
		||||
    return OS << "IC_StoreWeak";
 | 
			
		||||
  case IC_InitWeak:
 | 
			
		||||
    return OS << "IC_InitWeak";
 | 
			
		||||
  case IC_LoadWeak:
 | 
			
		||||
    return OS << "IC_LoadWeak";
 | 
			
		||||
  case IC_MoveWeak:
 | 
			
		||||
    return OS << "IC_MoveWeak";
 | 
			
		||||
  case IC_CopyWeak:
 | 
			
		||||
    return OS << "IC_CopyWeak";
 | 
			
		||||
  case IC_DestroyWeak:
 | 
			
		||||
    return OS << "IC_DestroyWeak";
 | 
			
		||||
  case IC_StoreStrong:
 | 
			
		||||
    return OS << "IC_StoreStrong";
 | 
			
		||||
  case IC_CallOrUser:
 | 
			
		||||
    return OS << "IC_CallOrUser";
 | 
			
		||||
  case IC_Call:
 | 
			
		||||
    return OS << "IC_Call";
 | 
			
		||||
  case IC_User:
 | 
			
		||||
    return OS << "IC_User";
 | 
			
		||||
  case IC_None:
 | 
			
		||||
    return OS << "IC_None";
 | 
			
		||||
  }
 | 
			
		||||
  llvm_unreachable("Unknown instruction class!");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
InstructionClass llvm::objcarc::GetFunctionClass(const Function *F) {
 | 
			
		||||
  Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
 | 
			
		||||
 | 
			
		||||
  // No arguments.
 | 
			
		||||
  if (AI == AE)
 | 
			
		||||
    return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
      .Case("objc_autoreleasePoolPush",  IC_AutoreleasepoolPush)
 | 
			
		||||
      .Default(IC_CallOrUser);
 | 
			
		||||
 | 
			
		||||
  // One argument.
 | 
			
		||||
  const Argument *A0 = AI++;
 | 
			
		||||
  if (AI == AE)
 | 
			
		||||
    // Argument is a pointer.
 | 
			
		||||
    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) {
 | 
			
		||||
      Type *ETy = PTy->getElementType();
 | 
			
		||||
      // Argument is i8*.
 | 
			
		||||
      if (ETy->isIntegerTy(8))
 | 
			
		||||
        return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
          .Case("objc_retain",                IC_Retain)
 | 
			
		||||
          .Case("objc_retainAutoreleasedReturnValue", IC_RetainRV)
 | 
			
		||||
          .Case("objc_retainBlock",           IC_RetainBlock)
 | 
			
		||||
          .Case("objc_release",               IC_Release)
 | 
			
		||||
          .Case("objc_autorelease",           IC_Autorelease)
 | 
			
		||||
          .Case("objc_autoreleaseReturnValue", IC_AutoreleaseRV)
 | 
			
		||||
          .Case("objc_autoreleasePoolPop",    IC_AutoreleasepoolPop)
 | 
			
		||||
          .Case("objc_retainedObject",        IC_NoopCast)
 | 
			
		||||
          .Case("objc_unretainedObject",      IC_NoopCast)
 | 
			
		||||
          .Case("objc_unretainedPointer",     IC_NoopCast)
 | 
			
		||||
          .Case("objc_retain_autorelease",    IC_FusedRetainAutorelease)
 | 
			
		||||
          .Case("objc_retainAutorelease",     IC_FusedRetainAutorelease)
 | 
			
		||||
          .Case("objc_retainAutoreleaseReturnValue",IC_FusedRetainAutoreleaseRV)
 | 
			
		||||
          .Default(IC_CallOrUser);
 | 
			
		||||
 | 
			
		||||
      // Argument is i8**
 | 
			
		||||
      if (PointerType *Pte = dyn_cast<PointerType>(ETy))
 | 
			
		||||
        if (Pte->getElementType()->isIntegerTy(8))
 | 
			
		||||
          return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
            .Case("objc_loadWeakRetained",      IC_LoadWeakRetained)
 | 
			
		||||
            .Case("objc_loadWeak",              IC_LoadWeak)
 | 
			
		||||
            .Case("objc_destroyWeak",           IC_DestroyWeak)
 | 
			
		||||
            .Default(IC_CallOrUser);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  // Two arguments, first is i8**.
 | 
			
		||||
  const Argument *A1 = AI++;
 | 
			
		||||
  if (AI == AE)
 | 
			
		||||
    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType()))
 | 
			
		||||
      if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType()))
 | 
			
		||||
        if (Pte->getElementType()->isIntegerTy(8))
 | 
			
		||||
          if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) {
 | 
			
		||||
            Type *ETy1 = PTy1->getElementType();
 | 
			
		||||
            // Second argument is i8*
 | 
			
		||||
            if (ETy1->isIntegerTy(8))
 | 
			
		||||
              return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
                .Case("objc_storeWeak",             IC_StoreWeak)
 | 
			
		||||
                .Case("objc_initWeak",              IC_InitWeak)
 | 
			
		||||
                .Case("objc_storeStrong",           IC_StoreStrong)
 | 
			
		||||
                .Default(IC_CallOrUser);
 | 
			
		||||
            // Second argument is i8**.
 | 
			
		||||
            if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
 | 
			
		||||
              if (Pte1->getElementType()->isIntegerTy(8))
 | 
			
		||||
                return StringSwitch<InstructionClass>(F->getName())
 | 
			
		||||
                  .Case("objc_moveWeak",              IC_MoveWeak)
 | 
			
		||||
                  .Case("objc_copyWeak",              IC_CopyWeak)
 | 
			
		||||
                  .Default(IC_CallOrUser);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
  // Anything else.
 | 
			
		||||
  return IC_CallOrUser;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue