16504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman//===- ObjCARCExpand.cpp - ObjC ARC Optimization --------------------------===// 26504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman// 36504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman// The LLVM Compiler Infrastructure 46504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman// 56504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman// This file is distributed under the University of Illinois Open Source 66504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman// License. See LICENSE.TXT for details. 76504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman// 86504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman//===----------------------------------------------------------------------===// 96504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// \file 106504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// This file defines ObjC ARC optimizations. ARC stands for Automatic 116504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// Reference Counting and is a system for managing reference counts for objects 126504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// in Objective C. 136504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// 146504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// This specific file deals with early optimizations which perform certain 156504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// cleanup operations. 166504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// 176504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// WARNING: This file knows about certain library functions. It recognizes them 186504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// by name, and hardwires knowledge of their semantics. 196504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// 206504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// WARNING: This file knows about how certain Objective-C library functions are 216504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// used. Naive LLVM IR transformations which would otherwise be 226504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// behavior-preserving may break these assumptions. 236504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman/// 246504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman//===----------------------------------------------------------------------===// 256504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 266504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#include "ObjCARC.h" 27074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/ADT/StringRef.h" 28074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/IR/Function.h" 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstIterator.h" 30074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/IR/Instruction.h" 31074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/IR/Instructions.h" 32074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/IR/Value.h" 33074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/Pass.h" 34074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/PassAnalysisSupport.h" 35074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/PassRegistry.h" 36074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/PassSupport.h" 37074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/Support/Casting.h" 38074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/Support/Debug.h" 39074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman#include "llvm/Support/raw_ostream.h" 40074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "objc-arc-expand" 42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 43074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesmannamespace llvm { 44074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman class Module; 45074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman} 46074ddd6f014b8b3488e53d22a961874230afb0d5Michael Gottesman 476504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanusing namespace llvm; 486504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanusing namespace llvm::objcarc; 496504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 506504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmannamespace { 516504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman /// \brief Early ARC transformations. 526504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman class ObjCARCExpand : public FunctionPass { 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override; 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool doInitialization(Module &M) override; 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &F) override; 566504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 576504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman /// A flag indicating whether this optimization pass should run. 586504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman bool Run; 596504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 606504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman public: 616504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman static char ID; 626504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman ObjCARCExpand() : FunctionPass(ID) { 636504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman initializeObjCARCExpandPass(*PassRegistry::getPassRegistry()); 646504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman } 656504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman }; 666504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman} 676504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 686504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanchar ObjCARCExpand::ID = 0; 696504255a2257c53df8ab191c1db4517139f5dc8cMichael GottesmanINITIALIZE_PASS(ObjCARCExpand, 706504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman "objc-arc-expand", "ObjC ARC expansion", false, false) 716504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 726504255a2257c53df8ab191c1db4517139f5dc8cMichael GottesmanPass *llvm::createObjCARCExpandPass() { 736504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman return new ObjCARCExpand(); 746504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman} 756504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 766504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanvoid ObjCARCExpand::getAnalysisUsage(AnalysisUsage &AU) const { 776504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman AU.setPreservesCFG(); 786504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman} 796504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 806504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanbool ObjCARCExpand::doInitialization(Module &M) { 816504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman Run = ModuleHasARC(M); 826504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman return false; 836504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman} 846504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 856504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanbool ObjCARCExpand::runOnFunction(Function &F) { 866504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman if (!EnableARCOpts) 876504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman return false; 886504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 896504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman // If nothing in the Module uses ARC, don't do anything. 906504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman if (!Run) 916504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman return false; 926504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 936504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman bool Changed = false; 946504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 956504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman DEBUG(dbgs() << "ObjCARCExpand: Visiting Function: " << F.getName() << "\n"); 966504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 976504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) { 986504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman Instruction *Inst = &*I; 996504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 1006504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman DEBUG(dbgs() << "ObjCARCExpand: Visiting: " << *Inst << "\n"); 1016504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 1026504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman switch (GetBasicInstructionClass(Inst)) { 1036504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman case IC_Retain: 1046504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman case IC_RetainRV: 1056504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman case IC_Autorelease: 1066504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman case IC_AutoreleaseRV: 1076504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman case IC_FusedRetainAutorelease: 1086504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman case IC_FusedRetainAutoreleaseRV: { 1096504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman // These calls return their argument verbatim, as a low-level 1106504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman // optimization. However, this makes high-level optimizations 1116504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman // harder. Undo any uses of this optimization that the front-end 1126504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman // emitted here. We'll redo them in the contract pass. 1136504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman Changed = true; 1146504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman Value *Value = cast<CallInst>(Inst)->getArgOperand(0); 1156504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman DEBUG(dbgs() << "ObjCARCExpand: Old = " << *Inst << "\n" 1166504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman " New = " << *Value << "\n"); 1176504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman Inst->replaceAllUsesWith(Value); 1186504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman break; 1196504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman } 1206504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman default: 1216504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman break; 1226504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman } 1236504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman } 1246504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 1256504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman DEBUG(dbgs() << "ObjCARCExpand: Finished List.\n\n"); 1266504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman 1276504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman return Changed; 1286504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman} 129