• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 using namespace llvm;
25 
26 namespace llvm {
27 // Insn resources.
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;
32 
33 public:
HexagonResource(unsigned s)34   HexagonResource(unsigned s) { setUnits(s); };
35 
setUnits(unsigned s)36   void setUnits(unsigned s) {
37     Slots = s & ~(~0U << HEXAGON_PACKET_SIZE);
38   };
39   unsigned setWeight(unsigned s);
40 
getUnits()41   unsigned getUnits() const { return (Slots); };
getWeight()42   unsigned getWeight() const { return (Weight); };
43 
44   // Check if the resources are in ascending slot order.
lessUnits(const HexagonResource & A,const HexagonResource & B)45   static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
46     return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
47   };
48   // Check if the resources are in ascending weight order.
lessWeight(const HexagonResource & A,const HexagonResource & B)49   static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
50     return (A.getWeight() < B.getWeight());
51   };
52 };
53 
54 // HVX insn resources.
55 class HexagonCVIResource : public HexagonResource {
56   typedef std::pair<unsigned, unsigned> UnitsAndLanes;
57   typedef llvm::DenseMap<unsigned, UnitsAndLanes> TypeUnitsAndLanes;
58 
59   // Available HVX slots.
60   enum {
61     CVI_NONE = 0,
62     CVI_XLANE = 1 << 0,
63     CVI_SHIFT = 1 << 1,
64     CVI_MPY0 = 1 << 2,
65     CVI_MPY1 = 1 << 3
66   };
67 
68   static bool SetUp;
69   static bool setup();
70   static TypeUnitsAndLanes *TUL;
71 
72   // Count of adjacent slots that the insn requires to be executed.
73   unsigned Lanes;
74   // Flag whether the insn is a load or a store.
75   bool Load, Store;
76   // Flag whether the HVX resources are valid.
77   bool Valid;
78 
setLanes(unsigned l)79   void setLanes(unsigned l) { Lanes = l; };
80   void setLoad(bool f = true) { Load = f; };
81   void setStore(bool f = true) { Store = f; };
82 
83 public:
84   HexagonCVIResource(MCInstrInfo const &MCII, unsigned s, MCInst const *id);
85 
isValid()86   bool isValid() const { return (Valid); };
getLanes()87   unsigned getLanes() const { return (Lanes); };
mayLoad()88   bool mayLoad() const { return (Load); };
mayStore()89   bool mayStore() const { return (Store); };
90 };
91 
92 // Handle to an insn used by the shuffling algorithm.
93 class HexagonInstr {
94   friend class HexagonShuffler;
95 
96   MCInst const *ID;
97   MCInst const *Extender;
98   HexagonResource Core;
99   HexagonCVIResource CVI;
100   bool SoloException;
101 
102 public:
103   HexagonInstr(MCInstrInfo const &MCII, MCInst const *id,
104                MCInst const *Extender, unsigned s, bool x = false)
ID(id)105       : ID(id), Extender(Extender), Core(s), CVI(MCII, s, id),
106         SoloException(x){};
107 
getDesc()108   MCInst const *getDesc() const { return (ID); };
109 
getExtender()110   MCInst const *getExtender() const { return Extender; }
111 
isSoloException()112   unsigned isSoloException() const { return (SoloException); };
113 
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));
117   };
118   // Check if the handles are in ascending order by core slots.
lessCore(const HexagonInstr & A,const HexagonInstr & B)119   static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
120     return (HexagonResource::lessUnits(A.Core, B.Core));
121   };
122   // Check if the handles are in ascending order by HVX slots.
lessCVI(const HexagonInstr & A,const HexagonInstr & B)123   static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B) {
124     return (HexagonResource::lessUnits(A.CVI, B.CVI));
125   };
126 };
127 
128 // Bundle shuffler.
129 class HexagonShuffler {
130   typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>
131       HexagonPacket;
132 
133   // Insn handles in a bundle.
134   HexagonPacket Packet;
135 
136   // Shuffling error code.
137   unsigned Error;
138 
139 protected:
140   int64_t BundleFlags;
141   MCInstrInfo const &MCII;
142   MCSubtargetInfo const &STI;
143 
144 public:
145   typedef HexagonPacket::iterator iterator;
146 
147   enum {
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.
158   };
159 
160   explicit HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
161 
162   // Reset to initial state.
163   void reset();
164   // Check if the bundle may be validly shuffled.
165   bool check();
166   // Reorder the insn handles in the bundle.
167   bool shuffle();
168 
size()169   unsigned size() const { return (Packet.size()); };
170 
begin()171   iterator begin() { return (Packet.begin()); };
end()172   iterator end() { return (Packet.end()); };
173 
174   // Add insn handle to the bundle .
175   void append(MCInst const *ID, MCInst const *Extender, unsigned S,
176               bool X = false);
177 
178   // Return the error code for the last check or shuffling of the bundle.
setError(unsigned Err)179   void setError(unsigned Err) { Error = Err; };
getError()180   unsigned getError() const { return (Error); };
181 };
182 }
183 
184 #endif // HEXAGONSHUFFLER_H
185