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 #include "HexagonInstrInfo.h" 230b57cec5SDimitry Andric #include "HexagonRegisterInfo.h" 240b57cec5SDimitry Andric #include "HexagonSubtarget.h" 250b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h" 260b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 270b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 280b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 290b57cec5SDimitry Andric #include "llvm/CodeGen/LivePhysRegs.h" 300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 360b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 370b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 380b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 390b57cec5SDimitry Andric #include "llvm/Pass.h" 400b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 410b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 420b57cec5SDimitry Andric #include <algorithm> 430b57cec5SDimitry Andric #include <cassert> 440b57cec5SDimitry Andric #include <iterator> 450b57cec5SDimitry Andric #include <limits> 460b57cec5SDimitry Andric #include <utility> 470b57cec5SDimitry Andric 48fe6060f1SDimitry Andric #define DEBUG_TYPE "hexmux" 49fe6060f1SDimitry 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); 163bdd1243dSDimitry Andric for (MCPhysReg R : D.implicit_defs()) 164bdd1243dSDimitry Andric expandReg(R, Defs); 165bdd1243dSDimitry Andric for (MCPhysReg R : D.implicit_uses()) 166bdd1243dSDimitry Andric expandReg(R, Uses); 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric // Look over all operands, and collect explicit defs and uses. 1690b57cec5SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 1700b57cec5SDimitry Andric if (!MO.isReg() || MO.isImplicit()) 1710b57cec5SDimitry Andric continue; 1728bcb0991SDimitry Andric Register R = MO.getReg(); 1730b57cec5SDimitry Andric BitVector &Set = MO.isDef() ? Defs : Uses; 1740b57cec5SDimitry Andric expandReg(R, Set); 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric void HexagonGenMux::buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X, 1790b57cec5SDimitry Andric DefUseInfoMap &DUM) { 1800b57cec5SDimitry Andric unsigned Index = 0; 1810b57cec5SDimitry Andric unsigned NR = HRI->getNumRegs(); 1820b57cec5SDimitry Andric BitVector Defs(NR), Uses(NR); 1830b57cec5SDimitry Andric 184349cc55cSDimitry Andric for (MachineInstr &MI : B) { 185349cc55cSDimitry Andric I2X.insert(std::make_pair(&MI, Index)); 1860b57cec5SDimitry Andric Defs.reset(); 1870b57cec5SDimitry Andric Uses.reset(); 188349cc55cSDimitry Andric getDefsUses(&MI, Defs, Uses); 1890b57cec5SDimitry Andric DUM.insert(std::make_pair(Index, DefUseInfo(Defs, Uses))); 1900b57cec5SDimitry Andric Index++; 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric bool HexagonGenMux::isCondTransfer(unsigned Opc) const { 1950b57cec5SDimitry Andric switch (Opc) { 1960b57cec5SDimitry Andric case Hexagon::A2_tfrt: 1970b57cec5SDimitry Andric case Hexagon::A2_tfrf: 1980b57cec5SDimitry Andric case Hexagon::C2_cmoveit: 1990b57cec5SDimitry Andric case Hexagon::C2_cmoveif: 2000b57cec5SDimitry Andric return true; 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric return false; 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric unsigned HexagonGenMux::getMuxOpcode(const MachineOperand &Src1, 2060b57cec5SDimitry Andric const MachineOperand &Src2) const { 2070b57cec5SDimitry Andric bool IsReg1 = Src1.isReg(), IsReg2 = Src2.isReg(); 2080b57cec5SDimitry Andric if (IsReg1) 2090b57cec5SDimitry Andric return IsReg2 ? Hexagon::C2_mux : Hexagon::C2_muxir; 2100b57cec5SDimitry Andric if (IsReg2) 2110b57cec5SDimitry Andric return Hexagon::C2_muxri; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric // Neither is a register. The first source is extendable, but the second 2140b57cec5SDimitry Andric // is not (s8). 2150b57cec5SDimitry Andric if (Src2.isImm() && isInt<8>(Src2.getImm())) 2160b57cec5SDimitry Andric return Hexagon::C2_muxii; 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric return 0; 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) { 2220b57cec5SDimitry Andric bool Changed = false; 2230b57cec5SDimitry Andric InstrIndexMap I2X; 2240b57cec5SDimitry Andric DefUseInfoMap DUM; 2250b57cec5SDimitry Andric buildMaps(B, I2X, DUM); 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric using CondsetMap = DenseMap<unsigned, CondsetInfo>; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric CondsetMap CM; 2300b57cec5SDimitry Andric MuxInfoList ML; 2310b57cec5SDimitry Andric 232349cc55cSDimitry Andric for (MachineInstr &MI : llvm::make_early_inc_range(B)) { 233349cc55cSDimitry Andric unsigned Opc = MI.getOpcode(); 2340b57cec5SDimitry Andric if (!isCondTransfer(Opc)) 2350b57cec5SDimitry Andric continue; 236349cc55cSDimitry Andric Register DR = MI.getOperand(0).getReg(); 2370b57cec5SDimitry Andric if (isRegPair(DR)) 2380b57cec5SDimitry Andric continue; 239349cc55cSDimitry Andric MachineOperand &PredOp = MI.getOperand(1); 2400b57cec5SDimitry Andric if (PredOp.isUndef()) 2410b57cec5SDimitry Andric continue; 2420b57cec5SDimitry Andric 2438bcb0991SDimitry Andric Register PR = PredOp.getReg(); 244349cc55cSDimitry Andric unsigned Idx = I2X.lookup(&MI); 2450b57cec5SDimitry Andric CondsetMap::iterator F = CM.find(DR); 2460b57cec5SDimitry Andric bool IfTrue = HII->isPredicatedTrue(Opc); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric // If there is no record of a conditional transfer for this register, 2490b57cec5SDimitry Andric // or the predicate register differs, create a new record for it. 2500b57cec5SDimitry Andric if (F != CM.end() && F->second.PredR != PR) { 2510b57cec5SDimitry Andric CM.erase(F); 2520b57cec5SDimitry Andric F = CM.end(); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric if (F == CM.end()) { 2550b57cec5SDimitry Andric auto It = CM.insert(std::make_pair(DR, CondsetInfo())); 2560b57cec5SDimitry Andric F = It.first; 2570b57cec5SDimitry Andric F->second.PredR = PR; 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric CondsetInfo &CI = F->second; 2600b57cec5SDimitry Andric if (IfTrue) 2610b57cec5SDimitry Andric CI.TrueX = Idx; 2620b57cec5SDimitry Andric else 2630b57cec5SDimitry Andric CI.FalseX = Idx; 2640b57cec5SDimitry Andric if (CI.TrueX == std::numeric_limits<unsigned>::max() || 2650b57cec5SDimitry Andric CI.FalseX == std::numeric_limits<unsigned>::max()) 2660b57cec5SDimitry Andric continue; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric // There is now a complete definition of DR, i.e. we have the predicate 2690b57cec5SDimitry Andric // register, the definition if-true, and definition if-false. 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric // First, check if the definitions are far enough from the definition 2720b57cec5SDimitry Andric // of the predicate register. 2730b57cec5SDimitry Andric unsigned MinX = std::min(CI.TrueX, CI.FalseX); 2740b57cec5SDimitry Andric unsigned MaxX = std::max(CI.TrueX, CI.FalseX); 2750b57cec5SDimitry Andric // Specifically, check if the predicate definition is within a prescribed 2760b57cec5SDimitry Andric // distance from the farther of the two predicated instructions. 2770b57cec5SDimitry Andric unsigned SearchX = (MaxX >= MinPredDist) ? MaxX-MinPredDist : 0; 2780b57cec5SDimitry Andric bool NearDef = false; 2790b57cec5SDimitry Andric for (unsigned X = SearchX; X < MaxX; ++X) { 2800b57cec5SDimitry Andric const DefUseInfo &DU = DUM.lookup(X); 2810b57cec5SDimitry Andric if (!DU.Defs[PR]) 2820b57cec5SDimitry Andric continue; 2830b57cec5SDimitry Andric NearDef = true; 2840b57cec5SDimitry Andric break; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric if (NearDef) 2870b57cec5SDimitry Andric continue; 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric // The predicate register is not defined in the last few instructions. 2900b57cec5SDimitry Andric // Check if the conversion to MUX is possible (either "up", i.e. at the 2910b57cec5SDimitry Andric // place of the earlier partial definition, or "down", where the later 2920b57cec5SDimitry Andric // definition is located). Examine all defs and uses between these two 2930b57cec5SDimitry Andric // definitions. 2940b57cec5SDimitry Andric // SR1, SR2 - source registers from the first and the second definition. 2950b57cec5SDimitry Andric MachineBasicBlock::iterator It1 = B.begin(), It2 = B.begin(); 2960b57cec5SDimitry Andric std::advance(It1, MinX); 2970b57cec5SDimitry Andric std::advance(It2, MaxX); 2980b57cec5SDimitry Andric MachineInstr &Def1 = *It1, &Def2 = *It2; 2990b57cec5SDimitry Andric MachineOperand *Src1 = &Def1.getOperand(2), *Src2 = &Def2.getOperand(2); 3000b57cec5SDimitry Andric Register SR1 = Src1->isReg() ? Src1->getReg() : Register(); 3010b57cec5SDimitry Andric Register SR2 = Src2->isReg() ? Src2->getReg() : Register(); 3020b57cec5SDimitry Andric bool Failure = false, CanUp = true, CanDown = true; 3030b57cec5SDimitry Andric for (unsigned X = MinX+1; X < MaxX; X++) { 3040b57cec5SDimitry Andric const DefUseInfo &DU = DUM.lookup(X); 3050b57cec5SDimitry Andric if (DU.Defs[PR] || DU.Defs[DR] || DU.Uses[DR]) { 3060b57cec5SDimitry Andric Failure = true; 3070b57cec5SDimitry Andric break; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric if (CanDown && DU.Defs[SR1]) 3100b57cec5SDimitry Andric CanDown = false; 3110b57cec5SDimitry Andric if (CanUp && DU.Defs[SR2]) 3120b57cec5SDimitry Andric CanUp = false; 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric if (Failure || (!CanUp && !CanDown)) 3150b57cec5SDimitry Andric continue; 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric MachineOperand *SrcT = (MinX == CI.TrueX) ? Src1 : Src2; 3180b57cec5SDimitry Andric MachineOperand *SrcF = (MinX == CI.FalseX) ? Src1 : Src2; 3190b57cec5SDimitry Andric // Prefer "down", since this will move the MUX farther away from the 3200b57cec5SDimitry Andric // predicate definition. 3210b57cec5SDimitry Andric MachineBasicBlock::iterator At = CanDown ? Def2 : Def1; 3220b57cec5SDimitry Andric ML.push_back(MuxInfo(At, DR, PR, SrcT, SrcF, Def1, Def2)); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric for (MuxInfo &MX : ML) { 3260b57cec5SDimitry Andric unsigned MxOpc = getMuxOpcode(*MX.SrcT, *MX.SrcF); 3270b57cec5SDimitry Andric if (!MxOpc) 3280b57cec5SDimitry Andric continue; 3294824e7fdSDimitry Andric // Basic correctness check: since we are deleting instructions, validate the 330480093f4SDimitry Andric // iterators. There is a possibility that one of Def1 or Def2 is translated 331480093f4SDimitry Andric // to "mux" and being considered for other "mux" instructions. 332480093f4SDimitry Andric if (!MX.At->getParent() || !MX.Def1->getParent() || !MX.Def2->getParent()) 333480093f4SDimitry Andric continue; 334480093f4SDimitry Andric 3350b57cec5SDimitry Andric MachineBasicBlock &B = *MX.At->getParent(); 3360b57cec5SDimitry Andric const DebugLoc &DL = B.findDebugLoc(MX.At); 3370b57cec5SDimitry Andric auto NewMux = BuildMI(B, MX.At, DL, HII->get(MxOpc), MX.DefR) 3380b57cec5SDimitry Andric .addReg(MX.PredR) 3390b57cec5SDimitry Andric .add(*MX.SrcT) 3400b57cec5SDimitry Andric .add(*MX.SrcF); 3410b57cec5SDimitry Andric NewMux->clearKillInfo(); 342480093f4SDimitry Andric B.remove(MX.Def1); 343480093f4SDimitry Andric B.remove(MX.Def2); 3440b57cec5SDimitry Andric Changed = true; 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric // Fix up kill flags. 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric LivePhysRegs LPR(*HRI); 3500b57cec5SDimitry Andric LPR.addLiveOuts(B); 3510b57cec5SDimitry Andric auto IsLive = [&LPR,this] (unsigned Reg) -> bool { 3520b57cec5SDimitry Andric for (MCSubRegIterator S(Reg, HRI, true); S.isValid(); ++S) 3530b57cec5SDimitry Andric if (LPR.contains(*S)) 3540b57cec5SDimitry Andric return true; 3550b57cec5SDimitry Andric return false; 3560b57cec5SDimitry Andric }; 357349cc55cSDimitry Andric for (MachineInstr &I : llvm::reverse(B)) { 358349cc55cSDimitry Andric if (I.isDebugInstr()) 3590b57cec5SDimitry Andric continue; 3600b57cec5SDimitry Andric // This isn't 100% accurate, but it's safe. 3610b57cec5SDimitry Andric // It won't detect (as a kill) a case like this 3620b57cec5SDimitry Andric // r0 = add r0, 1 <-- r0 should be "killed" 3630b57cec5SDimitry Andric // ... = r0 364349cc55cSDimitry Andric for (MachineOperand &Op : I.operands()) { 3650b57cec5SDimitry Andric if (!Op.isReg() || !Op.isUse()) 3660b57cec5SDimitry Andric continue; 3670b57cec5SDimitry Andric assert(Op.getSubReg() == 0 && "Should have physical registers only"); 3680b57cec5SDimitry Andric bool Live = IsLive(Op.getReg()); 3690b57cec5SDimitry Andric Op.setIsKill(!Live); 3700b57cec5SDimitry Andric } 371349cc55cSDimitry Andric LPR.stepBackward(I); 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric return Changed; 3750b57cec5SDimitry Andric } 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric bool HexagonGenMux::runOnMachineFunction(MachineFunction &MF) { 3780b57cec5SDimitry Andric if (skipFunction(MF.getFunction())) 3790b57cec5SDimitry Andric return false; 3800b57cec5SDimitry Andric HII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo(); 3810b57cec5SDimitry Andric HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); 3820b57cec5SDimitry Andric bool Changed = false; 3830b57cec5SDimitry Andric for (auto &I : MF) 3840b57cec5SDimitry Andric Changed |= genMuxInBlock(I); 3850b57cec5SDimitry Andric return Changed; 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric FunctionPass *llvm::createHexagonGenMux() { 3890b57cec5SDimitry Andric return new HexagonGenMux(); 3900b57cec5SDimitry Andric } 391