}
}
+ /// 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;
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));
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;
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)) {
}
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;
}
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)) {
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;
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;
}
!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))
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);
}
// 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
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));
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)
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());
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.
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;
}
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);
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;
}
}
}
- if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
- II->getIntrinsicID() == Intrinsic::lifetime_end) {
+ if (II->isLifetimeStartOrEnd()) {
LLVM_DEBUG(dbgs() << "Ignoring lifetime intrinsic.\n");
++CurInst;
continue;
// 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;
}
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
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))