1 //===- HexagonShuffler.h - Instruction bundle shuffling ---------*- C++ -*-===//
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 LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
16 #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
19 #include "MCTargetDesc/HexagonMCInstrInfo.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/MathExtras.h"
24 #include "llvm/Support/SMLoc.h"
33 class MCSubtargetInfo;
36 class HexagonResource {
37 // Mask of the slots or units that may execute the insn and
38 // the weight or priority that the insn requires to be assigned a slot.
39 unsigned Slots, Weight;
42 HexagonResource(unsigned s) { setUnits(s); }
44 void setUnits(unsigned s) {
45 Slots = s & ((1u << HEXAGON_PACKET_SIZE) - 1);
49 unsigned setWeight(unsigned s);
51 unsigned getUnits() const { return (Slots); }
52 unsigned getWeight() const { return (Weight); }
54 // Check if the resources are in ascending slot order.
55 static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
56 return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
59 // Check if the resources are in ascending weight order.
60 static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
61 return (A.getWeight() < B.getWeight());
65 // HVX insn resources.
66 class HexagonCVIResource : public HexagonResource {
68 using UnitsAndLanes = std::pair<unsigned, unsigned>;
69 using TypeUnitsAndLanes = DenseMap<unsigned, UnitsAndLanes>;
72 // Available HVX slots.
82 // Count of adjacent slots that the insn requires to be executed.
84 // Flag whether the insn is a load or a store.
86 // Flag whether the HVX resources are valid.
89 void setLanes(unsigned l) { Lanes = l; }
90 void setLoad(bool f = true) { Load = f; }
91 void setStore(bool f = true) { Store = f; }
94 HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII,
95 unsigned s, MCInst const *id);
97 static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU);
99 bool isValid() const { return Valid; }
100 unsigned getLanes() const { return Lanes; }
101 bool mayLoad() const { return Load; }
102 bool mayStore() const { return Store; }
105 // Handle to an insn used by the shuffling algorithm.
107 friend class HexagonShuffler;
110 MCInst const *Extender;
111 HexagonResource Core;
112 HexagonCVIResource CVI;
115 HexagonInstr(HexagonCVIResource::TypeUnitsAndLanes *T,
116 MCInstrInfo const &MCII, MCInst const *id,
117 MCInst const *Extender, unsigned s)
118 : ID(id), Extender(Extender), Core(s), CVI(T, MCII, s, id) {}
120 MCInst const &getDesc() const { return *ID; }
121 MCInst const *getExtender() const { return Extender; }
123 // Check if the handles are in ascending order for shuffling purposes.
124 bool operator<(const HexagonInstr &B) const {
125 return (HexagonResource::lessWeight(B.Core, Core));
128 // Check if the handles are in ascending order by core slots.
129 static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
130 return (HexagonResource::lessUnits(A.Core, B.Core));
133 // Check if the handles are in ascending order by HVX slots.
134 static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B) {
135 return (HexagonResource::lessUnits(A.CVI, B.CVI));
140 class HexagonShuffler {
141 using HexagonPacket =
142 SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>;
144 // Insn handles in a bundle.
145 HexagonPacket Packet;
146 HexagonPacket PacketSave;
148 HexagonCVIResource::TypeUnitsAndLanes TUL;
153 MCInstrInfo const &MCII;
154 MCSubtargetInfo const &STI;
157 std::vector<std::pair<SMLoc, std::string>> AppliedRestrictions;
158 void applySlotRestrictions();
159 void restrictSlot1AOK();
160 void restrictNoSlot1Store();
163 using iterator = HexagonPacket::iterator;
165 HexagonShuffler(MCContext &Context, bool ReportErrors,
166 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 bool isMemReorderDisabled() const {
178 return (BundleFlags & HexagonMCInstrInfo::memReorderDisabledMask) != 0;
181 iterator begin() { return (Packet.begin()); }
182 iterator end() { return (Packet.end()); }
184 // Add insn handle to the bundle .
185 void append(MCInst const &ID, MCInst const *Extender, unsigned S);
187 // Return the error code for the last check or shuffling of the bundle.
188 void reportError(Twine const &Msg);
191 } // end namespace llvm
193 #endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H