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