//===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- 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 /// Interface for Targets to specify which operations they can successfully /// select and how the others should be expanded most efficiently. /// //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGenTypes/LowLevelType.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/CommandLine.h" #include <cassert> #include <cstdint> #include <tuple> #include <utility> namespace llvm { extern cl::opt<bool> DisableGISelLegalityCheck; class MachineFunction; class raw_ostream; class LegalizerHelper; class LostDebugLocObserver; class MachineInstr; class MachineRegisterInfo; class MCInstrInfo; namespace LegalizeActions { enum LegalizeAction : std::uint8_t { … }; } // end namespace LegalizeActions raw_ostream &operator<<(raw_ostream &OS, LegalizeActions::LegalizeAction Action); LegalizeAction; /// The LegalityQuery object bundles together all the information that's needed /// to decide whether a given operation is legal or not. /// For efficiency, it doesn't make a copy of Types so care must be taken not /// to free it before using the query. struct LegalityQuery { … }; /// The result of a query. It either indicates a final answer of Legal or /// Unsupported or describes an action that must be taken to make an operation /// more legal. struct LegalizeActionStep { … }; LegalityPredicate; LegalizeMutation; namespace LegalityPredicates { struct TypePairAndMemDesc { … }; /// True iff P is false. template <typename Predicate> Predicate predNot(Predicate P) { … } /// True iff P0 and P1 are true. template<typename Predicate> Predicate all(Predicate P0, Predicate P1) { … } /// True iff all given predicates are true. template<typename Predicate, typename... Args> Predicate all(Predicate P0, Predicate P1, Args... args) { … } /// True iff P0 or P1 are true. template<typename Predicate> Predicate any(Predicate P0, Predicate P1) { … } /// True iff any given predicates are true. template<typename Predicate, typename... Args> Predicate any(Predicate P0, Predicate P1, Args... args) { … } /// True iff the given type index is the specified type. LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit); /// True iff the given type index is one of the specified types. LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list<LLT> TypesInit); /// True iff the given type index is not the specified type. inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) { … } /// True iff the given types for the given pair of type indexes is one of the /// specified type pairs. LegalityPredicate typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1, std::initializer_list<std::pair<LLT, LLT>> TypesInit); /// True iff the given types for the given pair of type indexes is one of the /// specified type pairs. LegalityPredicate typePairAndMemDescInSet( unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit); /// True iff the specified type index is a scalar. LegalityPredicate isScalar(unsigned TypeIdx); /// True iff the specified type index is a vector. LegalityPredicate isVector(unsigned TypeIdx); /// True iff the specified type index is a pointer (with any address space). LegalityPredicate isPointer(unsigned TypeIdx); /// True iff the specified type index is a pointer with the specified address /// space. LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace); /// True if the type index is a vector with element type \p EltTy LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy); /// True iff the specified type index is a scalar that's narrower than the given /// size. LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size); /// True iff the specified type index is a scalar that's wider than the given /// size. LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size); /// True iff the specified type index is a scalar or vector with an element type /// that's narrower than the given size. LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size); /// True iff the specified type index is a scalar or a vector with an element /// type that's wider than the given size. LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size); /// True iff the specified type index is a scalar whose size is not a multiple /// of Size. LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size); /// True iff the specified type index is a scalar whose size is not a power of /// 2. LegalityPredicate sizeNotPow2(unsigned TypeIdx); /// True iff the specified type index is a scalar or vector whose element size /// is not a power of 2. LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx); /// True if the total bitwidth of the specified type index is \p Size bits. LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size); /// True iff the specified type indices are both the same bit size. LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1); /// True iff the first type index has a larger total bit size than second type /// index. LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1); /// True iff the first type index has a smaller total bit size than second type /// index. LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1); /// True iff the specified MMO index has a size (rounded to bytes) that is not a /// power of 2. LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx); /// True iff the specified MMO index has a size that is not an even byte size, /// or that even byte size is not a power of 2. LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx); /// True iff the specified type index is a vector whose element count is not a /// power of 2. LegalityPredicate numElementsNotPow2(unsigned TypeIdx); /// True iff the specified MMO index has at an atomic ordering of at Ordering or /// stronger. LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering); } // end namespace LegalityPredicates namespace LegalizeMutations { /// Select this specific type for the given type index. LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty); /// Keep the same type as the given type index. LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx); /// Keep the same scalar or element type as the given type index. LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx); /// Keep the same scalar or element type as the given type. LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty); /// Keep the same scalar or element type as \p TypeIdx, but take the number of /// elements from \p FromTypeIdx. LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx); /// Keep the same scalar or element type as \p TypeIdx, but take the number of /// elements from \p Ty. LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty); /// Change the scalar size or element size to have the same scalar size as type /// index \p FromIndex. Unlike changeElementTo, this discards pointer types and /// only changes the size. LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx); /// Widen the scalar type or vector element type for the given type index to the /// next power of 2. LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0); /// Widen the scalar type or vector element type for the given type index to /// next multiple of \p Size. LegalizeMutation widenScalarOrEltToNextMultipleOf(unsigned TypeIdx, unsigned Size); /// Add more elements to the type for the given type index to the next power of /// 2. LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0); /// Break up the vector type for the given type index into the element type. LegalizeMutation scalarize(unsigned TypeIdx); } // end namespace LegalizeMutations /// A single rule in a legalizer info ruleset. /// The specified action is chosen when the predicate is true. Where appropriate /// for the action (e.g. for WidenScalar) the new type is selected using the /// given mutator. class LegalizeRule { … }; class LegalizeRuleSet { … }; class LegalizerInfo { … }; #ifndef NDEBUG /// Checks that MIR is fully legal, returns an illegal instruction if it's not, /// nullptr otherwise const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF); #endif } // end namespace llvm. #endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H