xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- HexagonExpandCondsets.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 // Replace mux instructions with the corresponding legal instructions.
100b57cec5SDimitry Andric // It is meant to work post-SSA, but still on virtual registers. It was
110b57cec5SDimitry Andric // originally placed between register coalescing and machine instruction
120b57cec5SDimitry Andric // scheduler.
130b57cec5SDimitry Andric // In this place in the optimization sequence, live interval analysis had
140b57cec5SDimitry Andric // been performed, and the live intervals should be preserved. A large part
150b57cec5SDimitry Andric // of the code deals with preserving the liveness information.
160b57cec5SDimitry Andric //
170b57cec5SDimitry Andric // Liveness tracking aside, the main functionality of this pass is divided
180b57cec5SDimitry Andric // into two steps. The first step is to replace an instruction
190b57cec5SDimitry Andric //   %0 = C2_mux %1, %2, %3
200b57cec5SDimitry Andric // with a pair of conditional transfers
210b57cec5SDimitry Andric //   %0 = A2_tfrt %1, %2
220b57cec5SDimitry Andric //   %0 = A2_tfrf %1, %3
230b57cec5SDimitry Andric // It is the intention that the execution of this pass could be terminated
240b57cec5SDimitry Andric // after this step, and the code generated would be functionally correct.
250b57cec5SDimitry Andric //
260b57cec5SDimitry Andric // If the uses of the source values %1 and %2 are kills, and their
270b57cec5SDimitry Andric // definitions are predicable, then in the second step, the conditional
280b57cec5SDimitry Andric // transfers will then be rewritten as predicated instructions. E.g.
290b57cec5SDimitry Andric //   %0 = A2_or %1, %2
300b57cec5SDimitry Andric //   %3 = A2_tfrt %99, killed %0
310b57cec5SDimitry Andric // will be rewritten as
320b57cec5SDimitry Andric //   %3 = A2_port %99, %1, %2
330b57cec5SDimitry Andric //
340b57cec5SDimitry Andric // This replacement has two variants: "up" and "down". Consider this case:
350b57cec5SDimitry Andric //   %0 = A2_or %1, %2
360b57cec5SDimitry Andric //   ... [intervening instructions] ...
370b57cec5SDimitry Andric //   %3 = A2_tfrt %99, killed %0
380b57cec5SDimitry Andric // variant "up":
390b57cec5SDimitry Andric //   %3 = A2_port %99, %1, %2
400b57cec5SDimitry Andric //   ... [intervening instructions, %0->vreg3] ...
410b57cec5SDimitry Andric //   [deleted]
420b57cec5SDimitry Andric // variant "down":
430b57cec5SDimitry Andric //   [deleted]
440b57cec5SDimitry Andric //   ... [intervening instructions] ...
450b57cec5SDimitry Andric //   %3 = A2_port %99, %1, %2
460b57cec5SDimitry Andric //
470b57cec5SDimitry Andric // Both, one or none of these variants may be valid, and checks are made
480b57cec5SDimitry Andric // to rule out inapplicable variants.
490b57cec5SDimitry Andric //
500b57cec5SDimitry Andric // As an additional optimization, before either of the two steps above is
510b57cec5SDimitry Andric // executed, the pass attempts to coalesce the target register with one of
520b57cec5SDimitry Andric // the source registers, e.g. given an instruction
530b57cec5SDimitry Andric //   %3 = C2_mux %0, %1, %2
540b57cec5SDimitry Andric // %3 will be coalesced with either %1 or %2. If this succeeds,
550b57cec5SDimitry Andric // the instruction would then be (for example)
560b57cec5SDimitry Andric //   %3 = C2_mux %0, %3, %2
570b57cec5SDimitry Andric // and, under certain circumstances, this could result in only one predicated
580b57cec5SDimitry Andric // instruction:
590b57cec5SDimitry Andric //   %3 = A2_tfrf %0, %2
600b57cec5SDimitry Andric //
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric // Splitting a definition of a register into two predicated transfers
630b57cec5SDimitry Andric // creates a complication in liveness tracking. Live interval computation
640b57cec5SDimitry Andric // will see both instructions as actual definitions, and will mark the
650b57cec5SDimitry Andric // first one as dead. The definition is not actually dead, and this
660b57cec5SDimitry Andric // situation will need to be fixed. For example:
670b57cec5SDimitry Andric //   dead %1 = A2_tfrt ...  ; marked as dead
680b57cec5SDimitry Andric //   %1 = A2_tfrf ...
690b57cec5SDimitry Andric //
700b57cec5SDimitry Andric // Since any of the individual predicated transfers may end up getting
710b57cec5SDimitry Andric // removed (in case it is an identity copy), some pre-existing def may
720b57cec5SDimitry Andric // be marked as dead after live interval recomputation:
730b57cec5SDimitry Andric //   dead %1 = ...          ; marked as dead
740b57cec5SDimitry Andric //   ...
750b57cec5SDimitry Andric //   %1 = A2_tfrf ...       ; if A2_tfrt is removed
760b57cec5SDimitry Andric // This case happens if %1 was used as a source in A2_tfrt, which means
770b57cec5SDimitry Andric // that is it actually live at the A2_tfrf, and so the now dead definition
780b57cec5SDimitry Andric // of %1 will need to be updated to non-dead at some point.
790b57cec5SDimitry Andric //
800b57cec5SDimitry Andric // This issue could be remedied by adding implicit uses to the predicated
810b57cec5SDimitry Andric // transfers, but this will create a problem with subsequent predication,
820b57cec5SDimitry Andric // since the transfers will no longer be possible to reorder. To avoid
830b57cec5SDimitry Andric // that, the initial splitting will not add any implicit uses. These
840b57cec5SDimitry Andric // implicit uses will be added later, after predication. The extra price,
850b57cec5SDimitry Andric // however, is that finding the locations where the implicit uses need
860b57cec5SDimitry Andric // to be added, and updating the live ranges will be more involved.
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric #include "HexagonInstrInfo.h"
890b57cec5SDimitry Andric #include "HexagonRegisterInfo.h"
900b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
910b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
920b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
930b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
940b57cec5SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
950b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
960b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
970b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
980b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
990b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
1000b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
1010b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
1020b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
1030b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
1040b57cec5SDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
1050b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
1060b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
1070b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
1080b57cec5SDimitry Andric #include "llvm/IR/Function.h"
109480093f4SDimitry Andric #include "llvm/InitializePasses.h"
1100b57cec5SDimitry Andric #include "llvm/MC/LaneBitmask.h"
1110b57cec5SDimitry Andric #include "llvm/Pass.h"
1120b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
1130b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
1140b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
1150b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
1160b57cec5SDimitry Andric #include <cassert>
1170b57cec5SDimitry Andric #include <iterator>
1185f757f3fSDimitry Andric #include <map>
1190b57cec5SDimitry Andric #include <set>
1200b57cec5SDimitry Andric #include <utility>
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric #define DEBUG_TYPE "expand-condsets"
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric using namespace llvm;
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric static cl::opt<unsigned> OptTfrLimit("expand-condsets-tfr-limit",
1270b57cec5SDimitry Andric   cl::init(~0U), cl::Hidden, cl::desc("Max number of mux expansions"));
1280b57cec5SDimitry Andric static cl::opt<unsigned> OptCoaLimit("expand-condsets-coa-limit",
1290b57cec5SDimitry Andric   cl::init(~0U), cl::Hidden, cl::desc("Max number of segment coalescings"));
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric namespace llvm {
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   void initializeHexagonExpandCondsetsPass(PassRegistry&);
1340b57cec5SDimitry Andric   FunctionPass *createHexagonExpandCondsets();
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric } // end namespace llvm
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric namespace {
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   class HexagonExpandCondsets : public MachineFunctionPass {
1410b57cec5SDimitry Andric   public:
1420b57cec5SDimitry Andric     static char ID;
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric     HexagonExpandCondsets() : MachineFunctionPass(ID) {
1450b57cec5SDimitry Andric       if (OptCoaLimit.getPosition())
1460b57cec5SDimitry Andric         CoaLimitActive = true, CoaLimit = OptCoaLimit;
1470b57cec5SDimitry Andric       if (OptTfrLimit.getPosition())
1480b57cec5SDimitry Andric         TfrLimitActive = true, TfrLimit = OptTfrLimit;
1490b57cec5SDimitry Andric       initializeHexagonExpandCondsetsPass(*PassRegistry::getPassRegistry());
1500b57cec5SDimitry Andric     }
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric     StringRef getPassName() const override { return "Hexagon Expand Condsets"; }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric     void getAnalysisUsage(AnalysisUsage &AU) const override {
155*0fca6ea1SDimitry Andric       AU.addRequired<LiveIntervalsWrapperPass>();
156*0fca6ea1SDimitry Andric       AU.addPreserved<LiveIntervalsWrapperPass>();
157*0fca6ea1SDimitry Andric       AU.addPreserved<SlotIndexesWrapperPass>();
158*0fca6ea1SDimitry Andric       AU.addRequired<MachineDominatorTreeWrapperPass>();
159*0fca6ea1SDimitry Andric       AU.addPreserved<MachineDominatorTreeWrapperPass>();
1600b57cec5SDimitry Andric       MachineFunctionPass::getAnalysisUsage(AU);
1610b57cec5SDimitry Andric     }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric     bool runOnMachineFunction(MachineFunction &MF) override;
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   private:
1660b57cec5SDimitry Andric     const HexagonInstrInfo *HII = nullptr;
1670b57cec5SDimitry Andric     const TargetRegisterInfo *TRI = nullptr;
1680b57cec5SDimitry Andric     MachineDominatorTree *MDT;
1690b57cec5SDimitry Andric     MachineRegisterInfo *MRI = nullptr;
1700b57cec5SDimitry Andric     LiveIntervals *LIS = nullptr;
1710b57cec5SDimitry Andric     bool CoaLimitActive = false;
1720b57cec5SDimitry Andric     bool TfrLimitActive = false;
1730b57cec5SDimitry Andric     unsigned CoaLimit;
1740b57cec5SDimitry Andric     unsigned TfrLimit;
1750b57cec5SDimitry Andric     unsigned CoaCounter = 0;
1760b57cec5SDimitry Andric     unsigned TfrCounter = 0;
1770b57cec5SDimitry Andric 
178e8d8bef9SDimitry Andric     // FIXME: Consolidate duplicate definitions of RegisterRef
1790b57cec5SDimitry Andric     struct RegisterRef {
1800b57cec5SDimitry Andric       RegisterRef(const MachineOperand &Op) : Reg(Op.getReg()),
1810b57cec5SDimitry Andric           Sub(Op.getSubReg()) {}
1820b57cec5SDimitry Andric       RegisterRef(unsigned R = 0, unsigned S = 0) : Reg(R), Sub(S) {}
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric       bool operator== (RegisterRef RR) const {
1850b57cec5SDimitry Andric         return Reg == RR.Reg && Sub == RR.Sub;
1860b57cec5SDimitry Andric       }
1870b57cec5SDimitry Andric       bool operator!= (RegisterRef RR) const { return !operator==(RR); }
1880b57cec5SDimitry Andric       bool operator< (RegisterRef RR) const {
1890b57cec5SDimitry Andric         return Reg < RR.Reg || (Reg == RR.Reg && Sub < RR.Sub);
1900b57cec5SDimitry Andric       }
1910b57cec5SDimitry Andric 
192e8d8bef9SDimitry Andric       Register Reg;
193e8d8bef9SDimitry Andric       unsigned Sub;
1940b57cec5SDimitry Andric     };
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric     using ReferenceMap = DenseMap<unsigned, unsigned>;
1970b57cec5SDimitry Andric     enum { Sub_Low = 0x1, Sub_High = 0x2, Sub_None = (Sub_Low | Sub_High) };
1980b57cec5SDimitry Andric     enum { Exec_Then = 0x10, Exec_Else = 0x20 };
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric     unsigned getMaskForSub(unsigned Sub);
2010b57cec5SDimitry Andric     bool isCondset(const MachineInstr &MI);
202e8d8bef9SDimitry Andric     LaneBitmask getLaneMask(Register Reg, unsigned Sub);
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric     void addRefToMap(RegisterRef RR, ReferenceMap &Map, unsigned Exec);
2050b57cec5SDimitry Andric     bool isRefInMap(RegisterRef, ReferenceMap &Map, unsigned Exec);
2060b57cec5SDimitry Andric 
207e8d8bef9SDimitry Andric     void updateDeadsInRange(Register Reg, LaneBitmask LM, LiveRange &Range);
208e8d8bef9SDimitry Andric     void updateKillFlags(Register Reg);
209e8d8bef9SDimitry Andric     void updateDeadFlags(Register Reg);
210e8d8bef9SDimitry Andric     void recalculateLiveInterval(Register Reg);
2110b57cec5SDimitry Andric     void removeInstr(MachineInstr &MI);
212bdd1243dSDimitry Andric     void updateLiveness(const std::set<Register> &RegSet, bool Recalc,
2130b57cec5SDimitry Andric                         bool UpdateKills, bool UpdateDeads);
214bdd1243dSDimitry Andric     void distributeLiveIntervals(const std::set<Register> &Regs);
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric     unsigned getCondTfrOpcode(const MachineOperand &SO, bool Cond);
2170b57cec5SDimitry Andric     MachineInstr *genCondTfrFor(MachineOperand &SrcOp,
2180b57cec5SDimitry Andric         MachineBasicBlock::iterator At, unsigned DstR,
2190b57cec5SDimitry Andric         unsigned DstSR, const MachineOperand &PredOp, bool PredSense,
2200b57cec5SDimitry Andric         bool ReadUndef, bool ImpUse);
221e8d8bef9SDimitry Andric     bool split(MachineInstr &MI, std::set<Register> &UpdRegs);
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric     bool isPredicable(MachineInstr *MI);
2240b57cec5SDimitry Andric     MachineInstr *getReachingDefForPred(RegisterRef RD,
2250b57cec5SDimitry Andric         MachineBasicBlock::iterator UseIt, unsigned PredR, bool Cond);
2260b57cec5SDimitry Andric     bool canMoveOver(MachineInstr &MI, ReferenceMap &Defs, ReferenceMap &Uses);
2270b57cec5SDimitry Andric     bool canMoveMemTo(MachineInstr &MI, MachineInstr &ToI, bool IsDown);
2280b57cec5SDimitry Andric     void predicateAt(const MachineOperand &DefOp, MachineInstr &MI,
2290b57cec5SDimitry Andric                      MachineBasicBlock::iterator Where,
2300b57cec5SDimitry Andric                      const MachineOperand &PredOp, bool Cond,
231e8d8bef9SDimitry Andric                      std::set<Register> &UpdRegs);
2320b57cec5SDimitry Andric     void renameInRange(RegisterRef RO, RegisterRef RN, unsigned PredR,
2330b57cec5SDimitry Andric         bool Cond, MachineBasicBlock::iterator First,
2340b57cec5SDimitry Andric         MachineBasicBlock::iterator Last);
235e8d8bef9SDimitry Andric     bool predicate(MachineInstr &TfrI, bool Cond, std::set<Register> &UpdRegs);
236e8d8bef9SDimitry Andric     bool predicateInBlock(MachineBasicBlock &B, std::set<Register> &UpdRegs);
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric     bool isIntReg(RegisterRef RR, unsigned &BW);
2390b57cec5SDimitry Andric     bool isIntraBlocks(LiveInterval &LI);
2400b57cec5SDimitry Andric     bool coalesceRegisters(RegisterRef R1, RegisterRef R2);
2410b57cec5SDimitry Andric     bool coalesceSegments(const SmallVectorImpl<MachineInstr *> &Condsets,
242e8d8bef9SDimitry Andric                           std::set<Register> &UpdRegs);
2430b57cec5SDimitry Andric   };
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric } // end anonymous namespace
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric char HexagonExpandCondsets::ID = 0;
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric namespace llvm {
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   char &HexagonExpandCondsetsID = HexagonExpandCondsets::ID;
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric } // end namespace llvm
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(HexagonExpandCondsets, "expand-condsets",
2560b57cec5SDimitry Andric   "Hexagon Expand Condsets", false, false)
257*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
258*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
259*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
2600b57cec5SDimitry Andric INITIALIZE_PASS_END(HexagonExpandCondsets, "expand-condsets",
2610b57cec5SDimitry Andric   "Hexagon Expand Condsets", false, false)
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric unsigned HexagonExpandCondsets::getMaskForSub(unsigned Sub) {
2640b57cec5SDimitry Andric   switch (Sub) {
2650b57cec5SDimitry Andric     case Hexagon::isub_lo:
2660b57cec5SDimitry Andric     case Hexagon::vsub_lo:
2670b57cec5SDimitry Andric       return Sub_Low;
2680b57cec5SDimitry Andric     case Hexagon::isub_hi:
2690b57cec5SDimitry Andric     case Hexagon::vsub_hi:
2700b57cec5SDimitry Andric       return Sub_High;
2710b57cec5SDimitry Andric     case Hexagon::NoSubRegister:
2720b57cec5SDimitry Andric       return Sub_None;
2730b57cec5SDimitry Andric   }
2740b57cec5SDimitry Andric   llvm_unreachable("Invalid subregister");
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric bool HexagonExpandCondsets::isCondset(const MachineInstr &MI) {
2780b57cec5SDimitry Andric   unsigned Opc = MI.getOpcode();
2790b57cec5SDimitry Andric   switch (Opc) {
2800b57cec5SDimitry Andric     case Hexagon::C2_mux:
2810b57cec5SDimitry Andric     case Hexagon::C2_muxii:
2820b57cec5SDimitry Andric     case Hexagon::C2_muxir:
2830b57cec5SDimitry Andric     case Hexagon::C2_muxri:
2840b57cec5SDimitry Andric     case Hexagon::PS_pselect:
2850b57cec5SDimitry Andric         return true;
2860b57cec5SDimitry Andric       break;
2870b57cec5SDimitry Andric   }
2880b57cec5SDimitry Andric   return false;
2890b57cec5SDimitry Andric }
2900b57cec5SDimitry Andric 
291e8d8bef9SDimitry Andric LaneBitmask HexagonExpandCondsets::getLaneMask(Register Reg, unsigned Sub) {
292e8d8bef9SDimitry Andric   assert(Reg.isVirtual());
2930b57cec5SDimitry Andric   return Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub)
2940b57cec5SDimitry Andric                   : MRI->getMaxLaneMaskForVReg(Reg);
2950b57cec5SDimitry Andric }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric void HexagonExpandCondsets::addRefToMap(RegisterRef RR, ReferenceMap &Map,
2980b57cec5SDimitry Andric       unsigned Exec) {
2990b57cec5SDimitry Andric   unsigned Mask = getMaskForSub(RR.Sub) | Exec;
3000b57cec5SDimitry Andric   ReferenceMap::iterator F = Map.find(RR.Reg);
3010b57cec5SDimitry Andric   if (F == Map.end())
3020b57cec5SDimitry Andric     Map.insert(std::make_pair(RR.Reg, Mask));
3030b57cec5SDimitry Andric   else
3040b57cec5SDimitry Andric     F->second |= Mask;
3050b57cec5SDimitry Andric }
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric bool HexagonExpandCondsets::isRefInMap(RegisterRef RR, ReferenceMap &Map,
3080b57cec5SDimitry Andric       unsigned Exec) {
3090b57cec5SDimitry Andric   ReferenceMap::iterator F = Map.find(RR.Reg);
3100b57cec5SDimitry Andric   if (F == Map.end())
3110b57cec5SDimitry Andric     return false;
3120b57cec5SDimitry Andric   unsigned Mask = getMaskForSub(RR.Sub) | Exec;
3130b57cec5SDimitry Andric   if (Mask & F->second)
3140b57cec5SDimitry Andric     return true;
3150b57cec5SDimitry Andric   return false;
3160b57cec5SDimitry Andric }
3170b57cec5SDimitry Andric 
318e8d8bef9SDimitry Andric void HexagonExpandCondsets::updateKillFlags(Register Reg) {
3190b57cec5SDimitry Andric   auto KillAt = [this,Reg] (SlotIndex K, LaneBitmask LM) -> void {
3200b57cec5SDimitry Andric     // Set the <kill> flag on a use of Reg whose lane mask is contained in LM.
3210b57cec5SDimitry Andric     MachineInstr *MI = LIS->getInstructionFromIndex(K);
3220b57cec5SDimitry Andric     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
3230b57cec5SDimitry Andric       MachineOperand &Op = MI->getOperand(i);
3240b57cec5SDimitry Andric       if (!Op.isReg() || !Op.isUse() || Op.getReg() != Reg ||
3250b57cec5SDimitry Andric           MI->isRegTiedToDefOperand(i))
3260b57cec5SDimitry Andric         continue;
3270b57cec5SDimitry Andric       LaneBitmask SLM = getLaneMask(Reg, Op.getSubReg());
3280b57cec5SDimitry Andric       if ((SLM & LM) == SLM) {
3290b57cec5SDimitry Andric         // Only set the kill flag on the first encountered use of Reg in this
3300b57cec5SDimitry Andric         // instruction.
3310b57cec5SDimitry Andric         Op.setIsKill(true);
3320b57cec5SDimitry Andric         break;
3330b57cec5SDimitry Andric       }
3340b57cec5SDimitry Andric     }
3350b57cec5SDimitry Andric   };
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   LiveInterval &LI = LIS->getInterval(Reg);
3380b57cec5SDimitry Andric   for (auto I = LI.begin(), E = LI.end(); I != E; ++I) {
3390b57cec5SDimitry Andric     if (!I->end.isRegister())
3400b57cec5SDimitry Andric       continue;
3410b57cec5SDimitry Andric     // Do not mark the end of the segment as <kill>, if the next segment
3420b57cec5SDimitry Andric     // starts with a predicated instruction.
3430b57cec5SDimitry Andric     auto NextI = std::next(I);
3440b57cec5SDimitry Andric     if (NextI != E && NextI->start.isRegister()) {
3450b57cec5SDimitry Andric       MachineInstr *DefI = LIS->getInstructionFromIndex(NextI->start);
3460b57cec5SDimitry Andric       if (HII->isPredicated(*DefI))
3470b57cec5SDimitry Andric         continue;
3480b57cec5SDimitry Andric     }
3490b57cec5SDimitry Andric     bool WholeReg = true;
3500b57cec5SDimitry Andric     if (LI.hasSubRanges()) {
3510b57cec5SDimitry Andric       auto EndsAtI = [I] (LiveInterval::SubRange &S) -> bool {
3520b57cec5SDimitry Andric         LiveRange::iterator F = S.find(I->end);
3530b57cec5SDimitry Andric         return F != S.end() && I->end == F->end;
3540b57cec5SDimitry Andric       };
3550b57cec5SDimitry Andric       // Check if all subranges end at I->end. If so, make sure to kill
3560b57cec5SDimitry Andric       // the whole register.
3570b57cec5SDimitry Andric       for (LiveInterval::SubRange &S : LI.subranges()) {
3580b57cec5SDimitry Andric         if (EndsAtI(S))
3590b57cec5SDimitry Andric           KillAt(I->end, S.LaneMask);
3600b57cec5SDimitry Andric         else
3610b57cec5SDimitry Andric           WholeReg = false;
3620b57cec5SDimitry Andric       }
3630b57cec5SDimitry Andric     }
3640b57cec5SDimitry Andric     if (WholeReg)
3650b57cec5SDimitry Andric       KillAt(I->end, MRI->getMaxLaneMaskForVReg(Reg));
3660b57cec5SDimitry Andric   }
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric 
369e8d8bef9SDimitry Andric void HexagonExpandCondsets::updateDeadsInRange(Register Reg, LaneBitmask LM,
3700b57cec5SDimitry Andric                                                LiveRange &Range) {
371e8d8bef9SDimitry Andric   assert(Reg.isVirtual());
3720b57cec5SDimitry Andric   if (Range.empty())
3730b57cec5SDimitry Andric     return;
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   // Return two booleans: { def-modifes-reg, def-covers-reg }.
3760b57cec5SDimitry Andric   auto IsRegDef = [this,Reg,LM] (MachineOperand &Op) -> std::pair<bool,bool> {
3770b57cec5SDimitry Andric     if (!Op.isReg() || !Op.isDef())
3780b57cec5SDimitry Andric       return { false, false };
3798bcb0991SDimitry Andric     Register DR = Op.getReg(), DSR = Op.getSubReg();
380e8d8bef9SDimitry Andric     if (!DR.isVirtual() || DR != Reg)
3810b57cec5SDimitry Andric       return { false, false };
3820b57cec5SDimitry Andric     LaneBitmask SLM = getLaneMask(DR, DSR);
3830b57cec5SDimitry Andric     LaneBitmask A = SLM & LM;
3840b57cec5SDimitry Andric     return { A.any(), A == SLM };
3850b57cec5SDimitry Andric   };
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric   // The splitting step will create pairs of predicated definitions without
3880b57cec5SDimitry Andric   // any implicit uses (since implicit uses would interfere with predication).
3890b57cec5SDimitry Andric   // This can cause the reaching defs to become dead after live range
3900b57cec5SDimitry Andric   // recomputation, even though they are not really dead.
3910b57cec5SDimitry Andric   // We need to identify predicated defs that need implicit uses, and
3920b57cec5SDimitry Andric   // dead defs that are not really dead, and correct both problems.
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric   auto Dominate = [this] (SetVector<MachineBasicBlock*> &Defs,
3950b57cec5SDimitry Andric                           MachineBasicBlock *Dest) -> bool {
396bdd1243dSDimitry Andric     for (MachineBasicBlock *D : Defs) {
3970b57cec5SDimitry Andric       if (D != Dest && MDT->dominates(D, Dest))
3980b57cec5SDimitry Andric         return true;
399bdd1243dSDimitry Andric     }
4000b57cec5SDimitry Andric     MachineBasicBlock *Entry = &Dest->getParent()->front();
4010b57cec5SDimitry Andric     SetVector<MachineBasicBlock*> Work(Dest->pred_begin(), Dest->pred_end());
4020b57cec5SDimitry Andric     for (unsigned i = 0; i < Work.size(); ++i) {
4030b57cec5SDimitry Andric       MachineBasicBlock *B = Work[i];
4040b57cec5SDimitry Andric       if (Defs.count(B))
4050b57cec5SDimitry Andric         continue;
4060b57cec5SDimitry Andric       if (B == Entry)
4070b57cec5SDimitry Andric         return false;
4080b57cec5SDimitry Andric       for (auto *P : B->predecessors())
4090b57cec5SDimitry Andric         Work.insert(P);
4100b57cec5SDimitry Andric     }
4110b57cec5SDimitry Andric     return true;
4120b57cec5SDimitry Andric   };
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   // First, try to extend live range within individual basic blocks. This
4150b57cec5SDimitry Andric   // will leave us only with dead defs that do not reach any predicated
4160b57cec5SDimitry Andric   // defs in the same block.
4170b57cec5SDimitry Andric   SetVector<MachineBasicBlock*> Defs;
4180b57cec5SDimitry Andric   SmallVector<SlotIndex,4> PredDefs;
4190b57cec5SDimitry Andric   for (auto &Seg : Range) {
4200b57cec5SDimitry Andric     if (!Seg.start.isRegister())
4210b57cec5SDimitry Andric       continue;
4220b57cec5SDimitry Andric     MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start);
4230b57cec5SDimitry Andric     Defs.insert(DefI->getParent());
4240b57cec5SDimitry Andric     if (HII->isPredicated(*DefI))
4250b57cec5SDimitry Andric       PredDefs.push_back(Seg.start);
4260b57cec5SDimitry Andric   }
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric   SmallVector<SlotIndex,8> Undefs;
4290b57cec5SDimitry Andric   LiveInterval &LI = LIS->getInterval(Reg);
4300b57cec5SDimitry Andric   LI.computeSubRangeUndefs(Undefs, LM, *MRI, *LIS->getSlotIndexes());
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   for (auto &SI : PredDefs) {
4330b57cec5SDimitry Andric     MachineBasicBlock *BB = LIS->getMBBFromIndex(SI);
4340b57cec5SDimitry Andric     auto P = Range.extendInBlock(Undefs, LIS->getMBBStartIdx(BB), SI);
4350b57cec5SDimitry Andric     if (P.first != nullptr || P.second)
4360b57cec5SDimitry Andric       SI = SlotIndex();
4370b57cec5SDimitry Andric   }
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric   // Calculate reachability for those predicated defs that were not handled
4400b57cec5SDimitry Andric   // by the in-block extension.
4410b57cec5SDimitry Andric   SmallVector<SlotIndex,4> ExtTo;
4420b57cec5SDimitry Andric   for (auto &SI : PredDefs) {
4430b57cec5SDimitry Andric     if (!SI.isValid())
4440b57cec5SDimitry Andric       continue;
4450b57cec5SDimitry Andric     MachineBasicBlock *BB = LIS->getMBBFromIndex(SI);
4460b57cec5SDimitry Andric     if (BB->pred_empty())
4470b57cec5SDimitry Andric       continue;
4480b57cec5SDimitry Andric     // If the defs from this range reach SI via all predecessors, it is live.
4490b57cec5SDimitry Andric     // It can happen that SI is reached by the defs through some paths, but
4500b57cec5SDimitry Andric     // not all. In the IR coming into this optimization, SI would not be
4510b57cec5SDimitry Andric     // considered live, since the defs would then not jointly dominate SI.
4520b57cec5SDimitry Andric     // That means that SI is an overwriting def, and no implicit use is
4530b57cec5SDimitry Andric     // needed at this point. Do not add SI to the extension points, since
4540b57cec5SDimitry Andric     // extendToIndices will abort if there is no joint dominance.
4550b57cec5SDimitry Andric     // If the abort was avoided by adding extra undefs added to Undefs,
4560b57cec5SDimitry Andric     // extendToIndices could actually indicate that SI is live, contrary
4570b57cec5SDimitry Andric     // to the original IR.
4580b57cec5SDimitry Andric     if (Dominate(Defs, BB))
4590b57cec5SDimitry Andric       ExtTo.push_back(SI);
4600b57cec5SDimitry Andric   }
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric   if (!ExtTo.empty())
4630b57cec5SDimitry Andric     LIS->extendToIndices(Range, ExtTo, Undefs);
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   // Remove <dead> flags from all defs that are not dead after live range
4660b57cec5SDimitry Andric   // extension, and collect all def operands. They will be used to generate
4670b57cec5SDimitry Andric   // the necessary implicit uses.
4680b57cec5SDimitry Andric   // At the same time, add <dead> flag to all defs that are actually dead.
4690b57cec5SDimitry Andric   // This can happen, for example, when a mux with identical inputs is
4700b57cec5SDimitry Andric   // replaced with a COPY: the use of the predicate register disappears and
4710b57cec5SDimitry Andric   // the dead can become dead.
4720b57cec5SDimitry Andric   std::set<RegisterRef> DefRegs;
4730b57cec5SDimitry Andric   for (auto &Seg : Range) {
4740b57cec5SDimitry Andric     if (!Seg.start.isRegister())
4750b57cec5SDimitry Andric       continue;
4760b57cec5SDimitry Andric     MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start);
4770b57cec5SDimitry Andric     for (auto &Op : DefI->operands()) {
4780b57cec5SDimitry Andric       auto P = IsRegDef(Op);
4790b57cec5SDimitry Andric       if (P.second && Seg.end.isDead()) {
4800b57cec5SDimitry Andric         Op.setIsDead(true);
4810b57cec5SDimitry Andric       } else if (P.first) {
4820b57cec5SDimitry Andric         DefRegs.insert(Op);
4830b57cec5SDimitry Andric         Op.setIsDead(false);
4840b57cec5SDimitry Andric       }
4850b57cec5SDimitry Andric     }
4860b57cec5SDimitry Andric   }
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   // Now, add implicit uses to each predicated def that is reached
4890b57cec5SDimitry Andric   // by other defs.
4900b57cec5SDimitry Andric   for (auto &Seg : Range) {
4910b57cec5SDimitry Andric     if (!Seg.start.isRegister() || !Range.liveAt(Seg.start.getPrevSlot()))
4920b57cec5SDimitry Andric       continue;
4930b57cec5SDimitry Andric     MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start);
4940b57cec5SDimitry Andric     if (!HII->isPredicated(*DefI))
4950b57cec5SDimitry Andric       continue;
4960b57cec5SDimitry Andric     // Construct the set of all necessary implicit uses, based on the def
4970b57cec5SDimitry Andric     // operands in the instruction. We need to tie the implicit uses to
4980b57cec5SDimitry Andric     // the corresponding defs.
4990b57cec5SDimitry Andric     std::map<RegisterRef,unsigned> ImpUses;
5000b57cec5SDimitry Andric     for (unsigned i = 0, e = DefI->getNumOperands(); i != e; ++i) {
5010b57cec5SDimitry Andric       MachineOperand &Op = DefI->getOperand(i);
5020b57cec5SDimitry Andric       if (!Op.isReg() || !DefRegs.count(Op))
5030b57cec5SDimitry Andric         continue;
5040b57cec5SDimitry Andric       if (Op.isDef()) {
5050b57cec5SDimitry Andric         // Tied defs will always have corresponding uses, so no extra
5060b57cec5SDimitry Andric         // implicit uses are needed.
5070b57cec5SDimitry Andric         if (!Op.isTied())
5080b57cec5SDimitry Andric           ImpUses.insert({Op, i});
5090b57cec5SDimitry Andric       } else {
5100b57cec5SDimitry Andric         // This function can be called for the same register with different
5110b57cec5SDimitry Andric         // lane masks. If the def in this instruction was for the whole
5120b57cec5SDimitry Andric         // register, we can get here more than once. Avoid adding multiple
5130b57cec5SDimitry Andric         // implicit uses (or adding an implicit use when an explicit one is
5140b57cec5SDimitry Andric         // present).
5150b57cec5SDimitry Andric         if (Op.isTied())
5160b57cec5SDimitry Andric           ImpUses.erase(Op);
5170b57cec5SDimitry Andric       }
5180b57cec5SDimitry Andric     }
5190b57cec5SDimitry Andric     if (ImpUses.empty())
5200b57cec5SDimitry Andric       continue;
5210b57cec5SDimitry Andric     MachineFunction &MF = *DefI->getParent()->getParent();
522bdd1243dSDimitry Andric     for (auto [R, DefIdx] : ImpUses) {
5230b57cec5SDimitry Andric       MachineInstrBuilder(MF, DefI).addReg(R.Reg, RegState::Implicit, R.Sub);
524bdd1243dSDimitry Andric       DefI->tieOperands(DefIdx, DefI->getNumOperands()-1);
5250b57cec5SDimitry Andric     }
5260b57cec5SDimitry Andric   }
5270b57cec5SDimitry Andric }
5280b57cec5SDimitry Andric 
529e8d8bef9SDimitry Andric void HexagonExpandCondsets::updateDeadFlags(Register Reg) {
5300b57cec5SDimitry Andric   LiveInterval &LI = LIS->getInterval(Reg);
5310b57cec5SDimitry Andric   if (LI.hasSubRanges()) {
5320b57cec5SDimitry Andric     for (LiveInterval::SubRange &S : LI.subranges()) {
5330b57cec5SDimitry Andric       updateDeadsInRange(Reg, S.LaneMask, S);
5340b57cec5SDimitry Andric       LIS->shrinkToUses(S, Reg);
5350b57cec5SDimitry Andric     }
5360b57cec5SDimitry Andric     LI.clear();
5370b57cec5SDimitry Andric     LIS->constructMainRangeFromSubranges(LI);
5380b57cec5SDimitry Andric   } else {
5390b57cec5SDimitry Andric     updateDeadsInRange(Reg, MRI->getMaxLaneMaskForVReg(Reg), LI);
5400b57cec5SDimitry Andric   }
5410b57cec5SDimitry Andric }
5420b57cec5SDimitry Andric 
543e8d8bef9SDimitry Andric void HexagonExpandCondsets::recalculateLiveInterval(Register Reg) {
5440b57cec5SDimitry Andric   LIS->removeInterval(Reg);
5450b57cec5SDimitry Andric   LIS->createAndComputeVirtRegInterval(Reg);
5460b57cec5SDimitry Andric }
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric void HexagonExpandCondsets::removeInstr(MachineInstr &MI) {
5490b57cec5SDimitry Andric   LIS->RemoveMachineInstrFromMaps(MI);
5500b57cec5SDimitry Andric   MI.eraseFromParent();
5510b57cec5SDimitry Andric }
5520b57cec5SDimitry Andric 
553bdd1243dSDimitry Andric void HexagonExpandCondsets::updateLiveness(const std::set<Register> &RegSet,
554e8d8bef9SDimitry Andric                                            bool Recalc, bool UpdateKills,
555e8d8bef9SDimitry Andric                                            bool UpdateDeads) {
5560b57cec5SDimitry Andric   UpdateKills |= UpdateDeads;
557e8d8bef9SDimitry Andric   for (Register R : RegSet) {
558e8d8bef9SDimitry Andric     if (!R.isVirtual()) {
559e8d8bef9SDimitry Andric       assert(R.isPhysical());
5600b57cec5SDimitry Andric       // There shouldn't be any physical registers as operands, except
5610b57cec5SDimitry Andric       // possibly reserved registers.
5620b57cec5SDimitry Andric       assert(MRI->isReserved(R));
5630b57cec5SDimitry Andric       continue;
5640b57cec5SDimitry Andric     }
5650b57cec5SDimitry Andric     if (Recalc)
5660b57cec5SDimitry Andric       recalculateLiveInterval(R);
5670b57cec5SDimitry Andric     if (UpdateKills)
5680b57cec5SDimitry Andric       MRI->clearKillFlags(R);
5690b57cec5SDimitry Andric     if (UpdateDeads)
5700b57cec5SDimitry Andric       updateDeadFlags(R);
5710b57cec5SDimitry Andric     // Fixing <dead> flags may extend live ranges, so reset <kill> flags
5720b57cec5SDimitry Andric     // after that.
5730b57cec5SDimitry Andric     if (UpdateKills)
5740b57cec5SDimitry Andric       updateKillFlags(R);
5750b57cec5SDimitry Andric     LIS->getInterval(R).verify();
5760b57cec5SDimitry Andric   }
5770b57cec5SDimitry Andric }
5780b57cec5SDimitry Andric 
579bdd1243dSDimitry Andric void HexagonExpandCondsets::distributeLiveIntervals(
580bdd1243dSDimitry Andric     const std::set<Register> &Regs) {
581bdd1243dSDimitry Andric   ConnectedVNInfoEqClasses EQC(*LIS);
582bdd1243dSDimitry Andric   for (Register R : Regs) {
583bdd1243dSDimitry Andric     if (!R.isVirtual())
584bdd1243dSDimitry Andric       continue;
585bdd1243dSDimitry Andric     LiveInterval &LI = LIS->getInterval(R);
586bdd1243dSDimitry Andric     unsigned NumComp = EQC.Classify(LI);
587bdd1243dSDimitry Andric     if (NumComp == 1)
588bdd1243dSDimitry Andric       continue;
589bdd1243dSDimitry Andric 
590bdd1243dSDimitry Andric     SmallVector<LiveInterval*> NewLIs;
591bdd1243dSDimitry Andric     const TargetRegisterClass *RC = MRI->getRegClass(LI.reg());
592bdd1243dSDimitry Andric     for (unsigned I = 1; I < NumComp; ++I) {
593bdd1243dSDimitry Andric       Register NewR = MRI->createVirtualRegister(RC);
594bdd1243dSDimitry Andric       NewLIs.push_back(&LIS->createEmptyInterval(NewR));
595bdd1243dSDimitry Andric     }
596bdd1243dSDimitry Andric     EQC.Distribute(LI, NewLIs.begin(), *MRI);
597bdd1243dSDimitry Andric   }
598bdd1243dSDimitry Andric }
599bdd1243dSDimitry Andric 
6000b57cec5SDimitry Andric /// Get the opcode for a conditional transfer of the value in SO (source
6010b57cec5SDimitry Andric /// operand). The condition (true/false) is given in Cond.
6020b57cec5SDimitry Andric unsigned HexagonExpandCondsets::getCondTfrOpcode(const MachineOperand &SO,
6030b57cec5SDimitry Andric       bool IfTrue) {
6040b57cec5SDimitry Andric   if (SO.isReg()) {
605e8d8bef9SDimitry Andric     MCRegister PhysR;
6060b57cec5SDimitry Andric     RegisterRef RS = SO;
607e8d8bef9SDimitry Andric     if (RS.Reg.isVirtual()) {
6080b57cec5SDimitry Andric       const TargetRegisterClass *VC = MRI->getRegClass(RS.Reg);
6090b57cec5SDimitry Andric       assert(VC->begin() != VC->end() && "Empty register class");
6100b57cec5SDimitry Andric       PhysR = *VC->begin();
6110b57cec5SDimitry Andric     } else {
6120b57cec5SDimitry Andric       PhysR = RS.Reg;
6130b57cec5SDimitry Andric     }
614e8d8bef9SDimitry Andric     MCRegister PhysS = (RS.Sub == 0) ? PhysR : TRI->getSubReg(PhysR, RS.Sub);
6150b57cec5SDimitry Andric     const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysS);
6160b57cec5SDimitry Andric     switch (TRI->getRegSizeInBits(*RC)) {
6170b57cec5SDimitry Andric       case 32:
618bdd1243dSDimitry Andric         return IfTrue ? Hexagon::A2_tfrt : Hexagon::A2_tfrf;
6190b57cec5SDimitry Andric       case 64:
620bdd1243dSDimitry Andric         return IfTrue ? Hexagon::A2_tfrpt : Hexagon::A2_tfrpf;
6210b57cec5SDimitry Andric     }
6220b57cec5SDimitry Andric     llvm_unreachable("Invalid register operand");
6230b57cec5SDimitry Andric   }
6240b57cec5SDimitry Andric   switch (SO.getType()) {
6250b57cec5SDimitry Andric     case MachineOperand::MO_Immediate:
6260b57cec5SDimitry Andric     case MachineOperand::MO_FPImmediate:
6270b57cec5SDimitry Andric     case MachineOperand::MO_ConstantPoolIndex:
6280b57cec5SDimitry Andric     case MachineOperand::MO_TargetIndex:
6290b57cec5SDimitry Andric     case MachineOperand::MO_JumpTableIndex:
6300b57cec5SDimitry Andric     case MachineOperand::MO_ExternalSymbol:
6310b57cec5SDimitry Andric     case MachineOperand::MO_GlobalAddress:
6320b57cec5SDimitry Andric     case MachineOperand::MO_BlockAddress:
633bdd1243dSDimitry Andric       return IfTrue ? Hexagon::C2_cmoveit : Hexagon::C2_cmoveif;
6340b57cec5SDimitry Andric     default:
6350b57cec5SDimitry Andric       break;
6360b57cec5SDimitry Andric   }
6370b57cec5SDimitry Andric   llvm_unreachable("Unexpected source operand");
6380b57cec5SDimitry Andric }
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric /// Generate a conditional transfer, copying the value SrcOp to the
6410b57cec5SDimitry Andric /// destination register DstR:DstSR, and using the predicate register from
6420b57cec5SDimitry Andric /// PredOp. The Cond argument specifies whether the predicate is to be
6430b57cec5SDimitry Andric /// if(PredOp), or if(!PredOp).
6440b57cec5SDimitry Andric MachineInstr *HexagonExpandCondsets::genCondTfrFor(MachineOperand &SrcOp,
6450b57cec5SDimitry Andric       MachineBasicBlock::iterator At,
6460b57cec5SDimitry Andric       unsigned DstR, unsigned DstSR, const MachineOperand &PredOp,
6470b57cec5SDimitry Andric       bool PredSense, bool ReadUndef, bool ImpUse) {
6480b57cec5SDimitry Andric   MachineInstr *MI = SrcOp.getParent();
6490b57cec5SDimitry Andric   MachineBasicBlock &B = *At->getParent();
6500b57cec5SDimitry Andric   const DebugLoc &DL = MI->getDebugLoc();
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric   // Don't avoid identity copies here (i.e. if the source and the destination
6530b57cec5SDimitry Andric   // are the same registers). It is actually better to generate them here,
6540b57cec5SDimitry Andric   // since this would cause the copy to potentially be predicated in the next
6550b57cec5SDimitry Andric   // step. The predication will remove such a copy if it is unable to
6560b57cec5SDimitry Andric   /// predicate.
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   unsigned Opc = getCondTfrOpcode(SrcOp, PredSense);
6590b57cec5SDimitry Andric   unsigned DstState = RegState::Define | (ReadUndef ? RegState::Undef : 0);
6600b57cec5SDimitry Andric   unsigned PredState = getRegState(PredOp) & ~RegState::Kill;
6610b57cec5SDimitry Andric   MachineInstrBuilder MIB;
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric   if (SrcOp.isReg()) {
6640b57cec5SDimitry Andric     unsigned SrcState = getRegState(SrcOp);
6650b57cec5SDimitry Andric     if (RegisterRef(SrcOp) == RegisterRef(DstR, DstSR))
6660b57cec5SDimitry Andric       SrcState &= ~RegState::Kill;
6670b57cec5SDimitry Andric     MIB = BuildMI(B, At, DL, HII->get(Opc))
6680b57cec5SDimitry Andric             .addReg(DstR, DstState, DstSR)
6690b57cec5SDimitry Andric             .addReg(PredOp.getReg(), PredState, PredOp.getSubReg())
6700b57cec5SDimitry Andric             .addReg(SrcOp.getReg(), SrcState, SrcOp.getSubReg());
6710b57cec5SDimitry Andric   } else {
6720b57cec5SDimitry Andric     MIB = BuildMI(B, At, DL, HII->get(Opc))
6730b57cec5SDimitry Andric             .addReg(DstR, DstState, DstSR)
6740b57cec5SDimitry Andric             .addReg(PredOp.getReg(), PredState, PredOp.getSubReg())
6750b57cec5SDimitry Andric             .add(SrcOp);
6760b57cec5SDimitry Andric   }
6770b57cec5SDimitry Andric 
6780b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "created an initial copy: " << *MIB);
6790b57cec5SDimitry Andric   return &*MIB;
6800b57cec5SDimitry Andric }
6810b57cec5SDimitry Andric 
6820b57cec5SDimitry Andric /// Replace a MUX instruction MI with a pair A2_tfrt/A2_tfrf. This function
6830b57cec5SDimitry Andric /// performs all necessary changes to complete the replacement.
6840b57cec5SDimitry Andric bool HexagonExpandCondsets::split(MachineInstr &MI,
685e8d8bef9SDimitry Andric                                   std::set<Register> &UpdRegs) {
6860b57cec5SDimitry Andric   if (TfrLimitActive) {
6870b57cec5SDimitry Andric     if (TfrCounter >= TfrLimit)
6880b57cec5SDimitry Andric       return false;
6890b57cec5SDimitry Andric     TfrCounter++;
6900b57cec5SDimitry Andric   }
6910b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\nsplitting " << printMBBReference(*MI.getParent())
6920b57cec5SDimitry Andric                     << ": " << MI);
6930b57cec5SDimitry Andric   MachineOperand &MD = MI.getOperand(0);  // Definition
6940b57cec5SDimitry Andric   MachineOperand &MP = MI.getOperand(1);  // Predicate register
6950b57cec5SDimitry Andric   assert(MD.isDef());
6968bcb0991SDimitry Andric   Register DR = MD.getReg(), DSR = MD.getSubReg();
6970b57cec5SDimitry Andric   bool ReadUndef = MD.isUndef();
6980b57cec5SDimitry Andric   MachineBasicBlock::iterator At = MI;
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   auto updateRegs = [&UpdRegs] (const MachineInstr &MI) -> void {
701bdd1243dSDimitry Andric     for (auto &Op : MI.operands()) {
7020b57cec5SDimitry Andric       if (Op.isReg())
7030b57cec5SDimitry Andric         UpdRegs.insert(Op.getReg());
704bdd1243dSDimitry Andric     }
7050b57cec5SDimitry Andric   };
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric   // If this is a mux of the same register, just replace it with COPY.
7080b57cec5SDimitry Andric   // Ideally, this would happen earlier, so that register coalescing would
7090b57cec5SDimitry Andric   // see it.
7100b57cec5SDimitry Andric   MachineOperand &ST = MI.getOperand(2);
7110b57cec5SDimitry Andric   MachineOperand &SF = MI.getOperand(3);
7120b57cec5SDimitry Andric   if (ST.isReg() && SF.isReg()) {
7130b57cec5SDimitry Andric     RegisterRef RT(ST);
7140b57cec5SDimitry Andric     if (RT == RegisterRef(SF)) {
7150b57cec5SDimitry Andric       // Copy regs to update first.
7160b57cec5SDimitry Andric       updateRegs(MI);
7170b57cec5SDimitry Andric       MI.setDesc(HII->get(TargetOpcode::COPY));
7180b57cec5SDimitry Andric       unsigned S = getRegState(ST);
7190b57cec5SDimitry Andric       while (MI.getNumOperands() > 1)
72081ad6265SDimitry Andric         MI.removeOperand(MI.getNumOperands()-1);
7210b57cec5SDimitry Andric       MachineFunction &MF = *MI.getParent()->getParent();
7220b57cec5SDimitry Andric       MachineInstrBuilder(MF, MI).addReg(RT.Reg, S, RT.Sub);
7230b57cec5SDimitry Andric       return true;
7240b57cec5SDimitry Andric     }
7250b57cec5SDimitry Andric   }
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric   // First, create the two invididual conditional transfers, and add each
7280b57cec5SDimitry Andric   // of them to the live intervals information. Do that first and then remove
7290b57cec5SDimitry Andric   // the old instruction from live intervals.
7300b57cec5SDimitry Andric   MachineInstr *TfrT =
7310b57cec5SDimitry Andric       genCondTfrFor(ST, At, DR, DSR, MP, true, ReadUndef, false);
7320b57cec5SDimitry Andric   MachineInstr *TfrF =
7330b57cec5SDimitry Andric       genCondTfrFor(SF, At, DR, DSR, MP, false, ReadUndef, true);
7340b57cec5SDimitry Andric   LIS->InsertMachineInstrInMaps(*TfrT);
7350b57cec5SDimitry Andric   LIS->InsertMachineInstrInMaps(*TfrF);
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric   // Will need to recalculate live intervals for all registers in MI.
7380b57cec5SDimitry Andric   updateRegs(MI);
7390b57cec5SDimitry Andric 
7400b57cec5SDimitry Andric   removeInstr(MI);
7410b57cec5SDimitry Andric   return true;
7420b57cec5SDimitry Andric }
7430b57cec5SDimitry Andric 
7440b57cec5SDimitry Andric bool HexagonExpandCondsets::isPredicable(MachineInstr *MI) {
7450b57cec5SDimitry Andric   if (HII->isPredicated(*MI) || !HII->isPredicable(*MI))
7460b57cec5SDimitry Andric     return false;
7470b57cec5SDimitry Andric   if (MI->hasUnmodeledSideEffects() || MI->mayStore())
7480b57cec5SDimitry Andric     return false;
7490b57cec5SDimitry Andric   // Reject instructions with multiple defs (e.g. post-increment loads).
7500b57cec5SDimitry Andric   bool HasDef = false;
7510b57cec5SDimitry Andric   for (auto &Op : MI->operands()) {
7520b57cec5SDimitry Andric     if (!Op.isReg() || !Op.isDef())
7530b57cec5SDimitry Andric       continue;
7540b57cec5SDimitry Andric     if (HasDef)
7550b57cec5SDimitry Andric       return false;
7560b57cec5SDimitry Andric     HasDef = true;
7570b57cec5SDimitry Andric   }
758bdd1243dSDimitry Andric   for (auto &Mo : MI->memoperands()) {
7590b57cec5SDimitry Andric     if (Mo->isVolatile() || Mo->isAtomic())
7600b57cec5SDimitry Andric       return false;
761bdd1243dSDimitry Andric   }
7620b57cec5SDimitry Andric   return true;
7630b57cec5SDimitry Andric }
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric /// Find the reaching definition for a predicated use of RD. The RD is used
7660b57cec5SDimitry Andric /// under the conditions given by PredR and Cond, and this function will ignore
7670b57cec5SDimitry Andric /// definitions that set RD under the opposite conditions.
7680b57cec5SDimitry Andric MachineInstr *HexagonExpandCondsets::getReachingDefForPred(RegisterRef RD,
7690b57cec5SDimitry Andric       MachineBasicBlock::iterator UseIt, unsigned PredR, bool Cond) {
7700b57cec5SDimitry Andric   MachineBasicBlock &B = *UseIt->getParent();
7710b57cec5SDimitry Andric   MachineBasicBlock::iterator I = UseIt, S = B.begin();
7720b57cec5SDimitry Andric   if (I == S)
7730b57cec5SDimitry Andric     return nullptr;
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric   bool PredValid = true;
7760b57cec5SDimitry Andric   do {
7770b57cec5SDimitry Andric     --I;
7780b57cec5SDimitry Andric     MachineInstr *MI = &*I;
7790b57cec5SDimitry Andric     // Check if this instruction can be ignored, i.e. if it is predicated
7800b57cec5SDimitry Andric     // on the complementary condition.
7810b57cec5SDimitry Andric     if (PredValid && HII->isPredicated(*MI)) {
782*0fca6ea1SDimitry Andric       if (MI->readsRegister(PredR, /*TRI=*/nullptr) &&
783*0fca6ea1SDimitry Andric           (Cond != HII->isPredicatedTrue(*MI)))
7840b57cec5SDimitry Andric         continue;
7850b57cec5SDimitry Andric     }
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric     // Check the defs. If the PredR is defined, invalidate it. If RD is
7880b57cec5SDimitry Andric     // defined, return the instruction or 0, depending on the circumstances.
7890b57cec5SDimitry Andric     for (auto &Op : MI->operands()) {
7900b57cec5SDimitry Andric       if (!Op.isReg() || !Op.isDef())
7910b57cec5SDimitry Andric         continue;
7920b57cec5SDimitry Andric       RegisterRef RR = Op;
7930b57cec5SDimitry Andric       if (RR.Reg == PredR) {
7940b57cec5SDimitry Andric         PredValid = false;
7950b57cec5SDimitry Andric         continue;
7960b57cec5SDimitry Andric       }
7970b57cec5SDimitry Andric       if (RR.Reg != RD.Reg)
7980b57cec5SDimitry Andric         continue;
7990b57cec5SDimitry Andric       // If the "Reg" part agrees, there is still the subregister to check.
8000b57cec5SDimitry Andric       // If we are looking for %1:loreg, we can skip %1:hireg, but
8010b57cec5SDimitry Andric       // not %1 (w/o subregisters).
8020b57cec5SDimitry Andric       if (RR.Sub == RD.Sub)
8030b57cec5SDimitry Andric         return MI;
8040b57cec5SDimitry Andric       if (RR.Sub == 0 || RD.Sub == 0)
8050b57cec5SDimitry Andric         return nullptr;
8060b57cec5SDimitry Andric       // We have different subregisters, so we can continue looking.
8070b57cec5SDimitry Andric     }
8080b57cec5SDimitry Andric   } while (I != S);
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric   return nullptr;
8110b57cec5SDimitry Andric }
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric /// Check if the instruction MI can be safely moved over a set of instructions
8140b57cec5SDimitry Andric /// whose side-effects (in terms of register defs and uses) are expressed in
8150b57cec5SDimitry Andric /// the maps Defs and Uses. These maps reflect the conditional defs and uses
8160b57cec5SDimitry Andric /// that depend on the same predicate register to allow moving instructions
8170b57cec5SDimitry Andric /// over instructions predicated on the opposite condition.
8180b57cec5SDimitry Andric bool HexagonExpandCondsets::canMoveOver(MachineInstr &MI, ReferenceMap &Defs,
8190b57cec5SDimitry Andric                                         ReferenceMap &Uses) {
8200b57cec5SDimitry Andric   // In order to be able to safely move MI over instructions that define
8210b57cec5SDimitry Andric   // "Defs" and use "Uses", no def operand from MI can be defined or used
8220b57cec5SDimitry Andric   // and no use operand can be defined.
8230b57cec5SDimitry Andric   for (auto &Op : MI.operands()) {
8240b57cec5SDimitry Andric     if (!Op.isReg())
8250b57cec5SDimitry Andric       continue;
8260b57cec5SDimitry Andric     RegisterRef RR = Op;
8270b57cec5SDimitry Andric     // For physical register we would need to check register aliases, etc.
8280b57cec5SDimitry Andric     // and we don't want to bother with that. It would be of little value
8290b57cec5SDimitry Andric     // before the actual register rewriting (from virtual to physical).
830e8d8bef9SDimitry Andric     if (!RR.Reg.isVirtual())
8310b57cec5SDimitry Andric       return false;
8320b57cec5SDimitry Andric     // No redefs for any operand.
8330b57cec5SDimitry Andric     if (isRefInMap(RR, Defs, Exec_Then))
8340b57cec5SDimitry Andric       return false;
8350b57cec5SDimitry Andric     // For defs, there cannot be uses.
8360b57cec5SDimitry Andric     if (Op.isDef() && isRefInMap(RR, Uses, Exec_Then))
8370b57cec5SDimitry Andric       return false;
8380b57cec5SDimitry Andric   }
8390b57cec5SDimitry Andric   return true;
8400b57cec5SDimitry Andric }
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric /// Check if the instruction accessing memory (TheI) can be moved to the
8430b57cec5SDimitry Andric /// location ToI.
8440b57cec5SDimitry Andric bool HexagonExpandCondsets::canMoveMemTo(MachineInstr &TheI, MachineInstr &ToI,
8450b57cec5SDimitry Andric                                          bool IsDown) {
8460b57cec5SDimitry Andric   bool IsLoad = TheI.mayLoad(), IsStore = TheI.mayStore();
8470b57cec5SDimitry Andric   if (!IsLoad && !IsStore)
8480b57cec5SDimitry Andric     return true;
8490b57cec5SDimitry Andric   if (HII->areMemAccessesTriviallyDisjoint(TheI, ToI))
8500b57cec5SDimitry Andric     return true;
8510b57cec5SDimitry Andric   if (TheI.hasUnmodeledSideEffects())
8520b57cec5SDimitry Andric     return false;
8530b57cec5SDimitry Andric 
8540b57cec5SDimitry Andric   MachineBasicBlock::iterator StartI = IsDown ? TheI : ToI;
8550b57cec5SDimitry Andric   MachineBasicBlock::iterator EndI = IsDown ? ToI : TheI;
8560b57cec5SDimitry Andric   bool Ordered = TheI.hasOrderedMemoryRef();
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric   // Search for aliased memory reference in (StartI, EndI).
859bdd1243dSDimitry Andric   for (MachineInstr &MI : llvm::make_range(std::next(StartI), EndI)) {
860bdd1243dSDimitry Andric     if (MI.hasUnmodeledSideEffects())
8610b57cec5SDimitry Andric       return false;
862bdd1243dSDimitry Andric     bool L = MI.mayLoad(), S = MI.mayStore();
8630b57cec5SDimitry Andric     if (!L && !S)
8640b57cec5SDimitry Andric       continue;
865bdd1243dSDimitry Andric     if (Ordered && MI.hasOrderedMemoryRef())
8660b57cec5SDimitry Andric       return false;
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric     bool Conflict = (L && IsStore) || S;
8690b57cec5SDimitry Andric     if (Conflict)
8700b57cec5SDimitry Andric       return false;
8710b57cec5SDimitry Andric   }
8720b57cec5SDimitry Andric   return true;
8730b57cec5SDimitry Andric }
8740b57cec5SDimitry Andric 
8750b57cec5SDimitry Andric /// Generate a predicated version of MI (where the condition is given via
8760b57cec5SDimitry Andric /// PredR and Cond) at the point indicated by Where.
8770b57cec5SDimitry Andric void HexagonExpandCondsets::predicateAt(const MachineOperand &DefOp,
8780b57cec5SDimitry Andric                                         MachineInstr &MI,
8790b57cec5SDimitry Andric                                         MachineBasicBlock::iterator Where,
8800b57cec5SDimitry Andric                                         const MachineOperand &PredOp, bool Cond,
881e8d8bef9SDimitry Andric                                         std::set<Register> &UpdRegs) {
8820b57cec5SDimitry Andric   // The problem with updating live intervals is that we can move one def
8830b57cec5SDimitry Andric   // past another def. In particular, this can happen when moving an A2_tfrt
8840b57cec5SDimitry Andric   // over an A2_tfrf defining the same register. From the point of view of
8850b57cec5SDimitry Andric   // live intervals, these two instructions are two separate definitions,
8860b57cec5SDimitry Andric   // and each one starts another live segment. LiveIntervals's "handleMove"
8870b57cec5SDimitry Andric   // does not allow such moves, so we need to handle it ourselves. To avoid
8880b57cec5SDimitry Andric   // invalidating liveness data while we are using it, the move will be
8890b57cec5SDimitry Andric   // implemented in 4 steps: (1) add a clone of the instruction MI at the
8900b57cec5SDimitry Andric   // target location, (2) update liveness, (3) delete the old instruction,
8910b57cec5SDimitry Andric   // and (4) update liveness again.
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   MachineBasicBlock &B = *MI.getParent();
8940b57cec5SDimitry Andric   DebugLoc DL = Where->getDebugLoc();  // "Where" points to an instruction.
8950b57cec5SDimitry Andric   unsigned Opc = MI.getOpcode();
8960b57cec5SDimitry Andric   unsigned PredOpc = HII->getCondOpcode(Opc, !Cond);
8970b57cec5SDimitry Andric   MachineInstrBuilder MB = BuildMI(B, Where, DL, HII->get(PredOpc));
8980b57cec5SDimitry Andric   unsigned Ox = 0, NP = MI.getNumOperands();
8990b57cec5SDimitry Andric   // Skip all defs from MI first.
9000b57cec5SDimitry Andric   while (Ox < NP) {
9010b57cec5SDimitry Andric     MachineOperand &MO = MI.getOperand(Ox);
9020b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef())
9030b57cec5SDimitry Andric       break;
9040b57cec5SDimitry Andric     Ox++;
9050b57cec5SDimitry Andric   }
9060b57cec5SDimitry Andric   // Add the new def, then the predicate register, then the rest of the
9070b57cec5SDimitry Andric   // operands.
9080b57cec5SDimitry Andric   MB.addReg(DefOp.getReg(), getRegState(DefOp), DefOp.getSubReg());
9090b57cec5SDimitry Andric   MB.addReg(PredOp.getReg(), PredOp.isUndef() ? RegState::Undef : 0,
9100b57cec5SDimitry Andric             PredOp.getSubReg());
9110b57cec5SDimitry Andric   while (Ox < NP) {
9120b57cec5SDimitry Andric     MachineOperand &MO = MI.getOperand(Ox);
9130b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isImplicit())
9140b57cec5SDimitry Andric       MB.add(MO);
9150b57cec5SDimitry Andric     Ox++;
9160b57cec5SDimitry Andric   }
9170b57cec5SDimitry Andric   MB.cloneMemRefs(MI);
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric   MachineInstr *NewI = MB;
9200b57cec5SDimitry Andric   NewI->clearKillInfo();
9210b57cec5SDimitry Andric   LIS->InsertMachineInstrInMaps(*NewI);
9220b57cec5SDimitry Andric 
923bdd1243dSDimitry Andric   for (auto &Op : NewI->operands()) {
9240b57cec5SDimitry Andric     if (Op.isReg())
9250b57cec5SDimitry Andric       UpdRegs.insert(Op.getReg());
9260b57cec5SDimitry Andric   }
927bdd1243dSDimitry Andric }
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric /// In the range [First, Last], rename all references to the "old" register RO
9300b57cec5SDimitry Andric /// to the "new" register RN, but only in instructions predicated on the given
9310b57cec5SDimitry Andric /// condition.
9320b57cec5SDimitry Andric void HexagonExpandCondsets::renameInRange(RegisterRef RO, RegisterRef RN,
9330b57cec5SDimitry Andric       unsigned PredR, bool Cond, MachineBasicBlock::iterator First,
9340b57cec5SDimitry Andric       MachineBasicBlock::iterator Last) {
9350b57cec5SDimitry Andric   MachineBasicBlock::iterator End = std::next(Last);
936bdd1243dSDimitry Andric   for (MachineInstr &MI : llvm::make_range(First, End)) {
9370b57cec5SDimitry Andric     // Do not touch instructions that are not predicated, or are predicated
9380b57cec5SDimitry Andric     // on the opposite condition.
939bdd1243dSDimitry Andric     if (!HII->isPredicated(MI))
9400b57cec5SDimitry Andric       continue;
941*0fca6ea1SDimitry Andric     if (!MI.readsRegister(PredR, /*TRI=*/nullptr) ||
942*0fca6ea1SDimitry Andric         (Cond != HII->isPredicatedTrue(MI)))
9430b57cec5SDimitry Andric       continue;
9440b57cec5SDimitry Andric 
945bdd1243dSDimitry Andric     for (auto &Op : MI.operands()) {
9460b57cec5SDimitry Andric       if (!Op.isReg() || RO != RegisterRef(Op))
9470b57cec5SDimitry Andric         continue;
9480b57cec5SDimitry Andric       Op.setReg(RN.Reg);
9490b57cec5SDimitry Andric       Op.setSubReg(RN.Sub);
9500b57cec5SDimitry Andric       // In practice, this isn't supposed to see any defs.
9510b57cec5SDimitry Andric       assert(!Op.isDef() && "Not expecting a def");
9520b57cec5SDimitry Andric     }
9530b57cec5SDimitry Andric   }
9540b57cec5SDimitry Andric }
9550b57cec5SDimitry Andric 
9560b57cec5SDimitry Andric /// For a given conditional copy, predicate the definition of the source of
9570b57cec5SDimitry Andric /// the copy under the given condition (using the same predicate register as
9580b57cec5SDimitry Andric /// the copy).
9590b57cec5SDimitry Andric bool HexagonExpandCondsets::predicate(MachineInstr &TfrI, bool Cond,
960e8d8bef9SDimitry Andric                                       std::set<Register> &UpdRegs) {
9610b57cec5SDimitry Andric   // TfrI - A2_tfr[tf] Instruction (not A2_tfrsi).
9620b57cec5SDimitry Andric   unsigned Opc = TfrI.getOpcode();
9630b57cec5SDimitry Andric   (void)Opc;
9640b57cec5SDimitry Andric   assert(Opc == Hexagon::A2_tfrt || Opc == Hexagon::A2_tfrf);
9650b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\nattempt to predicate if-" << (Cond ? "true" : "false")
9660b57cec5SDimitry Andric                     << ": " << TfrI);
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric   MachineOperand &MD = TfrI.getOperand(0);
9690b57cec5SDimitry Andric   MachineOperand &MP = TfrI.getOperand(1);
9700b57cec5SDimitry Andric   MachineOperand &MS = TfrI.getOperand(2);
9710b57cec5SDimitry Andric   // The source operand should be a <kill>. This is not strictly necessary,
9720b57cec5SDimitry Andric   // but it makes things a lot simpler. Otherwise, we would need to rename
9730b57cec5SDimitry Andric   // some registers, which would complicate the transformation considerably.
9740b57cec5SDimitry Andric   if (!MS.isKill())
9750b57cec5SDimitry Andric     return false;
9760b57cec5SDimitry Andric   // Avoid predicating instructions that define a subregister if subregister
9770b57cec5SDimitry Andric   // liveness tracking is not enabled.
9780b57cec5SDimitry Andric   if (MD.getSubReg() && !MRI->shouldTrackSubRegLiveness(MD.getReg()))
9790b57cec5SDimitry Andric     return false;
9800b57cec5SDimitry Andric 
9810b57cec5SDimitry Andric   RegisterRef RT(MS);
9828bcb0991SDimitry Andric   Register PredR = MP.getReg();
9830b57cec5SDimitry Andric   MachineInstr *DefI = getReachingDefForPred(RT, TfrI, PredR, Cond);
9840b57cec5SDimitry Andric   if (!DefI || !isPredicable(DefI))
9850b57cec5SDimitry Andric     return false;
9860b57cec5SDimitry Andric 
9870b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Source def: " << *DefI);
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric   // Collect the information about registers defined and used between the
9900b57cec5SDimitry Andric   // DefI and the TfrI.
9910b57cec5SDimitry Andric   // Map: reg -> bitmask of subregs
9920b57cec5SDimitry Andric   ReferenceMap Uses, Defs;
9930b57cec5SDimitry Andric   MachineBasicBlock::iterator DefIt = DefI, TfrIt = TfrI;
9940b57cec5SDimitry Andric 
9950b57cec5SDimitry Andric   // Check if the predicate register is valid between DefI and TfrI.
9960b57cec5SDimitry Andric   // If it is, we can then ignore instructions predicated on the negated
9970b57cec5SDimitry Andric   // conditions when collecting def and use information.
9980b57cec5SDimitry Andric   bool PredValid = true;
999bdd1243dSDimitry Andric   for (MachineInstr &MI : llvm::make_range(std::next(DefIt), TfrIt)) {
1000bdd1243dSDimitry Andric     if (!MI.modifiesRegister(PredR, nullptr))
10010b57cec5SDimitry Andric       continue;
10020b57cec5SDimitry Andric     PredValid = false;
10030b57cec5SDimitry Andric     break;
10040b57cec5SDimitry Andric   }
10050b57cec5SDimitry Andric 
1006bdd1243dSDimitry Andric   for (MachineInstr &MI : llvm::make_range(std::next(DefIt), TfrIt)) {
10070b57cec5SDimitry Andric     // If this instruction is predicated on the same register, it could
10080b57cec5SDimitry Andric     // potentially be ignored.
10090b57cec5SDimitry Andric     // By default assume that the instruction executes on the same condition
10100b57cec5SDimitry Andric     // as TfrI (Exec_Then), and also on the opposite one (Exec_Else).
10110b57cec5SDimitry Andric     unsigned Exec = Exec_Then | Exec_Else;
1012*0fca6ea1SDimitry Andric     if (PredValid && HII->isPredicated(MI) &&
1013*0fca6ea1SDimitry Andric         MI.readsRegister(PredR, /*TRI=*/nullptr))
1014bdd1243dSDimitry Andric       Exec = (Cond == HII->isPredicatedTrue(MI)) ? Exec_Then : Exec_Else;
10150b57cec5SDimitry Andric 
1016bdd1243dSDimitry Andric     for (auto &Op : MI.operands()) {
10170b57cec5SDimitry Andric       if (!Op.isReg())
10180b57cec5SDimitry Andric         continue;
10190b57cec5SDimitry Andric       // We don't want to deal with physical registers. The reason is that
10200b57cec5SDimitry Andric       // they can be aliased with other physical registers. Aliased virtual
10210b57cec5SDimitry Andric       // registers must share the same register number, and can only differ
10220b57cec5SDimitry Andric       // in the subregisters, which we are keeping track of. Physical
10230b57cec5SDimitry Andric       // registers ters no longer have subregisters---their super- and
10240b57cec5SDimitry Andric       // subregisters are other physical registers, and we are not checking
10250b57cec5SDimitry Andric       // that.
10260b57cec5SDimitry Andric       RegisterRef RR = Op;
1027e8d8bef9SDimitry Andric       if (!RR.Reg.isVirtual())
10280b57cec5SDimitry Andric         return false;
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric       ReferenceMap &Map = Op.isDef() ? Defs : Uses;
10310b57cec5SDimitry Andric       if (Op.isDef() && Op.isUndef()) {
10320b57cec5SDimitry Andric         assert(RR.Sub && "Expecting a subregister on <def,read-undef>");
10330b57cec5SDimitry Andric         // If this is a <def,read-undef>, then it invalidates the non-written
10340b57cec5SDimitry Andric         // part of the register. For the purpose of checking the validity of
10350b57cec5SDimitry Andric         // the move, assume that it modifies the whole register.
10360b57cec5SDimitry Andric         RR.Sub = 0;
10370b57cec5SDimitry Andric       }
10380b57cec5SDimitry Andric       addRefToMap(RR, Map, Exec);
10390b57cec5SDimitry Andric     }
10400b57cec5SDimitry Andric   }
10410b57cec5SDimitry Andric 
10420b57cec5SDimitry Andric   // The situation:
10430b57cec5SDimitry Andric   //   RT = DefI
10440b57cec5SDimitry Andric   //   ...
10450b57cec5SDimitry Andric   //   RD = TfrI ..., RT
10460b57cec5SDimitry Andric 
10470b57cec5SDimitry Andric   // If the register-in-the-middle (RT) is used or redefined between
10480b57cec5SDimitry Andric   // DefI and TfrI, we may not be able proceed with this transformation.
10490b57cec5SDimitry Andric   // We can ignore a def that will not execute together with TfrI, and a
10500b57cec5SDimitry Andric   // use that will. If there is such a use (that does execute together with
10510b57cec5SDimitry Andric   // TfrI), we will not be able to move DefI down. If there is a use that
10520b57cec5SDimitry Andric   // executed if TfrI's condition is false, then RT must be available
10530b57cec5SDimitry Andric   // unconditionally (cannot be predicated).
10540b57cec5SDimitry Andric   // Essentially, we need to be able to rename RT to RD in this segment.
10550b57cec5SDimitry Andric   if (isRefInMap(RT, Defs, Exec_Then) || isRefInMap(RT, Uses, Exec_Else))
10560b57cec5SDimitry Andric     return false;
10570b57cec5SDimitry Andric   RegisterRef RD = MD;
10580b57cec5SDimitry Andric   // If the predicate register is defined between DefI and TfrI, the only
10590b57cec5SDimitry Andric   // potential thing to do would be to move the DefI down to TfrI, and then
10600b57cec5SDimitry Andric   // predicate. The reaching def (DefI) must be movable down to the location
10610b57cec5SDimitry Andric   // of the TfrI.
10620b57cec5SDimitry Andric   // If the target register of the TfrI (RD) is not used or defined between
10630b57cec5SDimitry Andric   // DefI and TfrI, consider moving TfrI up to DefI.
10640b57cec5SDimitry Andric   bool CanUp =   canMoveOver(TfrI, Defs, Uses);
10650b57cec5SDimitry Andric   bool CanDown = canMoveOver(*DefI, Defs, Uses);
10660b57cec5SDimitry Andric   // The TfrI does not access memory, but DefI could. Check if it's safe
10670b57cec5SDimitry Andric   // to move DefI down to TfrI.
1068bdd1243dSDimitry Andric   if (DefI->mayLoadOrStore()) {
10690b57cec5SDimitry Andric     if (!canMoveMemTo(*DefI, TfrI, true))
10700b57cec5SDimitry Andric       CanDown = false;
1071bdd1243dSDimitry Andric   }
10720b57cec5SDimitry Andric 
10730b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Can move up: " << (CanUp ? "yes" : "no")
10740b57cec5SDimitry Andric                     << ", can move down: " << (CanDown ? "yes\n" : "no\n"));
10750b57cec5SDimitry Andric   MachineBasicBlock::iterator PastDefIt = std::next(DefIt);
10760b57cec5SDimitry Andric   if (CanUp)
10770b57cec5SDimitry Andric     predicateAt(MD, *DefI, PastDefIt, MP, Cond, UpdRegs);
10780b57cec5SDimitry Andric   else if (CanDown)
10790b57cec5SDimitry Andric     predicateAt(MD, *DefI, TfrIt, MP, Cond, UpdRegs);
10800b57cec5SDimitry Andric   else
10810b57cec5SDimitry Andric     return false;
10820b57cec5SDimitry Andric 
10830b57cec5SDimitry Andric   if (RT != RD) {
10840b57cec5SDimitry Andric     renameInRange(RT, RD, PredR, Cond, PastDefIt, TfrIt);
10850b57cec5SDimitry Andric     UpdRegs.insert(RT.Reg);
10860b57cec5SDimitry Andric   }
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric   removeInstr(TfrI);
10890b57cec5SDimitry Andric   removeInstr(*DefI);
10900b57cec5SDimitry Andric   return true;
10910b57cec5SDimitry Andric }
10920b57cec5SDimitry Andric 
10930b57cec5SDimitry Andric /// Predicate all cases of conditional copies in the specified block.
10940b57cec5SDimitry Andric bool HexagonExpandCondsets::predicateInBlock(MachineBasicBlock &B,
1095e8d8bef9SDimitry Andric                                              std::set<Register> &UpdRegs) {
10960b57cec5SDimitry Andric   bool Changed = false;
1097349cc55cSDimitry Andric   for (MachineInstr &MI : llvm::make_early_inc_range(B)) {
1098349cc55cSDimitry Andric     unsigned Opc = MI.getOpcode();
10990b57cec5SDimitry Andric     if (Opc == Hexagon::A2_tfrt || Opc == Hexagon::A2_tfrf) {
1100349cc55cSDimitry Andric       bool Done = predicate(MI, (Opc == Hexagon::A2_tfrt), UpdRegs);
11010b57cec5SDimitry Andric       if (!Done) {
11020b57cec5SDimitry Andric         // If we didn't predicate I, we may need to remove it in case it is
11030b57cec5SDimitry Andric         // an "identity" copy, e.g.  %1 = A2_tfrt %2, %1.
1104349cc55cSDimitry Andric         if (RegisterRef(MI.getOperand(0)) == RegisterRef(MI.getOperand(2))) {
1105bdd1243dSDimitry Andric           for (auto &Op : MI.operands()) {
11060b57cec5SDimitry Andric             if (Op.isReg())
11070b57cec5SDimitry Andric               UpdRegs.insert(Op.getReg());
1108bdd1243dSDimitry Andric           }
1109349cc55cSDimitry Andric           removeInstr(MI);
11100b57cec5SDimitry Andric         }
11110b57cec5SDimitry Andric       }
11120b57cec5SDimitry Andric       Changed |= Done;
11130b57cec5SDimitry Andric     }
11140b57cec5SDimitry Andric   }
11150b57cec5SDimitry Andric   return Changed;
11160b57cec5SDimitry Andric }
11170b57cec5SDimitry Andric 
11180b57cec5SDimitry Andric bool HexagonExpandCondsets::isIntReg(RegisterRef RR, unsigned &BW) {
1119e8d8bef9SDimitry Andric   if (!RR.Reg.isVirtual())
11200b57cec5SDimitry Andric     return false;
11210b57cec5SDimitry Andric   const TargetRegisterClass *RC = MRI->getRegClass(RR.Reg);
11220b57cec5SDimitry Andric   if (RC == &Hexagon::IntRegsRegClass) {
11230b57cec5SDimitry Andric     BW = 32;
11240b57cec5SDimitry Andric     return true;
11250b57cec5SDimitry Andric   }
11260b57cec5SDimitry Andric   if (RC == &Hexagon::DoubleRegsRegClass) {
11270b57cec5SDimitry Andric     BW = (RR.Sub != 0) ? 32 : 64;
11280b57cec5SDimitry Andric     return true;
11290b57cec5SDimitry Andric   }
11300b57cec5SDimitry Andric   return false;
11310b57cec5SDimitry Andric }
11320b57cec5SDimitry Andric 
11330b57cec5SDimitry Andric bool HexagonExpandCondsets::isIntraBlocks(LiveInterval &LI) {
113404eeddc0SDimitry Andric   for (LiveRange::Segment &LR : LI) {
11350b57cec5SDimitry Andric     // Range must start at a register...
11360b57cec5SDimitry Andric     if (!LR.start.isRegister())
11370b57cec5SDimitry Andric       return false;
11380b57cec5SDimitry Andric     // ...and end in a register or in a dead slot.
11390b57cec5SDimitry Andric     if (!LR.end.isRegister() && !LR.end.isDead())
11400b57cec5SDimitry Andric       return false;
11410b57cec5SDimitry Andric   }
11420b57cec5SDimitry Andric   return true;
11430b57cec5SDimitry Andric }
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric bool HexagonExpandCondsets::coalesceRegisters(RegisterRef R1, RegisterRef R2) {
11460b57cec5SDimitry Andric   if (CoaLimitActive) {
11470b57cec5SDimitry Andric     if (CoaCounter >= CoaLimit)
11480b57cec5SDimitry Andric       return false;
11490b57cec5SDimitry Andric     CoaCounter++;
11500b57cec5SDimitry Andric   }
11510b57cec5SDimitry Andric   unsigned BW1, BW2;
11520b57cec5SDimitry Andric   if (!isIntReg(R1, BW1) || !isIntReg(R2, BW2) || BW1 != BW2)
11530b57cec5SDimitry Andric     return false;
11540b57cec5SDimitry Andric   if (MRI->isLiveIn(R1.Reg))
11550b57cec5SDimitry Andric     return false;
11560b57cec5SDimitry Andric   if (MRI->isLiveIn(R2.Reg))
11570b57cec5SDimitry Andric     return false;
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric   LiveInterval &L1 = LIS->getInterval(R1.Reg);
11600b57cec5SDimitry Andric   LiveInterval &L2 = LIS->getInterval(R2.Reg);
11610b57cec5SDimitry Andric   if (L2.empty())
11620b57cec5SDimitry Andric     return false;
11630b57cec5SDimitry Andric   if (L1.hasSubRanges() || L2.hasSubRanges())
11640b57cec5SDimitry Andric     return false;
11650b57cec5SDimitry Andric   bool Overlap = L1.overlaps(L2);
11660b57cec5SDimitry Andric 
11670b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "compatible registers: ("
11680b57cec5SDimitry Andric                     << (Overlap ? "overlap" : "disjoint") << ")\n  "
11690b57cec5SDimitry Andric                     << printReg(R1.Reg, TRI, R1.Sub) << "  " << L1 << "\n  "
11700b57cec5SDimitry Andric                     << printReg(R2.Reg, TRI, R2.Sub) << "  " << L2 << "\n");
11710b57cec5SDimitry Andric   if (R1.Sub || R2.Sub)
11720b57cec5SDimitry Andric     return false;
11730b57cec5SDimitry Andric   if (Overlap)
11740b57cec5SDimitry Andric     return false;
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric   // Coalescing could have a negative impact on scheduling, so try to limit
11770b57cec5SDimitry Andric   // to some reasonable extent. Only consider coalescing segments, when one
11780b57cec5SDimitry Andric   // of them does not cross basic block boundaries.
11790b57cec5SDimitry Andric   if (!isIntraBlocks(L1) && !isIntraBlocks(L2))
11800b57cec5SDimitry Andric     return false;
11810b57cec5SDimitry Andric 
11820b57cec5SDimitry Andric   MRI->replaceRegWith(R2.Reg, R1.Reg);
11830b57cec5SDimitry Andric 
11840b57cec5SDimitry Andric   // Move all live segments from L2 to L1.
11850b57cec5SDimitry Andric   using ValueInfoMap = DenseMap<VNInfo *, VNInfo *>;
11860b57cec5SDimitry Andric   ValueInfoMap VM;
118704eeddc0SDimitry Andric   for (LiveRange::Segment &I : L2) {
118804eeddc0SDimitry Andric     VNInfo *NewVN, *OldVN = I.valno;
11890b57cec5SDimitry Andric     ValueInfoMap::iterator F = VM.find(OldVN);
11900b57cec5SDimitry Andric     if (F == VM.end()) {
119104eeddc0SDimitry Andric       NewVN = L1.getNextValue(I.valno->def, LIS->getVNInfoAllocator());
11920b57cec5SDimitry Andric       VM.insert(std::make_pair(OldVN, NewVN));
11930b57cec5SDimitry Andric     } else {
11940b57cec5SDimitry Andric       NewVN = F->second;
11950b57cec5SDimitry Andric     }
119604eeddc0SDimitry Andric     L1.addSegment(LiveRange::Segment(I.start, I.end, NewVN));
11970b57cec5SDimitry Andric   }
1198e8d8bef9SDimitry Andric   while (!L2.empty())
11990b57cec5SDimitry Andric     L2.removeSegment(*L2.begin());
12000b57cec5SDimitry Andric   LIS->removeInterval(R2.Reg);
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric   updateKillFlags(R1.Reg);
12030b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "coalesced: " << L1 << "\n");
12040b57cec5SDimitry Andric   L1.verify();
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric   return true;
12070b57cec5SDimitry Andric }
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric /// Attempt to coalesce one of the source registers to a MUX instruction with
12100b57cec5SDimitry Andric /// the destination register. This could lead to having only one predicated
12110b57cec5SDimitry Andric /// instruction in the end instead of two.
12120b57cec5SDimitry Andric bool HexagonExpandCondsets::coalesceSegments(
12130b57cec5SDimitry Andric     const SmallVectorImpl<MachineInstr *> &Condsets,
1214e8d8bef9SDimitry Andric     std::set<Register> &UpdRegs) {
12150b57cec5SDimitry Andric   SmallVector<MachineInstr*,16> TwoRegs;
12160b57cec5SDimitry Andric   for (MachineInstr *MI : Condsets) {
12170b57cec5SDimitry Andric     MachineOperand &S1 = MI->getOperand(2), &S2 = MI->getOperand(3);
12180b57cec5SDimitry Andric     if (!S1.isReg() && !S2.isReg())
12190b57cec5SDimitry Andric       continue;
12200b57cec5SDimitry Andric     TwoRegs.push_back(MI);
12210b57cec5SDimitry Andric   }
12220b57cec5SDimitry Andric 
12230b57cec5SDimitry Andric   bool Changed = false;
12240b57cec5SDimitry Andric   for (MachineInstr *CI : TwoRegs) {
12250b57cec5SDimitry Andric     RegisterRef RD = CI->getOperand(0);
12260b57cec5SDimitry Andric     RegisterRef RP = CI->getOperand(1);
12270b57cec5SDimitry Andric     MachineOperand &S1 = CI->getOperand(2), &S2 = CI->getOperand(3);
12280b57cec5SDimitry Andric     bool Done = false;
12290b57cec5SDimitry Andric     // Consider this case:
12300b57cec5SDimitry Andric     //   %1 = instr1 ...
12310b57cec5SDimitry Andric     //   %2 = instr2 ...
12320b57cec5SDimitry Andric     //   %0 = C2_mux ..., %1, %2
12330b57cec5SDimitry Andric     // If %0 was coalesced with %1, we could end up with the following
12340b57cec5SDimitry Andric     // code:
12350b57cec5SDimitry Andric     //   %0 = instr1 ...
12360b57cec5SDimitry Andric     //   %2 = instr2 ...
12370b57cec5SDimitry Andric     //   %0 = A2_tfrf ..., %2
12380b57cec5SDimitry Andric     // which will later become:
12390b57cec5SDimitry Andric     //   %0 = instr1 ...
12400b57cec5SDimitry Andric     //   %0 = instr2_cNotPt ...
12410b57cec5SDimitry Andric     // i.e. there will be an unconditional definition (instr1) of %0
12420b57cec5SDimitry Andric     // followed by a conditional one. The output dependency was there before
12430b57cec5SDimitry Andric     // and it unavoidable, but if instr1 is predicable, we will no longer be
12440b57cec5SDimitry Andric     // able to predicate it here.
12450b57cec5SDimitry Andric     // To avoid this scenario, don't coalesce the destination register with
12460b57cec5SDimitry Andric     // a source register that is defined by a predicable instruction.
12470b57cec5SDimitry Andric     if (S1.isReg()) {
12480b57cec5SDimitry Andric       RegisterRef RS = S1;
12490b57cec5SDimitry Andric       MachineInstr *RDef = getReachingDefForPred(RS, CI, RP.Reg, true);
12500b57cec5SDimitry Andric       if (!RDef || !HII->isPredicable(*RDef)) {
12510b57cec5SDimitry Andric         Done = coalesceRegisters(RD, RegisterRef(S1));
12520b57cec5SDimitry Andric         if (Done) {
12530b57cec5SDimitry Andric           UpdRegs.insert(RD.Reg);
12540b57cec5SDimitry Andric           UpdRegs.insert(S1.getReg());
12550b57cec5SDimitry Andric         }
12560b57cec5SDimitry Andric       }
12570b57cec5SDimitry Andric     }
12580b57cec5SDimitry Andric     if (!Done && S2.isReg()) {
12590b57cec5SDimitry Andric       RegisterRef RS = S2;
12600b57cec5SDimitry Andric       MachineInstr *RDef = getReachingDefForPred(RS, CI, RP.Reg, false);
12610b57cec5SDimitry Andric       if (!RDef || !HII->isPredicable(*RDef)) {
12620b57cec5SDimitry Andric         Done = coalesceRegisters(RD, RegisterRef(S2));
12630b57cec5SDimitry Andric         if (Done) {
12640b57cec5SDimitry Andric           UpdRegs.insert(RD.Reg);
12650b57cec5SDimitry Andric           UpdRegs.insert(S2.getReg());
12660b57cec5SDimitry Andric         }
12670b57cec5SDimitry Andric       }
12680b57cec5SDimitry Andric     }
12690b57cec5SDimitry Andric     Changed |= Done;
12700b57cec5SDimitry Andric   }
12710b57cec5SDimitry Andric   return Changed;
12720b57cec5SDimitry Andric }
12730b57cec5SDimitry Andric 
12740b57cec5SDimitry Andric bool HexagonExpandCondsets::runOnMachineFunction(MachineFunction &MF) {
12750b57cec5SDimitry Andric   if (skipFunction(MF.getFunction()))
12760b57cec5SDimitry Andric     return false;
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric   HII = static_cast<const HexagonInstrInfo*>(MF.getSubtarget().getInstrInfo());
12790b57cec5SDimitry Andric   TRI = MF.getSubtarget().getRegisterInfo();
1280*0fca6ea1SDimitry Andric   MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1281*0fca6ea1SDimitry Andric   LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
12820b57cec5SDimitry Andric   MRI = &MF.getRegInfo();
12830b57cec5SDimitry Andric 
1284*0fca6ea1SDimitry Andric   LLVM_DEBUG(LIS->print(dbgs() << "Before expand-condsets\n"));
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric   bool Changed = false;
1287e8d8bef9SDimitry Andric   std::set<Register> CoalUpd, PredUpd;
12880b57cec5SDimitry Andric 
12890b57cec5SDimitry Andric   SmallVector<MachineInstr*,16> Condsets;
1290bdd1243dSDimitry Andric   for (auto &B : MF) {
1291bdd1243dSDimitry Andric     for (auto &I : B) {
12920b57cec5SDimitry Andric       if (isCondset(I))
12930b57cec5SDimitry Andric         Condsets.push_back(&I);
1294bdd1243dSDimitry Andric     }
1295bdd1243dSDimitry Andric   }
12960b57cec5SDimitry Andric 
12970b57cec5SDimitry Andric   // Try to coalesce the target of a mux with one of its sources.
12980b57cec5SDimitry Andric   // This could eliminate a register copy in some circumstances.
12990b57cec5SDimitry Andric   Changed |= coalesceSegments(Condsets, CoalUpd);
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric   // Update kill flags on all source operands. This is done here because
13020b57cec5SDimitry Andric   // at this moment (when expand-condsets runs), there are no kill flags
13030b57cec5SDimitry Andric   // in the IR (they have been removed by live range analysis).
13040b57cec5SDimitry Andric   // Updating them right before we split is the easiest, because splitting
13050b57cec5SDimitry Andric   // adds definitions which would interfere with updating kills afterwards.
1306e8d8bef9SDimitry Andric   std::set<Register> KillUpd;
1307bdd1243dSDimitry Andric   for (MachineInstr *MI : Condsets) {
1308bdd1243dSDimitry Andric     for (MachineOperand &Op : MI->operands()) {
1309bdd1243dSDimitry Andric       if (Op.isReg() && Op.isUse()) {
13100b57cec5SDimitry Andric         if (!CoalUpd.count(Op.getReg()))
13110b57cec5SDimitry Andric           KillUpd.insert(Op.getReg());
1312bdd1243dSDimitry Andric       }
1313bdd1243dSDimitry Andric     }
1314bdd1243dSDimitry Andric   }
13150b57cec5SDimitry Andric   updateLiveness(KillUpd, false, true, false);
1316*0fca6ea1SDimitry Andric   LLVM_DEBUG(LIS->print(dbgs() << "After coalescing\n"));
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric   // First, simply split all muxes into a pair of conditional transfers
13190b57cec5SDimitry Andric   // and update the live intervals to reflect the new arrangement. The
13200b57cec5SDimitry Andric   // goal is to update the kill flags, since predication will rely on
13210b57cec5SDimitry Andric   // them.
13220b57cec5SDimitry Andric   for (MachineInstr *MI : Condsets)
13230b57cec5SDimitry Andric     Changed |= split(*MI, PredUpd);
13240b57cec5SDimitry Andric   Condsets.clear(); // The contents of Condsets are invalid here anyway.
13250b57cec5SDimitry Andric 
13260b57cec5SDimitry Andric   // Do not update live ranges after splitting. Recalculation of live
13270b57cec5SDimitry Andric   // intervals removes kill flags, which were preserved by splitting on
13280b57cec5SDimitry Andric   // the source operands of condsets. These kill flags are needed by
13290b57cec5SDimitry Andric   // predication, and after splitting they are difficult to recalculate
13300b57cec5SDimitry Andric   // (because of predicated defs), so make sure they are left untouched.
13310b57cec5SDimitry Andric   // Predication does not use live intervals.
1332*0fca6ea1SDimitry Andric   LLVM_DEBUG(LIS->print(dbgs() << "After splitting\n"));
13330b57cec5SDimitry Andric 
13340b57cec5SDimitry Andric   // Traverse all blocks and collapse predicable instructions feeding
13350b57cec5SDimitry Andric   // conditional transfers into predicated instructions.
13360b57cec5SDimitry Andric   // Walk over all the instructions again, so we may catch pre-existing
13370b57cec5SDimitry Andric   // cases that were not created in the previous step.
13380b57cec5SDimitry Andric   for (auto &B : MF)
13390b57cec5SDimitry Andric     Changed |= predicateInBlock(B, PredUpd);
1340*0fca6ea1SDimitry Andric   LLVM_DEBUG(LIS->print(dbgs() << "After predicating\n"));
13410b57cec5SDimitry Andric 
13420b57cec5SDimitry Andric   PredUpd.insert(CoalUpd.begin(), CoalUpd.end());
13430b57cec5SDimitry Andric   updateLiveness(PredUpd, true, true, true);
13440b57cec5SDimitry Andric 
1345bdd1243dSDimitry Andric   if (Changed)
1346bdd1243dSDimitry Andric     distributeLiveIntervals(PredUpd);
1347bdd1243dSDimitry Andric 
13480b57cec5SDimitry Andric   LLVM_DEBUG({
13490b57cec5SDimitry Andric     if (Changed)
1350*0fca6ea1SDimitry Andric       LIS->print(dbgs() << "After expand-condsets\n");
13510b57cec5SDimitry Andric   });
13520b57cec5SDimitry Andric 
13530b57cec5SDimitry Andric   return Changed;
13540b57cec5SDimitry Andric }
13550b57cec5SDimitry Andric 
13560b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13570b57cec5SDimitry Andric //                         Public Constructor Functions
13580b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13590b57cec5SDimitry Andric FunctionPass *llvm::createHexagonExpandCondsets() {
13600b57cec5SDimitry Andric   return new HexagonExpandCondsets();
13610b57cec5SDimitry Andric }
1362