Revert "[SILOptimizer] Don't diagnose infinite recursion if a branch terminates (#19724)"

This reverts commit e94450e840.

rdar://45080912
This commit is contained in:
Graydon Hoare
2018-10-07 23:54:17 -07:00
parent 08acbf33de
commit cc16ddfd13
18 changed files with 104 additions and 183 deletions

View File

@@ -24,7 +24,6 @@
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILModule.h"
#include "swift/Strings.h"
using namespace swift;
//===----------------------------------------------------------------------===//
@@ -337,80 +336,6 @@ bool SILBasicBlock::isEntry() const {
return this == &*getParent()->begin();
}
//===----------------------------------------------------------------------===//
// Program Termination Point Analysis
//===----------------------------------------------------------------------===//
static bool ignorableApplyInstInUnreachableBlock(const ApplyInst *AI) {
const auto *Fn = AI->getReferencedFunction();
if (!Fn)
return false;
return Fn->hasSemanticsAttr(SEMANTICS_PROGRAMTERMINATION_POINT);
}
static bool ignorableBuiltinInstInUnreachableBlock(const BuiltinInst *BI) {
const BuiltinInfo &BInfo = BI->getBuiltinInfo();
if (BInfo.ID == BuiltinValueKind::CondUnreachable)
return true;
const IntrinsicInfo &IInfo = BI->getIntrinsicInfo();
if (IInfo.ID == llvm::Intrinsic::trap)
return true;
return false;
}
// Match a call to a basic block that's going to terminate
// with no side effects.
bool SILBasicBlock::isProgramTerminationPoint() const {
// Do a quick check at the beginning to make sure that our terminator is
// actually an unreachable. This ensures that in many cases this function will
// exit early and quickly.
auto II = rbegin();
if (!isa<UnreachableInst>(*II))
return false;
auto IE = rend();
while (II != IE) {
// 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 (ignorableApplyInstInUnreachableBlock(AI)) {
++II;
continue;
}
}
// Check for builtins that we can ignore.
if (auto *BI = dyn_cast<BuiltinInst>(&*II)) {
if (ignorableBuiltinInstInUnreachableBlock(BI)) {
++II;
continue;
}
}
// If we can't ignore the instruction, return false.
return false;
}
// Otherwise, we have an unreachable and every instruction is inert in an
// unreachable BB.
return true;
}
/// Declared out of line so we can have a declaration of SILArgument.
PhiArgumentArrayRef SILBasicBlock::getPhiArguments() const {
return PhiArgumentArrayRef(getArguments(), [](SILArgument *arg) {