aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp')
-rw-r--r--llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp83
1 files changed, 37 insertions, 46 deletions
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index 86d161116e8c..62161b5b6b40 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -32,6 +32,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/EHPersonalities.h"
+#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstIterator.h"
@@ -63,13 +64,12 @@ namespace {
class ObjCARCContract {
bool Changed;
+ bool CFGChanged;
AAResults *AA;
DominatorTree *DT;
ProvenanceAnalysis PA;
ARCRuntimeEntryPoints EP;
-
- /// A flag indicating whether this optimization pass should run.
- bool Run;
+ BundledRetainClaimRVs *BundledInsts = nullptr;
/// The inline asm string to insert between calls and RetainRV calls to make
/// the optimization work on targets which need it.
@@ -98,6 +98,7 @@ class ObjCARCContract {
public:
bool init(Module &M);
bool run(Function &F, AAResults *AA, DominatorTree *DT);
+ bool hasCFGChanged() const { return CFGChanged; }
};
class ObjCARCContractLegacyPass : public FunctionPass {
@@ -304,32 +305,6 @@ findRetainForStoreStrongContraction(Value *New, StoreInst *Store,
return Retain;
}
-/// Create a call instruction with the correct funclet token. Should be used
-/// instead of calling CallInst::Create directly.
-static CallInst *
-createCallInst(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
- const Twine &NameStr, Instruction *InsertBefore,
- const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
- SmallVector<OperandBundleDef, 1> OpBundles;
- if (!BlockColors.empty()) {
- const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second;
- assert(CV.size() == 1 && "non-unique color for block!");
- Instruction *EHPad = CV.front()->getFirstNonPHI();
- if (EHPad->isEHPad())
- OpBundles.emplace_back("funclet", EHPad);
- }
-
- return CallInst::Create(FTy, Func, Args, OpBundles, NameStr, InsertBefore);
-}
-
-static CallInst *
-createCallInst(FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr,
- Instruction *InsertBefore,
- const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
- return createCallInst(Func.getFunctionType(), Func.getCallee(), Args, NameStr,
- InsertBefore, BlockColors);
-}
-
/// Attempt to merge an objc_release with a store, load, and objc_retain to form
/// an objc_storeStrong. An objc_storeStrong:
///
@@ -411,7 +386,8 @@ void ObjCARCContract::tryToContractReleaseIntoStoreStrong(
if (Args[1]->getType() != I8X)
Args[1] = new BitCastInst(Args[1], I8X, "", Store);
Function *Decl = EP.get(ARCRuntimeEntryPointKind::StoreStrong);
- CallInst *StoreStrong = createCallInst(Decl, Args, "", Store, BlockColors);
+ CallInst *StoreStrong =
+ objcarc::createCallInstWithColors(Decl, Args, "", Store, BlockColors);
StoreStrong->setDoesNotThrow();
StoreStrong->setDebugLoc(Store->getDebugLoc());
@@ -456,9 +432,14 @@ bool ObjCARCContract::tryToPeepholeInstruction(
case ARCInstKind::RetainRV:
case ARCInstKind::ClaimRV: {
// If we're compiling for a target which needs a special inline-asm
- // marker to do the return value optimization, insert it now.
+ // marker to do the return value optimization and the retainRV/claimRV call
+ // wasn't bundled with a call, insert the marker now.
if (!RVInstMarker)
return false;
+
+ if (BundledInsts->contains(Inst))
+ return false;
+
BasicBlock::iterator BBI = Inst->getIterator();
BasicBlock *InstParent = Inst->getParent();
@@ -486,7 +467,7 @@ bool ObjCARCContract::tryToPeepholeInstruction(
RVInstMarker->getString(),
/*Constraints=*/"", /*hasSideEffects=*/true);
- createCallInst(IA, None, "", Inst, BlockColors);
+ objcarc::createCallInstWithColors(IA, None, "", Inst, BlockColors);
}
decline_rv_optimization:
return false;
@@ -525,6 +506,12 @@ bool ObjCARCContract::tryToPeepholeInstruction(
Inst->eraseFromParent();
return true;
default:
+ if (auto *CI = dyn_cast<CallInst>(Inst))
+ if (CI->getIntrinsicID() == Intrinsic::objc_clang_arc_noop_use) {
+ // Remove calls to @llvm.objc.clang.arc.noop.use(...).
+ Changed = true;
+ CI->eraseFromParent();
+ }
return true;
}
}
@@ -534,16 +521,10 @@ bool ObjCARCContract::tryToPeepholeInstruction(
//===----------------------------------------------------------------------===//
bool ObjCARCContract::init(Module &M) {
- // If nothing in the Module uses ARC, don't do anything.
- Run = ModuleHasARC(M);
- if (!Run)
- return false;
-
EP.init(&M);
// Initialize RVInstMarker.
- const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
- RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
+ RVInstMarker = getRVInstMarker(M);
return false;
}
@@ -552,14 +533,16 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
if (!EnableARCOpts)
return false;
- // If nothing in the Module uses ARC, don't do anything.
- if (!Run)
- return false;
-
- Changed = false;
+ Changed = CFGChanged = false;
AA = A;
DT = D;
PA.setAA(A);
+ BundledRetainClaimRVs BRV(EP, true);
+ BundledInsts = &BRV;
+
+ std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT);
+ Changed |= R.first;
+ CFGChanged |= R.second;
DenseMap<BasicBlock *, ColorVector> BlockColors;
if (F.hasPersonalityFn() &&
@@ -584,6 +567,13 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
+ if (auto *CI = dyn_cast<CallInst>(Inst))
+ if (objcarc::hasAttachedCallOpBundle(CI)) {
+ BundledInsts->insertRVCallWithColors(&*I, CI, BlockColors);
+ --I;
+ Changed = true;
+ }
+
// First try to peephole Inst. If there is nothing further we can do in
// terms of undoing objc-arc-expand, process the next inst.
if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
@@ -733,7 +723,6 @@ INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
- AU.setPreservesCFG();
}
Pass *llvm::createObjCARCContractPass() {
@@ -757,9 +746,11 @@ PreservedAnalyses ObjCARCContractPass::run(Function &F,
bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
&AM.getResult<DominatorTreeAnalysis>(F));
+ bool CFGChanged = OCAC.hasCFGChanged();
if (Changed) {
PreservedAnalyses PA;
- PA.preserveSet<CFGAnalyses>();
+ if (!CFGChanged)
+ PA.preserveSet<CFGAnalyses>();
return PA;
}
return PreservedAnalyses::all();