llvm-6502/lib/Transforms/ObjCARC/ObjCARCExpand.cpp
Chandler Carruth 876ac60880 [Modules] Move InstIterator out of the Support library, where it had no
business.

This header includes Function and BasicBlock and directly uses the
interfaces of both classes. It has to do with the IR, it even has that
in the name. =] Put it in the library it belongs to.

This is one step toward making LLVM's Support library survive a C++
modules bootstrap.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202814 91177308-0d34-0410-b5e6-96231b3b80d8
2014-03-04 10:30:26 +00:00

129 lines
3.7 KiB
C++

//===- ObjCARCExpand.cpp - ObjC ARC Optimization --------------------------===//
//
// 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 ObjC ARC optimizations. ARC stands for Automatic
/// Reference Counting and is a system for managing reference counts for objects
/// in Objective C.
///
/// This specific file deals with early optimizations which perform certain
/// cleanup operations.
///
/// 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.
///
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "objc-arc-expand"
#include "ObjCARC.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/PassAnalysisSupport.h"
#include "llvm/PassRegistry.h"
#include "llvm/PassSupport.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
class Module;
}
using namespace llvm;
using namespace llvm::objcarc;
namespace {
/// \brief Early ARC transformations.
class ObjCARCExpand : public FunctionPass {
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool doInitialization(Module &M);
virtual bool runOnFunction(Function &F);
/// A flag indicating whether this optimization pass should run.
bool Run;
public:
static char ID;
ObjCARCExpand() : FunctionPass(ID) {
initializeObjCARCExpandPass(*PassRegistry::getPassRegistry());
}
};
}
char ObjCARCExpand::ID = 0;
INITIALIZE_PASS(ObjCARCExpand,
"objc-arc-expand", "ObjC ARC expansion", false, false)
Pass *llvm::createObjCARCExpandPass() {
return new ObjCARCExpand();
}
void ObjCARCExpand::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
}
bool ObjCARCExpand::doInitialization(Module &M) {
Run = ModuleHasARC(M);
return false;
}
bool ObjCARCExpand::runOnFunction(Function &F) {
if (!EnableARCOpts)
return false;
// If nothing in the Module uses ARC, don't do anything.
if (!Run)
return false;
bool Changed = false;
DEBUG(dbgs() << "ObjCARCExpand: Visiting Function: " << F.getName() << "\n");
for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) {
Instruction *Inst = &*I;
DEBUG(dbgs() << "ObjCARCExpand: Visiting: " << *Inst << "\n");
switch (GetBasicInstructionClass(Inst)) {
case IC_Retain:
case IC_RetainRV:
case IC_Autorelease:
case IC_AutoreleaseRV:
case IC_FusedRetainAutorelease:
case IC_FusedRetainAutoreleaseRV: {
// These calls return their argument verbatim, as a low-level
// optimization. However, this makes high-level optimizations
// harder. Undo any uses of this optimization that the front-end
// emitted here. We'll redo them in the contract pass.
Changed = true;
Value *Value = cast<CallInst>(Inst)->getArgOperand(0);
DEBUG(dbgs() << "ObjCARCExpand: Old = " << *Inst << "\n"
" New = " << *Value << "\n");
Inst->replaceAllUsesWith(Value);
break;
}
default:
break;
}
}
DEBUG(dbgs() << "ObjCARCExpand: Finished List.\n\n");
return Changed;
}