8e70280c1a0d3518de4288cf86b590cc4a90bcee
[oota-llvm.git] / lib / Target / Hexagon / MCTargetDesc / HexagonMCShuffler.cpp
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"
18 #include "MCTargetDesc/HexagonMCInstrInfo.h"
19 #include "MCTargetDesc/HexagonMCShuffler.h"
20 #include "MCTargetDesc/HexagonMCTargetDesc.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/raw_ostream.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) {
32   if (HexagonMCInstrInfo::isBundle(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) {
53   if (HexagonMCInstrInfo::isBundle(MCB)) {
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
77 void HexagonMCShuffler::copyTo(MCInst &MCB) {
78   MCB.clear();
79   MCB.addOperand(MCOperand::createImm(BundleFlags));
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));
87     MCB.addOperand(MCOperand::createInst(MI));
88   }
89 }
90
91 bool HexagonMCShuffler::reshuffleTo(MCInst &MCB) {
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
101 bool llvm::HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
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");
130     case HexagonShuffler::SHUFFLE_ERROR_INVALID:
131       llvm_unreachable("invalid packet");
132     case HexagonShuffler::SHUFFLE_ERROR_STORES:
133       llvm_unreachable("too many stores");
134     case HexagonShuffler::SHUFFLE_ERROR_LOADS:
135       llvm_unreachable("too many loads");
136     case HexagonShuffler::SHUFFLE_ERROR_BRANCHES:
137       llvm_unreachable("too many branches");
138     case HexagonShuffler::SHUFFLE_ERROR_NOSLOTS:
139       llvm_unreachable("no suitable slot");
140     case HexagonShuffler::SHUFFLE_ERROR_SLOTS:
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
151 llvm::HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
152                        MCContext &Context, MCInst &MCB,
153                        SmallVector<DuplexCandidate, 8> possibleDuplexes) {
154
155   if (DisableShuffle)
156     return HexagonShuffler::SHUFFLE_SUCCESS;
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");
166     return HexagonShuffler::SHUFFLE_SUCCESS;
167   } else if (!HexagonMCInstrInfo::isBundle(MCB)) {
168     DEBUG(dbgs() << "Skipping stand-alone insn");
169     return HexagonShuffler::SHUFFLE_SUCCESS;
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);
183       doneShuffling = true;
184       return HexagonShuffler::SHUFFLE_SUCCESS;
185     }
186     // try shuffle with this duplex
187     doneShuffling = MCS.reshuffleTo(MCB);
188     shuffleError = MCS.getError();
189
190     if (doneShuffling)
191       break;
192   }
193
194   if (doneShuffling == false) {
195     HexagonMCShuffler MCS(MCII, STI, MCB);
196     doneShuffling = MCS.reshuffleTo(MCB); // shuffle
197     shuffleError = MCS.getError();
198   }
199   if (!doneShuffling)
200     return shuffleError;
201
202   return HexagonShuffler::SHUFFLE_SUCCESS;
203 }
204
205 bool llvm::HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
206                             MCInst &MCB, MCInst const *AddMI, int fixupCount) {
207   if (!HexagonMCInstrInfo::isBundle(MCB) || !AddMI)
208     return false;
209
210   // if fixups present, make sure we don't insert too many nops that would
211   // later prevent an extender from being inserted.
212   unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB);
213   if (bundleSize >= HEXAGON_PACKET_SIZE)
214     return false;
215   if (fixupCount >= 2) {
216     return false;
217   } else {
218     if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount)
219       return false;
220   }
221
222   if (DisableShuffle)
223     return false;
224
225   HexagonMCShuffler MCS(MCII, STI, MCB, AddMI);
226   if (!MCS.reshuffleTo(MCB)) {
227     unsigned shuffleError = MCS.getError();
228     switch (shuffleError) {
229     default:
230       return false;
231     case HexagonShuffler::SHUFFLE_SUCCESS: // single instruction case
232       return true;
233     }
234   }
235
236   return true;
237 }