/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCShuffler.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | |
14 | | #define DEBUG_TYPE "hexagon-shuffle" |
15 | | |
16 | | #include "MCTargetDesc/HexagonMCShuffler.h" |
17 | | #include "MCTargetDesc/HexagonMCInstrInfo.h" |
18 | | #include "MCTargetDesc/HexagonShuffler.h" |
19 | | #include "llvm/MC/MCInst.h" |
20 | | #include "llvm/MC/MCInstrDesc.h" |
21 | | #include "llvm/MC/MCInstrInfo.h" |
22 | | #include "llvm/Support/CommandLine.h" |
23 | | #include "llvm/Support/Debug.h" |
24 | | #include "llvm/Support/raw_ostream.h" |
25 | | #include <cassert> |
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 | 100k | void HexagonMCShuffler::init(MCInst &MCB) { |
34 | 100k | if (HexagonMCInstrInfo::isBundle(MCB)) { |
35 | 100k | MCInst const *Extender = nullptr; |
36 | 100k | // Copy the bundle for the shuffling. |
37 | 160k | for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCB)) { |
38 | 160k | MCInst &MI = *const_cast<MCInst *>(I.getInst()); |
39 | 160k | LLVM_DEBUG(dbgs() << "Shuffling: " << MCII.getName(MI.getOpcode()) |
40 | 160k | << '\n'); |
41 | 160k | assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo()); |
42 | 160k | |
43 | 160k | if (!HexagonMCInstrInfo::isImmext(MI)) { |
44 | 152k | append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI)); |
45 | 152k | Extender = nullptr; |
46 | 152k | } else |
47 | 8.61k | Extender = &MI; |
48 | 160k | } |
49 | 100k | } |
50 | 100k | |
51 | 100k | Loc = MCB.getLoc(); |
52 | 100k | BundleFlags = MCB.getOperand(0).getImm(); |
53 | 100k | } |
54 | | |
55 | | void HexagonMCShuffler::init(MCInst &MCB, MCInst const &AddMI, |
56 | 0 | bool bInsertAtFront) { |
57 | 0 | if (HexagonMCInstrInfo::isBundle(MCB)) { |
58 | 0 | if (bInsertAtFront) |
59 | 0 | append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI)); |
60 | 0 | MCInst const *Extender = nullptr; |
61 | 0 | // Copy the bundle for the shuffling. |
62 | 0 | for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) { |
63 | 0 | assert(!HexagonMCInstrInfo::getDesc(MCII, *I.getInst()).isPseudo()); |
64 | 0 | MCInst &MI = *const_cast<MCInst *>(I.getInst()); |
65 | 0 | if (!HexagonMCInstrInfo::isImmext(MI)) { |
66 | 0 | append(MI, Extender, HexagonMCInstrInfo::getUnits(MCII, STI, MI)); |
67 | 0 | Extender = nullptr; |
68 | 0 | } else |
69 | 0 | Extender = &MI; |
70 | 0 | } |
71 | 0 | if (!bInsertAtFront) |
72 | 0 | append(AddMI, nullptr, HexagonMCInstrInfo::getUnits(MCII, STI, AddMI)); |
73 | 0 | } |
74 | 0 |
|
75 | 0 | Loc = MCB.getLoc(); |
76 | 0 | BundleFlags = MCB.getOperand(0).getImm(); |
77 | 0 | } |
78 | | |
79 | 93.3k | void HexagonMCShuffler::copyTo(MCInst &MCB) { |
80 | 93.3k | MCB.clear(); |
81 | 93.3k | MCB.addOperand(MCOperand::createImm(BundleFlags)); |
82 | 93.3k | MCB.setLoc(Loc); |
83 | 93.3k | // Copy the results into the bundle. |
84 | 236k | for (HexagonShuffler::iterator I = begin(); I != end(); ++I142k ) { |
85 | 142k | |
86 | 142k | MCInst const &MI = I->getDesc(); |
87 | 142k | MCInst const *Extender = I->getExtender(); |
88 | 142k | if (Extender) |
89 | 8.00k | MCB.addOperand(MCOperand::createInst(Extender)); |
90 | 142k | MCB.addOperand(MCOperand::createInst(&MI)); |
91 | 142k | } |
92 | 93.3k | } |
93 | | |
94 | 93.2k | bool HexagonMCShuffler::reshuffleTo(MCInst &MCB) { |
95 | 93.2k | if (shuffle()) { |
96 | 92.9k | // Copy the results into the bundle. |
97 | 92.9k | copyTo(MCB); |
98 | 92.9k | return true; |
99 | 92.9k | } |
100 | 309 | LLVM_DEBUG(MCB.dump()); |
101 | 309 | return false; |
102 | 309 | } |
103 | | |
104 | | bool llvm::HexagonMCShuffle(MCContext &Context, bool Fatal, |
105 | | MCInstrInfo const &MCII, MCSubtargetInfo const &STI, |
106 | 70.3k | MCInst &MCB) { |
107 | 70.3k | HexagonMCShuffler MCS(Context, Fatal, MCII, STI, MCB); |
108 | 70.3k | |
109 | 70.3k | if (DisableShuffle) |
110 | 213 | // Ignore if user chose so. |
111 | 213 | return false; |
112 | 70.1k | |
113 | 70.1k | if (!HexagonMCInstrInfo::bundleSize(MCB)) { |
114 | 15 | // There once was a bundle: |
115 | 15 | // BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5, |
116 | 15 | // implicit-def %d7, ... |
117 | 15 | // * %d2 = IMPLICIT_DEF; flags: |
118 | 15 | // * %d7 = IMPLICIT_DEF; flags: |
119 | 15 | // After the IMPLICIT_DEFs were removed by the asm printer, the bundle |
120 | 15 | // became empty. |
121 | 15 | LLVM_DEBUG(dbgs() << "Skipping empty bundle"); |
122 | 15 | return false; |
123 | 70.0k | } else if (!HexagonMCInstrInfo::isBundle(MCB)) { |
124 | 0 | LLVM_DEBUG(dbgs() << "Skipping stand-alone insn"); |
125 | 0 | return false; |
126 | 0 | } |
127 | 70.0k | |
128 | 70.0k | return MCS.reshuffleTo(MCB); |
129 | 70.0k | } |
130 | | |
131 | | bool |
132 | | llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII, |
133 | | MCSubtargetInfo const &STI, MCInst &MCB, |
134 | 23.3k | SmallVector<DuplexCandidate, 8> possibleDuplexes) { |
135 | 23.3k | if (DisableShuffle) |
136 | 71 | return false; |
137 | 23.2k | |
138 | 23.2k | if (!HexagonMCInstrInfo::bundleSize(MCB)) { |
139 | 14 | // There once was a bundle: |
140 | 14 | // BUNDLE implicit-def %d2, implicit-def %r4, implicit-def %r5, |
141 | 14 | // implicit-def %d7, ... |
142 | 14 | // * %d2 = IMPLICIT_DEF; flags: |
143 | 14 | // * %d7 = IMPLICIT_DEF; flags: |
144 | 14 | // After the IMPLICIT_DEFs were removed by the asm printer, the bundle |
145 | 14 | // became empty. |
146 | 14 | LLVM_DEBUG(dbgs() << "Skipping empty bundle"); |
147 | 14 | return false; |
148 | 23.2k | } else if (!HexagonMCInstrInfo::isBundle(MCB)) { |
149 | 0 | LLVM_DEBUG(dbgs() << "Skipping stand-alone insn"); |
150 | 0 | return false; |
151 | 0 | } |
152 | 23.2k | |
153 | 23.2k | bool doneShuffling = false; |
154 | 23.5k | while (possibleDuplexes.size() > 0 && (!doneShuffling)1.37k ) { |
155 | 1.37k | // case of Duplex Found |
156 | 1.37k | DuplexCandidate duplexToTry = possibleDuplexes.pop_back_val(); |
157 | 1.37k | MCInst Attempt(MCB); |
158 | 1.37k | HexagonMCInstrInfo::replaceDuplex(Context, Attempt, duplexToTry); |
159 | 1.37k | HexagonMCShuffler MCS(Context, false, MCII, STI, Attempt); // copy packet to the shuffler |
160 | 1.37k | if (MCS.size() == 1) { // case of one duplex |
161 | 423 | // copy the created duplex in the shuffler to the bundle |
162 | 423 | MCS.copyTo(MCB); |
163 | 423 | return false; |
164 | 423 | } |
165 | 956 | // try shuffle with this duplex |
166 | 956 | doneShuffling = MCS.reshuffleTo(MCB); |
167 | 956 | |
168 | 956 | if (doneShuffling) |
169 | 652 | break; |
170 | 956 | } |
171 | 23.2k | |
172 | 23.2k | if (22.8k !doneShuffling22.8k ) { |
173 | 22.1k | HexagonMCShuffler MCS(Context, false, MCII, STI, MCB); |
174 | 22.1k | doneShuffling = MCS.reshuffleTo(MCB); // shuffle |
175 | 22.1k | } |
176 | 22.8k | if (!doneShuffling) |
177 | 1 | return true; |
178 | 22.8k | |
179 | 22.8k | return false; |
180 | 22.8k | } |
181 | | |
182 | | bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII, |
183 | | MCSubtargetInfo const &STI, MCInst &MCB, |
184 | 0 | MCInst const &AddMI, int fixupCount) { |
185 | 0 | if (!HexagonMCInstrInfo::isBundle(MCB)) |
186 | 0 | return false; |
187 | 0 | |
188 | 0 | // if fixups present, make sure we don't insert too many nops that would |
189 | 0 | // later prevent an extender from being inserted. |
190 | 0 | unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB); |
191 | 0 | if (bundleSize >= HEXAGON_PACKET_SIZE) |
192 | 0 | return false; |
193 | 0 | bool bhasDuplex = HexagonMCInstrInfo::hasDuplex(MCII, MCB); |
194 | 0 | if (fixupCount >= 2) { |
195 | 0 | if (bhasDuplex) { |
196 | 0 | if (bundleSize >= HEXAGON_PACKET_SIZE - 1) { |
197 | 0 | return false; |
198 | 0 | } |
199 | 0 | } else { |
200 | 0 | return false; |
201 | 0 | } |
202 | 0 | } else { |
203 | 0 | if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount) |
204 | 0 | return false; |
205 | 0 | } |
206 | 0 | |
207 | 0 | if (DisableShuffle) |
208 | 0 | return false; |
209 | 0 | |
210 | 0 | // mgl: temporary code (shuffler doesn't take into account the fact that |
211 | 0 | // a duplex takes up two slots. for example, 3 nops can be put into a packet |
212 | 0 | // containing a duplex oversubscribing slots by 1). |
213 | 0 | unsigned maxBundleSize = (HexagonMCInstrInfo::hasImmExt(MCB)) |
214 | 0 | ? HEXAGON_PACKET_SIZE |
215 | 0 | : HEXAGON_PACKET_SIZE - 1; |
216 | 0 | if (bhasDuplex && bundleSize >= maxBundleSize) |
217 | 0 | return false; |
218 | 0 | |
219 | 0 | HexagonMCShuffler MCS(Context, false, MCII, STI, MCB, AddMI, false); |
220 | 0 | return MCS.reshuffleTo(MCB); |
221 | 0 | } |