]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r302069, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / 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 & ((1u << HEXAGON_PACKET_SIZE) - 1);
39     setWeight(s);
40   };
41   unsigned setWeight(unsigned s);
42
43   unsigned getUnits() const { return (Slots); };
44   unsigned getWeight() const { return (Weight); };
45
46   // Check if the resources are in ascending slot order.
47   static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
48     return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
49   };
50   // Check if the resources are in ascending weight order.
51   static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
52     return (A.getWeight() < B.getWeight());
53   };
54 };
55
56 // HVX insn resources.
57 class HexagonCVIResource : public HexagonResource {
58 public:
59   typedef std::pair<unsigned, unsigned> UnitsAndLanes;
60   typedef llvm::DenseMap<unsigned, UnitsAndLanes> TypeUnitsAndLanes;
61
62 private:
63   // Available HVX slots.
64   enum {
65     CVI_NONE = 0,
66     CVI_XLANE = 1 << 0,
67     CVI_SHIFT = 1 << 1,
68     CVI_MPY0 = 1 << 2,
69     CVI_MPY1 = 1 << 3
70   };
71
72   TypeUnitsAndLanes *TUL;
73
74   // Count of adjacent slots that the insn requires to be executed.
75   unsigned Lanes;
76   // Flag whether the insn is a load or a store.
77   bool Load, Store;
78   // Flag whether the HVX resources are valid.
79   bool Valid;
80
81   void setLanes(unsigned l) { Lanes = l; };
82   void setLoad(bool f = true) { Load = f; };
83   void setStore(bool f = true) { Store = f; };
84
85 public:
86   HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII,
87                      unsigned s, MCInst const *id);
88   static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU);
89
90   bool isValid() const { return Valid; };
91   unsigned getLanes() const { return Lanes; };
92   bool mayLoad() const { return Load; };
93   bool mayStore() const { return Store; };
94 };
95
96 // Handle to an insn used by the shuffling algorithm.
97 class HexagonInstr {
98   friend class HexagonShuffler;
99
100   MCInst const *ID;
101   MCInst const *Extender;
102   HexagonResource Core;
103   HexagonCVIResource CVI;
104
105 public:
106   HexagonInstr(HexagonCVIResource::TypeUnitsAndLanes *T,
107                MCInstrInfo const &MCII, MCInst const *id,
108                MCInst const *Extender, unsigned s)
109       : ID(id), Extender(Extender), Core(s), CVI(T, MCII, s, id) {};
110
111   MCInst const &getDesc() const { return *ID; };
112
113   MCInst const *getExtender() const { return Extender; }
114
115   // Check if the handles are in ascending order for shuffling purposes.
116   bool operator<(const HexagonInstr &B) const {
117     return (HexagonResource::lessWeight(B.Core, Core));
118   };
119   // Check if the handles are in ascending order by core slots.
120   static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
121     return (HexagonResource::lessUnits(A.Core, B.Core));
122   };
123   // Check if the handles are in ascending order by HVX slots.
124   static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B) {
125     return (HexagonResource::lessUnits(A.CVI, B.CVI));
126   };
127 };
128
129 // Bundle shuffler.
130 class HexagonShuffler {
131   typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>
132       HexagonPacket;
133
134   // Insn handles in a bundle.
135   HexagonPacket Packet;
136   HexagonPacket PacketSave;
137
138   HexagonCVIResource::TypeUnitsAndLanes TUL;
139
140 protected:
141   MCContext &Context;
142   int64_t BundleFlags;
143   MCInstrInfo const &MCII;
144   MCSubtargetInfo const &STI;
145   SMLoc Loc;
146   bool ReportErrors;
147
148 public:
149   typedef HexagonPacket::iterator iterator;
150
151   HexagonShuffler(MCContext &Context, bool ReportErrors,
152                   MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
153
154   // Reset to initial state.
155   void reset();
156   // Check if the bundle may be validly shuffled.
157   bool check();
158   // Reorder the insn handles in the bundle.
159   bool shuffle();
160
161   unsigned size() const { return (Packet.size()); };
162
163   iterator begin() { return (Packet.begin()); };
164   iterator end() { return (Packet.end()); };
165
166   // Add insn handle to the bundle .
167   void append(MCInst const &ID, MCInst const *Extender, unsigned S);
168
169   // Return the error code for the last check or shuffling of the bundle.
170   void reportError(llvm::Twine const &Msg);
171 };
172 } // namespace llvm
173
174 #endif // HEXAGONSHUFFLER_H