xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/ByteProvider.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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