Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/ObjCARC/ObjCARCExpand.cpp
35269 views
//===- ObjCARCExpand.cpp - ObjC ARC Optimization --------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7/// \file8/// This file defines ObjC ARC optimizations. ARC stands for Automatic9/// Reference Counting and is a system for managing reference counts for objects10/// in Objective C.11///12/// This specific file deals with early optimizations which perform certain13/// cleanup operations.14///15/// WARNING: This file knows about certain library functions. It recognizes them16/// by name, and hardwires knowledge of their semantics.17///18/// WARNING: This file knows about how certain Objective-C library functions are19/// used. Naive LLVM IR transformations which would otherwise be20/// behavior-preserving may break these assumptions.21///22//===----------------------------------------------------------------------===//2324#include "llvm/Analysis/ObjCARCAnalysisUtils.h"25#include "llvm/IR/Function.h"26#include "llvm/IR/InstIterator.h"27#include "llvm/IR/Instruction.h"28#include "llvm/IR/Instructions.h"29#include "llvm/IR/PassManager.h"30#include "llvm/IR/Value.h"31#include "llvm/Support/Casting.h"32#include "llvm/Support/Debug.h"33#include "llvm/Support/raw_ostream.h"34#include "llvm/Transforms/ObjCARC.h"3536#define DEBUG_TYPE "objc-arc-expand"3738using namespace llvm;39using namespace llvm::objcarc;4041namespace {42static bool runImpl(Function &F) {43if (!EnableARCOpts)44return false;4546// If nothing in the Module uses ARC, don't do anything.47if (!ModuleHasARC(*F.getParent()))48return false;4950bool Changed = false;5152LLVM_DEBUG(dbgs() << "ObjCARCExpand: Visiting Function: " << F.getName()53<< "\n");5455for (Instruction &Inst : instructions(&F)) {56LLVM_DEBUG(dbgs() << "ObjCARCExpand: Visiting: " << Inst << "\n");5758switch (GetBasicARCInstKind(&Inst)) {59case ARCInstKind::Retain:60case ARCInstKind::RetainRV:61case ARCInstKind::Autorelease:62case ARCInstKind::AutoreleaseRV:63case ARCInstKind::FusedRetainAutorelease:64case ARCInstKind::FusedRetainAutoreleaseRV: {65// These calls return their argument verbatim, as a low-level66// optimization. However, this makes high-level optimizations67// harder. Undo any uses of this optimization that the front-end68// emitted here. We'll redo them in the contract pass.69Changed = true;70Value *Value = cast<CallInst>(&Inst)->getArgOperand(0);71LLVM_DEBUG(dbgs() << "ObjCARCExpand: Old = " << Inst72<< "\n"73" New = "74<< *Value << "\n");75Inst.replaceAllUsesWith(Value);76break;77}78default:79break;80}81}8283LLVM_DEBUG(dbgs() << "ObjCARCExpand: Finished List.\n\n");8485return Changed;86}8788} // namespace8990PreservedAnalyses ObjCARCExpandPass::run(Function &F,91FunctionAnalysisManager &AM) {92if (!runImpl(F))93return PreservedAnalyses::all();94PreservedAnalyses PA;95PA.preserveSet<CFGAnalyses>();96return PA;97}9899100