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