blob: 7bd54fdfa3d58091a945d5d1f0015ed91227844b [file] [log] [blame]
Colin LeMahieub23c47b2015-05-31 21:57:09 +00001//===----- 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
Chandler Carruth6bda14b2017-06-06 11:49:48 +000017#include "MCTargetDesc/HexagonMCShuffler.h"
Colin LeMahieub23c47b2015-05-31 21:57:09 +000018#include "Hexagon.h"
19#include "MCTargetDesc/HexagonMCInstrInfo.h"
Eugene Zelenko52889212017-08-01 21:20:10 +000020#include "MCTargetDesc/HexagonShuffler.h"
21#include "llvm/MC/MCInst.h"
22#include "llvm/MC/MCInstrDesc.h"
23#include "llvm/MC/MCInstrInfo.h"
Colin LeMahieub23c47b2015-05-31 21:57:09 +000024#include "llvm/Support/CommandLine.h"
25#include "llvm/Support/Debug.h"
Colin LeMahieua97365b2015-05-31 22:29:33 +000026#include "llvm/Support/raw_ostream.h"
Eugene Zelenko52889212017-08-01 21:20:10 +000027#include <cassert>
Colin LeMahieub23c47b2015-05-31 21:57:09 +000028
29using namespace llvm;
30
31static cl::opt<bool>
32 DisableShuffle("disable-hexagon-shuffle", cl::Hidden, cl::init(false),
33 cl::desc("Disable Hexagon instruction shuffling"));
34
35void 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)) {
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000040 MCInst &MI = *const_cast<MCInst *>(I.getInst());
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +000041 DEBUG(dbgs() << "Shuffling: " << MCII.getName(MI.getOpcode()) << '\n');
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000042 assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo());
Colin LeMahieub23c47b2015-05-31 21:57:09 +000043
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000044 if (!HexagonMCInstrInfo::isImmext(MI)) {
45 append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
Colin LeMahieub23c47b2015-05-31 21:57:09 +000046 Extender = nullptr;
47 } else
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000048 Extender = &MI;
Colin LeMahieub23c47b2015-05-31 21:57:09 +000049 }
50 }
51
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000052 Loc = MCB.getLoc();
Colin LeMahieub23c47b2015-05-31 21:57:09 +000053 BundleFlags = MCB.getOperand(0).getImm();
54}
55
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000056void HexagonMCShuffler::init(MCInst &MCB, MCInst const &AddMI,
Colin LeMahieub23c47b2015-05-31 21:57:09 +000057 bool bInsertAtFront) {
58 if (HexagonMCInstrInfo::isBundle(MCB)) {
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000059 if (bInsertAtFront)
60 append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
Colin LeMahieub23c47b2015-05-31 21:57:09 +000061 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());
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000065 MCInst &MI = *const_cast<MCInst *>(I.getInst());
66 if (!HexagonMCInstrInfo::isImmext(MI)) {
67 append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI));
Colin LeMahieub23c47b2015-05-31 21:57:09 +000068 Extender = nullptr;
69 } else
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000070 Extender = &MI;
Colin LeMahieub23c47b2015-05-31 21:57:09 +000071 }
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000072 if (!bInsertAtFront)
73 append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI));
Colin LeMahieub23c47b2015-05-31 21:57:09 +000074 }
75
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000076 Loc = MCB.getLoc();
Colin LeMahieub23c47b2015-05-31 21:57:09 +000077 BundleFlags = MCB.getOperand(0).getImm();
78}
79
80void HexagonMCShuffler::copyTo(MCInst &MCB) {
81 MCB.clear();
82 MCB.addOperand(MCOperand::createImm(BundleFlags));
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000083 MCB.setLoc(Loc);
Colin LeMahieub23c47b2015-05-31 21:57:09 +000084 // Copy the results into the bundle.
85 for (HexagonShuffler::iterator I = begin(); I != end(); ++I) {
86
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000087 MCInst const &MI = I->getDesc();
Colin LeMahieub23c47b2015-05-31 21:57:09 +000088 MCInst const *Extender = I->getExtender();
89 if (Extender)
90 MCB.addOperand(MCOperand::createInst(Extender));
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000091 MCB.addOperand(MCOperand::createInst(&MI));
Colin LeMahieub23c47b2015-05-31 21:57:09 +000092 }
93}
94
95bool HexagonMCShuffler::reshuffleTo(MCInst &MCB) {
96 if (shuffle()) {
97 // Copy the results into the bundle.
98 copyTo(MCB);
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000099 return true;
100 }
101 DEBUG(MCB.dump());
102 return false;
Colin LeMahieub23c47b2015-05-31 21:57:09 +0000103}
104
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000105bool llvm::HexagonMCShuffle(MCContext &Context, bool Fatal,
106 MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
107 MCInst &MCB) {
108 HexagonMCShuffler MCS(Context, Fatal, MCII, STI, MCB);
Colin LeMahieub23c47b2015-05-31 21:57:09 +0000109
110 if (DisableShuffle)
111 // Ignore if user chose so.
112 return false;
113
114 if (!HexagonMCInstrInfo::bundleSize(MCB)) {
115 // There once was a bundle:
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000116 // BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5,
117 // implicit-def %d7, ...
118 // * %d2 = IMPLICIT_DEF; flags:
119 // * %d7 = IMPLICIT_DEF; flags:
Colin LeMahieub23c47b2015-05-31 21:57:09 +0000120 // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
121 // became empty.
122 DEBUG(dbgs() << "Skipping empty bundle");
123 return false;
124 } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
125 DEBUG(dbgs() << "Skipping stand-alone insn");
126 return false;
127 }
128
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000129 return MCS.reshuffleTo(MCB);
Colin LeMahieub23c47b2015-05-31 21:57:09 +0000130}
131
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000132bool
133llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
134 MCSubtargetInfo const &STI, MCInst &MCB,
Colin LeMahieube8c4532015-06-05 16:00:11 +0000135 SmallVector<DuplexCandidate, 8> possibleDuplexes) {
Colin LeMahieube8c4532015-06-05 16:00:11 +0000136 if (DisableShuffle)
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000137 return false;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000138
139 if (!HexagonMCInstrInfo::bundleSize(MCB)) {
140 // There once was a bundle:
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000141 // BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5,
142 // implicit-def %d7, ...
143 // * %d2 = IMPLICIT_DEF; flags:
144 // * %d7 = IMPLICIT_DEF; flags:
Colin LeMahieube8c4532015-06-05 16:00:11 +0000145 // After the IMPLICIT_DEFs were removed by the asm printer, the bundle
146 // became empty.
147 DEBUG(dbgs() << "Skipping empty bundle");
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000148 return false;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000149 } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
150 DEBUG(dbgs() << "Skipping stand-alone insn");
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000151 return false;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000152 }
153
154 bool doneShuffling = false;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000155 while (possibleDuplexes.size() > 0 && (!doneShuffling)) {
156 // case of Duplex Found
157 DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val();
158 MCInst Attempt(MCB);
159 HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry);
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000160 HexagonMCShuffler MCS(Context, false, MCII, STI, Attempt); // copy packet to the shuffler
Colin LeMahieube8c4532015-06-05 16:00:11 +0000161 if (MCS.size() == 1) { // case of one duplex
162 // copy the created duplex in the shuffler to the bundle
163 MCS.copyTo(MCB);
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000164 return false;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000165 }
166 // try shuffle with this duplex
167 doneShuffling = MCS.reshuffleTo(MCB);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000168
169 if (doneShuffling)
170 break;
171 }
172
Eugene Zelenko52889212017-08-01 21:20:10 +0000173 if (!doneShuffling) {
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000174 HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);
Colin LeMahieube8c4532015-06-05 16:00:11 +0000175 doneShuffling = MCS.reshuffleTo(MCB); // shuffle
Colin LeMahieube8c4532015-06-05 16:00:11 +0000176 }
177 if (!doneShuffling)
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000178 return true;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000179
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000180 return false;
Colin LeMahieube8c4532015-06-05 16:00:11 +0000181}
182
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000183bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
184 MCSubtargetInfo const &STI, MCInst &MCB,
185 MCInst const &AddMI, int fixupCount) {
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000186 if (!HexagonMCInstrInfo::isBundle(MCB))
Colin LeMahieub23c47b2015-05-31 21:57:09 +0000187 return false;
188
189 // if fixups present, make sure we don't insert too many nops that would
190 // later prevent an extender from being inserted.
191 unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB);
192 if (bundleSize >= HEXAGON_PACKET_SIZE)
193 return false;
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000194 bool bhasDuplex = HexagonMCInstrInfo::hasDuplex(MCII, MCB);
Colin LeMahieub23c47b2015-05-31 21:57:09 +0000195 if (fixupCount >= 2) {
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000196 if (bhasDuplex) {
197 if (bundleSize >= HEXAGON_PACKET_SIZE - 1) {
198 return false;
199 }
200 } else {
201 return false;
202 }
Colin LeMahieub23c47b2015-05-31 21:57:09 +0000203 } else {
204 if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount)
205 return false;
206 }
207
208 if (DisableShuffle)
209 return false;
210
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000211 // mgl: temporary code (shuffler doesn't take into account the fact that
212 // a duplex takes up two slots. for example, 3 nops can be put into a packet
213 // containing a duplex oversubscribing slots by 1).
214 unsigned maxBundleSize = (HexagonMCInstrInfo::hasImmExt(MCB))
215 ? HEXAGON_PACKET_SIZE
216 : HEXAGON_PACKET_SIZE - 1;
217 if (bhasDuplex && bundleSize >= maxBundleSize)
218 return false;
219
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000220 HexagonMCShuffler MCS(Context, false, MCII, STI, MCB, AddMI, false);
221 return MCS.reshuffleTo(MCB);
Colin LeMahieub23c47b2015-05-31 21:57:09 +0000222}