Nuke isSideEffectFree

We can now compute the same result with Inst.mayHaveSideEffects(). NFC.

Swift SVN r25742
This commit is contained in:
Arnold Schwaighofer
2015-03-04 05:03:44 +00:00
parent 6bdedc769f
commit 951dc2875a
11 changed files with 17 additions and 69 deletions

View File

@@ -64,9 +64,6 @@ namespace swift {
/// dead when this instruction is removed.
void eraseUsesOfInstruction(SILInstruction *Inst);
/// Does the passed in BuiltinInst have any side effects?
bool isSideEffectFree(BuiltinInst *FR);
/// Does the passed in BuiltinInst touch memory at all?
bool isReadNone(BuiltinInst *FR);

View File

@@ -643,12 +643,18 @@ SILInstruction::MemoryBehavior SILInstruction::getMemoryBehavior() const {
// Handle LLVM intrinsic functions.
const IntrinsicInfo & IInfo = BI->getIntrinsicInfo();
if (IInfo.ID != llvm::Intrinsic::not_intrinsic)
if (IInfo.ID != llvm::Intrinsic::not_intrinsic) {
// Read-only.
if (IInfo.hasAttribute(llvm::Attribute::ReadOnly) &&
IInfo.hasAttribute(llvm::Attribute::NoUnwind))
return MemoryBehavior::MayRead;
// Read-none?
return IInfo.hasAttribute(llvm::Attribute::ReadNone) &&
IInfo.hasAttribute(llvm::Attribute::NoUnwind)
? MemoryBehavior::None
: MemoryBehavior::MayHaveSideEffects;
}
}
// Handle functions that have an effects attribute.
if (auto *AI = dyn_cast<ApplyInst>(this))

View File

@@ -92,7 +92,7 @@ static bool canApplyDecrementRefCount(BuiltinInst *BI, SILValue Ptr,
AliasAnalysis *AA) {
// If we have a builtin that is side effect free, we can commute the
// builtin and the retain.
if (isSideEffectFree(BI))
if (!BI->mayHaveSideEffects())
return false;
return canApplyDecrementRefCount(BI->getArguments(), Ptr, AA);

View File

@@ -728,7 +728,7 @@ MemBehavior MemoryBehaviorVisitor::visitBuiltinInst(BuiltinInst *BI) {
}
// If the builtin is side effect free, then it can only read memory.
if (isSideEffectFree(BI)) {
if (!BI->mayHaveSideEffects()) {
DEBUG(llvm::dbgs() << " Found apply of side effect free builtin. "
"Returning MayRead.\n");
return MemBehavior::MayRead;

View File

@@ -72,12 +72,6 @@ enum class ArrayBoundsEffect {
kMayChangeAny // Might change any array.
};
static bool mayHaveSideEffects(SILInstruction *I) {
if (auto *BI = dyn_cast<BuiltinInst>(I))
return !isSideEffectFree(BI);
return I->mayHaveSideEffects();
}
static SILValue getArrayStructPointer(ArrayCallKind K, SILValue Array) {
assert(K != ArrayCallKind::kNone);
@@ -182,7 +176,7 @@ mayChangeArraySize(SILInstruction *I, ArrayCallKind &Kind, SILValue &Array,
return ArrayBoundsEffect::kMayChangeArg;
}
if (!mayHaveSideEffects(I))
if (!I->mayHaveSideEffects())
return ArrayBoundsEffect::kNone;
// A store to an alloc_stack can't possibly store to the array size which is

View File

@@ -471,11 +471,8 @@ bool COWArrayOpt::isRetainReleasedBeforeMutate(SILInstruction *RetainInst,
if (ArrayUserSet.count(II)) // May be an array mutation.
break;
} else if (II->mayHaveSideEffects()) {
if (auto *BI = dyn_cast<BuiltinInst>(II))
if(isSideEffectFree(BI))
} else if (!II->mayHaveSideEffects()) {
continue;
break;
}
}
DEBUG(llvm::dbgs() << " Skipping Array: retained in loop!\n "
@@ -737,9 +734,6 @@ bool COWArrayOpt::hasLoopOnlyDestructorSafeArrayOperations() {
// Instructions without side effects are safe.
if (!Inst->mayHaveSideEffects())
continue;
if (auto *BI = dyn_cast<BuiltinInst>(Inst))
if(isSideEffectFree(BI))
continue;
if (isa<CondFailInst>(Inst))
continue;
if (isa<AllocationInst>(Inst) || isa<DeallocStackInst>(Inst))

View File

@@ -35,9 +35,6 @@ namespace {
// FIXME: Reconcile the similarities between this and
// isInstructionTriviallyDead.
static bool seemsUseful(SILInstruction *I) {
if (auto *BI = dyn_cast<BuiltinInst>(I))
return !isSideEffectFree(BI);
if (I->mayHaveSideEffects())
return true;

View File

@@ -154,15 +154,6 @@ static bool doesDestructorHaveSideEffects(AllocRefInst *ARI) {
}
}
// If I is an apply calling a builtin that does not have side effects, we
// can ignore it.
if (auto *BI = dyn_cast<BuiltinInst>(&I))
if (isSideEffectFree(BI)) {
DEBUG(llvm::dbgs() << " SAFE! No side effect "
"builtin.\n");
continue;
}
// Storing into the object can be ignored.
if (auto *SI = dyn_cast<StoreInst>(&I))
if (SI->getDest().stripAddressProjections().getDef() == Self) {

View File

@@ -79,13 +79,6 @@ static bool hasLoopInvariantOperands(SILInstruction *I, SILLoop *L) {
});
}
static bool mayHaveSideEffects(SILInstruction *I) {
if (auto *BI = dyn_cast<BuiltinInst>(I))
return !isSideEffectFree(BI);
return I->mayHaveSideEffects();
}
static bool mayRead(SILInstruction *I) {
if (auto *BI = dyn_cast<BuiltinInst>(I))
return !isReadNone(BI);
@@ -159,7 +152,7 @@ static bool sinkCondFail(SILLoop *Loop) {
CFs.clear();
LIOfPair = nullptr;
}
} else if (mayHaveSideEffects(&Inst)) {
} else if (Inst.mayHaveSideEffects()) {
CFs.clear();
LIOfPair = nullptr;
}
@@ -208,7 +201,7 @@ static bool hoistInstructions(SILLoop *Loop, DominanceInfo *DT, SILLoopInfo *LI,
// Remove clobbered loads we have seen before.
removeWrittenTo(AA, SafeReads, &Inst);
if (mayHaveSideEffects(&Inst))
if (Inst.mayHaveSideEffects())
Writes.push_back(&Inst);
}
}
@@ -256,7 +249,7 @@ static bool hoistInstructions(SILLoop *Loop, DominanceInfo *DT, SILLoopInfo *LI,
// invariant. We must hoist them so that we preserve memory safety. A
// cond_fail that would have protected (executed before) a memory access
// must - after hoisting - also be executed before said access.
if (mayHaveSideEffects(Inst) && !isa<CondFailInst>(Inst)) {
if (Inst->mayHaveSideEffects() && !isa<CondFailInst>(Inst)) {
DEBUG(llvm::dbgs() << " not side effect free\n");
continue;
}
@@ -317,7 +310,7 @@ static bool sinkFixLiftime(SILLoop *Loop, DominanceInfo *DomTree,
for (auto &Inst : *BB) {
if (auto FLI = dyn_cast<FixLifetimeInst>(&Inst)) {
FixLifetimeInsts.push_back(FLI);
} else if (mayHaveSideEffects(&Inst) && !isa<LoadInst>(&Inst) &&
} else if (Inst.mayHaveSideEffects() && !isa<LoadInst>(&Inst) &&
!isa<StoreInst>(&Inst)) {
DEBUG(llvm::errs() << " mayhavesideeffects because of" << Inst);
DEBUG(Inst.getParent()->dump());

View File

@@ -114,10 +114,6 @@ static bool canSinkInstruction(SILInstruction *Inst) {
/// \brief Returns true if this instruction is a skip barrier, which means that
/// we can't sink other instructions past it.
static bool isSinkBarrier(SILInstruction *Inst) {
// We know that some calls do not have side effects.
if (auto *BI = dyn_cast<BuiltinInst>(Inst))
return !isSideEffectFree(BI);
if (isa<TermInst>(Inst))
return false;

View File

@@ -28,26 +28,6 @@ using namespace swift;
// Do we use array.props?
static bool HaveArrayProperty = true;
bool
swift::isSideEffectFree(BuiltinInst *FR) {
// First, check if we are dealing with a swift builtin.
const BuiltinInfo &BInfo = FR->getBuiltinInfo();
if (BInfo.ID != BuiltinValueKind::None) {
return BInfo.isReadNone();
}
// Second, specialcase llvm intrinsic.
const IntrinsicInfo & IInfo = FR->getIntrinsicInfo();
if (IInfo.ID != llvm::Intrinsic::not_intrinsic) {
return ( (IInfo.hasAttribute(llvm::Attribute::ReadNone) ||
IInfo.hasAttribute(llvm::Attribute::ReadOnly)) &&
IInfo.hasAttribute(llvm::Attribute::NoUnwind) );
}
llvm_unreachable("All cases are covered.");
}
bool swift::isReadNone(BuiltinInst *FR) {
// First, check if we are dealing with a swift builtin.
const BuiltinInfo &BInfo = FR->getBuiltinInfo();
@@ -87,7 +67,7 @@ swift::isInstructionTriviallyDead(SILInstruction *I) {
return false;
if (auto *BI = dyn_cast<BuiltinInst>(I)) {
return isSideEffectFree(BI);
return !BI->mayHaveSideEffects();
}
// condfail instructions that obviously can't fail are dead.