LLVM  4.0.0
HexagonMCShuffler.cpp
Go to the documentation of this file.
1 //===----- HexagonMCShuffler.cpp - MC 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 #define DEBUG_TYPE "hexagon-shuffle"
16 
17 #include "Hexagon.h"
22 #include "llvm/Support/Debug.h"
24 
25 using namespace llvm;
26 
27 static cl::opt<bool>
28  DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false),
29  cl::desc("Disable Hexagon instruction shuffling"));
30 
31 void HexagonMCShuffler::init(MCInst &MCB) {
33  MCInst const *Extender = nullptr;
34  // Copy the bundle for the shuffling.
35  for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
36  assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo());
37  MCInst *MI = const_cast<MCInst *>(I.getInst());
38 
39  if (!HexagonMCInstrInfo::isImmext(*MI)) {
40  append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, *MI),
41  false);
42  Extender = nullptr;
43  } else
44  Extender = MI;
45  }
46  }
47 
48  BundleFlags = MCB.getOperand(0).getImm();
49 }
50 
51 void HexagonMCShuffler::init(MCInst &MCB, MCInst const *AddMI,
52  bool bInsertAtFront) {
54  if (bInsertAtFront && AddMI)
55  append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, *AddMI),
56  false);
57  MCInst const *Extender = nullptr;
58  // Copy the bundle for the shuffling.
59  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
60  assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo());
61  MCInst *MI = const_cast<MCInst *>(I.getInst());
62  if (!HexagonMCInstrInfo::isImmext(*MI)) {
63  append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, *MI),
64  false);
65  Extender = nullptr;
66  } else
67  Extender = MI;
68  }
69  if (!bInsertAtFront && AddMI)
70  append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, *AddMI),
71  false);
72  }
73 
74  BundleFlags = MCB.getOperand(0).getImm();
75 }
76 
78  MCB.clear();
80  // Copy the results into the bundle.
81  for (HexagonShuffler::iterator I = begin(); I != end(); ++I) {
82 
83  MCInst const *MI = I->getDesc();
84  MCInst const *Extender = I->getExtender();
85  if (Extender)
86  MCB.addOperand(MCOperand::createInst(Extender));
88  }
89 }
90 
92  if (shuffle()) {
93  // Copy the results into the bundle.
94  copyTo(MCB);
95  } else
96  DEBUG(MCB.dump());
97 
98  return (!getError());
99 }
100 
102  MCInst &MCB) {
103  HexagonMCShuffler MCS(MCII, STI, MCB);
104 
105  if (DisableShuffle)
106  // Ignore if user chose so.
107  return false;
108 
109  if (!HexagonMCInstrInfo::bundleSize(MCB)) {
110  // There once was a bundle:
111  // BUNDLE %D2<imp-def>, %R4<imp-def>, %R5<imp-def>, %D7<imp-def>, ...
112  // * %D2<def> = IMPLICIT_DEF; flags:
113  // * %D7<def> = IMPLICIT_DEF; flags:
114  // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
115  // became empty.
116  DEBUG(dbgs() << "Skipping empty bundle");
117  return false;
118  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
119  DEBUG(dbgs() << "Skipping stand-alone insn");
120  return false;
121  }
122 
123  // Reorder the bundle and copy the result.
124  if (!MCS.reshuffleTo(MCB)) {
125  // Unless there is any error, which should not happen at this point.
126  unsigned shuffleError = MCS.getError();
127  switch (shuffleError) {
128  default:
129  llvm_unreachable("unknown error");
131  llvm_unreachable("invalid packet");
133  llvm_unreachable("too many stores");
135  llvm_unreachable("too many loads");
137  llvm_unreachable("too many branches");
139  llvm_unreachable("no suitable slot");
141  llvm_unreachable("over-subscribed slots");
142  case HexagonShuffler::SHUFFLE_SUCCESS: // Single instruction case.
143  return true;
144  }
145  }
146 
147  return true;
148 }
149 
150 unsigned
152  MCContext &Context, MCInst &MCB,
153  SmallVector<DuplexCandidate, 8> possibleDuplexes) {
154 
155  if (DisableShuffle)
157 
158  if (!HexagonMCInstrInfo::bundleSize(MCB)) {
159  // There once was a bundle:
160  // BUNDLE %D2<imp-def>, %R4<imp-def>, %R5<imp-def>, %D7<imp-def>, ...
161  // * %D2<def> = IMPLICIT_DEF; flags:
162  // * %D7<def> = IMPLICIT_DEF; flags:
163  // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
164  // became empty.
165  DEBUG(dbgs() << "Skipping empty bundle");
167  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
168  DEBUG(dbgs() << "Skipping stand-alone insn");
170  }
171 
172  bool doneShuffling = false;
173  unsigned shuffleError;
174  while (possibleDuplexes.size() > 0 && (!doneShuffling)) {
175  // case of Duplex Found
176  DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val();
177  MCInst Attempt(MCB);
178  HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry);
179  HexagonMCShuffler MCS(MCII, STI, Attempt); // copy packet to the shuffler
180  if (MCS.size() == 1) { // case of one duplex
181  // copy the created duplex in the shuffler to the bundle
182  MCS.copyTo(MCB);
184  }
185  // try shuffle with this duplex
186  doneShuffling = MCS.reshuffleTo(MCB);
187  shuffleError = MCS.getError();
188 
189  if (doneShuffling)
190  break;
191  }
192 
193  if (doneShuffling == false) {
194  HexagonMCShuffler MCS(MCII, STI, MCB);
195  doneShuffling = MCS.reshuffleTo(MCB); // shuffle
196  shuffleError = MCS.getError();
197  }
198  if (!doneShuffling)
199  return shuffleError;
200 
202 }
203 
205  MCInst &MCB, MCInst const *AddMI, int fixupCount) {
206  if (!HexagonMCInstrInfo::isBundle(MCB) || !AddMI)
207  return false;
208 
209  // if fixups present, make sure we don't insert too many nops that would
210  // later prevent an extender from being inserted.
211  unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB);
212  if (bundleSize >= HEXAGON_PACKET_SIZE)
213  return false;
214  if (fixupCount >= 2) {
215  return false;
216  } else {
217  if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount)
218  return false;
219  }
220 
221  if (DisableShuffle)
222  return false;
223 
224  HexagonMCShuffler MCS(MCII, STI, MCB, AddMI);
225  if (!MCS.reshuffleTo(MCB)) {
226  unsigned shuffleError = MCS.getError();
227  switch (shuffleError) {
228  default:
229  return false;
230  case HexagonShuffler::SHUFFLE_SUCCESS: // single instruction case
231  return true;
232  }
233  }
234 
235  return true;
236 }
LLVMContext & Context
void clear()
Definition: MCInst.h:172
unsigned getError() const
bool isBundle(MCInst const &MCI)
No free slots for store insns.
bool isImmext(MCInst const &MCI)
bool reshuffleTo(MCInst &MCB)
#define HEXAGON_PACKET_SIZE
Definition: Hexagon.h:33
void replaceDuplex(MCContext &Context, MCInst &MCB, DuplexCandidate Candidate)
Context object for machine code objects.
Definition: MCContext.h:51
No free slots for branch insns.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
No free slots for load insns.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
MCSubtargetInfo const & STI
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
unsigned size() const
iterator_range< MCInst::const_iterator > bundleInstructions(MCInst const &MCI)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void append(MCInst const *ID, MCInst const *Extender, unsigned S, bool X=false)
MCInstrInfo const & MCII
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
bool HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &)
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:382
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
int64_t getImm() const
Definition: MCInst.h:74
static MCOperand createInst(const MCInst *Val)
Definition: MCInst.h:135
#define I(x, y, z)
Definition: MD5.cpp:54
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
MCSubtargetInfo - Generic base class for all target subtargets.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
size_t bundleSize(MCInst const &MCI)
static cl::opt< bool > DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false), cl::desc("Disable Hexagon instruction shuffling"))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
#define DEBUG(X)
Definition: Debug.h:100
void dump() const
Definition: MCInst.cpp:66
unsigned getUnits(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
Return the slots used by the insn.
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164