LLVM  14.0.0git
HexagonMCShuffler.cpp
Go to the documentation of this file.
1 //===----- HexagonMCShuffler.cpp - MC bundle shuffling --------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This implements the shuffling of insns inside a bundle according to the
10 // packet formation rules of the Hexagon ISA.
11 //
12 //===----------------------------------------------------------------------===//
13 
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrDesc.h"
19 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/Support/Debug.h"
23 #include <cassert>
24 
25 #define DEBUG_TYPE "hexagon-shuffle"
26 
27 using namespace llvm;
28 
29 static cl::opt<bool>
30  DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false),
31  cl::desc("Disable Hexagon instruction shuffling"));
32 
33 void HexagonMCShuffler::init(MCInst &MCB) {
35  MCInst const *Extender = nullptr;
36  // Copy the bundle for the shuffling.
37  for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
38  MCInst &MI = *const_cast<MCInst *>(I.getInst());
39  LLVM_DEBUG(dbgs() << "Shuffling: " << MCII.getName(MI.getOpcode())
40  << '\n');
42 
45  Extender = nullptr;
46  } else
47  Extender = &MI;
48  }
49  }
50 
51  Loc = MCB.getLoc();
52  BundleFlags = MCB.getOperand(0).getImm();
53 }
54 
55 void HexagonMCShuffler::init(MCInst &MCB, MCInst const &AddMI,
56  bool bInsertAtFront) {
58  if (bInsertAtFront)
59  append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
60  MCInst const *Extender = nullptr;
61  // Copy the bundle for the shuffling.
62  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
64  MCInst &MI = *const_cast<MCInst *>(I.getInst());
67  Extender = nullptr;
68  } else
69  Extender = &MI;
70  }
71  if (!bInsertAtFront)
72  append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
73  }
74 
75  Loc = MCB.getLoc();
76  BundleFlags = MCB.getOperand(0).getImm();
77 }
78 
80  MCB.clear();
82  MCB.setLoc(Loc);
83  // Copy the results into the bundle.
84  for (HexagonShuffler::iterator I = begin(); I != end(); ++I) {
85 
86  MCInst const &MI = I->getDesc();
87  MCInst const *Extender = I->getExtender();
88  if (Extender)
89  MCB.addOperand(MCOperand::createInst(Extender));
91  }
92 }
93 
95  if (shuffle()) {
96  // Copy the results into the bundle.
97  copyTo(MCB);
98  return true;
99  }
100  LLVM_DEBUG(MCB.dump());
101  return false;
102 }
103 
105  MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
106  MCInst &MCB) {
107  HexagonMCShuffler MCS(Context, Fatal, MCII, STI, MCB);
108 
109  if (DisableShuffle)
110  // Ignore if user chose so.
111  return false;
112 
113  if (!HexagonMCInstrInfo::bundleSize(MCB)) {
114  // There once was a bundle:
115  // BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5,
116  // implicit-def %d7, ...
117  // * %d2 = IMPLICIT_DEF; flags:
118  // * %d7 = IMPLICIT_DEF; flags:
119  // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
120  // became empty.
121  LLVM_DEBUG(dbgs() << "Skipping empty bundle");
122  return false;
123  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
124  LLVM_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 implicit-def %d2, implicit-def %r4, implicit-def %r5,
141  // implicit-def %d7, ...
142  // * %d2 = IMPLICIT_DEF; flags:
143  // * %d7 = IMPLICIT_DEF; flags:
144  // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
145  // became empty.
146  LLVM_DEBUG(dbgs() << "Skipping empty bundle");
147  return false;
148  } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
149  LLVM_DEBUG(dbgs() << "Skipping stand-alone insn");
150  return false;
151  }
152 
153  bool doneShuffling = false;
154  while (possibleDuplexes.size() > 0 && (!doneShuffling)) {
155  // case of Duplex Found
156  DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val();
157  MCInst Attempt(MCB);
158  HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry);
159  HexagonMCShuffler MCS(Context, false, MCII, STI, Attempt); // copy packet to the shuffler
160  if (MCS.size() == 1) { // case of one duplex
161  // copy the created duplex in the shuffler to the bundle
162  MCS.copyTo(MCB);
163  return false;
164  }
165  // try shuffle with this duplex
166  doneShuffling = MCS.reshuffleTo(MCB);
167 
168  if (doneShuffling)
169  break;
170  }
171 
172  if (!doneShuffling) {
173  HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);
174  doneShuffling = MCS.reshuffleTo(MCB); // shuffle
175  }
176  if (!doneShuffling)
177  return true;
178 
179  return false;
180 }
181 
183  MCSubtargetInfo const &STI, MCInst &MCB,
184  MCInst const &AddMI, int fixupCount) {
186  return false;
187 
188  // if fixups present, make sure we don't insert too many nops that would
189  // later prevent an extender from being inserted.
190  unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB);
192  return false;
193  bool bhasDuplex = HexagonMCInstrInfo::hasDuplex(MCII, MCB);
194  if (fixupCount >= 2) {
195  if (bhasDuplex) {
196  if (bundleSize >= HEXAGON_PACKET_SIZE - 1) {
197  return false;
198  }
199  } else {
200  return false;
201  }
202  } else {
203  if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount)
204  return false;
205  }
206 
207  if (DisableShuffle)
208  return false;
209 
210  // mgl: temporary code (shuffler doesn't take into account the fact that
211  // a duplex takes up two slots. for example, 3 nops can be put into a packet
212  // containing a duplex oversubscribing slots by 1).
213  unsigned maxBundleSize = (HexagonMCInstrInfo::hasImmExt(MCB))
215  : HEXAGON_PACKET_SIZE - 1;
216  if (bhasDuplex && bundleSize >= maxBundleSize)
217  return false;
218 
219  HexagonMCShuffler MCS(Context, false, MCII, STI, MCB, AddMI, false);
220  return MCS.reshuffleTo(MCB);
221 }
llvm::HexagonShuffler::MCII
const MCInstrInfo & MCII
Definition: HexagonShuffler.h:174
llvm::HexagonShuffler::begin
iterator begin()
Definition: HexagonShuffler.h:218
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::HexagonMCInstrInfo::getDesc
const MCInstrDesc & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:248
llvm::DuplexCandidate
Definition: HexagonMCInstrInfo.h:34
llvm::HexagonShuffler::shuffle
bool shuffle()
Definition: HexagonShuffler.cpp:634
MCInstrDesc.h
llvm::HexagonShuffler::Loc
SMLoc Loc
Definition: HexagonShuffler.h:176
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
llvm::MCInstrDesc::isPseudo
bool isPseudo() const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
Definition: MCInstrDesc.h:264
llvm::HexagonMCInstrInfo::hasDuplex
bool hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:477
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
HexagonShuffler.h
llvm::HexagonShuffler::iterator
HexagonPacket::iterator iterator
Definition: HexagonShuffler.h:197
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
llvm::MCInst::dump
void dump() const
Definition: MCInst.cpp:104
llvm::HexagonMCInstrInfo::isImmext
bool isImmext(MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:635
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::HexagonMCInstrInfo::replaceDuplex
void replaceDuplex(MCContext &Context, MCInst &MCI, DuplexCandidate Candidate)
Definition: HexagonMCInstrInfo.cpp:975
llvm::HexagonMCShuffler
Definition: HexagonMCShuffler.h:29
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
CommandLine.h
HexagonMCShuffler.h
llvm::HexagonMCInstrInfo::hasImmExt
bool hasImmExt(MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:493
HexagonMCInstrInfo.h
llvm::HexagonShuffler::size
unsigned size() const
Definition: HexagonShuffler.h:212
llvm::HexagonMCInstrInfo::isBundle
bool isBundle(MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:532
MCInstrInfo.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
MCInst.h
llvm::HexagonMCInstrInfo::bundleInstructions
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:103
llvm::HexagonMCInstrInfo::bundleSize
size_t bundleSize(MCInst const &MCI)
Definition: HexagonMCInstrInfo.cpp:116
llvm::MCOperand::createInst
static MCOperand createInst(const MCInst *Val)
Definition: MCInst.h:169
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
llvm::HexagonShuffler::end
iterator end()
Definition: HexagonShuffler.h:219
llvm::cl::opt< bool >
llvm::HexagonMCShuffle
bool HexagonMCShuffle(MCContext &Context, bool Fatal, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &MCB)
Definition: HexagonMCShuffler.cpp:104
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::HexagonShuffler::BundleFlags
int64_t BundleFlags
Definition: HexagonShuffler.h:173
llvm::MCInstrInfo::getName
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition: MCInstrInfo.h:68
llvm::HexagonShuffler::STI
const MCSubtargetInfo & STI
Definition: HexagonShuffler.h:175
llvm::HexagonShuffler::append
void append(MCInst const &ID, MCInst const *Extender, unsigned S)
Definition: HexagonShuffler.cpp:180
llvm::X86II::isPseudo
bool isPseudo(uint64_t TSFlags)
Definition: X86BaseInfo.h:974
llvm::HexagonMCShuffler::reshuffleTo
bool reshuffleTo(MCInst &MCB)
Definition: HexagonMCShuffler.cpp:94
llvm::MCInst::getLoc
SMLoc getLoc() const
Definition: MCInst.h:204
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:25
llvm::MCInst::setLoc
void setLoc(SMLoc loc)
Definition: MCInst.h:203
llvm::HexagonMCInstrInfo::getUnits
unsigned getUnits(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI)
Return the slots used by the insn.
Definition: HexagonMCInstrInfo.cpp:443
DisableShuffle
static cl::opt< bool > DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false), cl::desc("Disable Hexagon instruction shuffling"))
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
llvm::HexagonMCShuffler::copyTo
void copyTo(MCInst &MCB)
Definition: HexagonMCShuffler.cpp:79
llvm::cl::desc
Definition: CommandLine.h:414
raw_ostream.h
HEXAGON_PACKET_SIZE
#define HEXAGON_PACKET_SIZE
Definition: HexagonMCTargetDesc.h:36
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
Debug.h
llvm::MCInst::clear
void clear()
Definition: MCInst.h:215