//===- AssumeBundleQueries.h - utilis to query assume bundles ---*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file contain tools to query into assume bundles. assume bundles can be // built using utilities from Transform/Utils/AssumeBundleBuilder.h // //===----------------------------------------------------------------------===// #ifndef LLVM_ANALYSIS_ASSUMEBUNDLEQUERIES_H #define LLVM_ANALYSIS_ASSUMEBUNDLEQUERIES_H #include "llvm/ADT/DenseMap.h" #include "llvm/IR/IntrinsicInst.h" namespace llvm { class AssumptionCache; class DominatorTree; class Instruction; /// Index of elements in the operand bundle. /// If the element exist it is guaranteed to be what is specified in this enum /// but it may not exist. enum AssumeBundleArg { … }; /// Query the operand bundle of an llvm.assume to find a single attribute of /// the specified kind applied on a specified Value. /// /// This has a non-constant complexity. It should only be used when a single /// attribute is going to be queried. /// /// Return true iff the queried attribute was found. /// If ArgVal is set. the argument will be stored to ArgVal. bool hasAttributeInAssume(AssumeInst &Assume, Value *IsOn, StringRef AttrName, uint64_t *ArgVal = nullptr); inline bool hasAttributeInAssume(AssumeInst &Assume, Value *IsOn, Attribute::AttrKind Kind, uint64_t *ArgVal = nullptr) { … } template<> struct DenseMapInfo<Attribute::AttrKind> { … }; /// The map Key contains the Value on for which the attribute is valid and /// the Attribute that is valid for that value. /// If the Attribute is not on any value, the Value is nullptr. RetainedKnowledgeKey; struct MinMax { … }; /// A mapping from intrinsics (=`llvm.assume` calls) to a value range /// (=knowledge) that is encoded in them. How the value range is interpreted /// depends on the RetainedKnowledgeKey that was used to get this out of the /// RetainedKnowledgeMap. Assume2KnowledgeMap; RetainedKnowledgeMap; /// Insert into the map all the informations contained in the operand bundles of /// the llvm.assume. This should be used instead of hasAttributeInAssume when /// many queries are going to be made on the same llvm.assume. /// String attributes are not inserted in the map. /// If the IR changes the map will be outdated. void fillMapFromAssume(AssumeInst &Assume, RetainedKnowledgeMap &Result); /// Represent one information held inside an operand bundle of an llvm.assume. /// AttrKind is the property that holds. /// WasOn if not null is that Value for which AttrKind holds. /// ArgValue is optionally an argument of the attribute. /// For example if we know that %P has an alignment of at least four: /// - AttrKind will be Attribute::Alignment. /// - WasOn will be %P. /// - ArgValue will be 4. struct RetainedKnowledge { … }; /// Retreive the information help by Assume on the operand at index Idx. /// Assume should be an llvm.assume and Idx should be in the operand bundle. RetainedKnowledge getKnowledgeFromOperandInAssume(AssumeInst &Assume, unsigned Idx); /// Retreive the information help by the Use U of an llvm.assume. the use should /// be in the operand bundle. inline RetainedKnowledge getKnowledgeFromUseInAssume(const Use *U) { … } /// Tag in operand bundle indicating that this bundle should be ignored. constexpr StringRef IgnoreBundleTag = …; /// Return true iff the operand bundles of the provided llvm.assume doesn't /// contain any valuable information. This is true when: /// - The operand bundle is empty /// - The operand bundle only contains information about dropped values or /// constant folded values. /// /// the argument to the call of llvm.assume may still be useful even if the /// function returned true. bool isAssumeWithEmptyBundle(const AssumeInst &Assume); /// Return a valid Knowledge associated to the Use U if its Attribute kind is /// in AttrKinds. RetainedKnowledge getKnowledgeFromUse(const Use *U, ArrayRef<Attribute::AttrKind> AttrKinds); /// Return a valid Knowledge associated to the Value V if its Attribute kind is /// in AttrKinds and it matches the Filter. RetainedKnowledge getKnowledgeForValue( const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds, AssumptionCache *AC = nullptr, function_ref<bool(RetainedKnowledge, Instruction *, const CallBase::BundleOpInfo *)> Filter = [](auto...) { … }; /// Return a valid Knowledge associated to the Value V if its Attribute kind is /// in AttrKinds and the knowledge is suitable to be used in the context of /// CtxI. RetainedKnowledge getKnowledgeValidInContext( const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds, const Instruction *CtxI, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr); /// This extracts the Knowledge from an element of an operand bundle. /// This is mostly for use in the assume builder. RetainedKnowledge getKnowledgeFromBundle(AssumeInst &Assume, const CallBase::BundleOpInfo &BOI); } // namespace llvm #endif