1 //===-- include/llvm/CodeGen/ByteProvider.h - Map bytes ---------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // \file 10 // This file implements ByteProvider. The purpose of ByteProvider is to provide 11 // a map between a target node's byte (byte position is DestOffset) and the 12 // source (and byte position) that provides it (in Src and SrcOffset 13 // respectively) See CodeGen/SelectionDAG/DAGCombiner.cpp MatchLoadCombine 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_CODEGEN_BYTEPROVIDER_H 18 #define LLVM_CODEGEN_BYTEPROVIDER_H 19 20 #include <optional> 21 #include <type_traits> 22 23 namespace llvm { 24 25 /// Represents known origin of an individual byte in combine pattern. The 26 /// value of the byte is either constant zero, or comes from memory / 27 /// some other productive instruction (e.g. arithmetic instructions). 28 /// Bit manipulation instructions like shifts are not ByteProviders, rather 29 /// are used to extract Bytes. 30 template <typename ISelOp> class ByteProvider { 31 private: ByteProvider(std::optional<ISelOp> Src,int64_t DestOffset,int64_t SrcOffset)32 ByteProvider(std::optional<ISelOp> Src, int64_t DestOffset, int64_t SrcOffset) 33 : Src(Src), DestOffset(DestOffset), SrcOffset(SrcOffset) {} 34 35 // TODO -- use constraint in c++20 36 // Does this type correspond with an operation in selection DAG 37 template <typename T> class is_op { 38 private: 39 using yes = std::true_type; 40 using no = std::false_type; 41 42 // Only allow classes with member function getOpcode 43 template <typename U> 44 static auto test(int) -> decltype(std::declval<U>().getOpcode(), yes()); 45 46 template <typename> static no test(...); 47 48 public: 49 using remove_pointer_t = typename std::remove_pointer<T>::type; 50 static constexpr bool value = 51 std::is_same<decltype(test<remove_pointer_t>(0)), yes>::value; 52 }; 53 54 public: 55 // For constant zero providers Src is set to nullopt. For actual providers 56 // Src represents the node which originally produced the relevant bits. 57 std::optional<ISelOp> Src = std::nullopt; 58 // DestOffset is the offset of the byte in the dest we are trying to map for. 59 int64_t DestOffset = 0; 60 // SrcOffset is the offset in the ultimate source node that maps to the 61 // DestOffset 62 int64_t SrcOffset = 0; 63 64 ByteProvider() = default; 65 getSrc(std::optional<ISelOp> Val,int64_t ByteOffset,int64_t VectorOffset)66 static ByteProvider getSrc(std::optional<ISelOp> Val, int64_t ByteOffset, 67 int64_t VectorOffset) { 68 static_assert(is_op<ISelOp>().value, 69 "ByteProviders must contain an operation in selection DAG."); 70 return ByteProvider(Val, ByteOffset, VectorOffset); 71 } 72 getConstantZero()73 static ByteProvider getConstantZero() { 74 return ByteProvider<ISelOp>(std::nullopt, 0, 0); 75 } isConstantZero()76 bool isConstantZero() const { return !Src; } 77 hasSrc()78 bool hasSrc() const { return Src.has_value(); } 79 hasSameSrc(const ByteProvider & Other)80 bool hasSameSrc(const ByteProvider &Other) const { return Other.Src == Src; } 81 82 bool operator==(const ByteProvider &Other) const { 83 return Other.Src == Src && Other.DestOffset == DestOffset && 84 Other.SrcOffset == SrcOffset; 85 } 86 }; 87 } // end namespace llvm 88 89 #endif // LLVM_CODEGEN_BYTEPROVIDER_H 90