mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-16 11:24:39 +00:00
[objc-arc] Updated ObjCARCContract to use ARCRuntimeEntryPoints.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185742 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "objc-arc-contract"
|
#define DEBUG_TYPE "objc-arc-contract"
|
||||||
#include "ObjCARC.h"
|
#include "ObjCARC.h"
|
||||||
|
#include "ARCRuntimeEntryPoints.h"
|
||||||
#include "DependencyAnalysis.h"
|
#include "DependencyAnalysis.h"
|
||||||
#include "ProvenanceAnalysis.h"
|
#include "ProvenanceAnalysis.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
@@ -52,23 +53,11 @@ namespace {
|
|||||||
AliasAnalysis *AA;
|
AliasAnalysis *AA;
|
||||||
DominatorTree *DT;
|
DominatorTree *DT;
|
||||||
ProvenanceAnalysis PA;
|
ProvenanceAnalysis PA;
|
||||||
|
ARCRuntimeEntryPoints EP;
|
||||||
|
|
||||||
/// A flag indicating whether this optimization pass should run.
|
/// A flag indicating whether this optimization pass should run.
|
||||||
bool Run;
|
bool Run;
|
||||||
|
|
||||||
/// Declarations for ObjC runtime functions, for use in creating calls to
|
|
||||||
/// them. These are initialized lazily to avoid cluttering up the Module
|
|
||||||
/// with unused declarations.
|
|
||||||
|
|
||||||
/// Declaration for objc_storeStrong().
|
|
||||||
Constant *StoreStrongCallee;
|
|
||||||
/// Declaration for objc_retainAutorelease().
|
|
||||||
Constant *RetainAutoreleaseCallee;
|
|
||||||
/// Declaration for objc_retainAutoreleaseReturnValue().
|
|
||||||
Constant *RetainAutoreleaseRVCallee;
|
|
||||||
/// Declaration for objc_retainAutoreleasedReturnValue().
|
|
||||||
Constant *RetainRVCallee;
|
|
||||||
|
|
||||||
/// The inline asm string to insert between calls and RetainRV calls to make
|
/// The inline asm string to insert between calls and RetainRV calls to make
|
||||||
/// the optimization work on targets which need it.
|
/// the optimization work on targets which need it.
|
||||||
const MDString *RetainRVMarker;
|
const MDString *RetainRVMarker;
|
||||||
@@ -78,11 +67,6 @@ namespace {
|
|||||||
/// "tail".
|
/// "tail".
|
||||||
SmallPtrSet<CallInst *, 8> StoreStrongCalls;
|
SmallPtrSet<CallInst *, 8> StoreStrongCalls;
|
||||||
|
|
||||||
Constant *getStoreStrongCallee(Module *M);
|
|
||||||
Constant *getRetainRVCallee(Module *M);
|
|
||||||
Constant *getRetainAutoreleaseCallee(Module *M);
|
|
||||||
Constant *getRetainAutoreleaseRVCallee(Module *M);
|
|
||||||
|
|
||||||
bool OptimizeRetainCall(Function &F, Instruction *Retain);
|
bool OptimizeRetainCall(Function &F, Instruction *Retain);
|
||||||
|
|
||||||
bool ContractAutorelease(Function &F, Instruction *Autorelease,
|
bool ContractAutorelease(Function &F, Instruction *Autorelease,
|
||||||
@@ -125,74 +109,6 @@ void ObjCARCContract::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
AU.setPreservesCFG();
|
AU.setPreservesCFG();
|
||||||
}
|
}
|
||||||
|
|
||||||
Constant *ObjCARCContract::getStoreStrongCallee(Module *M) {
|
|
||||||
if (!StoreStrongCallee) {
|
|
||||||
LLVMContext &C = M->getContext();
|
|
||||||
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
|
|
||||||
Type *I8XX = PointerType::getUnqual(I8X);
|
|
||||||
Type *Params[] = { I8XX, I8X };
|
|
||||||
|
|
||||||
AttributeSet Attr = AttributeSet()
|
|
||||||
.addAttribute(M->getContext(), AttributeSet::FunctionIndex,
|
|
||||||
Attribute::NoUnwind)
|
|
||||||
.addAttribute(M->getContext(), 1, Attribute::NoCapture);
|
|
||||||
|
|
||||||
StoreStrongCallee =
|
|
||||||
M->getOrInsertFunction(
|
|
||||||
"objc_storeStrong",
|
|
||||||
FunctionType::get(Type::getVoidTy(C), Params, /*isVarArg=*/false),
|
|
||||||
Attr);
|
|
||||||
}
|
|
||||||
return StoreStrongCallee;
|
|
||||||
}
|
|
||||||
|
|
||||||
Constant *ObjCARCContract::getRetainAutoreleaseCallee(Module *M) {
|
|
||||||
if (!RetainAutoreleaseCallee) {
|
|
||||||
LLVMContext &C = M->getContext();
|
|
||||||
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
|
|
||||||
Type *Params[] = { I8X };
|
|
||||||
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
|
|
||||||
AttributeSet Attribute =
|
|
||||||
AttributeSet().addAttribute(M->getContext(), AttributeSet::FunctionIndex,
|
|
||||||
Attribute::NoUnwind);
|
|
||||||
RetainAutoreleaseCallee =
|
|
||||||
M->getOrInsertFunction("objc_retainAutorelease", FTy, Attribute);
|
|
||||||
}
|
|
||||||
return RetainAutoreleaseCallee;
|
|
||||||
}
|
|
||||||
|
|
||||||
Constant *ObjCARCContract::getRetainAutoreleaseRVCallee(Module *M) {
|
|
||||||
if (!RetainAutoreleaseRVCallee) {
|
|
||||||
LLVMContext &C = M->getContext();
|
|
||||||
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
|
|
||||||
Type *Params[] = { I8X };
|
|
||||||
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
|
|
||||||
AttributeSet Attribute =
|
|
||||||
AttributeSet().addAttribute(M->getContext(), AttributeSet::FunctionIndex,
|
|
||||||
Attribute::NoUnwind);
|
|
||||||
RetainAutoreleaseRVCallee =
|
|
||||||
M->getOrInsertFunction("objc_retainAutoreleaseReturnValue", FTy,
|
|
||||||
Attribute);
|
|
||||||
}
|
|
||||||
return RetainAutoreleaseRVCallee;
|
|
||||||
}
|
|
||||||
|
|
||||||
Constant *ObjCARCContract::getRetainRVCallee(Module *M) {
|
|
||||||
if (!RetainRVCallee) {
|
|
||||||
LLVMContext &C = M->getContext();
|
|
||||||
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
|
|
||||||
Type *Params[] = { I8X };
|
|
||||||
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
|
|
||||||
AttributeSet Attribute =
|
|
||||||
AttributeSet().addAttribute(M->getContext(), AttributeSet::FunctionIndex,
|
|
||||||
Attribute::NoUnwind);
|
|
||||||
RetainRVCallee =
|
|
||||||
M->getOrInsertFunction("objc_retainAutoreleasedReturnValue", FTy,
|
|
||||||
Attribute);
|
|
||||||
}
|
|
||||||
return RetainRVCallee;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a
|
/// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a
|
||||||
/// return value. We do this late so we do not disrupt the dataflow analysis in
|
/// return value. We do this late so we do not disrupt the dataflow analysis in
|
||||||
/// ObjCARCOpt.
|
/// ObjCARCOpt.
|
||||||
@@ -222,7 +138,8 @@ ObjCARCContract::OptimizeRetainCall(Function &F, Instruction *Retain) {
|
|||||||
|
|
||||||
// We do not have to worry about tail calls/does not throw since
|
// We do not have to worry about tail calls/does not throw since
|
||||||
// retain/retainRV have the same properties.
|
// retain/retainRV have the same properties.
|
||||||
cast<CallInst>(Retain)->setCalledFunction(getRetainRVCallee(F.getParent()));
|
Constant *Decl = EP.get(ARCRuntimeEntryPoints::EPT_RetainRV);
|
||||||
|
cast<CallInst>(Retain)->setCalledFunction(Decl);
|
||||||
|
|
||||||
DEBUG(dbgs() << "New: " << *Retain << "\n");
|
DEBUG(dbgs() << "New: " << *Retain << "\n");
|
||||||
return true;
|
return true;
|
||||||
@@ -272,10 +189,10 @@ ObjCARCContract::ContractAutorelease(Function &F, Instruction *Autorelease,
|
|||||||
" Old Retain: "
|
" Old Retain: "
|
||||||
<< *Retain << "\n");
|
<< *Retain << "\n");
|
||||||
|
|
||||||
if (Class == IC_AutoreleaseRV)
|
Constant *Decl = EP.get(Class == IC_AutoreleaseRV ?
|
||||||
Retain->setCalledFunction(getRetainAutoreleaseRVCallee(F.getParent()));
|
ARCRuntimeEntryPoints::EPT_RetainAutoreleaseRV :
|
||||||
else
|
ARCRuntimeEntryPoints::EPT_RetainAutorelease);
|
||||||
Retain->setCalledFunction(getRetainAutoreleaseCallee(F.getParent()));
|
Retain->setCalledFunction(Decl);
|
||||||
|
|
||||||
DEBUG(dbgs() << " New Retain: "
|
DEBUG(dbgs() << " New Retain: "
|
||||||
<< *Retain << "\n");
|
<< *Retain << "\n");
|
||||||
@@ -356,9 +273,8 @@ void ObjCARCContract::ContractRelease(Instruction *Release,
|
|||||||
Args[0] = new BitCastInst(Args[0], I8XX, "", Store);
|
Args[0] = new BitCastInst(Args[0], I8XX, "", Store);
|
||||||
if (Args[1]->getType() != I8X)
|
if (Args[1]->getType() != I8X)
|
||||||
Args[1] = new BitCastInst(Args[1], I8X, "", Store);
|
Args[1] = new BitCastInst(Args[1], I8X, "", Store);
|
||||||
CallInst *StoreStrong =
|
Constant *Decl = EP.get(ARCRuntimeEntryPoints::EPT_StoreStrong);
|
||||||
CallInst::Create(getStoreStrongCallee(BB->getParent()->getParent()),
|
CallInst *StoreStrong = CallInst::Create(Decl, Args, "", Store);
|
||||||
Args, "", Store);
|
|
||||||
StoreStrong->setDoesNotThrow();
|
StoreStrong->setDoesNotThrow();
|
||||||
StoreStrong->setDebugLoc(Store->getDebugLoc());
|
StoreStrong->setDebugLoc(Store->getDebugLoc());
|
||||||
|
|
||||||
@@ -381,11 +297,7 @@ bool ObjCARCContract::doInitialization(Module &M) {
|
|||||||
if (!Run)
|
if (!Run)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// These are initialized lazily.
|
EP.Initialize(&M);
|
||||||
StoreStrongCallee = 0;
|
|
||||||
RetainAutoreleaseCallee = 0;
|
|
||||||
RetainAutoreleaseRVCallee = 0;
|
|
||||||
RetainRVCallee = 0;
|
|
||||||
|
|
||||||
// Initialize RetainRVMarker.
|
// Initialize RetainRVMarker.
|
||||||
RetainRVMarker = 0;
|
RetainRVMarker = 0;
|
||||||
|
Reference in New Issue
Block a user