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