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