brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.8 KiB · 838672d Raw
244 lines · c
1//===- HexagonShuffler.h - Instruction bundle shuffling ---------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This implements the shuffling of insns inside a bundle according to the10// packet formation rules of the Hexagon ISA.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H15#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H16 17#include "MCTargetDesc/HexagonMCInstrInfo.h"18#include "MCTargetDesc/HexagonMCTargetDesc.h"19#include "llvm/ADT/STLExtras.h"20#include "llvm/ADT/SmallVector.h"21#include "llvm/ADT/StringRef.h"22#include "llvm/Support/MathExtras.h"23#include "llvm/Support/SMLoc.h"24#include <cstdint>25#include <functional>26#include <optional>27#include <utility>28 29namespace llvm {30 31class MCContext;32class MCInst;33class MCInstrInfo;34class MCSubtargetInfo;35 36// Insn resources.37class HexagonResource {38  // Mask of the slots or units that may execute the insn and39  // the weight or priority that the insn requires to be assigned a slot.40  unsigned Slots, Weight;41 42public:43  HexagonResource(unsigned s) { setUnits(s); }44 45  void setUnits(unsigned s) {46    Slots = s & ((1u << HEXAGON_PACKET_SIZE) - 1);47    setWeight(s);48  }49 50  void setAllUnits() {51    setUnits(((1u << HEXAGON_PACKET_SIZE) - 1));52  }53  unsigned setWeight(unsigned s);54 55  unsigned getUnits() const { return (Slots); }56  unsigned getWeight() const { return (Weight); }57 58  // Check if the resources are in ascending slot order.59  static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {60    return (llvm::popcount(A.getUnits()) < llvm::popcount(B.getUnits()));61  }62 63  // Check if the resources are in ascending weight order.64  static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {65    return (A.getWeight() < B.getWeight());66  }67};68 69// HVX insn resources.70class HexagonCVIResource : public HexagonResource {71public:72  using UnitsAndLanes = std::pair<unsigned, unsigned>;73 74private:75  // Count of adjacent slots that the insn requires to be executed.76  unsigned Lanes;77  // Flag whether the insn is a load or a store.78  bool Load, Store;79  // Flag whether the HVX resources are valid.80  bool Valid;81 82  void setLanes(unsigned l) { Lanes = l; }83  void setLoad(bool f = true) { Load = f; }84  void setStore(bool f = true) { Store = f; }85 86public:87  HexagonCVIResource(MCInstrInfo const &MCII,88                     MCSubtargetInfo const &STI,89                     unsigned s, MCInst const *id);90 91  bool isValid() const { return Valid; }92  unsigned getLanes() const { return Lanes; }93  bool mayLoad() const { return Load; }94  bool mayStore() const { return Store; }95};96 97// Handle to an insn used by the shuffling algorithm.98class HexagonInstr {99  friend class HexagonShuffler;100 101  MCInst const *ID;102  MCInst const *Extender;103  HexagonResource Core;104  HexagonCVIResource CVI;105 106public:107  HexagonInstr(MCInstrInfo const &MCII,108               MCSubtargetInfo const &STI, MCInst const *id,109               MCInst const *Extender, unsigned s)110      : ID(id), Extender(Extender), Core(s), CVI(MCII, STI, s, id){};111 112  MCInst const &getDesc() const { return *ID; }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 120  // Check if the handles are in ascending order by core slots.121  static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {122    return (HexagonResource::lessUnits(A.Core, B.Core));123  }124 125  // Check if the handles are in ascending order by HVX slots.126  static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B) {127    return (HexagonResource::lessUnits(A.CVI, B.CVI));128  }129};130 131// Bundle shuffler.132class HexagonShuffler {133  using HexagonPacket =134      SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>;135 136  struct HexagonPacketSummary {137    // Number of memory operations, loads, solo loads, stores, solo stores,138    // single stores.139    unsigned memory;140    unsigned loads;141    unsigned load0;142    unsigned stores;143    unsigned store0;144    unsigned store1;145    unsigned NonZCVIloads;146    unsigned AllCVIloads;147    unsigned CVIstores;148    // Number of duplex insns149    unsigned duplex;150    unsigned pSlot3Cnt;151    std::optional<HexagonInstr *> PrefSlot3Inst;152    unsigned memops;153    unsigned ReservedSlotMask;154    SmallVector<HexagonInstr *, HEXAGON_PRESHUFFLE_PACKET_SIZE> branchInsts;155    std::optional<SMLoc> Slot1AOKLoc;156    std::optional<SMLoc> NoSlot1StoreLoc;157  };158  // Insn handles in a bundle.159  HexagonPacket Packet;160 161protected:162  MCContext &Context;163  int64_t BundleFlags;164  MCInstrInfo const &MCII;165  MCSubtargetInfo const &STI;166  SMLoc Loc;167  bool ReportErrors;168  bool CheckFailure;169  std::vector<std::pair<SMLoc, std::string>> AppliedRestrictions;170 171  bool applySlotRestrictions(HexagonPacketSummary const &Summary,172                             const bool DoShuffle);173  void restrictSlot1AOK(HexagonPacketSummary const &Summary);174  void restrictNoSlot1Store(HexagonPacketSummary const &Summary);175  void restrictNoSlot1();176  bool restrictStoreLoadOrder(HexagonPacketSummary const &Summary);177  void restrictBranchOrder(HexagonPacketSummary const &Summary);178  void restrictPreferSlot3(HexagonPacketSummary const &Summary,179                           const bool DoShuffle);180  void permitNonSlot();181 182  std::optional<HexagonPacket> tryAuction(HexagonPacketSummary const &Summary);183 184  HexagonPacketSummary GetPacketSummary();185  bool ValidPacketMemoryOps(HexagonPacketSummary const &Summary) const;186  bool ValidResourceUsage(HexagonPacketSummary const &Summary);187 188public:189  using iterator = HexagonPacket::iterator;190  using const_iterator = HexagonPacket::const_iterator;191  using packet_range = iterator_range<HexagonPacket::iterator>;192  using const_packet_range = iterator_range<HexagonPacket::const_iterator>;193 194  HexagonShuffler(MCContext &Context, bool ReportErrors,195                  MCInstrInfo const &MCII, MCSubtargetInfo const &STI);196 197  // Reset to initial state.198  void reset();199  // Check if the bundle may be validly shuffled.200  bool check(const bool RequireShuffle = true);201  // Reorder the insn handles in the bundle.202  bool shuffle();203 204  unsigned size() const { return (Packet.size()); }205 206  bool isMemReorderDisabled() const {207    return (BundleFlags & HexagonMCInstrInfo::memReorderDisabledMask) != 0;208  }209 210  iterator begin() { return (Packet.begin()); }211  iterator end() { return (Packet.end()); }212  const_iterator cbegin() const { return (Packet.begin()); }213  const_iterator cend() const { return (Packet.end()); }214  packet_range insts(HexagonPacket &P) {215    return make_range(P.begin(), P.end());216  }217  const_packet_range insts(HexagonPacket const &P) const {218    return make_range(P.begin(), P.end());219  }220  packet_range insts() { return make_range(begin(), end()); }221  const_packet_range insts() const { return make_range(cbegin(), cend()); }222 223  using InstPredicate = bool (*)(MCInstrInfo const &, MCInst const &);224 225  bool HasInstWith(InstPredicate Pred) const {226    return llvm::any_of(insts(), [&](HexagonInstr const &I) {227      MCInst const &Inst = I.getDesc();228      return (*Pred)(MCII, Inst);229    });230  }231 232  // Add insn handle to the bundle .233  void append(MCInst const &ID, MCInst const *Extender, unsigned S);234 235  // Return the error code for the last check or shuffling of the bundle.236  void reportError(Twine const &Msg);237  void reportResourceError(HexagonPacketSummary const &Summary, StringRef Err);238  void reportResourceUsage(HexagonPacketSummary const &Summary);239};240 241} // end namespace llvm242 243#endif //  LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H244