1 //===----- HexagonMCShuffler.cpp - MC bundle shuffling --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This implements the shuffling of insns inside a bundle according to the
11 // packet formation rules of the Hexagon ISA.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "hexagon-shuffle"
17 #include "MCTargetDesc/HexagonMCShuffler.h"
19 #include "MCTargetDesc/HexagonMCInstrInfo.h"
20 #include "MCTargetDesc/HexagonShuffler.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrDesc.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/Support/CommandLine.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/Support/raw_ostream.h"
32 DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false),
33 cl::desc("Disable Hexagon instruction shuffling"));
35 void HexagonMCShuffler::init(MCInst &MCB) {
36 if (HexagonMCInstrInfo::isBundle(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 LLVM_DEBUG(dbgs() << "Shuffling: " << MCII.getName(MI.getOpcode())
43 assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo());
45 if (!HexagonMCInstrInfo::isImmext(MI)) {
46 append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
54 BundleFlags = MCB.getOperand(0).getImm();
57 void HexagonMCShuffler::init(MCInst &MCB, MCInst const &AddMI,
58 bool bInsertAtFront) {
59 if (HexagonMCInstrInfo::isBundle(MCB)) {
61 append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
62 MCInst const *Extender = nullptr;
63 // Copy the bundle for the shuffling.
64 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
65 assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo());
66 MCInst &MI = *const_cast<MCInst *>(I.getInst());
67 if (!HexagonMCInstrInfo::isImmext(MI)) {
68 append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
74 append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
78 BundleFlags = MCB.getOperand(0).getImm();
81 void HexagonMCShuffler::copyTo(MCInst &MCB) {
83 MCB.addOperand(MCOperand::createImm(BundleFlags));
85 // Copy the results into the bundle.
86 for (HexagonShuffler::iterator I = begin(); I != end(); ++I) {
88 MCInst const &MI = I->getDesc();
89 MCInst const *Extender = I->getExtender();
91 MCB.addOperand(MCOperand::createInst(Extender));
92 MCB.addOperand(MCOperand::createInst(&MI));
96 bool HexagonMCShuffler::reshuffleTo(MCInst &MCB) {
98 // Copy the results into the bundle.
102 LLVM_DEBUG(MCB.dump());
106 bool llvm::HexagonMCShuffle(MCContext &Context, bool Fatal,
107 MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
109 HexagonMCShuffler MCS(Context, Fatal, MCII, STI, MCB);
112 // Ignore if user chose so.
115 if (!HexagonMCInstrInfo::bundleSize(MCB)) {
116 // There once was a bundle:
117 // BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5,
118 // implicit-def %d7, ...
119 // * %d2 = IMPLICIT_DEF; flags:
120 // * %d7 = IMPLICIT_DEF; flags:
121 // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
123 LLVM_DEBUG(dbgs() << "Skipping empty bundle");
125 } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
126 LLVM_DEBUG(dbgs() << "Skipping stand-alone insn");
130 return MCS.reshuffleTo(MCB);
134 llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
135 MCSubtargetInfo const &STI, MCInst &MCB,
136 SmallVector<DuplexCandidate, 8> possibleDuplexes) {
140 if (!HexagonMCInstrInfo::bundleSize(MCB)) {
141 // There once was a bundle:
142 // BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5,
143 // implicit-def %d7, ...
144 // * %d2 = IMPLICIT_DEF; flags:
145 // * %d7 = IMPLICIT_DEF; flags:
146 // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
148 LLVM_DEBUG(dbgs() << "Skipping empty bundle");
150 } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
151 LLVM_DEBUG(dbgs() << "Skipping stand-alone insn");
155 bool doneShuffling = false;
156 while (possibleDuplexes.size() > 0 && (!doneShuffling)) {
157 // case of Duplex Found
158 DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val();
160 HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry);
161 HexagonMCShuffler MCS(Context, false, MCII, STI, Attempt); // copy packet to the shuffler
162 if (MCS.size() == 1) { // case of one duplex
163 // copy the created duplex in the shuffler to the bundle
167 // try shuffle with this duplex
168 doneShuffling = MCS.reshuffleTo(MCB);
174 if (!doneShuffling) {
175 HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);
176 doneShuffling = MCS.reshuffleTo(MCB); // shuffle
184 bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
185 MCSubtargetInfo const &STI, MCInst &MCB,
186 MCInst const &AddMI, int fixupCount) {
187 if (!HexagonMCInstrInfo::isBundle(MCB))
190 // if fixups present, make sure we don't insert too many nops that would
191 // later prevent an extender from being inserted.
192 unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB);
193 if (bundleSize >= HEXAGON_PACKET_SIZE)
195 bool bhasDuplex = HexagonMCInstrInfo::hasDuplex(MCII, MCB);
196 if (fixupCount >= 2) {
198 if (bundleSize >= HEXAGON_PACKET_SIZE - 1) {
205 if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount)
212 // mgl: temporary code (shuffler doesn't take into account the fact that
213 // a duplex takes up two slots. for example, 3 nops can be put into a packet
214 // containing a duplex oversubscribing slots by 1).
215 unsigned maxBundleSize = (HexagonMCInstrInfo::hasImmExt(MCB))
216 ? HEXAGON_PACKET_SIZE
217 : HEXAGON_PACKET_SIZE - 1;
218 if (bhasDuplex && bundleSize >= maxBundleSize)
221 HexagonMCShuffler MCS(Context, false, MCII, STI, MCB, AddMI, false);
222 return MCS.reshuffleTo(MCB);