LLVM 17.0.0git
HexagonShuffler.h
Go to the documentation of this file.
1//===- HexagonShuffler.h - Instruction bundle shuffling ---------*- 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// This implements the shuffling of insns inside a bundle according to the
10// packet formation rules of the Hexagon ISA.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
15#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
16
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/SMLoc.h"
25#include <cstdint>
26#include <functional>
27#include <optional>
28#include <utility>
29
30namespace llvm {
31
32class MCContext;
33class MCInst;
34class MCInstrInfo;
35class MCSubtargetInfo;
36
37// Insn resources.
39 // Mask of the slots or units that may execute the insn and
40 // the weight or priority that the insn requires to be assigned a slot.
41 unsigned Slots, Weight;
42
43public:
44 HexagonResource(unsigned s) { setUnits(s); }
45
46 void setUnits(unsigned s) {
47 Slots = s & ((1u << HEXAGON_PACKET_SIZE) - 1);
48 setWeight(s);
49 }
50
51 void setAllUnits() {
52 setUnits(((1u << HEXAGON_PACKET_SIZE) - 1));
53 }
54 unsigned setWeight(unsigned s);
55
56 unsigned getUnits() const { return (Slots); }
57 unsigned getWeight() const { return (Weight); }
58
59 // Check if the resources are in ascending slot order.
60 static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
61 return (llvm::popcount(A.getUnits()) < llvm::popcount(B.getUnits()));
62 }
63
64 // Check if the resources are in ascending weight order.
65 static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
66 return (A.getWeight() < B.getWeight());
67 }
68};
69
70// HVX insn resources.
72public:
73 using UnitsAndLanes = std::pair<unsigned, unsigned>;
74
75private:
76 // Count of adjacent slots that the insn requires to be executed.
77 unsigned Lanes;
78 // Flag whether the insn is a load or a store.
79 bool Load, Store;
80 // Flag whether the HVX resources are valid.
81 bool Valid;
82
83 void setLanes(unsigned l) { Lanes = l; }
84 void setLoad(bool f = true) { Load = f; }
85 void setStore(bool f = true) { Store = f; }
86
87public:
88 HexagonCVIResource(MCInstrInfo const &MCII,
89 MCSubtargetInfo const &STI,
90 unsigned s, MCInst const *id);
91
92 bool isValid() const { return Valid; }
93 unsigned getLanes() const { return Lanes; }
94 bool mayLoad() const { return Load; }
95 bool mayStore() const { return Store; }
96};
97
98// Handle to an insn used by the shuffling algorithm.
100 friend class HexagonShuffler;
101
102 MCInst const *ID;
103 MCInst const *Extender;
104 HexagonResource Core;
106
107public:
109 MCSubtargetInfo const &STI, MCInst const *id,
110 MCInst const *Extender, unsigned s)
111 : ID(id), Extender(Extender), Core(s), CVI(MCII, STI, s, id){};
112
113 MCInst const &getDesc() const { return *ID; }
114 MCInst const *getExtender() const { return Extender; }
115
116 // Check if the handles are in ascending order for shuffling purposes.
117 bool operator<(const HexagonInstr &B) const {
118 return (HexagonResource::lessWeight(B.Core, Core));
119 }
120
121 // Check if the handles are in ascending order by core slots.
122 static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
123 return (HexagonResource::lessUnits(A.Core, B.Core));
124 }
125
126 // Check if the handles are in ascending order by HVX slots.
127 static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B) {
128 return (HexagonResource::lessUnits(A.CVI, B.CVI));
129 }
130};
131
132// Bundle shuffler.
134 using HexagonPacket =
136
137 struct HexagonPacketSummary {
138 // Number of memory operations, loads, solo loads, stores, solo stores,
139 // single stores.
140 unsigned memory;
141 unsigned loads;
142 unsigned load0;
143 unsigned stores;
144 unsigned store0;
145 unsigned store1;
146 unsigned NonZCVIloads;
147 unsigned AllCVIloads;
148 unsigned CVIstores;
149 // Number of duplex insns
150 unsigned duplex;
151 unsigned pSlot3Cnt;
152 std::optional<HexagonInstr *> PrefSlot3Inst;
153 unsigned memops;
154 unsigned ReservedSlotMask;
156 std::optional<SMLoc> Slot1AOKLoc;
157 std::optional<SMLoc> NoSlot1StoreLoc;
158 };
159 // Insn handles in a bundle.
160 HexagonPacket Packet;
161
162protected:
164 int64_t BundleFlags;
170 std::vector<std::pair<SMLoc, std::string>> AppliedRestrictions;
171
172 bool applySlotRestrictions(HexagonPacketSummary const &Summary,
173 const bool DoShuffle);
174 void restrictSlot1AOK(HexagonPacketSummary const &Summary);
175 void restrictNoSlot1Store(HexagonPacketSummary const &Summary);
177 bool restrictStoreLoadOrder(HexagonPacketSummary const &Summary);
178 void restrictBranchOrder(HexagonPacketSummary const &Summary);
179 void restrictPreferSlot3(HexagonPacketSummary const &Summary,
180 const bool DoShuffle);
181 void permitNonSlot();
182
183 std::optional<HexagonPacket> tryAuction(HexagonPacketSummary const &Summary);
184
185 HexagonPacketSummary GetPacketSummary();
186 bool ValidPacketMemoryOps(HexagonPacketSummary const &Summary) const;
187 bool ValidResourceUsage(HexagonPacketSummary const &Summary);
188
189public:
194
196 MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
197
198 // Reset to initial state.
199 void reset();
200 // Check if the bundle may be validly shuffled.
201 bool check(const bool RequireShuffle = true);
202 // Reorder the insn handles in the bundle.
203 bool shuffle();
204
205 unsigned size() const { return (Packet.size()); }
206
207 bool isMemReorderDisabled() const {
209 }
210
211 iterator begin() { return (Packet.begin()); }
212 iterator end() { return (Packet.end()); }
213 const_iterator cbegin() const { return (Packet.begin()); }
214 const_iterator cend() const { return (Packet.end()); }
216 return make_range(P.begin(), P.end());
217 }
219 return make_range(P.begin(), P.end());
220 }
223
224 using InstPredicate = bool (*)(MCInstrInfo const &, MCInst const &);
225
226 bool HasInstWith(InstPredicate Pred) const {
227 return llvm::any_of(insts(), [&](HexagonInstr const &I) {
228 MCInst const &Inst = I.getDesc();
229 return (*Pred)(MCII, Inst);
230 });
231 }
232
233 // Add insn handle to the bundle .
234 void append(MCInst const &ID, MCInst const *Extender, unsigned S);
235
236 // Return the error code for the last check or shuffling of the bundle.
237 void reportError(Twine const &Msg);
238 void reportResourceError(HexagonPacketSummary const &Summary, StringRef Err);
239 void reportResourceUsage(HexagonPacketSummary const &Summary);
240};
241
242} // end namespace llvm
243
244#endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file defines the DenseMap class.
#define check(cond)
#define HEXAGON_PACKET_SIZE
hexagon widen stores
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallVector class.
HexagonCVIResource(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, unsigned s, MCInst const *id)
unsigned getLanes() const
std::pair< unsigned, unsigned > UnitsAndLanes
MCInst const * getExtender() const
MCInst const & getDesc() const
bool operator<(const HexagonInstr &B) const
static bool lessCore(const HexagonInstr &A, const HexagonInstr &B)
static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B)
HexagonInstr(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const *id, MCInst const *Extender, unsigned s)
unsigned setWeight(unsigned s)
unsigned getUnits() const
HexagonResource(unsigned s)
unsigned getWeight() const
static bool lessWeight(const HexagonResource &A, const HexagonResource &B)
void setUnits(unsigned s)
static bool lessUnits(const HexagonResource &A, const HexagonResource &B)
unsigned size() const
const_iterator cbegin() const
packet_range insts(HexagonPacket &P)
bool(*)(MCInstrInfo const &, MCInst const &) InstPredicate
bool isMemReorderDisabled() const
void restrictNoSlot1Store(HexagonPacketSummary const &Summary)
void restrictSlot1AOK(HexagonPacketSummary const &Summary)
const_packet_range insts(HexagonPacket const &P) const
bool restrictStoreLoadOrder(HexagonPacketSummary const &Summary)
void reportError(Twine const &Msg)
void reportResourceError(HexagonPacketSummary const &Summary, StringRef Err)
HexagonPacketSummary GetPacketSummary()
bool ValidResourceUsage(HexagonPacketSummary const &Summary)
const_iterator cend() const
MCSubtargetInfo const & STI
void restrictBranchOrder(HexagonPacketSummary const &Summary)
const_packet_range insts() const
void append(MCInst const &ID, MCInst const *Extender, unsigned S)
bool applySlotRestrictions(HexagonPacketSummary const &Summary, const bool DoShuffle)
MCInstrInfo const & MCII
void reportResourceUsage(HexagonPacketSummary const &Summary)
bool ValidPacketMemoryOps(HexagonPacketSummary const &Summary) const
void restrictPreferSlot3(HexagonPacketSummary const &Summary, const bool DoShuffle)
bool HasInstWith(InstPredicate Pred) const
std::vector< std::pair< SMLoc, std::string > > AppliedRestrictions
std::optional< HexagonPacket > tryAuction(HexagonPacketSummary const &Summary)
Context object for machine code objects.
Definition: MCContext.h:76
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Generic base class for all target subtargets.
Represents a location in source code.
Definition: SMLoc.h:23
size_t size() const
Definition: SmallVector.h:91
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
A range adaptor for a pair of iterators.
constexpr int64_t memReorderDisabledMask
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition: bit.h:349
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1826