[codemotion] Extract out isARCInertTrapBB into ARCAnalysis from GARCOpts and teach SILCodeMotion to use it to not move retains into trap bbs.

This reduces the number of retains, releases in the stdlib by another 5% to
15167.

rdar://18328074

Swift SVN r21936
This commit is contained in:
Michael Gottesman
2014-09-13 03:15:29 +00:00
parent 2c50e5c1b2
commit f541019660
5 changed files with 87 additions and 56 deletions

View File

@@ -793,59 +793,6 @@ bool swift::arc::ARCSequenceDataflowEvaluator::run() {
return NestingDetected;
}
static bool ignoreableApplyInstInUnreachableBlock(ApplyInst *AI) {
if (auto *BFRI = dyn_cast<BuiltinFunctionRefInst>(AI->getCallee())) {
const BuiltinInfo &BInfo = BFRI->getBuiltinInfo();
if (BInfo.ID == BuiltinValueKind::CondUnreachable)
return true;
const IntrinsicInfo &IInfo = BFRI->getIntrinsicInfo();
if (IInfo.ID == llvm::Intrinsic::trap)
return true;
}
const char *fatalName =
"_TFSs18_fatalErrorMessageFTVSs12StaticStringS_S_Su_T_";
auto *FRI = dyn_cast<FunctionRefInst>(AI->getCallee());
if (!FRI || !FRI->getReferencedFunction()->getName().equals(fatalName))
return false;
return true;
}
/// Match a call to a BB with no ARC relevant side effects.
static bool matchNoSideEffectUnreachableBB(SILBasicBlock *BB) {
auto II = BB->begin(), IE = BB->end();
while (II != IE) {
if (isa<UnreachableInst>(&*II))
return true;
// Ignore any instructions without side effects.
if (!II->mayHaveSideEffects()) {
++II;
continue;
}
// Ignore cond fail.
if (isa<CondFailInst>(II)) {
++II;
continue;
}
// Check for apply insts that we can ignore.
if (auto *AI = dyn_cast<ApplyInst>(&*II)) {
if (ignoreableApplyInstInUnreachableBlock(AI)) {
++II;
continue;
}
}
return false;
}
return false;
}
void swift::arc::ARCBBState::initializeTrapStatus() {
IsTrapBB = matchNoSideEffectUnreachableBB(BB);
IsTrapBB = isARCInertTrapBB(BB);
}