From f16f139db40e6bf6462ca831eb1ec423c50aeef2 Mon Sep 17 00:00:00 2001 From: Tyker Date: Thu, 12 Mar 2020 00:39:05 +0100 Subject: Basis of dropping uses in llvm.assume. Summary: This patch adds the basic utilities to deal with dropable uses. dropable uses are uses that we rather drop than prevent transformations, for now they are limited to uses in llvm.assume. Reviewers: jdoerfert, sstefan1 Reviewed By: jdoerfert Subscribers: uenoku, lebedev.ri, mgorny, hiraditya, dexonsmith, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73404 --- llvm/lib/IR/Value.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'llvm/lib/IR/Value.cpp') diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index beb3989..8cd58975 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -141,6 +141,51 @@ bool Value::hasNUsesOrMore(unsigned N) const { return hasNItemsOrMore(use_begin(), use_end(), N); } +static bool isUnDroppableUser(const User *U) { return !U->isDroppable(); } + +Use *Value::getSingleUndroppableUse() { + Use *Result = nullptr; + for (Use &U : uses()) { + if (!U.getUser()->isDroppable()) { + if (Result) + return nullptr; + Result = &U; + } + } + return Result; +} + +bool Value::hasNUndroppableUses(unsigned int N) const { + return hasNItems(user_begin(), user_end(), N, isUnDroppableUser); +} + +bool Value::hasNUndroppableUsesOrMore(unsigned int N) const { + return hasNItemsOrMore(user_begin(), user_end(), N, isUnDroppableUser); +} + +void Value::dropDroppableUses( + llvm::function_ref ShouldDrop) { + SmallVector ToBeEdited; + for (Use &U : uses()) + if (U.getUser()->isDroppable() && ShouldDrop(&U)) + ToBeEdited.push_back(&U); + for (Use *U : ToBeEdited) { + U->removeFromList(); + if (auto *Assume = dyn_cast(U->getUser())) { + assert(Assume->getIntrinsicID() == Intrinsic::assume); + unsigned OpNo = U->getOperandNo(); + if (OpNo == 0) + Assume->setOperand(0, ConstantInt::getTrue(Assume->getContext())); + else { + Assume->setOperand(OpNo, UndefValue::get(U->get()->getType())); + CallInst::BundleOpInfo &BOI = Assume->getBundleOpInfoForOperand(OpNo); + BOI.Tag = getContext().pImpl->getOrInsertBundleTag("ignore"); + } + } else + llvm_unreachable("unkown droppable use"); + } +} + bool Value::isUsedInBasicBlock(const BasicBlock *BB) const { // This can be computed either by scanning the instructions in BB, or by // scanning the use list of this Value. Both lists can be very long, but -- cgit v1.1