10b57cec5SDimitry Andric //===- HexagonGenMux.cpp --------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric // During instruction selection, MUX instructions are generated for 100b57cec5SDimitry Andric // conditional assignments. Since such assignments often present an 110b57cec5SDimitry Andric // opportunity to predicate instructions, HexagonExpandCondsets 120b57cec5SDimitry Andric // expands MUXes into pairs of conditional transfers, and then proceeds 130b57cec5SDimitry Andric // with predication of the producers/consumers of the registers involved. 140b57cec5SDimitry Andric // This happens after exiting from the SSA form, but before the machine 150b57cec5SDimitry Andric // instruction scheduler. After the scheduler and after the register 160b57cec5SDimitry Andric // allocation there can be cases of pairs of conditional transfers 170b57cec5SDimitry Andric // resulting from a MUX where neither of them was further predicated. If 180b57cec5SDimitry Andric // these transfers are now placed far enough from the instruction defining 190b57cec5SDimitry Andric // the predicate register, they cannot use the .new form. In such cases it 200b57cec5SDimitry Andric // is better to collapse them back to a single MUX instruction. 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric #define DEBUG_TYPE "hexmux" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric #include "HexagonInstrInfo.h" 250b57cec5SDimitry Andric #include "HexagonRegisterInfo.h" 260b57cec5SDimitry Andric #include "HexagonSubtarget.h" 270b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h" 280b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 290b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 300b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/LivePhysRegs.h" 320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 360b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 370b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 380b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 390b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 400b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 410b57cec5SDimitry Andric #include "llvm/Pass.h" 420b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 430b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 440b57cec5SDimitry Andric #include <algorithm> 450b57cec5SDimitry Andric #include <cassert> 460b57cec5SDimitry Andric #include <iterator> 470b57cec5SDimitry Andric #include <limits> 480b57cec5SDimitry Andric #include <utility> 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric using namespace llvm; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric namespace llvm { 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric FunctionPass *createHexagonGenMux(); 550b57cec5SDimitry Andric void initializeHexagonGenMuxPass(PassRegistry& Registry); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric } // end namespace llvm 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric // Initialize this to 0 to always prefer generating mux by default. 600b57cec5SDimitry Andric static cl::opt<unsigned> MinPredDist("hexagon-gen-mux-threshold", cl::Hidden, 610b57cec5SDimitry Andric cl::init(0), cl::desc("Minimum distance between predicate definition and " 620b57cec5SDimitry Andric "farther of the two predicated uses")); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric namespace { 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric class HexagonGenMux : public MachineFunctionPass { 670b57cec5SDimitry Andric public: 680b57cec5SDimitry Andric static char ID; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric HexagonGenMux() : MachineFunctionPass(ID) {} 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric StringRef getPassName() const override { 730b57cec5SDimitry Andric return "Hexagon generate mux instructions"; 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 770b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric MachineFunctionProperties getRequiredProperties() const override { 830b57cec5SDimitry Andric return MachineFunctionProperties().set( 840b57cec5SDimitry Andric MachineFunctionProperties::Property::NoVRegs); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric private: 880b57cec5SDimitry Andric const HexagonInstrInfo *HII = nullptr; 890b57cec5SDimitry Andric const HexagonRegisterInfo *HRI = nullptr; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric struct CondsetInfo { 920b57cec5SDimitry Andric unsigned PredR = 0; 930b57cec5SDimitry Andric unsigned TrueX = std::numeric_limits<unsigned>::max(); 940b57cec5SDimitry Andric unsigned FalseX = std::numeric_limits<unsigned>::max(); 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric CondsetInfo() = default; 970b57cec5SDimitry Andric }; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric struct DefUseInfo { 1000b57cec5SDimitry Andric BitVector Defs, Uses; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric DefUseInfo() = default; 1030b57cec5SDimitry Andric DefUseInfo(const BitVector &D, const BitVector &U) : Defs(D), Uses(U) {} 1040b57cec5SDimitry Andric }; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric struct MuxInfo { 1070b57cec5SDimitry Andric MachineBasicBlock::iterator At; 1080b57cec5SDimitry Andric unsigned DefR, PredR; 1090b57cec5SDimitry Andric MachineOperand *SrcT, *SrcF; 1100b57cec5SDimitry Andric MachineInstr *Def1, *Def2; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric MuxInfo(MachineBasicBlock::iterator It, unsigned DR, unsigned PR, 1130b57cec5SDimitry Andric MachineOperand *TOp, MachineOperand *FOp, MachineInstr &D1, 1140b57cec5SDimitry Andric MachineInstr &D2) 1150b57cec5SDimitry Andric : At(It), DefR(DR), PredR(PR), SrcT(TOp), SrcF(FOp), Def1(&D1), 1160b57cec5SDimitry Andric Def2(&D2) {} 1170b57cec5SDimitry Andric }; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric using InstrIndexMap = DenseMap<MachineInstr *, unsigned>; 1200b57cec5SDimitry Andric using DefUseInfoMap = DenseMap<unsigned, DefUseInfo>; 1210b57cec5SDimitry Andric using MuxInfoList = SmallVector<MuxInfo, 4>; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric bool isRegPair(unsigned Reg) const { 1240b57cec5SDimitry Andric return Hexagon::DoubleRegsRegClass.contains(Reg); 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric void getSubRegs(unsigned Reg, BitVector &SRs) const; 1280b57cec5SDimitry Andric void expandReg(unsigned Reg, BitVector &Set) const; 1290b57cec5SDimitry Andric void getDefsUses(const MachineInstr *MI, BitVector &Defs, 1300b57cec5SDimitry Andric BitVector &Uses) const; 1310b57cec5SDimitry Andric void buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X, 1320b57cec5SDimitry Andric DefUseInfoMap &DUM); 1330b57cec5SDimitry Andric bool isCondTransfer(unsigned Opc) const; 1340b57cec5SDimitry Andric unsigned getMuxOpcode(const MachineOperand &Src1, 1350b57cec5SDimitry Andric const MachineOperand &Src2) const; 1360b57cec5SDimitry Andric bool genMuxInBlock(MachineBasicBlock &B); 1370b57cec5SDimitry Andric }; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric } // end anonymous namespace 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric char HexagonGenMux::ID = 0; 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric INITIALIZE_PASS(HexagonGenMux, "hexagon-gen-mux", 1440b57cec5SDimitry Andric "Hexagon generate mux instructions", false, false) 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric void HexagonGenMux::getSubRegs(unsigned Reg, BitVector &SRs) const { 1470b57cec5SDimitry Andric for (MCSubRegIterator I(Reg, HRI); I.isValid(); ++I) 1480b57cec5SDimitry Andric SRs[*I] = true; 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric void HexagonGenMux::expandReg(unsigned Reg, BitVector &Set) const { 1520b57cec5SDimitry Andric if (isRegPair(Reg)) 1530b57cec5SDimitry Andric getSubRegs(Reg, Set); 1540b57cec5SDimitry Andric else 1550b57cec5SDimitry Andric Set[Reg] = true; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric void HexagonGenMux::getDefsUses(const MachineInstr *MI, BitVector &Defs, 1590b57cec5SDimitry Andric BitVector &Uses) const { 1600b57cec5SDimitry Andric // First, get the implicit defs and uses for this instruction. 1610b57cec5SDimitry Andric unsigned Opc = MI->getOpcode(); 1620b57cec5SDimitry Andric const MCInstrDesc &D = HII->get(Opc); 1630b57cec5SDimitry Andric if (const MCPhysReg *R = D.ImplicitDefs) 1640b57cec5SDimitry Andric while (*R) 1650b57cec5SDimitry Andric expandReg(*R++, Defs); 1660b57cec5SDimitry Andric if (const MCPhysReg *R = D.ImplicitUses) 1670b57cec5SDimitry Andric while (*R) 1680b57cec5SDimitry Andric expandReg(*R++, Uses); 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric // Look over all operands, and collect explicit defs and uses. 1710b57cec5SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 1720b57cec5SDimitry Andric if (!MO.isReg() || MO.isImplicit()) 1730b57cec5SDimitry Andric continue; 1748bcb0991SDimitry Andric Register R = MO.getReg(); 1750b57cec5SDimitry Andric BitVector &Set = MO.isDef() ? Defs : Uses; 1760b57cec5SDimitry Andric expandReg(R, Set); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric } 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric void HexagonGenMux::buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X, 1810b57cec5SDimitry Andric DefUseInfoMap &DUM) { 1820b57cec5SDimitry Andric unsigned Index = 0; 1830b57cec5SDimitry Andric unsigned NR = HRI->getNumRegs(); 1840b57cec5SDimitry Andric BitVector Defs(NR), Uses(NR); 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric for (MachineBasicBlock::iterator I = B.begin(), E = B.end(); I != E; ++I) { 1870b57cec5SDimitry Andric MachineInstr *MI = &*I; 1880b57cec5SDimitry Andric I2X.insert(std::make_pair(MI, Index)); 1890b57cec5SDimitry Andric Defs.reset(); 1900b57cec5SDimitry Andric Uses.reset(); 1910b57cec5SDimitry Andric getDefsUses(MI, Defs, Uses); 1920b57cec5SDimitry Andric DUM.insert(std::make_pair(Index, DefUseInfo(Defs, Uses))); 1930b57cec5SDimitry Andric Index++; 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric bool HexagonGenMux::isCondTransfer(unsigned Opc) const { 1980b57cec5SDimitry Andric switch (Opc) { 1990b57cec5SDimitry Andric case Hexagon::A2_tfrt: 2000b57cec5SDimitry Andric case Hexagon::A2_tfrf: 2010b57cec5SDimitry Andric case Hexagon::C2_cmoveit: 2020b57cec5SDimitry Andric case Hexagon::C2_cmoveif: 2030b57cec5SDimitry Andric return true; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric return false; 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric unsigned HexagonGenMux::getMuxOpcode(const MachineOperand &Src1, 2090b57cec5SDimitry Andric const MachineOperand &Src2) const { 2100b57cec5SDimitry Andric bool IsReg1 = Src1.isReg(), IsReg2 = Src2.isReg(); 2110b57cec5SDimitry Andric if (IsReg1) 2120b57cec5SDimitry Andric return IsReg2 ? Hexagon::C2_mux : Hexagon::C2_muxir; 2130b57cec5SDimitry Andric if (IsReg2) 2140b57cec5SDimitry Andric return Hexagon::C2_muxri; 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric // Neither is a register. The first source is extendable, but the second 2170b57cec5SDimitry Andric // is not (s8). 2180b57cec5SDimitry Andric if (Src2.isImm() && isInt<8>(Src2.getImm())) 2190b57cec5SDimitry Andric return Hexagon::C2_muxii; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric return 0; 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) { 2250b57cec5SDimitry Andric bool Changed = false; 2260b57cec5SDimitry Andric InstrIndexMap I2X; 2270b57cec5SDimitry Andric DefUseInfoMap DUM; 2280b57cec5SDimitry Andric buildMaps(B, I2X, DUM); 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric using CondsetMap = DenseMap<unsigned, CondsetInfo>; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric CondsetMap CM; 2330b57cec5SDimitry Andric MuxInfoList ML; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric MachineBasicBlock::iterator NextI, End = B.end(); 2360b57cec5SDimitry Andric for (MachineBasicBlock::iterator I = B.begin(); I != End; I = NextI) { 2370b57cec5SDimitry Andric MachineInstr *MI = &*I; 2380b57cec5SDimitry Andric NextI = std::next(I); 2390b57cec5SDimitry Andric unsigned Opc = MI->getOpcode(); 2400b57cec5SDimitry Andric if (!isCondTransfer(Opc)) 2410b57cec5SDimitry Andric continue; 2428bcb0991SDimitry Andric Register DR = MI->getOperand(0).getReg(); 2430b57cec5SDimitry Andric if (isRegPair(DR)) 2440b57cec5SDimitry Andric continue; 2450b57cec5SDimitry Andric MachineOperand &PredOp = MI->getOperand(1); 2460b57cec5SDimitry Andric if (PredOp.isUndef()) 2470b57cec5SDimitry Andric continue; 2480b57cec5SDimitry Andric 2498bcb0991SDimitry Andric Register PR = PredOp.getReg(); 2500b57cec5SDimitry Andric unsigned Idx = I2X.lookup(MI); 2510b57cec5SDimitry Andric CondsetMap::iterator F = CM.find(DR); 2520b57cec5SDimitry Andric bool IfTrue = HII->isPredicatedTrue(Opc); 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric // If there is no record of a conditional transfer for this register, 2550b57cec5SDimitry Andric // or the predicate register differs, create a new record for it. 2560b57cec5SDimitry Andric if (F != CM.end() && F->second.PredR != PR) { 2570b57cec5SDimitry Andric CM.erase(F); 2580b57cec5SDimitry Andric F = CM.end(); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric if (F == CM.end()) { 2610b57cec5SDimitry Andric auto It = CM.insert(std::make_pair(DR, CondsetInfo())); 2620b57cec5SDimitry Andric F = It.first; 2630b57cec5SDimitry Andric F->second.PredR = PR; 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric CondsetInfo &CI = F->second; 2660b57cec5SDimitry Andric if (IfTrue) 2670b57cec5SDimitry Andric CI.TrueX = Idx; 2680b57cec5SDimitry Andric else 2690b57cec5SDimitry Andric CI.FalseX = Idx; 2700b57cec5SDimitry Andric if (CI.TrueX == std::numeric_limits<unsigned>::max() || 2710b57cec5SDimitry Andric CI.FalseX == std::numeric_limits<unsigned>::max()) 2720b57cec5SDimitry Andric continue; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric // There is now a complete definition of DR, i.e. we have the predicate 2750b57cec5SDimitry Andric // register, the definition if-true, and definition if-false. 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric // First, check if the definitions are far enough from the definition 2780b57cec5SDimitry Andric // of the predicate register. 2790b57cec5SDimitry Andric unsigned MinX = std::min(CI.TrueX, CI.FalseX); 2800b57cec5SDimitry Andric unsigned MaxX = std::max(CI.TrueX, CI.FalseX); 2810b57cec5SDimitry Andric // Specifically, check if the predicate definition is within a prescribed 2820b57cec5SDimitry Andric // distance from the farther of the two predicated instructions. 2830b57cec5SDimitry Andric unsigned SearchX = (MaxX >= MinPredDist) ? MaxX-MinPredDist : 0; 2840b57cec5SDimitry Andric bool NearDef = false; 2850b57cec5SDimitry Andric for (unsigned X = SearchX; X < MaxX; ++X) { 2860b57cec5SDimitry Andric const DefUseInfo &DU = DUM.lookup(X); 2870b57cec5SDimitry Andric if (!DU.Defs[PR]) 2880b57cec5SDimitry Andric continue; 2890b57cec5SDimitry Andric NearDef = true; 2900b57cec5SDimitry Andric break; 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric if (NearDef) 2930b57cec5SDimitry Andric continue; 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric // The predicate register is not defined in the last few instructions. 2960b57cec5SDimitry Andric // Check if the conversion to MUX is possible (either "up", i.e. at the 2970b57cec5SDimitry Andric // place of the earlier partial definition, or "down", where the later 2980b57cec5SDimitry Andric // definition is located). Examine all defs and uses between these two 2990b57cec5SDimitry Andric // definitions. 3000b57cec5SDimitry Andric // SR1, SR2 - source registers from the first and the second definition. 3010b57cec5SDimitry Andric MachineBasicBlock::iterator It1 = B.begin(), It2 = B.begin(); 3020b57cec5SDimitry Andric std::advance(It1, MinX); 3030b57cec5SDimitry Andric std::advance(It2, MaxX); 3040b57cec5SDimitry Andric MachineInstr &Def1 = *It1, &Def2 = *It2; 3050b57cec5SDimitry Andric MachineOperand *Src1 = &Def1.getOperand(2), *Src2 = &Def2.getOperand(2); 3060b57cec5SDimitry Andric Register SR1 = Src1->isReg() ? Src1->getReg() : Register(); 3070b57cec5SDimitry Andric Register SR2 = Src2->isReg() ? Src2->getReg() : Register(); 3080b57cec5SDimitry Andric bool Failure = false, CanUp = true, CanDown = true; 3090b57cec5SDimitry Andric for (unsigned X = MinX+1; X < MaxX; X++) { 3100b57cec5SDimitry Andric const DefUseInfo &DU = DUM.lookup(X); 3110b57cec5SDimitry Andric if (DU.Defs[PR] || DU.Defs[DR] || DU.Uses[DR]) { 3120b57cec5SDimitry Andric Failure = true; 3130b57cec5SDimitry Andric break; 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric if (CanDown && DU.Defs[SR1]) 3160b57cec5SDimitry Andric CanDown = false; 3170b57cec5SDimitry Andric if (CanUp && DU.Defs[SR2]) 3180b57cec5SDimitry Andric CanUp = false; 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric if (Failure || (!CanUp && !CanDown)) 3210b57cec5SDimitry Andric continue; 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric MachineOperand *SrcT = (MinX == CI.TrueX) ? Src1 : Src2; 3240b57cec5SDimitry Andric MachineOperand *SrcF = (MinX == CI.FalseX) ? Src1 : Src2; 3250b57cec5SDimitry Andric // Prefer "down", since this will move the MUX farther away from the 3260b57cec5SDimitry Andric // predicate definition. 3270b57cec5SDimitry Andric MachineBasicBlock::iterator At = CanDown ? Def2 : Def1; 3280b57cec5SDimitry Andric ML.push_back(MuxInfo(At, DR, PR, SrcT, SrcF, Def1, Def2)); 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric for (MuxInfo &MX : ML) { 3320b57cec5SDimitry Andric unsigned MxOpc = getMuxOpcode(*MX.SrcT, *MX.SrcF); 3330b57cec5SDimitry Andric if (!MxOpc) 3340b57cec5SDimitry Andric continue; 335*480093f4SDimitry Andric // Basic sanity check: since we are deleting instructions, validate the 336*480093f4SDimitry Andric // iterators. There is a possibility that one of Def1 or Def2 is translated 337*480093f4SDimitry Andric // to "mux" and being considered for other "mux" instructions. 338*480093f4SDimitry Andric if (!MX.At->getParent() || !MX.Def1->getParent() || !MX.Def2->getParent()) 339*480093f4SDimitry Andric continue; 340*480093f4SDimitry Andric 3410b57cec5SDimitry Andric MachineBasicBlock &B = *MX.At->getParent(); 3420b57cec5SDimitry Andric const DebugLoc &DL = B.findDebugLoc(MX.At); 3430b57cec5SDimitry Andric auto NewMux = BuildMI(B, MX.At, DL, HII->get(MxOpc), MX.DefR) 3440b57cec5SDimitry Andric .addReg(MX.PredR) 3450b57cec5SDimitry Andric .add(*MX.SrcT) 3460b57cec5SDimitry Andric .add(*MX.SrcF); 3470b57cec5SDimitry Andric NewMux->clearKillInfo(); 348*480093f4SDimitry Andric B.remove(MX.Def1); 349*480093f4SDimitry Andric B.remove(MX.Def2); 3500b57cec5SDimitry Andric Changed = true; 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric // Fix up kill flags. 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric LivePhysRegs LPR(*HRI); 3560b57cec5SDimitry Andric LPR.addLiveOuts(B); 3570b57cec5SDimitry Andric auto IsLive = [&LPR,this] (unsigned Reg) -> bool { 3580b57cec5SDimitry Andric for (MCSubRegIterator S(Reg, HRI, true); S.isValid(); ++S) 3590b57cec5SDimitry Andric if (LPR.contains(*S)) 3600b57cec5SDimitry Andric return true; 3610b57cec5SDimitry Andric return false; 3620b57cec5SDimitry Andric }; 3630b57cec5SDimitry Andric for (auto I = B.rbegin(), E = B.rend(); I != E; ++I) { 3640b57cec5SDimitry Andric if (I->isDebugInstr()) 3650b57cec5SDimitry Andric continue; 3660b57cec5SDimitry Andric // This isn't 100% accurate, but it's safe. 3670b57cec5SDimitry Andric // It won't detect (as a kill) a case like this 3680b57cec5SDimitry Andric // r0 = add r0, 1 <-- r0 should be "killed" 3690b57cec5SDimitry Andric // ... = r0 3700b57cec5SDimitry Andric for (MachineOperand &Op : I->operands()) { 3710b57cec5SDimitry Andric if (!Op.isReg() || !Op.isUse()) 3720b57cec5SDimitry Andric continue; 3730b57cec5SDimitry Andric assert(Op.getSubReg() == 0 && "Should have physical registers only"); 3740b57cec5SDimitry Andric bool Live = IsLive(Op.getReg()); 3750b57cec5SDimitry Andric Op.setIsKill(!Live); 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric LPR.stepBackward(*I); 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric return Changed; 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric bool HexagonGenMux::runOnMachineFunction(MachineFunction &MF) { 3840b57cec5SDimitry Andric if (skipFunction(MF.getFunction())) 3850b57cec5SDimitry Andric return false; 3860b57cec5SDimitry Andric HII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo(); 3870b57cec5SDimitry Andric HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); 3880b57cec5SDimitry Andric bool Changed = false; 3890b57cec5SDimitry Andric for (auto &I : MF) 3900b57cec5SDimitry Andric Changed |= genMuxInBlock(I); 3910b57cec5SDimitry Andric return Changed; 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric FunctionPass *llvm::createHexagonGenMux() { 3950b57cec5SDimitry Andric return new HexagonGenMux(); 3960b57cec5SDimitry Andric } 397