[Hexagon] Replace a static member variable in HexagonCVIResource (NFC)
[oota-llvm.git] / lib / Target / Hexagon / MCTargetDesc / HexagonShuffler.h
1 //===----- HexagonShuffler.h - Instruction bundle shuffling ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This implements the shuffling of insns inside a bundle according to the
11 // packet formation rules of the Hexagon ISA.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef HEXAGONSHUFFLER_H
16 #define HEXAGONSHUFFLER_H
17
18 #include "Hexagon.h"
19 #include "MCTargetDesc/HexagonMCInstrInfo.h"
20
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24
25 using namespace llvm;
26
27 namespace llvm {
28 // Insn resources.
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;
33
34 public:
35   HexagonResource(unsigned s) { setUnits(s); };
36
37   void setUnits(unsigned s) {
38     Slots = s & ~(~0U << HEXAGON_PACKET_SIZE);
39   };
40   unsigned setWeight(unsigned s);
41
42   unsigned getUnits() const { return (Slots); };
43   unsigned getWeight() const { return (Weight); };
44
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()));
48   };
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());
52   };
53 };
54
55 // HVX insn resources.
56 class HexagonCVIResource : public HexagonResource {
57 public:
58   typedef std::pair<unsigned, unsigned> UnitsAndLanes;
59   typedef llvm::DenseMap<unsigned, UnitsAndLanes> TypeUnitsAndLanes;
60
61 private:
62   // Available HVX slots.
63   enum {
64     CVI_NONE = 0,
65     CVI_XLANE = 1 << 0,
66     CVI_SHIFT = 1 << 1,
67     CVI_MPY0 = 1 << 2,
68     CVI_MPY1 = 1 << 3
69   };
70
71   TypeUnitsAndLanes *TUL;
72
73   // Count of adjacent slots that the insn requires to be executed.
74   unsigned Lanes;
75   // Flag whether the insn is a load or a store.
76   bool Load, Store;
77   // Flag whether the HVX resources are valid.
78   bool Valid;
79
80   void setLanes(unsigned l) { Lanes = l; };
81   void setLoad(bool f = true) { Load = f; };
82   void setStore(bool f = true) { Store = f; };
83
84 public:
85   HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII,
86                      unsigned s, MCInst const *id);
87   static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU);
88
89   bool isValid() const { return (Valid); };
90   unsigned getLanes() const { return (Lanes); };
91   bool mayLoad() const { return (Load); };
92   bool mayStore() const { return (Store); };
93 };
94
95 // Handle to an insn used by the shuffling algorithm.
96 class HexagonInstr {
97   friend class HexagonShuffler;
98
99   MCInst const *ID;
100   MCInst const *Extender;
101   HexagonResource Core;
102   HexagonCVIResource CVI;
103   bool SoloException;
104
105 public:
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),
110         SoloException(x) {};
111
112   MCInst const *getDesc() const { return (ID); };
113
114   MCInst const *getExtender() const { return Extender; }
115
116   unsigned isSoloException() const { return (SoloException); };
117
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));
121   };
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));
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.
133 class HexagonShuffler {
134   typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>
135       HexagonPacket;
136
137   // Insn handles in a bundle.
138   HexagonPacket Packet;
139
140   // Shuffling error code.
141   unsigned Error;
142
143   HexagonCVIResource::TypeUnitsAndLanes TUL;
144
145 protected:
146   int64_t BundleFlags;
147   MCInstrInfo const &MCII;
148   MCSubtargetInfo const &STI;
149
150 public:
151   typedef HexagonPacket::iterator iterator;
152
153   enum {
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.
164   };
165
166   explicit HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
167
168   // Reset to initial state.
169   void reset();
170   // Check if the bundle may be validly shuffled.
171   bool check();
172   // Reorder the insn handles in the bundle.
173   bool shuffle();
174
175   unsigned size() const { return (Packet.size()); };
176
177   iterator begin() { return (Packet.begin()); };
178   iterator end() { return (Packet.end()); };
179
180   // Add insn handle to the bundle .
181   void append(MCInst const *ID, MCInst const *Extender, unsigned S,
182               bool X = false);
183
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); };
187 };
188 }
189
190 #endif // HEXAGONSHUFFLER_H