1 //===--- HexagonGenMux.cpp ------------------------------------------------===// 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 // During instruction selection, MUX instructions are generated for 11 // conditional assignments. Since such assignments often present an 12 // opportunity to predicate instructions, HexagonExpandCondsets 13 // expands MUXes into pairs of conditional transfers, and then proceeds 14 // with predication of the producers/consumers of the registers involved. 15 // This happens after exiting from the SSA form, but before the machine 16 // instruction scheduler. After the scheduler and after the register 17 // allocation there can be cases of pairs of conditional transfers 18 // resulting from a MUX where neither of them was further predicated. If 19 // these transfers are now placed far enough from the instruction defining 20 // the predicate register, they cannot use the .new form. In such cases it 21 // is better to collapse them back to a single MUX instruction. 22 23 #define DEBUG_TYPE "hexmux" 24 25 #include "HexagonInstrInfo.h" 26 #include "HexagonRegisterInfo.h" 27 #include "HexagonSubtarget.h" 28 #include "llvm/ADT/BitVector.h" 29 #include "llvm/ADT/SmallVector.h" 30 #include "llvm/ADT/StringRef.h" 31 #include "llvm/CodeGen/MachineBasicBlock.h" 32 #include "llvm/CodeGen/MachineFunction.h" 33 #include "llvm/CodeGen/MachineFunctionPass.h" 34 #include "llvm/CodeGen/MachineInstr.h" 35 #include "llvm/CodeGen/MachineInstrBuilder.h" 36 #include "llvm/CodeGen/MachineOperand.h" 37 #include "llvm/IR/DebugLoc.h" 38 #include "llvm/MC/MCInstrDesc.h" 39 #include "llvm/MC/MCRegisterInfo.h" 40 #include "llvm/Pass.h" 41 #include "llvm/Support/MathExtras.h" 42 #include <algorithm> 43 #include <limits> 44 #include <iterator> 45 #include <utility> 46 47 using namespace llvm; 48 49 namespace llvm { 50 51 FunctionPass *createHexagonGenMux(); 52 void initializeHexagonGenMuxPass(PassRegistry& Registry); 53 54 } // end namespace llvm 55 56 namespace { 57 58 class HexagonGenMux : public MachineFunctionPass { 59 public: 60 static char ID; 61 62 HexagonGenMux() : MachineFunctionPass(ID), HII(nullptr), HRI(nullptr) { 63 initializeHexagonGenMuxPass(*PassRegistry::getPassRegistry()); 64 } 65 66 StringRef getPassName() const override { 67 return "Hexagon generate mux instructions"; 68 } 69 70 void getAnalysisUsage(AnalysisUsage &AU) const override { 71 MachineFunctionPass::getAnalysisUsage(AU); 72 } 73 74 bool runOnMachineFunction(MachineFunction &MF) override; 75 76 MachineFunctionProperties getRequiredProperties() const override { 77 return MachineFunctionProperties().set( 78 MachineFunctionProperties::Property::NoVRegs); 79 } 80 81 private: 82 const HexagonInstrInfo *HII; 83 const HexagonRegisterInfo *HRI; 84 85 struct CondsetInfo { 86 unsigned PredR = 0; 87 unsigned TrueX = std::numeric_limits<unsigned>::max(); 88 unsigned FalseX = std::numeric_limits<unsigned>::max(); 89 90 CondsetInfo() = default; 91 }; 92 93 struct DefUseInfo { 94 BitVector Defs, Uses; 95 96 DefUseInfo() = default; 97 DefUseInfo(const BitVector &D, const BitVector &U) : Defs(D), Uses(U) {} 98 }; 99 100 struct MuxInfo { 101 MachineBasicBlock::iterator At; 102 unsigned DefR, PredR; 103 MachineOperand *SrcT, *SrcF; 104 MachineInstr *Def1, *Def2; 105 106 MuxInfo(MachineBasicBlock::iterator It, unsigned DR, unsigned PR, 107 MachineOperand *TOp, MachineOperand *FOp, MachineInstr &D1, 108 MachineInstr &D2) 109 : At(It), DefR(DR), PredR(PR), SrcT(TOp), SrcF(FOp), Def1(&D1), 110 Def2(&D2) {} 111 }; 112 113 typedef DenseMap<MachineInstr*,unsigned> InstrIndexMap; 114 typedef DenseMap<unsigned,DefUseInfo> DefUseInfoMap; 115 typedef SmallVector<MuxInfo,4> MuxInfoList; 116 117 bool isRegPair(unsigned Reg) const { 118 return Hexagon::DoubleRegsRegClass.contains(Reg); 119 } 120 121 void getSubRegs(unsigned Reg, BitVector &SRs) const; 122 void expandReg(unsigned Reg, BitVector &Set) const; 123 void getDefsUses(const MachineInstr *MI, BitVector &Defs, 124 BitVector &Uses) const; 125 void buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X, 126 DefUseInfoMap &DUM); 127 bool isCondTransfer(unsigned Opc) const; 128 unsigned getMuxOpcode(const MachineOperand &Src1, 129 const MachineOperand &Src2) const; 130 bool genMuxInBlock(MachineBasicBlock &B); 131 }; 132 133 char HexagonGenMux::ID = 0; 134 135 } // end anonymous namespace 136 137 INITIALIZE_PASS(HexagonGenMux, "hexagon-mux", 138 "Hexagon generate mux instructions", false, false) 139 140 void HexagonGenMux::getSubRegs(unsigned Reg, BitVector &SRs) const { 141 for (MCSubRegIterator I(Reg, HRI); I.isValid(); ++I) 142 SRs[*I] = true; 143 } 144 145 void HexagonGenMux::expandReg(unsigned Reg, BitVector &Set) const { 146 if (isRegPair(Reg)) 147 getSubRegs(Reg, Set); 148 else 149 Set[Reg] = true; 150 } 151 152 void HexagonGenMux::getDefsUses(const MachineInstr *MI, BitVector &Defs, 153 BitVector &Uses) const { 154 // First, get the implicit defs and uses for this instruction. 155 unsigned Opc = MI->getOpcode(); 156 const MCInstrDesc &D = HII->get(Opc); 157 if (const MCPhysReg *R = D.ImplicitDefs) 158 while (*R) 159 expandReg(*R++, Defs); 160 if (const MCPhysReg *R = D.ImplicitUses) 161 while (*R) 162 expandReg(*R++, Uses); 163 164 // Look over all operands, and collect explicit defs and uses. 165 for (const MachineOperand &MO : MI->operands()) { 166 if (!MO.isReg() || MO.isImplicit()) 167 continue; 168 unsigned R = MO.getReg(); 169 BitVector &Set = MO.isDef() ? Defs : Uses; 170 expandReg(R, Set); 171 } 172 } 173 174 void HexagonGenMux::buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X, 175 DefUseInfoMap &DUM) { 176 unsigned Index = 0; 177 unsigned NR = HRI->getNumRegs(); 178 BitVector Defs(NR), Uses(NR); 179 180 for (MachineBasicBlock::iterator I = B.begin(), E = B.end(); I != E; ++I) { 181 MachineInstr *MI = &*I; 182 I2X.insert(std::make_pair(MI, Index)); 183 Defs.reset(); 184 Uses.reset(); 185 getDefsUses(MI, Defs, Uses); 186 DUM.insert(std::make_pair(Index, DefUseInfo(Defs, Uses))); 187 Index++; 188 } 189 } 190 191 bool HexagonGenMux::isCondTransfer(unsigned Opc) const { 192 switch (Opc) { 193 case Hexagon::A2_tfrt: 194 case Hexagon::A2_tfrf: 195 case Hexagon::C2_cmoveit: 196 case Hexagon::C2_cmoveif: 197 return true; 198 } 199 return false; 200 } 201 202 unsigned HexagonGenMux::getMuxOpcode(const MachineOperand &Src1, 203 const MachineOperand &Src2) const { 204 bool IsReg1 = Src1.isReg(), IsReg2 = Src2.isReg(); 205 if (IsReg1) 206 return IsReg2 ? Hexagon::C2_mux : Hexagon::C2_muxir; 207 if (IsReg2) 208 return Hexagon::C2_muxri; 209 210 // Neither is a register. The first source is extendable, but the second 211 // is not (s8). 212 if (Src2.isImm() && isInt<8>(Src2.getImm())) 213 return Hexagon::C2_muxii; 214 215 return 0; 216 } 217 218 bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) { 219 bool Changed = false; 220 InstrIndexMap I2X; 221 DefUseInfoMap DUM; 222 buildMaps(B, I2X, DUM); 223 224 typedef DenseMap<unsigned,CondsetInfo> CondsetMap; 225 CondsetMap CM; 226 MuxInfoList ML; 227 228 MachineBasicBlock::iterator NextI, End = B.end(); 229 for (MachineBasicBlock::iterator I = B.begin(); I != End; I = NextI) { 230 MachineInstr *MI = &*I; 231 NextI = std::next(I); 232 unsigned Opc = MI->getOpcode(); 233 if (!isCondTransfer(Opc)) 234 continue; 235 unsigned DR = MI->getOperand(0).getReg(); 236 if (isRegPair(DR)) 237 continue; 238 239 unsigned PR = MI->getOperand(1).getReg(); 240 unsigned Idx = I2X.lookup(MI); 241 CondsetMap::iterator F = CM.find(DR); 242 bool IfTrue = HII->isPredicatedTrue(Opc); 243 244 // If there is no record of a conditional transfer for this register, 245 // or the predicate register differs, create a new record for it. 246 if (F != CM.end() && F->second.PredR != PR) { 247 CM.erase(F); 248 F = CM.end(); 249 } 250 if (F == CM.end()) { 251 auto It = CM.insert(std::make_pair(DR, CondsetInfo())); 252 F = It.first; 253 F->second.PredR = PR; 254 } 255 CondsetInfo &CI = F->second; 256 if (IfTrue) 257 CI.TrueX = Idx; 258 else 259 CI.FalseX = Idx; 260 if (CI.TrueX == std::numeric_limits<unsigned>::max() || 261 CI.FalseX == std::numeric_limits<unsigned>::max()) 262 continue; 263 264 // There is now a complete definition of DR, i.e. we have the predicate 265 // register, the definition if-true, and definition if-false. 266 267 // First, check if both definitions are far enough from the definition 268 // of the predicate register. 269 unsigned MinX = std::min(CI.TrueX, CI.FalseX); 270 unsigned MaxX = std::max(CI.TrueX, CI.FalseX); 271 unsigned SearchX = (MaxX > 4) ? MaxX-4 : 0; 272 bool NearDef = false; 273 for (unsigned X = SearchX; X < MaxX; ++X) { 274 const DefUseInfo &DU = DUM.lookup(X); 275 if (!DU.Defs[PR]) 276 continue; 277 NearDef = true; 278 break; 279 } 280 if (NearDef) 281 continue; 282 283 // The predicate register is not defined in the last few instructions. 284 // Check if the conversion to MUX is possible (either "up", i.e. at the 285 // place of the earlier partial definition, or "down", where the later 286 // definition is located). Examine all defs and uses between these two 287 // definitions. 288 // SR1, SR2 - source registers from the first and the second definition. 289 MachineBasicBlock::iterator It1 = B.begin(), It2 = B.begin(); 290 std::advance(It1, MinX); 291 std::advance(It2, MaxX); 292 MachineInstr &Def1 = *It1, &Def2 = *It2; 293 MachineOperand *Src1 = &Def1.getOperand(2), *Src2 = &Def2.getOperand(2); 294 unsigned SR1 = Src1->isReg() ? Src1->getReg() : 0; 295 unsigned SR2 = Src2->isReg() ? Src2->getReg() : 0; 296 bool Failure = false, CanUp = true, CanDown = true; 297 for (unsigned X = MinX+1; X < MaxX; X++) { 298 const DefUseInfo &DU = DUM.lookup(X); 299 if (DU.Defs[PR] || DU.Defs[DR] || DU.Uses[DR]) { 300 Failure = true; 301 break; 302 } 303 if (CanDown && DU.Defs[SR1]) 304 CanDown = false; 305 if (CanUp && DU.Defs[SR2]) 306 CanUp = false; 307 } 308 if (Failure || (!CanUp && !CanDown)) 309 continue; 310 311 MachineOperand *SrcT = (MinX == CI.TrueX) ? Src1 : Src2; 312 MachineOperand *SrcF = (MinX == CI.FalseX) ? Src1 : Src2; 313 // Prefer "down", since this will move the MUX farther away from the 314 // predicate definition. 315 MachineBasicBlock::iterator At = CanDown ? Def2 : Def1; 316 ML.push_back(MuxInfo(At, DR, PR, SrcT, SrcF, Def1, Def2)); 317 } 318 319 for (unsigned I = 0, N = ML.size(); I < N; ++I) { 320 MuxInfo &MX = ML[I]; 321 MachineBasicBlock &B = *MX.At->getParent(); 322 DebugLoc DL = MX.At->getDebugLoc(); 323 unsigned MxOpc = getMuxOpcode(*MX.SrcT, *MX.SrcF); 324 if (!MxOpc) 325 continue; 326 BuildMI(B, MX.At, DL, HII->get(MxOpc), MX.DefR) 327 .addReg(MX.PredR) 328 .addOperand(*MX.SrcT) 329 .addOperand(*MX.SrcF); 330 B.erase(MX.Def1); 331 B.erase(MX.Def2); 332 Changed = true; 333 } 334 335 return Changed; 336 } 337 338 bool HexagonGenMux::runOnMachineFunction(MachineFunction &MF) { 339 if (skipFunction(*MF.getFunction())) 340 return false; 341 HII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo(); 342 HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); 343 bool Changed = false; 344 for (auto &I : MF) 345 Changed |= genMuxInBlock(I); 346 return Changed; 347 } 348 349 FunctionPass *llvm::createHexagonGenMux() { 350 return new HexagonGenMux(); 351 } 352