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 
HexagonGenMux()700b57cec5SDimitry Andric     HexagonGenMux() : MachineFunctionPass(ID) {}
710b57cec5SDimitry Andric 
getPassName() const720b57cec5SDimitry Andric     StringRef getPassName() const override {
730b57cec5SDimitry Andric       return "Hexagon generate mux instructions";
740b57cec5SDimitry Andric     }
750b57cec5SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const760b57cec5SDimitry 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 
getRequiredProperties() const820b57cec5SDimitry 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;
DefUseInfo__anonbc17b4c50111::HexagonGenMux::DefUseInfo1030b57cec5SDimitry 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 
MuxInfo__anonbc17b4c50111::HexagonGenMux::MuxInfo1120b57cec5SDimitry 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 
isRegPair(unsigned Reg) const1230b57cec5SDimitry 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 
getSubRegs(unsigned Reg,BitVector & SRs) const1460b57cec5SDimitry Andric void HexagonGenMux::getSubRegs(unsigned Reg, BitVector &SRs) const {
14706c3fb27SDimitry Andric   for (MCPhysReg I : HRI->subregs(Reg))
14806c3fb27SDimitry Andric     SRs[I] = true;
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric 
expandReg(unsigned Reg,BitVector & Set) const1510b57cec5SDimitry 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 
getDefsUses(const MachineInstr * MI,BitVector & Defs,BitVector & Uses) const1580b57cec5SDimitry 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 
buildMaps(MachineBasicBlock & B,InstrIndexMap & I2X,DefUseInfoMap & DUM)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 
isCondTransfer(unsigned Opc) const1940b57cec5SDimitry 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 
getMuxOpcode(const MachineOperand & Src1,const MachineOperand & Src2) const2050b57cec5SDimitry 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 
genMuxInBlock(MachineBasicBlock & B)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 {
35206c3fb27SDimitry Andric     for (MCPhysReg S : HRI->subregs_inclusive(Reg))
35306c3fb27SDimitry 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 
runOnMachineFunction(MachineFunction & MF)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 
createHexagonGenMux()3880b57cec5SDimitry Andric FunctionPass *llvm::createHexagonGenMux() {
3890b57cec5SDimitry Andric   return new HexagonGenMux();
3900b57cec5SDimitry Andric }
391