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 "llvm/ADT/STLExtras.h" 21 #include "llvm/Support/DataTypes.h" 22 #include <optional> 23 #include <type_traits> 24 25 namespace llvm { 26 27 /// Represents known origin of an individual byte in combine pattern. The 28 /// value of the byte is either constant zero, or comes from memory / 29 /// some other productive instruction (e.g. arithmetic instructions). 30 /// Bit manipulation instructions like shifts are not ByteProviders, rather 31 /// are used to extract Bytes. 32 template <typename ISelOp> class ByteProvider { 33 private: ByteProvider(std::optional<ISelOp> Src,int64_t DestOffset,int64_t SrcOffset)34 ByteProvider(std::optional<ISelOp> Src, int64_t DestOffset, int64_t SrcOffset) 35 : Src(Src), DestOffset(DestOffset), SrcOffset(SrcOffset) {} 36 37 // TODO -- use constraint in c++20 38 // Does this type correspond with an operation in selection DAG 39 // Only allow classes with member function getOpcode 40 template <typename U> 41 using check_has_getOpcode = 42 decltype(std::declval<std::remove_pointer_t<U> &>().getOpcode()); 43 44 template <typename U> 45 static constexpr bool has_getOpcode = 46 is_detected<check_has_getOpcode, U>::value; 47 48 public: 49 // For constant zero providers Src is set to nullopt. For actual providers 50 // Src represents the node which originally produced the relevant bits. 51 std::optional<ISelOp> Src = std::nullopt; 52 // DestOffset is the offset of the byte in the dest we are trying to map for. 53 int64_t DestOffset = 0; 54 // SrcOffset is the offset in the ultimate source node that maps to the 55 // DestOffset 56 int64_t SrcOffset = 0; 57 58 ByteProvider() = default; 59 getSrc(std::optional<ISelOp> Val,int64_t ByteOffset,int64_t VectorOffset)60 static ByteProvider getSrc(std::optional<ISelOp> Val, int64_t ByteOffset, 61 int64_t VectorOffset) { 62 static_assert(has_getOpcode<ISelOp>, 63 "ByteProviders must contain an operation in selection DAG."); 64 return ByteProvider(Val, ByteOffset, VectorOffset); 65 } 66 getConstantZero()67 static ByteProvider getConstantZero() { 68 return ByteProvider<ISelOp>(std::nullopt, 0, 0); 69 } isConstantZero()70 bool isConstantZero() const { return !Src; } 71 hasSrc()72 bool hasSrc() const { return Src.has_value(); } 73 hasSameSrc(const ByteProvider & Other)74 bool hasSameSrc(const ByteProvider &Other) const { return Other.Src == Src; } 75 76 bool operator==(const ByteProvider &Other) const { 77 return Other.Src == Src && Other.DestOffset == DestOffset && 78 Other.SrcOffset == SrcOffset; 79 } 80 }; 81 } // end namespace llvm 82 83 #endif // LLVM_CODEGEN_BYTEPROVIDER_H 84