//=== unittests/CodeGen/IRMatchers.h - Match on the LLVM IR -----*- 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 // //===----------------------------------------------------------------------===// /// \file /// This file provides a simple mechanism for performing search operations over /// IR including metadata and types. It allows writing complex search patterns /// using understandable syntax. For instance, the code: /// /// \code /// const BasicBlock *BB = ... /// const Instruction *I = match(BB, /// MInstruction(Instruction::Store, /// MConstInt(4, 8), /// MMTuple( /// MMTuple( /// MMString("omnipotent char"), /// MMTuple( /// MMString("Simple C/C++ TBAA")), /// MConstInt(0, 64)), /// MSameAs(0), /// MConstInt(0)))); /// \endcode /// /// searches the basic block BB for the 'store' instruction, first argument of /// which is 'i8 4', and the attached metadata has an item described by the /// given tree. //===----------------------------------------------------------------------===// #ifndef CLANG_UNITTESTS_CODEGEN_IRMATCHERS_H #define CLANG_UNITTESTS_CODEGEN_IRMATCHERS_H #include "llvm/ADT/PointerUnion.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Value.h" namespace llvm { /// Keeps information about pending match queries. /// /// This class stores state of all unfinished match actions. It allows to /// use queries like "this operand is the same as n-th operand", which are /// hard to implement otherwise. /// class MatcherContext { … }; /// Base of all matcher classes. /// class Matcher { … }; /// Base class of matchers that test particular entity. /// template<typename T> class EntityMatcher : public Matcher { … }; /// Matcher that matches any entity of the specified kind. /// template<typename T> class AnyMatcher : public EntityMatcher<T> { … }; /// Matcher that tests if the current entity satisfies the specified /// condition. /// template<typename T> class CondMatcher : public EntityMatcher<T> { … }; /// Matcher that save pointer to the entity that satisfies condition of the // specified matcher. /// template<typename T> class SavingMatcher : public EntityMatcher<T> { … }; /// Matcher that checks that the entity is identical to another entity in the /// same container. /// class SameAsMatcher : public Matcher { … }; /// Matcher that tests if the entity is a constant integer. /// class ConstantIntMatcher : public Matcher { … }; /// Value matcher tuned to test instructions. /// class InstructionMatcher : public EntityMatcher<Value> { … }; /// Matcher that tests type of the current value using the specified /// type matcher. /// class ValueTypeMatcher : public EntityMatcher<Value> { … }; /// Matcher that matches string metadata. /// class NameMetaMatcher : public EntityMatcher<Metadata> { … }; /// Matcher that matches metadata tuples. /// class MTupleMatcher : public EntityMatcher<Metadata> { … }; // Helper function used to construct matchers. inline std::shared_ptr<Matcher> MSameAs(unsigned N) { … } template<typename... T> std::shared_ptr<InstructionMatcher> MInstruction(unsigned C, T... Args) { … } inline std::shared_ptr<Matcher> MConstInt(uint64_t V, unsigned W = 0) { … } inline std::shared_ptr<EntityMatcher<Value>> MValType(std::shared_ptr<EntityMatcher<Type>> T) { … } inline std::shared_ptr<EntityMatcher<Value>> MValType(const Type *T) { … } inline std::shared_ptr<EntityMatcher<Type>> MType(std::function<bool(const Type &)> C) { … } inline std::shared_ptr<EntityMatcher<Metadata>> MMAny() { … } inline std::shared_ptr<EntityMatcher<Metadata>> MMSave(const Metadata *&V, std::shared_ptr<EntityMatcher<Metadata>> M) { … } inline std::shared_ptr<EntityMatcher<Metadata>> MMString(const char *Name) { … } template<typename... T> std::shared_ptr<EntityMatcher<Metadata>> MMTuple(T... Args) { … } /// Looks for the instruction that satisfies condition of the specified /// matcher inside the given basic block. /// \returns Pointer to the found instruction or nullptr if such instruction /// was not found. /// inline const Instruction *match(const BasicBlock *BB, std::shared_ptr<Matcher> M) { … } /// Looks for the instruction that satisfies condition of the specified /// matcher starting from the specified instruction inside the same basic block. /// /// The given instruction is not checked. /// inline const Instruction *matchNext(const Instruction *I, std::shared_ptr<Matcher> M) { … } } #endif