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 // Handle to an insn used by the shuffling algorithm. 55 class HexagonInstr { 56 friend class HexagonShuffler; 57 58 MCInst const *ID; 59 MCInst const *Extender; 60 HexagonResource Core; 61 bool SoloException; 62 63 public: 64 HexagonInstr(MCInst const *id, MCInst const *Extender, unsigned s, 65 bool x = false) ID(id)66 : ID(id), Extender(Extender), Core(s), SoloException(x){}; 67 getDesc()68 MCInst const *getDesc() const { return (ID); }; 69 getExtender()70 MCInst const *getExtender() const { return Extender; } 71 isSoloException()72 unsigned isSoloException() const { return (SoloException); }; 73 74 // Check if the handles are in ascending order for shuffling purposes. 75 bool operator<(const HexagonInstr &B) const { 76 return (HexagonResource::lessWeight(B.Core, Core)); 77 }; 78 // Check if the handles are in ascending order by core slots. lessCore(const HexagonInstr & A,const HexagonInstr & B)79 static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) { 80 return (HexagonResource::lessUnits(A.Core, B.Core)); 81 }; 82 }; 83 84 // Bundle shuffler. 85 class HexagonShuffler { 86 typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE> 87 HexagonPacket; 88 89 // Insn handles in a bundle. 90 HexagonPacket Packet; 91 92 // Shuffling error code. 93 unsigned Error; 94 95 protected: 96 int64_t BundleFlags; 97 MCInstrInfo const &MCII; 98 MCSubtargetInfo const &STI; 99 100 public: 101 typedef HexagonPacket::iterator iterator; 102 103 enum { 104 SHUFFLE_SUCCESS = 0, ///< Successful operation. 105 SHUFFLE_ERROR_INVALID, ///< Invalid bundle. 106 SHUFFLE_ERROR_STORES, ///< No free slots for store insns. 107 SHUFFLE_ERROR_LOADS, ///< No free slots for load insns. 108 SHUFFLE_ERROR_BRANCHES, ///< No free slots for branch insns. 109 SHUFFLE_ERROR_NOSLOTS, ///< No free slots for other insns. 110 SHUFFLE_ERROR_SLOTS, ///< Over-subscribed slots. 111 SHUFFLE_ERROR_UNKNOWN ///< Unknown error. 112 }; 113 114 explicit HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI); 115 116 // Reset to initial state. 117 void reset(); 118 // Check if the bundle may be validly shuffled. 119 bool check(); 120 // Reorder the insn handles in the bundle. 121 bool shuffle(); 122 size()123 unsigned size() const { return (Packet.size()); }; 124 begin()125 iterator begin() { return (Packet.begin()); }; end()126 iterator end() { return (Packet.end()); }; 127 128 // Add insn handle to the bundle . 129 void append(MCInst const *ID, MCInst const *Extender, unsigned S, 130 bool X = false); 131 132 // Return the error code for the last check or shuffling of the bundle. setError(unsigned Err)133 void setError(unsigned Err) { Error = Err; }; getError()134 unsigned getError() const { return (Error); }; 135 }; 136 } 137 138 #endif // HEXAGONSHUFFLER_H 139