/src/keystone/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.cpp
Line | Count | Source |
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/Debug.h" |
22 | | #include "llvm/Support/raw_ostream.h" |
23 | | |
24 | | using namespace llvm_ks; |
25 | | |
26 | | static bool DisableShuffle = false; |
27 | | |
28 | 16.5k | void HexagonMCShuffler::init(MCInst &MCB) { |
29 | 16.5k | if (HexagonMCInstrInfo::isBundle(MCB)) { |
30 | 16.5k | MCInst const *Extender = nullptr; |
31 | | // Copy the bundle for the shuffling. |
32 | 28.5k | for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCB)) { |
33 | 28.5k | assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo()); |
34 | 28.5k | MCInst *MI = const_cast<MCInst *>(I.getInst()); |
35 | | |
36 | 28.5k | if (!HexagonMCInstrInfo::isImmext(*MI)) { |
37 | 21.7k | append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, *MI), |
38 | 21.7k | false); |
39 | 21.7k | Extender = nullptr; |
40 | 21.7k | } else |
41 | 6.82k | Extender = MI; |
42 | 28.5k | } |
43 | 16.5k | } |
44 | | |
45 | 16.5k | BundleFlags = MCB.getOperand(0).getImm(); |
46 | 16.5k | } |
47 | | |
48 | | void HexagonMCShuffler::init(MCInst &MCB, MCInst const *AddMI, |
49 | 0 | bool bInsertAtFront) { |
50 | 0 | if (HexagonMCInstrInfo::isBundle(MCB)) { |
51 | 0 | if (bInsertAtFront && AddMI) |
52 | 0 | append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, *AddMI), |
53 | 0 | false); |
54 | 0 | MCInst const *Extender = nullptr; |
55 | | // Copy the bundle for the shuffling. |
56 | 0 | for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) { |
57 | 0 | assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo()); |
58 | 0 | MCInst *MI = const_cast<MCInst *>(I.getInst()); |
59 | 0 | if (!HexagonMCInstrInfo::isImmext(*MI)) { |
60 | 0 | append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, *MI), |
61 | 0 | false); |
62 | 0 | Extender = nullptr; |
63 | 0 | } else |
64 | 0 | Extender = MI; |
65 | 0 | } |
66 | 0 | if (!bInsertAtFront && AddMI) |
67 | 0 | append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, *AddMI), |
68 | 0 | false); |
69 | 0 | } |
70 | | |
71 | 0 | BundleFlags = MCB.getOperand(0).getImm(); |
72 | 0 | } |
73 | | |
74 | 9.37k | void HexagonMCShuffler::copyTo(MCInst &MCB) { |
75 | 9.37k | MCB.clear(); |
76 | 9.37k | MCB.addOperand(MCOperand::createImm(BundleFlags)); |
77 | | // Copy the results into the bundle. |
78 | 18.7k | for (HexagonShuffler::iterator I = begin(); I != end(); ++I) { |
79 | | |
80 | 9.41k | MCInst const *MI = I->getDesc(); |
81 | 9.41k | MCInst const *Extender = I->getExtender(); |
82 | 9.41k | if (Extender) |
83 | 1.14k | MCB.addOperand(MCOperand::createInst(Extender)); |
84 | 9.41k | MCB.addOperand(MCOperand::createInst(MI)); |
85 | 9.41k | } |
86 | 9.37k | } |
87 | | |
88 | 9.36k | bool HexagonMCShuffler::reshuffleTo(MCInst &MCB) { |
89 | 9.36k | if (shuffle()) { |
90 | | // Copy the results into the bundle. |
91 | 9.36k | copyTo(MCB); |
92 | 9.36k | } |
93 | | // else |
94 | | // DEBUG(MCB.dump()); |
95 | | |
96 | 9.36k | return (!getError()); |
97 | 9.36k | } |
98 | | |
99 | | bool llvm_ks::HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, |
100 | 6.32k | MCInst &MCB) { |
101 | 6.32k | HexagonMCShuffler MCS(MCII, STI, MCB); |
102 | | |
103 | 6.32k | if (DisableShuffle) |
104 | | // Ignore if user chose so. |
105 | 0 | return false; |
106 | | |
107 | 6.32k | if (!HexagonMCInstrInfo::bundleSize(MCB)) { |
108 | | // There once was a bundle: |
109 | | // BUNDLE %D2<imp-def>, %R4<imp-def>, %R5<imp-def>, %D7<imp-def>, ... |
110 | | // * %D2<def> = IMPLICIT_DEF; flags: |
111 | | // * %D7<def> = IMPLICIT_DEF; flags: |
112 | | // After the IMPLICIT_DEFs were removed by the asm printer, the bundle |
113 | | // became empty. |
114 | 80 | DEBUG(dbgs() << "Skipping empty bundle"); |
115 | 80 | return false; |
116 | 6.24k | } else if (!HexagonMCInstrInfo::isBundle(MCB)) { |
117 | 0 | DEBUG(dbgs() << "Skipping stand-alone insn"); |
118 | 0 | return false; |
119 | 0 | } |
120 | | |
121 | | // Reorder the bundle and copy the result. |
122 | 6.24k | if (!MCS.reshuffleTo(MCB)) { |
123 | | // Unless there is any error, which should not happen at this point. |
124 | 0 | unsigned shuffleError = MCS.getError(); |
125 | 0 | switch (shuffleError) { |
126 | 0 | default: |
127 | 0 | llvm_unreachable("unknown error"); |
128 | 0 | case HexagonShuffler::SHUFFLE_ERROR_INVALID: |
129 | 0 | llvm_unreachable("invalid packet"); |
130 | 0 | case HexagonShuffler::SHUFFLE_ERROR_STORES: |
131 | 0 | llvm_unreachable("too many stores"); |
132 | 0 | case HexagonShuffler::SHUFFLE_ERROR_LOADS: |
133 | 0 | llvm_unreachable("too many loads"); |
134 | 0 | case HexagonShuffler::SHUFFLE_ERROR_BRANCHES: |
135 | 0 | llvm_unreachable("too many branches"); |
136 | 0 | case HexagonShuffler::SHUFFLE_ERROR_NOSLOTS: |
137 | 0 | llvm_unreachable("no suitable slot"); |
138 | 0 | case HexagonShuffler::SHUFFLE_ERROR_SLOTS: |
139 | 0 | llvm_unreachable("over-subscribed slots"); |
140 | 0 | case HexagonShuffler::SHUFFLE_SUCCESS: // Single instruction case. |
141 | 0 | return true; |
142 | 0 | } |
143 | 0 | } |
144 | | |
145 | 6.24k | return true; |
146 | 6.24k | } |
147 | | |
148 | | unsigned |
149 | | llvm_ks::HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, |
150 | | MCContext &Context, MCInst &MCB, |
151 | 3.16k | SmallVector<DuplexCandidate, 8> possibleDuplexes) { |
152 | | |
153 | 3.16k | if (DisableShuffle) |
154 | 0 | return HexagonShuffler::SHUFFLE_SUCCESS; |
155 | | |
156 | 3.16k | if (!HexagonMCInstrInfo::bundleSize(MCB)) { |
157 | | // There once was a bundle: |
158 | | // BUNDLE %D2<imp-def>, %R4<imp-def>, %R5<imp-def>, %D7<imp-def>, ... |
159 | | // * %D2<def> = IMPLICIT_DEF; flags: |
160 | | // * %D7<def> = IMPLICIT_DEF; flags: |
161 | | // After the IMPLICIT_DEFs were removed by the asm printer, the bundle |
162 | | // became empty. |
163 | 40 | DEBUG(dbgs() << "Skipping empty bundle"); |
164 | 40 | return HexagonShuffler::SHUFFLE_SUCCESS; |
165 | 3.12k | } else if (!HexagonMCInstrInfo::isBundle(MCB)) { |
166 | 0 | DEBUG(dbgs() << "Skipping stand-alone insn"); |
167 | 0 | return HexagonShuffler::SHUFFLE_SUCCESS; |
168 | 0 | } |
169 | | |
170 | 3.12k | bool doneShuffling = false; |
171 | 3.12k | unsigned shuffleError; |
172 | 3.12k | while (possibleDuplexes.size() > 0 && (!doneShuffling)) { |
173 | | // case of Duplex Found |
174 | 9 | DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val(); |
175 | 9 | MCInst Attempt(MCB); |
176 | 9 | HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry); |
177 | 9 | HexagonMCShuffler MCS(MCII, STI, Attempt); // copy packet to the shuffler |
178 | 9 | if (MCS.size() == 1) { // case of one duplex |
179 | | // copy the created duplex in the shuffler to the bundle |
180 | 5 | MCS.copyTo(MCB); |
181 | 5 | doneShuffling = true; |
182 | 5 | return HexagonShuffler::SHUFFLE_SUCCESS; |
183 | 5 | } |
184 | | // try shuffle with this duplex |
185 | 4 | doneShuffling = MCS.reshuffleTo(MCB); |
186 | 4 | shuffleError = MCS.getError(); |
187 | | |
188 | 4 | if (doneShuffling) |
189 | 4 | break; |
190 | 4 | } |
191 | | |
192 | 3.12k | if (doneShuffling == false) { |
193 | 3.11k | HexagonMCShuffler MCS(MCII, STI, MCB); |
194 | 3.11k | doneShuffling = MCS.reshuffleTo(MCB); // shuffle |
195 | 3.11k | shuffleError = MCS.getError(); |
196 | 3.11k | } |
197 | 3.12k | if (!doneShuffling) |
198 | 0 | return shuffleError; |
199 | | |
200 | 3.12k | return HexagonShuffler::SHUFFLE_SUCCESS; |
201 | 3.12k | } |
202 | | |
203 | | bool llvm_ks::HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, |
204 | 0 | MCInst &MCB, MCInst const *AddMI, int fixupCount) { |
205 | 0 | if (!HexagonMCInstrInfo::isBundle(MCB) || !AddMI) |
206 | 0 | return false; |
207 | | |
208 | | // if fixups present, make sure we don't insert too many nops that would |
209 | | // later prevent an extender from being inserted. |
210 | 0 | unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB); |
211 | 0 | if (bundleSize >= HEXAGON_PACKET_SIZE) |
212 | 0 | return false; |
213 | 0 | if (fixupCount >= 2) { |
214 | 0 | return false; |
215 | 0 | } else { |
216 | 0 | if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount) |
217 | 0 | return false; |
218 | 0 | } |
219 | | |
220 | 0 | if (DisableShuffle) |
221 | 0 | return false; |
222 | | |
223 | 0 | HexagonMCShuffler MCS(MCII, STI, MCB, AddMI); |
224 | 0 | if (!MCS.reshuffleTo(MCB)) { |
225 | 0 | unsigned shuffleError = MCS.getError(); |
226 | 0 | switch (shuffleError) { |
227 | 0 | default: |
228 | 0 | return false; |
229 | 0 | case HexagonShuffler::SHUFFLE_SUCCESS: // single instruction case |
230 | 0 | return true; |
231 | 0 | } |
232 | 0 | } |
233 | | |
234 | 0 | return true; |
235 | 0 | } |