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"
28 class HexagonResource {
29 // Mask of the slots or units that may execute the insn and
30 // the weight or priority that the insn requires to be assigned a slot.
31 unsigned Slots, Weight;
34 HexagonResource(unsigned s) { setUnits(s); };
36 void setUnits(unsigned s) {
37 Slots = s & ~(~0U << HEXAGON_PACKET_SIZE);
39 unsigned setWeight(unsigned s);
41 unsigned getUnits() const { return (Slots); };
42 unsigned getWeight() const { return (Weight); };
44 // Check if the resources are in ascending slot order.
45 static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
46 return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
48 // Check if the resources are in ascending weight order.
49 static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
50 return (A.getWeight() < B.getWeight());
54 // HVX insn resources.
55 class HexagonCVIResource : public HexagonResource {
56 typedef std::pair<unsigned, unsigned> UnitsAndLanes;
57 typedef llvm::DenseMap<unsigned, UnitsAndLanes> TypeUnitsAndLanes;
59 // Available HVX slots.
70 static TypeUnitsAndLanes *TUL;
72 // Count of adjacent slots that the insn requires to be executed.
74 // Flag whether the insn is a load or a store.
76 // Flag whether the HVX resources are valid.
79 void setLanes(unsigned l) { Lanes = l; };
80 void setLoad(bool f = true) { Load = f; };
81 void setStore(bool f = true) { Store = f; };
84 HexagonCVIResource(MCInstrInfo const &MCII, unsigned s, MCInst const *id);
86 bool isValid() const { return (Valid); };
87 unsigned getLanes() const { return (Lanes); };
88 bool mayLoad() const { return (Load); };
89 bool mayStore() const { return (Store); };
92 // Handle to an insn used by the shuffling algorithm.
94 friend class HexagonShuffler;
97 MCInst const *Extender;
99 HexagonCVIResource CVI;
103 HexagonInstr(MCInstrInfo const &MCII, MCInst const *id,
104 MCInst const *Extender, unsigned s, bool x = false)
105 : ID(id), Extender(Extender), Core(s), CVI(MCII, s, id),
108 MCInst const *getDesc() const { return (ID); };
110 MCInst const *getExtender() const { return Extender; }
112 unsigned isSoloException() const { return (SoloException); };
114 // Check if the handles are in ascending order for shuffling purposes.
115 bool operator<(const HexagonInstr &B) const {
116 return (HexagonResource::lessWeight(B.Core, Core));
118 // Check if the handles are in ascending order by core slots.
119 static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
120 return (HexagonResource::lessUnits(A.Core, B.Core));
122 // Check if the handles are in ascending order by HVX slots.
123 static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B) {
124 return (HexagonResource::lessUnits(A.CVI, B.CVI));
129 class HexagonShuffler {
130 typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>
133 // Insn handles in a bundle.
134 HexagonPacket Packet;
136 // Shuffling error code.
141 MCInstrInfo const &MCII;
142 MCSubtargetInfo const &STI;
145 typedef HexagonPacket::iterator iterator;
148 SHUFFLE_SUCCESS = 0, ///< Successful operation.
149 SHUFFLE_ERROR_INVALID, ///< Invalid bundle.
150 SHUFFLE_ERROR_STORES, ///< No free slots for store insns.
151 SHUFFLE_ERROR_LOADS, ///< No free slots for load insns.
152 SHUFFLE_ERROR_BRANCHES, ///< No free slots for branch insns.
153 SHUFFLE_ERROR_NOSLOTS, ///< No free slots for other insns.
154 SHUFFLE_ERROR_SLOTS, ///< Over-subscribed slots.
155 SHUFFLE_ERROR_ERRATA2, ///< Errata violation (v60).
156 SHUFFLE_ERROR_STORE_LOAD_CONFLICT, ///< store/load conflict
157 SHUFFLE_ERROR_UNKNOWN ///< Unknown error.
160 explicit HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
162 // Reset to initial state.
164 // Check if the bundle may be validly shuffled.
166 // Reorder the insn handles in the bundle.
169 unsigned size() const { return (Packet.size()); };
171 iterator begin() { return (Packet.begin()); };
172 iterator end() { return (Packet.end()); };
174 // Add insn handle to the bundle .
175 void append(MCInst const *ID, MCInst const *Extender, unsigned S,
178 // Return the error code for the last check or shuffling of the bundle.
179 void setError(unsigned Err) { Error = Err; };
180 unsigned getError() const { return (Error); };
184 #endif // HEXAGONSHUFFLER_H