Coverage Report

Created: 2025-08-25 07:49

/src/keystone/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h
Line
Count
Source (jump to first uncovered line)
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
#include "llvm/MC/MCSubtargetInfo.h"
24
25
using namespace llvm_ks;
26
27
namespace llvm_ks {
28
// Insn resources.
29
class HexagonResource {
30
  // Mask of the slots or units that may execute the insn and
31
  // the weight or priority that the insn requires to be assigned a slot.
32
  unsigned Slots, Weight;
33
34
public:
35
36.7k
  HexagonResource(unsigned s) { setUnits(s); };
36
37
55.1k
  void setUnits(unsigned s) {
38
55.1k
    Slots = s & ~(~0U << HEXAGON_PACKET_SIZE);
39
55.1k
  };
40
  unsigned setWeight(unsigned s);
41
42
47.6k
  unsigned getUnits() const { return (Slots); };
43
10
  unsigned getWeight() const { return (Weight); };
44
45
  // Check if the resources are in ascending slot order.
46
6.12k
  static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
47
6.12k
    return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
48
6.12k
  };
49
  // Check if the resources are in ascending weight order.
50
5
  static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
51
5
    return (A.getWeight() < B.getWeight());
52
5
  };
53
};
54
55
// HVX insn resources.
56
class HexagonCVIResource : public HexagonResource {
57
public:
58
  typedef std::pair<unsigned, unsigned> UnitsAndLanes;
59
  typedef llvm_ks::DenseMap<unsigned, UnitsAndLanes> TypeUnitsAndLanes;
60
61
private:
62
  // Available HVX slots.
63
  enum {
64
    CVI_NONE = 0,
65
    CVI_XLANE = 1 << 0,
66
    CVI_SHIFT = 1 << 1,
67
    CVI_MPY0 = 1 << 2,
68
    CVI_MPY1 = 1 << 3
69
  };
70
71
  TypeUnitsAndLanes *TUL;
72
73
  // Count of adjacent slots that the insn requires to be executed.
74
  unsigned Lanes;
75
  // Flag whether the insn is a load or a store.
76
  bool Load, Store;
77
  // Flag whether the HVX resources are valid.
78
  bool Valid;
79
80
18.3k
  void setLanes(unsigned l) { Lanes = l; };
81
18.3k
  void setLoad(bool f = true) { Load = f; };
82
18.3k
  void setStore(bool f = true) { Store = f; };
83
84
public:
85
  HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII,
86
                     unsigned s, MCInst const *id);
87
  static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU);
88
89
0
  bool isValid() const { return (Valid); };
90
6.38k
  unsigned getLanes() const { return (Lanes); };
91
0
  bool mayLoad() const { return (Load); };
92
0
  bool mayStore() const { return (Store); };
93
};
94
95
// Handle to an insn used by the shuffling algorithm.
96
class HexagonInstr {
97
  friend class HexagonShuffler;
98
99
  MCInst const *ID;
100
  MCInst const *Extender;
101
  HexagonResource Core;
102
  HexagonCVIResource CVI;
103
  bool SoloException;
104
105
public:
106
  HexagonInstr(HexagonCVIResource::TypeUnitsAndLanes *T,
107
               MCInstrInfo const &MCII, MCInst const *id,
108
               MCInst const *Extender, unsigned s, bool x = false)
109
18.3k
      : ID(id), Extender(Extender), Core(s), CVI(T, MCII, s, id),
110
18.3k
        SoloException(x) {};
111
112
27.9k
  MCInst const *getDesc() const { return (ID); };
113
114
8.72k
  MCInst const *getExtender() const { return Extender; }
115
116
0
  unsigned isSoloException() const { return (SoloException); };
117
118
  // Check if the handles are in ascending order for shuffling purposes.
119
5
  bool operator<(const HexagonInstr &B) const {
120
5
    return (HexagonResource::lessWeight(B.Core, Core));
121
5
  };
122
  // Check if the handles are in ascending order by core slots.
123
6.11k
  static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
124
6.11k
    return (HexagonResource::lessUnits(A.Core, B.Core));
125
6.11k
  };
126
  // Check if the handles are in ascending order by HVX slots.
127
18
  static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B) {
128
18
    return (HexagonResource::lessUnits(A.CVI, B.CVI));
129
18
  };
130
};
131
132
// Bundle shuffler.
133
class HexagonShuffler {
134
  typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>
135
      HexagonPacket;
136
137
  // Insn handles in a bundle.
138
  HexagonPacket Packet;
139
140
  // Shuffling error code.
141
  unsigned Error;
142
143
  HexagonCVIResource::TypeUnitsAndLanes TUL;
144
145
protected:
146
  int64_t BundleFlags;
147
  MCInstrInfo const &MCII;
148
  MCSubtargetInfo const &STI;
149
150
public:
151
  typedef HexagonPacket::iterator iterator;
152
153
  enum {
154
    SHUFFLE_SUCCESS = 0,    ///< Successful operation.
155
    SHUFFLE_ERROR_INVALID,  ///< Invalid bundle.
156
    SHUFFLE_ERROR_STORES,   ///< No free slots for store insns.
157
    SHUFFLE_ERROR_LOADS,    ///< No free slots for load insns.
158
    SHUFFLE_ERROR_BRANCHES, ///< No free slots for branch insns.
159
    SHUFFLE_ERROR_NOSLOTS,  ///< No free slots for other insns.
160
    SHUFFLE_ERROR_SLOTS,    ///< Over-subscribed slots.
161
    SHUFFLE_ERROR_ERRATA2, ///< Errata violation (v60).
162
    SHUFFLE_ERROR_STORE_LOAD_CONFLICT, ///< store/load conflict
163
    SHUFFLE_ERROR_UNKNOWN   ///< Unknown error.
164
  };
165
166
  explicit HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
167
168
  // Reset to initial state.
169
  void reset();
170
  // Check if the bundle may be validly shuffled.
171
  bool check();
172
  // Reorder the insn handles in the bundle.
173
  bool shuffle();
174
175
17.4k
  unsigned size() const { return (Packet.size()); };
176
177
56.3k
  iterator begin() { return (Packet.begin()); };
178
112k
  iterator end() { return (Packet.end()); };
179
180
  // Add insn handle to the bundle .
181
  void append(MCInst const *ID, MCInst const *Extender, unsigned S,
182
              bool X = false);
183
184
  // Return the error code for the last check or shuffling of the bundle.
185
0
  void setError(unsigned Err) { Error = Err; };
186
20.4k
  unsigned getError() const { return (Error); };
187
};
188
}
189
190
#endif // HEXAGONSHUFFLER_H