16948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//===----- HexagonShuffler.h - Instruction bundle shuffling ---------------===//
26948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//
36948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//                     The LLVM Compiler Infrastructure
46948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//
56948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source
66948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// License. See LICENSE.TXT for details.
76948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//
86948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
96948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//
106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// This implements the shuffling of insns inside a bundle according to the
116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// packet formation rules of the Hexagon ISA.
126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//
136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#ifndef HEXAGONSHUFFLER_H
166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#define HEXAGONSHUFFLER_H
176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "Hexagon.h"
196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "MCTargetDesc/HexagonMCInstrInfo.h"
206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/ADT/SmallVector.h"
226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/MC/MCInstrInfo.h"
236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarusing namespace llvm;
256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarnamespace llvm {
276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Insn resources.
286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarclass HexagonResource {
296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Mask of the slots or units that may execute the insn and
306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // the weight or priority that the insn requires to be assigned a slot.
316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned Slots, Weight;
326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarpublic:
346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  HexagonResource(unsigned s) { setUnits(s); };
356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void setUnits(unsigned s) {
37cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Slots = s & ~(~0U << HEXAGON_PACKET_SIZE);
386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  };
396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned setWeight(unsigned s);
406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned getUnits() const { return (Slots); };
426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned getWeight() const { return (Weight); };
436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Check if the resources are in ascending slot order.
456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  };
486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Check if the resources are in ascending weight order.
496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return (A.getWeight() < B.getWeight());
516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  };
526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar};
536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
54cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// HVX insn resources.
55cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarclass HexagonCVIResource : public HexagonResource {
56cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  typedef std::pair<unsigned, unsigned> UnitsAndLanes;
57cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  typedef llvm::DenseMap<unsigned, UnitsAndLanes> TypeUnitsAndLanes;
58cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
59cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Available HVX slots.
60cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  enum {
61cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    CVI_NONE = 0,
62cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    CVI_XLANE = 1 << 0,
63cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    CVI_SHIFT = 1 << 1,
64cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    CVI_MPY0 = 1 << 2,
65cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    CVI_MPY1 = 1 << 3
66cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  };
67cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
68cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  static bool SetUp;
69cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  static bool setup();
70cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  static TypeUnitsAndLanes *TUL;
71cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
72cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Count of adjacent slots that the insn requires to be executed.
73cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  unsigned Lanes;
74cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Flag whether the insn is a load or a store.
75cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  bool Load, Store;
76cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Flag whether the HVX resources are valid.
77cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  bool Valid;
78cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
79cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  void setLanes(unsigned l) { Lanes = l; };
80cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  void setLoad(bool f = true) { Load = f; };
81cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  void setStore(bool f = true) { Store = f; };
82cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
83cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarpublic:
84cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  HexagonCVIResource(MCInstrInfo const &MCII, unsigned s, MCInst const *id);
85cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
86cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  bool isValid() const { return (Valid); };
87cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  unsigned getLanes() const { return (Lanes); };
88cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  bool mayLoad() const { return (Load); };
89cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  bool mayStore() const { return (Store); };
90cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar};
91cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Handle to an insn used by the shuffling algorithm.
936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarclass HexagonInstr {
946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  friend class HexagonShuffler;
956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCInst const *ID;
976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCInst const *Extender;
986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  HexagonResource Core;
99cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  HexagonCVIResource CVI;
1006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool SoloException;
1016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarpublic:
103cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  HexagonInstr(MCInstrInfo const &MCII, MCInst const *id,
104cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar               MCInst const *Extender, unsigned s, bool x = false)
105cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      : ID(id), Extender(Extender), Core(s), CVI(MCII, s, id),
106cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        SoloException(x){};
1076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCInst const *getDesc() const { return (ID); };
1096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCInst const *getExtender() const { return Extender; }
1116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned isSoloException() const { return (SoloException); };
1136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Check if the handles are in ascending order for shuffling purposes.
1156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool operator<(const HexagonInstr &B) const {
1166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return (HexagonResource::lessWeight(B.Core, Core));
1176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  };
1186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Check if the handles are in ascending order by core slots.
1196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
1206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return (HexagonResource::lessUnits(A.Core, B.Core));
1216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  };
122cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Check if the handles are in ascending order by HVX slots.
123cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B) {
124cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return (HexagonResource::lessUnits(A.CVI, B.CVI));
125cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  };
1266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar};
1276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// Bundle shuffler.
1296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarclass HexagonShuffler {
1306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>
1316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      HexagonPacket;
1326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Insn handles in a bundle.
1346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  HexagonPacket Packet;
1356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Shuffling error code.
1376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned Error;
1386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarprotected:
1406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  int64_t BundleFlags;
1416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCInstrInfo const &MCII;
1426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCSubtargetInfo const &STI;
1436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarpublic:
1456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  typedef HexagonPacket::iterator iterator;
1466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  enum {
1486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SHUFFLE_SUCCESS = 0,    ///< Successful operation.
1496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SHUFFLE_ERROR_INVALID,  ///< Invalid bundle.
1506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SHUFFLE_ERROR_STORES,   ///< No free slots for store insns.
1516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SHUFFLE_ERROR_LOADS,    ///< No free slots for load insns.
1526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SHUFFLE_ERROR_BRANCHES, ///< No free slots for branch insns.
1536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SHUFFLE_ERROR_NOSLOTS,  ///< No free slots for other insns.
1546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SHUFFLE_ERROR_SLOTS,    ///< Over-subscribed slots.
155cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    SHUFFLE_ERROR_ERRATA2, ///< Errata violation (v60).
156cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    SHUFFLE_ERROR_STORE_LOAD_CONFLICT, ///< store/load conflict
1576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SHUFFLE_ERROR_UNKNOWN   ///< Unknown error.
1586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  };
1596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  explicit HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
1616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Reset to initial state.
1636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void reset();
1646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Check if the bundle may be validly shuffled.
1656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool check();
1666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Reorder the insn handles in the bundle.
1676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool shuffle();
1686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned size() const { return (Packet.size()); };
1706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  iterator begin() { return (Packet.begin()); };
1726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  iterator end() { return (Packet.end()); };
1736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Add insn handle to the bundle .
1756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void append(MCInst const *ID, MCInst const *Extender, unsigned S,
1766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar              bool X = false);
1776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Return the error code for the last check or shuffling of the bundle.
1796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void setError(unsigned Err) { Error = Err; };
1806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned getError() const { return (Error); };
1816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar};
1826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
1836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#endif // HEXAGONSHUFFLER_H
185