LLVM  6.0.0svn
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 
18 #include "Hexagon.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrDesc.h"
23 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/Support/Debug.h"
27 #include <cassert>
28 
29 using namespace llvm;
30 
31 static cl::opt<bool>
32  DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false),
33  cl::desc("Disable Hexagon instruction shuffling"));
34 
35 void HexagonMCShuffler::init(MCInst &MCB) {
37  MCInst const *Extender = nullptr;
38  // Copy the bundle for the shuffling.
39  for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
40  MCInst &MI = *const_cast<MCInst *>(I.getInst());
41  DEBUG(dbgs() << "Shuffling: " << MCII.getName(MI.getOpcode()) << '\n');
42  assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo());
43 
45  append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
46  Extender = nullptr;
47  } else
48  Extender = &MI;
49  }
50  }
51 
52  Loc = MCB.getLoc();
53  BundleFlags = MCB.getOperand(0).getImm();
54 }
55 
56 void HexagonMCShuffler::init(MCInst &MCB, MCInst const &AddMI,
57  bool bInsertAtFront) {
59  if (bInsertAtFront)
60  append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
61  MCInst const *Extender = nullptr;
62  // Copy the bundle for the shuffling.
63  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
64  assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo());
65  MCInst &MI = *const_cast<MCInst *>(I.getInst());
67  append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
68  Extender = nullptr;
69  } else
70  Extender = &MI;
71  }
72  if (!bInsertAtFront)
73  append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
74  }
75 
76  Loc = MCB.getLoc();
77  BundleFlags = MCB.getOperand(0).getImm();
78 }
79 
81  MCB.clear();
83  MCB.setLoc(Loc);
84  // Copy the results into the bundle.
85  for (HexagonShuffler::iterator I = begin(); I != end(); ++I) {
86 
87  MCInst const &MI = I->getDesc();
88  MCInst const *Extender = I->getExtender();
89  if (Extender)
90  MCB.addOperand(MCOperand::createInst(Extender));
92  }
93 }
94 
96  if (shuffle()) {
97  // Copy the results into the bundle.
98  copyTo(MCB);
99  return true;
100  }
101  DEBUG(MCB.dump());
102  return false;
103 }
104 
106  MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
107  MCInst &MCB) {
108  HexagonMCShuffler MCS(Context, Fatal, MCII, STI, MCB);
109 
110  if (DisableShuffle)
111  // Ignore if user chose so.
112  return false;
113 
114  if (!HexagonMCInstrInfo::bundleSize(MCB)) {
115  // There once was a bundle:
116  // BUNDLE %D2<imp-def>, %R4<imp-def>, %R5<imp-def>, %D7<imp-def>, ...
117  // * %D2<def> = IMPLICIT_DEF; flags:
118  // * %D7<def> = IMPLICIT_DEF; flags:
119  // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
120  // became empty.
121  DEBUG(dbgs() << "Skipping empty bundle");
122  return false;
123  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
124  DEBUG(dbgs() << "Skipping stand-alone insn");
125  return false;
126  }
127 
128  return MCS.reshuffleTo(MCB);
129 }
130 
131 bool
133  MCSubtargetInfo const &STI, MCInst &MCB,
134  SmallVector<DuplexCandidate, 8> possibleDuplexes) {
135  if (DisableShuffle)
136  return false;
137 
138  if (!HexagonMCInstrInfo::bundleSize(MCB)) {
139  // There once was a bundle:
140  // BUNDLE %D2<imp-def>, %R4<imp-def>, %R5<imp-def>, %D7<imp-def>, ...
141  // * %D2<def> = IMPLICIT_DEF; flags:
142  // * %D7<def> = IMPLICIT_DEF; flags:
143  // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
144  // became empty.
145  DEBUG(dbgs() << "Skipping empty bundle");
146  return false;
147  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
148  DEBUG(dbgs() << "Skipping stand-alone insn");
149  return false;
150  }
151 
152  bool doneShuffling = false;
153  while (possibleDuplexes.size() > 0 && (!doneShuffling)) {
154  // case of Duplex Found
155  DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val();
156  MCInst Attempt(MCB);
157  HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry);
158  HexagonMCShuffler MCS(Context, false, MCII, STI, Attempt); // copy packet to the shuffler
159  if (MCS.size() == 1) { // case of one duplex
160  // copy the created duplex in the shuffler to the bundle
161  MCS.copyTo(MCB);
162  return false;
163  }
164  // try shuffle with this duplex
165  doneShuffling = MCS.reshuffleTo(MCB);
166 
167  if (doneShuffling)
168  break;
169  }
170 
171  if (!doneShuffling) {
172  HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);
173  doneShuffling = MCS.reshuffleTo(MCB); // shuffle
174  }
175  if (!doneShuffling)
176  return true;
177 
178  return false;
179 }
180 
182  MCSubtargetInfo const &STI, MCInst &MCB,
183  MCInst const &AddMI, int fixupCount) {
185  return false;
186 
187  // if fixups present, make sure we don't insert too many nops that would
188  // later prevent an extender from being inserted.
189  unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB);
190  if (bundleSize >= HEXAGON_PACKET_SIZE)
191  return false;
192  bool bhasDuplex = HexagonMCInstrInfo::hasDuplex(MCII, MCB);
193  if (fixupCount >= 2) {
194  if (bhasDuplex) {
195  if (bundleSize >= HEXAGON_PACKET_SIZE - 1) {
196  return false;
197  }
198  } else {
199  return false;
200  }
201  } else {
202  if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount)
203  return false;
204  }
205 
206  if (DisableShuffle)
207  return false;
208 
209  // mgl: temporary code (shuffler doesn't take into account the fact that
210  // a duplex takes up two slots. for example, 3 nops can be put into a packet
211  // containing a duplex oversubscribing slots by 1).
212  unsigned maxBundleSize = (HexagonMCInstrInfo::hasImmExt(MCB))
214  : HEXAGON_PACKET_SIZE - 1;
215  if (bhasDuplex && bundleSize >= maxBundleSize)
216  return false;
217 
218  HexagonMCShuffler MCS(Context, false, MCII, STI, MCB, AddMI, false);
219  return MCS.reshuffleTo(MCB);
220 }
void replaceDuplex(MCContext &Context, MCInst &MCI, DuplexCandidate Candidate)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
void clear()
Definition: MCInst.h:189
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
void append(MCInst const &ID, MCInst const *Extender, unsigned S)
bool isBundle(MCInst const &MCI)
unsigned size() const
bool isImmext(MCInst const &MCI)
bool reshuffleTo(MCInst &MCB)
#define HEXAGON_PACKET_SIZE
Definition: Hexagon.h:33
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
Context object for machine code objects.
Definition: MCContext.h:59
HexagonPacket::iterator iterator
bool HexagonMCShuffle(MCContext &Context, bool Fatal, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &MCB)
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
int64_t getImm() const
Definition: MCInst.h:76
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:406
MCSubtargetInfo const & STI
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
bool hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition: MCInstrInfo.h:51
void setLoc(SMLoc loc)
Definition: MCInst.h:177
void dump() const
Definition: MCInst.cpp:70
MCInstrInfo const & MCII
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:180
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:385
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
SMLoc getLoc() const
Definition: MCInst.h:178
static MCOperand createInst(const MCInst *Val)
Definition: MCInst.h:144
#define I(x, y, z)
Definition: MD5.cpp:58
MCSubtargetInfo - Generic base class for all target subtargets.
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"))
bool hasImmExt(MCInst const &MCI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
#define DEBUG(X)
Definition: Debug.h:118
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:184
unsigned getOpcode() const
Definition: MCInst.h:172
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123