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