1 //===----- HexagonShuffler.h - Instruction bundle shuffling ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This implements the shuffling of insns inside a bundle according to the
11 // packet formation rules of the Hexagon ISA.
13 //===----------------------------------------------------------------------===//
15 #ifndef HEXAGONSHUFFLER_H
16 #define HEXAGONSHUFFLER_H
19 #include "MCTargetDesc/HexagonMCInstrInfo.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
29 class HexagonResource {
30 // Mask of the slots or units that may execute the insn and
31 // the weight or priority that the insn requires to be assigned a slot.
32 unsigned Slots, Weight;
35 HexagonResource(unsigned s) { setUnits(s); };
37 void setUnits(unsigned s) {
38 Slots = s & ~(~0U << HEXAGON_PACKET_SIZE);
40 unsigned setWeight(unsigned s);
42 unsigned getUnits() const { return (Slots); };
43 unsigned getWeight() const { return (Weight); };
45 // Check if the resources are in ascending slot order.
46 static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
47 return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
49 // Check if the resources are in ascending weight order.
50 static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
51 return (A.getWeight() < B.getWeight());
55 // HVX insn resources.
56 class HexagonCVIResource : public HexagonResource {
58 typedef std::pair<unsigned, unsigned> UnitsAndLanes;
59 typedef llvm::DenseMap<unsigned, UnitsAndLanes> TypeUnitsAndLanes;
62 // Available HVX slots.
71 TypeUnitsAndLanes *TUL;
73 // Count of adjacent slots that the insn requires to be executed.
75 // Flag whether the insn is a load or a store.
77 // Flag whether the HVX resources are valid.
80 void setLanes(unsigned l) { Lanes = l; };
81 void setLoad(bool f = true) { Load = f; };
82 void setStore(bool f = true) { Store = f; };
85 HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII,
86 unsigned s, MCInst const *id);
87 static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU);
89 bool isValid() const { return (Valid); };
90 unsigned getLanes() const { return (Lanes); };
91 bool mayLoad() const { return (Load); };
92 bool mayStore() const { return (Store); };
95 // Handle to an insn used by the shuffling algorithm.
97 friend class HexagonShuffler;
100 MCInst const *Extender;
101 HexagonResource Core;
102 HexagonCVIResource CVI;
106 HexagonInstr(HexagonCVIResource::TypeUnitsAndLanes *T,
107 MCInstrInfo const &MCII, MCInst const *id,
108 MCInst const *Extender, unsigned s, bool x = false)
109 : ID(id), Extender(Extender), Core(s), CVI(T, MCII, s, id),
112 MCInst const *getDesc() const { return (ID); };
114 MCInst const *getExtender() const { return Extender; }
116 unsigned isSoloException() const { return (SoloException); };
118 // Check if the handles are in ascending order for shuffling purposes.
119 bool operator<(const HexagonInstr &B) const {
120 return (HexagonResource::lessWeight(B.Core, Core));
122 // Check if the handles are in ascending order by core slots.
123 static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
124 return (HexagonResource::lessUnits(A.Core, B.Core));
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));
133 class HexagonShuffler {
134 typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>
137 // Insn handles in a bundle.
138 HexagonPacket Packet;
140 // Shuffling error code.
143 HexagonCVIResource::TypeUnitsAndLanes TUL;
147 MCInstrInfo const &MCII;
148 MCSubtargetInfo const &STI;
151 typedef HexagonPacket::iterator iterator;
154 SHUFFLE_SUCCESS = 0, ///< Successful operation.
155 SHUFFLE_ERROR_INVALID, ///< Invalid bundle.
156 SHUFFLE_ERROR_STORES, ///< No free slots for store insns.
157 SHUFFLE_ERROR_LOADS, ///< No free slots for load insns.
158 SHUFFLE_ERROR_BRANCHES, ///< No free slots for branch insns.
159 SHUFFLE_ERROR_NOSLOTS, ///< No free slots for other insns.
160 SHUFFLE_ERROR_SLOTS, ///< Over-subscribed slots.
161 SHUFFLE_ERROR_ERRATA2, ///< Errata violation (v60).
162 SHUFFLE_ERROR_STORE_LOAD_CONFLICT, ///< store/load conflict
163 SHUFFLE_ERROR_UNKNOWN ///< Unknown error.
166 explicit HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
168 // Reset to initial state.
170 // Check if the bundle may be validly shuffled.
172 // Reorder the insn handles in the bundle.
175 unsigned size() const { return (Packet.size()); };
177 iterator begin() { return (Packet.begin()); };
178 iterator end() { return (Packet.end()); };
180 // Add insn handle to the bundle .
181 void append(MCInst const *ID, MCInst const *Extender, unsigned S,
184 // Return the error code for the last check or shuffling of the bundle.
185 void setError(unsigned Err) { Error = Err; };
186 unsigned getError() const { return (Error); };
190 #endif // HEXAGONSHUFFLER_H