[IR] Add Instruction::isLifetimeStartOrEnd, NFC

Instruction::isLifetimeStartOrEnd() checks whether an Instruction is an
llvm.lifetime.start or an llvm.lifetime.end intrinsic.

This was suggested as a cleanup in D55967.

Differential Revision: https://reviews.llvm.org/D56019

llvm-svn: 349964
This commit is contained in:
Vedant Kumar 2018-12-21 21:49:40 +00:00
parent 8ed73c2058
commit b264d69de7
18 changed files with 41 additions and 69 deletions

View File

@ -582,6 +582,10 @@ public:
}
}
/// Return true if the instruction is a llvm.lifetime.start or
/// llvm.lifetime.end marker.
bool isLifetimeStartOrEnd() const;
/// Return a pointer to the next non-debug instruction in the same basic
/// block as 'this', or nullptr if no such instruction exists.
const Instruction *getNextNonDebugInstruction() const;

View File

@ -323,11 +323,8 @@ bool StackSafetyLocalAnalysis::analyzeAllUses(const Value *Ptr, UseInfo &US) {
case Instruction::Invoke: {
ImmutableCallSite CS(I);
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end)
break;
}
if (I->isLifetimeStartOrEnd())
break;
if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
US.updateRange(getMemIntrinsicAccessRange(MI, UI, Ptr));

View File

@ -3822,8 +3822,7 @@ bool llvm::onlyUsedByLifetimeMarkers(const Value *V) {
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U);
if (!II) return false;
if (II->getIntrinsicID() != Intrinsic::lifetime_start &&
II->getIntrinsicID() != Intrinsic::lifetime_end)
if (!II->isLifetimeStartOrEnd())
return false;
}
return true;

View File

@ -324,11 +324,8 @@ bool SafeStack::IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize) {
case Instruction::Invoke: {
ImmutableCallSite CS(I);
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end)
continue;
}
if (I->isLifetimeStartOrEnd())
continue;
if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
if (!IsMemIntrinsicSafe(MI, UI, AllocaPtr, AllocaSize)) {

View File

@ -46,11 +46,10 @@ const StackColoring::LiveRange &StackColoring::getLiveRange(AllocaInst *AI) {
}
bool StackColoring::readMarker(Instruction *I, bool *IsStart) {
auto *II = dyn_cast<IntrinsicInst>(I);
if (!II || (II->getIntrinsicID() != Intrinsic::lifetime_start &&
II->getIntrinsicID() != Intrinsic::lifetime_end))
if (!I->isLifetimeStartOrEnd())
return false;
auto *II = cast<IntrinsicInst>(I);
*IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
return true;
}

View File

@ -157,14 +157,6 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool &IsLarge,
return NeedsProtector;
}
static bool isLifetimeInst(const Instruction *I) {
if (const auto Intrinsic = dyn_cast<IntrinsicInst>(I)) {
const auto Id = Intrinsic->getIntrinsicID();
return Id == Intrinsic::lifetime_start || Id == Intrinsic::lifetime_end;
}
return false;
}
bool StackProtector::HasAddressTaken(const Instruction *AI) {
for (const User *U : AI->users()) {
if (const StoreInst *SI = dyn_cast<StoreInst>(U)) {
@ -175,7 +167,7 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) {
return true;
} else if (const CallInst *CI = dyn_cast<CallInst>(U)) {
// Ignore intrinsics that are not calls. TODO: Use isLoweredToCall().
if (!isa<DbgInfoIntrinsic>(CI) && !isLifetimeInst(CI))
if (!isa<DbgInfoIntrinsic>(CI) && !CI->isLifetimeStartOrEnd())
return true;
} else if (isa<InvokeInst>(U)) {
return true;

View File

@ -206,10 +206,8 @@ const Instruction* BasicBlock::getFirstNonPHIOrDbgOrLifetime() const {
if (isa<PHINode>(I) || isa<DbgInfoIntrinsic>(I))
continue;
if (auto *II = dyn_cast<IntrinsicInst>(&I))
if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end)
continue;
if (I.isLifetimeStartOrEnd())
continue;
return &I;
}

View File

@ -598,6 +598,14 @@ bool Instruction::isSafeToRemove() const {
!this->isTerminator();
}
bool Instruction::isLifetimeStartOrEnd() const {
auto II = dyn_cast<IntrinsicInst>(this);
if (!II)
return false;
Intrinsic::ID ID = II->getIntrinsicID();
return ID == Intrinsic::lifetime_start || ID == Intrinsic::lifetime_end;
}
const Instruction *Instruction::getNextNonDebugInstruction() const {
for (const Instruction *I = getNextNode(); I; I = I->getNextNode())
if (!isa<DbgInfoIntrinsic>(I))

View File

@ -851,12 +851,8 @@ int PartialInlinerImpl::computeBBInlineCost(BasicBlock *BB) {
break;
}
IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(&I);
if (IntrInst) {
if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_start ||
IntrInst->getIntrinsicID() == Intrinsic::lifetime_end)
continue;
}
if (I.isLifetimeStartOrEnd())
continue;
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
InlineCost += getCallsiteCost(CallSite(CI), DL);

View File

@ -116,13 +116,10 @@ isOnlyCopiedFromConstantGlobal(Value *V, MemTransferInst *&TheCopy,
}
// Lifetime intrinsics can be handled by the caller.
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end) {
assert(II->use_empty() && "Lifetime markers have no result to use!");
ToDelete.push_back(II);
continue;
}
if (I->isLifetimeStartOrEnd()) {
assert(I->use_empty() && "Lifetime markers have no result to use!");
ToDelete.push_back(I);
continue;
}
// If this is isn't our memcpy/memmove, reject it as something we can't

View File

@ -1005,7 +1005,7 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
if (ID == Intrinsic::localescape) LocalEscapeCall = &II;
if (!ASan.UseAfterScope)
return;
if (ID != Intrinsic::lifetime_start && ID != Intrinsic::lifetime_end)
if (!II.isLifetimeStartOrEnd())
return;
// Found lifetime intrinsic, add ASan instrumentation if necessary.
ConstantInt *Size = dyn_cast<ConstantInt>(II.getArgOperand(0));

View File

@ -919,8 +919,7 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpy, Value *cpyDest,
continue;
}
if (const IntrinsicInst *IT = dyn_cast<IntrinsicInst>(U))
if (IT->getIntrinsicID() == Intrinsic::lifetime_start ||
IT->getIntrinsicID() == Intrinsic::lifetime_end)
if (IT->isLifetimeStartOrEnd())
continue;
if (U != C && U != cpy)

View File

@ -913,8 +913,7 @@ private:
if (!IsOffsetKnown)
return PI.setAborted(&II);
if (II.getIntrinsicID() == Intrinsic::lifetime_start ||
II.getIntrinsicID() == Intrinsic::lifetime_end) {
if (II.isLifetimeStartOrEnd()) {
ConstantInt *Length = cast<ConstantInt>(II.getArgOperand(0));
uint64_t Size = std::min(AllocSize - Offset.getLimitedValue(),
Length->getLimitedValue());
@ -1807,8 +1806,7 @@ static bool isVectorPromotionViableForSlice(Partition &P, const Slice &S,
if (!S.isSplittable())
return false; // Skip any unsplittable intrinsics.
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U->getUser())) {
if (II->getIntrinsicID() != Intrinsic::lifetime_start &&
II->getIntrinsicID() != Intrinsic::lifetime_end)
if (!II->isLifetimeStartOrEnd())
return false;
} else if (U->get()->getType()->getPointerElementType()->isStructTy()) {
// Disable vector promotion when there are loads or stores of an FCA.
@ -2029,8 +2027,7 @@ static bool isIntegerWideningViableForSlice(const Slice &S,
if (!S.isSplittable())
return false; // Skip any unsplittable intrinsics.
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U->getUser())) {
if (II->getIntrinsicID() != Intrinsic::lifetime_start &&
II->getIntrinsicID() != Intrinsic::lifetime_end)
if (!II->isLifetimeStartOrEnd())
return false;
} else {
return false;
@ -3013,8 +3010,7 @@ private:
}
bool visitIntrinsicInst(IntrinsicInst &II) {
assert(II.getIntrinsicID() == Intrinsic::lifetime_start ||
II.getIntrinsicID() == Intrinsic::lifetime_end);
assert(II.isLifetimeStartOrEnd());
LLVM_DEBUG(dbgs() << " original: " << II << "\n");
assert(II.getArgOperand(1) == OldPtr);

View File

@ -332,8 +332,7 @@ bool CodeExtractor::isLegalToShrinkwrapLifetimeMarkers(
default: {
IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(&II);
if (IntrInst) {
if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_start ||
IntrInst->getIntrinsicID() == Intrinsic::lifetime_end)
if (IntrInst->isLifetimeStartOrEnd())
break;
return false;
}

View File

@ -483,8 +483,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst,
}
}
if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end) {
if (II->isLifetimeStartOrEnd()) {
LLVM_DEBUG(dbgs() << "Ignoring lifetime intrinsic.\n");
++CurInst;
continue;

View File

@ -1320,16 +1320,10 @@ static Value *HandleByValArgument(Value *Arg, Instruction *TheCall,
// Check whether this Value is used by a lifetime intrinsic.
static bool isUsedByLifetimeMarker(Value *V) {
for (User *U : V->users()) {
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) {
switch (II->getIntrinsicID()) {
default: break;
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
for (User *U : V->users())
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U))
if (II->isLifetimeStartOrEnd())
return true;
}
}
}
return false;
}

View File

@ -393,8 +393,7 @@ bool llvm::wouldInstructionBeTriviallyDead(Instruction *I,
return true;
// Lifetime intrinsics are dead when their right-hand is undef.
if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
II->getIntrinsicID() == Intrinsic::lifetime_end)
if (II->isLifetimeStartOrEnd())
return isa<UndefValue>(II->getArgOperand(1));
// Assumptions are dead if their condition is trivially true. Guards on

View File

@ -82,8 +82,7 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) {
if (SI->isVolatile())
return false;
} else if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) {
if (II->getIntrinsicID() != Intrinsic::lifetime_start &&
II->getIntrinsicID() != Intrinsic::lifetime_end)
if (!II->isLifetimeStartOrEnd())
return false;
} else if (const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
if (BCI->getType() != Type::getInt8PtrTy(U->getContext(), AS))