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 return HexagonShuffler::SHUFFLE_SUCCESS; 184 } 185 // try shuffle with this duplex 186 doneShuffling = MCS.reshuffleTo(MCB); 187 shuffleError = MCS.getError(); 188 189 if (doneShuffling) 190 break; 191 } 192 193 if (doneShuffling == false) { 194 HexagonMCShuffler MCS(MCII, STI, MCB); 195 doneShuffling = MCS.reshuffleTo(MCB); // shuffle 196 shuffleError = MCS.getError(); 197 } 198 if (!doneShuffling) 199 return shuffleError; 200 201 return HexagonShuffler::SHUFFLE_SUCCESS; 202 } 203 204 bool llvm::HexagonMCShuffle(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, 205 MCInst &MCB, MCInst const *AddMI, int fixupCount) { 206 if (!HexagonMCInstrInfo::isBundle(MCB) || !AddMI) 207 return false; 208 209 // if fixups present, make sure we don't insert too many nops that would 210 // later prevent an extender from being inserted. 211 unsigned int bundleSize = HexagonMCInstrInfo::bundleSize(MCB); 212 if (bundleSize >= HEXAGON_PACKET_SIZE) 213 return false; 214 if (fixupCount >= 2) { 215 return false; 216 } else { 217 if (bundleSize == HEXAGON_PACKET_SIZE - 1 && fixupCount) 218 return false; 219 } 220 221 if (DisableShuffle) 222 return false; 223 224 HexagonMCShuffler MCS(MCII, STI, MCB, AddMI); 225 if (!MCS.reshuffleTo(MCB)) { 226 unsigned shuffleError = MCS.getError(); 227 switch (shuffleError) { 228 default: 229 return false; 230 case HexagonShuffler::SHUFFLE_SUCCESS: // single instruction case 231 return true; 232 } 233 } 234 235 return true; 236 } 237