HexagonGenPredicate.cpp revision 341825
1327952Sdim//===- HexagonGenPredicate.cpp --------------------------------------------===// 2286425Sdim// 3286425Sdim// The LLVM Compiler Infrastructure 4286425Sdim// 5286425Sdim// This file is distributed under the University of Illinois Open Source 6286425Sdim// License. See LICENSE.TXT for details. 7286425Sdim// 8286425Sdim//===----------------------------------------------------------------------===// 9286425Sdim 10314564Sdim#include "HexagonInstrInfo.h" 11314564Sdim#include "HexagonSubtarget.h" 12286425Sdim#include "llvm/ADT/SetVector.h" 13314564Sdim#include "llvm/ADT/StringRef.h" 14314564Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 15286425Sdim#include "llvm/CodeGen/MachineDominators.h" 16314564Sdim#include "llvm/CodeGen/MachineFunction.h" 17286425Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 18314564Sdim#include "llvm/CodeGen/MachineInstr.h" 19286425Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 20314564Sdim#include "llvm/CodeGen/MachineOperand.h" 21286425Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 22327952Sdim#include "llvm/CodeGen/TargetRegisterInfo.h" 23314564Sdim#include "llvm/IR/DebugLoc.h" 24314564Sdim#include "llvm/Pass.h" 25314564Sdim#include "llvm/Support/Compiler.h" 26286425Sdim#include "llvm/Support/Debug.h" 27314564Sdim#include "llvm/Support/ErrorHandling.h" 28286425Sdim#include "llvm/Support/raw_ostream.h" 29314564Sdim#include <cassert> 30314564Sdim#include <iterator> 31314564Sdim#include <map> 32286425Sdim#include <queue> 33286425Sdim#include <set> 34314564Sdim#include <utility> 35286425Sdim 36321369Sdim#define DEBUG_TYPE "gen-pred" 37321369Sdim 38286425Sdimusing namespace llvm; 39286425Sdim 40286425Sdimnamespace llvm { 41314564Sdim 42286425Sdim void initializeHexagonGenPredicatePass(PassRegistry& Registry); 43286425Sdim FunctionPass *createHexagonGenPredicate(); 44286425Sdim 45314564Sdim} // end namespace llvm 46314564Sdim 47286425Sdimnamespace { 48314564Sdim 49286425Sdim struct Register { 50286425Sdim unsigned R, S; 51314564Sdim 52286425Sdim Register(unsigned r = 0, unsigned s = 0) : R(r), S(s) {} 53286425Sdim Register(const MachineOperand &MO) : R(MO.getReg()), S(MO.getSubReg()) {} 54314564Sdim 55286425Sdim bool operator== (const Register &Reg) const { 56286425Sdim return R == Reg.R && S == Reg.S; 57286425Sdim } 58314564Sdim 59286425Sdim bool operator< (const Register &Reg) const { 60286425Sdim return R < Reg.R || (R == Reg.R && S < Reg.S); 61286425Sdim } 62286425Sdim }; 63314564Sdim 64286425Sdim struct PrintRegister { 65314564Sdim friend raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &PR); 66314564Sdim 67286425Sdim PrintRegister(Register R, const TargetRegisterInfo &I) : Reg(R), TRI(I) {} 68314564Sdim 69286425Sdim private: 70286425Sdim Register Reg; 71286425Sdim const TargetRegisterInfo &TRI; 72286425Sdim }; 73314564Sdim 74286425Sdim raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &PR) 75286425Sdim LLVM_ATTRIBUTE_UNUSED; 76286425Sdim raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &PR) { 77327952Sdim return OS << printReg(PR.Reg.R, &PR.TRI, PR.Reg.S); 78286425Sdim } 79286425Sdim 80286425Sdim class HexagonGenPredicate : public MachineFunctionPass { 81286425Sdim public: 82286425Sdim static char ID; 83314564Sdim 84327952Sdim HexagonGenPredicate() : MachineFunctionPass(ID) { 85286425Sdim initializeHexagonGenPredicatePass(*PassRegistry::getPassRegistry()); 86286425Sdim } 87314564Sdim 88314564Sdim StringRef getPassName() const override { 89286425Sdim return "Hexagon generate predicate operations"; 90286425Sdim } 91314564Sdim 92314564Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 93286425Sdim AU.addRequired<MachineDominatorTree>(); 94286425Sdim AU.addPreserved<MachineDominatorTree>(); 95286425Sdim MachineFunctionPass::getAnalysisUsage(AU); 96286425Sdim } 97286425Sdim 98314564Sdim bool runOnMachineFunction(MachineFunction &MF) override; 99314564Sdim 100286425Sdim private: 101327952Sdim using VectOfInst = SetVector<MachineInstr *>; 102327952Sdim using SetOfReg = std::set<Register>; 103327952Sdim using RegToRegMap = std::map<Register, Register>; 104286425Sdim 105327952Sdim const HexagonInstrInfo *TII = nullptr; 106327952Sdim const HexagonRegisterInfo *TRI = nullptr; 107327952Sdim MachineRegisterInfo *MRI = nullptr; 108286425Sdim SetOfReg PredGPRs; 109286425Sdim VectOfInst PUsers; 110286425Sdim RegToRegMap G2P; 111286425Sdim 112286425Sdim bool isPredReg(unsigned R); 113286425Sdim void collectPredicateGPR(MachineFunction &MF); 114286425Sdim void processPredicateGPR(const Register &Reg); 115286425Sdim unsigned getPredForm(unsigned Opc); 116286425Sdim bool isConvertibleToPredForm(const MachineInstr *MI); 117286425Sdim bool isScalarCmp(unsigned Opc); 118286425Sdim bool isScalarPred(Register PredReg); 119286425Sdim Register getPredRegFor(const Register &Reg); 120286425Sdim bool convertToPredForm(MachineInstr *MI); 121286425Sdim bool eliminatePredCopies(MachineFunction &MF); 122286425Sdim }; 123286425Sdim 124314564Sdim} // end anonymous namespace 125314564Sdim 126327952Sdimchar HexagonGenPredicate::ID = 0; 127327952Sdim 128286425SdimINITIALIZE_PASS_BEGIN(HexagonGenPredicate, "hexagon-gen-pred", 129286425Sdim "Hexagon generate predicate operations", false, false) 130286425SdimINITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 131286425SdimINITIALIZE_PASS_END(HexagonGenPredicate, "hexagon-gen-pred", 132286425Sdim "Hexagon generate predicate operations", false, false) 133286425Sdim 134286425Sdimbool HexagonGenPredicate::isPredReg(unsigned R) { 135286425Sdim if (!TargetRegisterInfo::isVirtualRegister(R)) 136286425Sdim return false; 137286425Sdim const TargetRegisterClass *RC = MRI->getRegClass(R); 138286425Sdim return RC == &Hexagon::PredRegsRegClass; 139286425Sdim} 140286425Sdim 141286425Sdimunsigned HexagonGenPredicate::getPredForm(unsigned Opc) { 142286425Sdim using namespace Hexagon; 143286425Sdim 144286425Sdim switch (Opc) { 145286425Sdim case A2_and: 146286425Sdim case A2_andp: 147286425Sdim return C2_and; 148286425Sdim case A4_andn: 149286425Sdim case A4_andnp: 150286425Sdim return C2_andn; 151286425Sdim case M4_and_and: 152286425Sdim return C4_and_and; 153286425Sdim case M4_and_andn: 154286425Sdim return C4_and_andn; 155286425Sdim case M4_and_or: 156286425Sdim return C4_and_or; 157286425Sdim 158286425Sdim case A2_or: 159286425Sdim case A2_orp: 160286425Sdim return C2_or; 161286425Sdim case A4_orn: 162286425Sdim case A4_ornp: 163286425Sdim return C2_orn; 164286425Sdim case M4_or_and: 165286425Sdim return C4_or_and; 166286425Sdim case M4_or_andn: 167286425Sdim return C4_or_andn; 168286425Sdim case M4_or_or: 169286425Sdim return C4_or_or; 170286425Sdim 171286425Sdim case A2_xor: 172286425Sdim case A2_xorp: 173286425Sdim return C2_xor; 174286425Sdim 175286425Sdim case C2_tfrrp: 176286425Sdim return COPY; 177286425Sdim } 178286425Sdim // The opcode corresponding to 0 is TargetOpcode::PHI. We can use 0 here 179286425Sdim // to denote "none", but we need to make sure that none of the valid opcodes 180286425Sdim // that we return will ever be 0. 181309124Sdim static_assert(PHI == 0, "Use different value for <none>"); 182286425Sdim return 0; 183286425Sdim} 184286425Sdim 185286425Sdimbool HexagonGenPredicate::isConvertibleToPredForm(const MachineInstr *MI) { 186286425Sdim unsigned Opc = MI->getOpcode(); 187286425Sdim if (getPredForm(Opc) != 0) 188286425Sdim return true; 189286425Sdim 190286425Sdim // Comparisons against 0 are also convertible. This does not apply to 191286425Sdim // A4_rcmpeqi or A4_rcmpneqi, since they produce values 0 or 1, which 192286425Sdim // may not match the value that the predicate register would have if 193286425Sdim // it was converted to a predicate form. 194286425Sdim switch (Opc) { 195286425Sdim case Hexagon::C2_cmpeqi: 196286425Sdim case Hexagon::C4_cmpneqi: 197286425Sdim if (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) 198286425Sdim return true; 199286425Sdim break; 200286425Sdim } 201286425Sdim return false; 202286425Sdim} 203286425Sdim 204286425Sdimvoid HexagonGenPredicate::collectPredicateGPR(MachineFunction &MF) { 205286425Sdim for (MachineFunction::iterator A = MF.begin(), Z = MF.end(); A != Z; ++A) { 206286425Sdim MachineBasicBlock &B = *A; 207286425Sdim for (MachineBasicBlock::iterator I = B.begin(), E = B.end(); I != E; ++I) { 208286425Sdim MachineInstr *MI = &*I; 209286425Sdim unsigned Opc = MI->getOpcode(); 210286425Sdim switch (Opc) { 211286425Sdim case Hexagon::C2_tfrpr: 212286425Sdim case TargetOpcode::COPY: 213286425Sdim if (isPredReg(MI->getOperand(1).getReg())) { 214286425Sdim Register RD = MI->getOperand(0); 215286425Sdim if (TargetRegisterInfo::isVirtualRegister(RD.R)) 216286425Sdim PredGPRs.insert(RD); 217286425Sdim } 218286425Sdim break; 219286425Sdim } 220286425Sdim } 221286425Sdim } 222286425Sdim} 223286425Sdim 224286425Sdimvoid HexagonGenPredicate::processPredicateGPR(const Register &Reg) { 225341825Sdim LLVM_DEBUG(dbgs() << __func__ << ": " << printReg(Reg.R, TRI, Reg.S) << "\n"); 226327952Sdim using use_iterator = MachineRegisterInfo::use_iterator; 227327952Sdim 228286425Sdim use_iterator I = MRI->use_begin(Reg.R), E = MRI->use_end(); 229286425Sdim if (I == E) { 230341825Sdim LLVM_DEBUG(dbgs() << "Dead reg: " << printReg(Reg.R, TRI, Reg.S) << '\n'); 231286425Sdim MachineInstr *DefI = MRI->getVRegDef(Reg.R); 232286425Sdim DefI->eraseFromParent(); 233286425Sdim return; 234286425Sdim } 235286425Sdim 236286425Sdim for (; I != E; ++I) { 237286425Sdim MachineInstr *UseI = I->getParent(); 238286425Sdim if (isConvertibleToPredForm(UseI)) 239286425Sdim PUsers.insert(UseI); 240286425Sdim } 241286425Sdim} 242286425Sdim 243286425SdimRegister HexagonGenPredicate::getPredRegFor(const Register &Reg) { 244286425Sdim // Create a predicate register for a given Reg. The newly created register 245286425Sdim // will have its value copied from Reg, so that it can be later used as 246286425Sdim // an operand in other instructions. 247286425Sdim assert(TargetRegisterInfo::isVirtualRegister(Reg.R)); 248286425Sdim RegToRegMap::iterator F = G2P.find(Reg); 249286425Sdim if (F != G2P.end()) 250286425Sdim return F->second; 251286425Sdim 252341825Sdim LLVM_DEBUG(dbgs() << __func__ << ": " << PrintRegister(Reg, *TRI)); 253286425Sdim MachineInstr *DefI = MRI->getVRegDef(Reg.R); 254286425Sdim assert(DefI); 255286425Sdim unsigned Opc = DefI->getOpcode(); 256286425Sdim if (Opc == Hexagon::C2_tfrpr || Opc == TargetOpcode::COPY) { 257286425Sdim assert(DefI->getOperand(0).isDef() && DefI->getOperand(1).isUse()); 258286425Sdim Register PR = DefI->getOperand(1); 259286425Sdim G2P.insert(std::make_pair(Reg, PR)); 260341825Sdim LLVM_DEBUG(dbgs() << " -> " << PrintRegister(PR, *TRI) << '\n'); 261286425Sdim return PR; 262286425Sdim } 263286425Sdim 264286425Sdim MachineBasicBlock &B = *DefI->getParent(); 265286425Sdim DebugLoc DL = DefI->getDebugLoc(); 266286425Sdim const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass; 267286425Sdim unsigned NewPR = MRI->createVirtualRegister(PredRC); 268286425Sdim 269286425Sdim // For convertible instructions, do not modify them, so that they can 270296417Sdim // be converted later. Generate a copy from Reg to NewPR. 271286425Sdim if (isConvertibleToPredForm(DefI)) { 272286425Sdim MachineBasicBlock::iterator DefIt = DefI; 273286425Sdim BuildMI(B, std::next(DefIt), DL, TII->get(TargetOpcode::COPY), NewPR) 274286425Sdim .addReg(Reg.R, 0, Reg.S); 275286425Sdim G2P.insert(std::make_pair(Reg, Register(NewPR))); 276341825Sdim LLVM_DEBUG(dbgs() << " -> !" << PrintRegister(Register(NewPR), *TRI) 277341825Sdim << '\n'); 278286425Sdim return Register(NewPR); 279286425Sdim } 280286425Sdim 281286425Sdim llvm_unreachable("Invalid argument"); 282286425Sdim} 283286425Sdim 284286425Sdimbool HexagonGenPredicate::isScalarCmp(unsigned Opc) { 285286425Sdim switch (Opc) { 286286425Sdim case Hexagon::C2_cmpeq: 287286425Sdim case Hexagon::C2_cmpgt: 288286425Sdim case Hexagon::C2_cmpgtu: 289286425Sdim case Hexagon::C2_cmpeqp: 290286425Sdim case Hexagon::C2_cmpgtp: 291286425Sdim case Hexagon::C2_cmpgtup: 292286425Sdim case Hexagon::C2_cmpeqi: 293286425Sdim case Hexagon::C2_cmpgti: 294286425Sdim case Hexagon::C2_cmpgtui: 295286425Sdim case Hexagon::C2_cmpgei: 296286425Sdim case Hexagon::C2_cmpgeui: 297286425Sdim case Hexagon::C4_cmpneqi: 298286425Sdim case Hexagon::C4_cmpltei: 299286425Sdim case Hexagon::C4_cmplteui: 300286425Sdim case Hexagon::C4_cmpneq: 301286425Sdim case Hexagon::C4_cmplte: 302286425Sdim case Hexagon::C4_cmplteu: 303286425Sdim case Hexagon::A4_cmpbeq: 304286425Sdim case Hexagon::A4_cmpbeqi: 305286425Sdim case Hexagon::A4_cmpbgtu: 306286425Sdim case Hexagon::A4_cmpbgtui: 307286425Sdim case Hexagon::A4_cmpbgt: 308286425Sdim case Hexagon::A4_cmpbgti: 309286425Sdim case Hexagon::A4_cmpheq: 310286425Sdim case Hexagon::A4_cmphgt: 311286425Sdim case Hexagon::A4_cmphgtu: 312286425Sdim case Hexagon::A4_cmpheqi: 313286425Sdim case Hexagon::A4_cmphgti: 314286425Sdim case Hexagon::A4_cmphgtui: 315286425Sdim return true; 316286425Sdim } 317286425Sdim return false; 318286425Sdim} 319286425Sdim 320286425Sdimbool HexagonGenPredicate::isScalarPred(Register PredReg) { 321286425Sdim std::queue<Register> WorkQ; 322286425Sdim WorkQ.push(PredReg); 323286425Sdim 324286425Sdim while (!WorkQ.empty()) { 325286425Sdim Register PR = WorkQ.front(); 326286425Sdim WorkQ.pop(); 327286425Sdim const MachineInstr *DefI = MRI->getVRegDef(PR.R); 328286425Sdim if (!DefI) 329286425Sdim return false; 330286425Sdim unsigned DefOpc = DefI->getOpcode(); 331286425Sdim switch (DefOpc) { 332286425Sdim case TargetOpcode::COPY: { 333286425Sdim const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass; 334286425Sdim if (MRI->getRegClass(PR.R) != PredRC) 335286425Sdim return false; 336286425Sdim // If it is a copy between two predicate registers, fall through. 337321369Sdim LLVM_FALLTHROUGH; 338286425Sdim } 339286425Sdim case Hexagon::C2_and: 340286425Sdim case Hexagon::C2_andn: 341286425Sdim case Hexagon::C4_and_and: 342286425Sdim case Hexagon::C4_and_andn: 343286425Sdim case Hexagon::C4_and_or: 344286425Sdim case Hexagon::C2_or: 345286425Sdim case Hexagon::C2_orn: 346286425Sdim case Hexagon::C4_or_and: 347286425Sdim case Hexagon::C4_or_andn: 348286425Sdim case Hexagon::C4_or_or: 349286425Sdim case Hexagon::C4_or_orn: 350286425Sdim case Hexagon::C2_xor: 351286425Sdim // Add operands to the queue. 352314564Sdim for (const MachineOperand &MO : DefI->operands()) 353314564Sdim if (MO.isReg() && MO.isUse()) 354314564Sdim WorkQ.push(Register(MO.getReg())); 355286425Sdim break; 356286425Sdim 357286425Sdim // All non-vector compares are ok, everything else is bad. 358286425Sdim default: 359286425Sdim return isScalarCmp(DefOpc); 360286425Sdim } 361286425Sdim } 362286425Sdim 363286425Sdim return true; 364286425Sdim} 365286425Sdim 366286425Sdimbool HexagonGenPredicate::convertToPredForm(MachineInstr *MI) { 367341825Sdim LLVM_DEBUG(dbgs() << __func__ << ": " << MI << " " << *MI); 368286425Sdim 369286425Sdim unsigned Opc = MI->getOpcode(); 370286425Sdim assert(isConvertibleToPredForm(MI)); 371286425Sdim unsigned NumOps = MI->getNumOperands(); 372286425Sdim for (unsigned i = 0; i < NumOps; ++i) { 373286425Sdim MachineOperand &MO = MI->getOperand(i); 374286425Sdim if (!MO.isReg() || !MO.isUse()) 375286425Sdim continue; 376286425Sdim Register Reg(MO); 377314564Sdim if (Reg.S && Reg.S != Hexagon::isub_lo) 378286425Sdim return false; 379286425Sdim if (!PredGPRs.count(Reg)) 380286425Sdim return false; 381286425Sdim } 382286425Sdim 383286425Sdim MachineBasicBlock &B = *MI->getParent(); 384286425Sdim DebugLoc DL = MI->getDebugLoc(); 385286425Sdim 386286425Sdim unsigned NewOpc = getPredForm(Opc); 387286425Sdim // Special case for comparisons against 0. 388286425Sdim if (NewOpc == 0) { 389286425Sdim switch (Opc) { 390286425Sdim case Hexagon::C2_cmpeqi: 391286425Sdim NewOpc = Hexagon::C2_not; 392286425Sdim break; 393286425Sdim case Hexagon::C4_cmpneqi: 394286425Sdim NewOpc = TargetOpcode::COPY; 395286425Sdim break; 396286425Sdim default: 397286425Sdim return false; 398286425Sdim } 399286425Sdim 400286425Sdim // If it's a scalar predicate register, then all bits in it are 401286425Sdim // the same. Otherwise, to determine whether all bits are 0 or not 402286425Sdim // we would need to use any8. 403286425Sdim Register PR = getPredRegFor(MI->getOperand(1)); 404286425Sdim if (!isScalarPred(PR)) 405286425Sdim return false; 406286425Sdim // This will skip the immediate argument when creating the predicate 407286425Sdim // version instruction. 408286425Sdim NumOps = 2; 409286425Sdim } 410286425Sdim 411286425Sdim // Some sanity: check that def is in operand #0. 412286425Sdim MachineOperand &Op0 = MI->getOperand(0); 413286425Sdim assert(Op0.isDef()); 414286425Sdim Register OutR(Op0); 415286425Sdim 416286425Sdim // Don't use getPredRegFor, since it will create an association between 417286425Sdim // the argument and a created predicate register (i.e. it will insert a 418286425Sdim // copy if a new predicate register is created). 419286425Sdim const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass; 420286425Sdim Register NewPR = MRI->createVirtualRegister(PredRC); 421286425Sdim MachineInstrBuilder MIB = BuildMI(B, MI, DL, TII->get(NewOpc), NewPR.R); 422286425Sdim 423286425Sdim // Add predicate counterparts of the GPRs. 424286425Sdim for (unsigned i = 1; i < NumOps; ++i) { 425286425Sdim Register GPR = MI->getOperand(i); 426286425Sdim Register Pred = getPredRegFor(GPR); 427286425Sdim MIB.addReg(Pred.R, 0, Pred.S); 428286425Sdim } 429341825Sdim LLVM_DEBUG(dbgs() << "generated: " << *MIB); 430286425Sdim 431286425Sdim // Generate a copy-out: NewGPR = NewPR, and replace all uses of OutR 432286425Sdim // with NewGPR. 433286425Sdim const TargetRegisterClass *RC = MRI->getRegClass(OutR.R); 434286425Sdim unsigned NewOutR = MRI->createVirtualRegister(RC); 435286425Sdim BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), NewOutR) 436286425Sdim .addReg(NewPR.R, 0, NewPR.S); 437286425Sdim MRI->replaceRegWith(OutR.R, NewOutR); 438286425Sdim MI->eraseFromParent(); 439286425Sdim 440286425Sdim // If the processed instruction was C2_tfrrp (i.e. Rn = Pm; Pk = Rn), 441286425Sdim // then the output will be a predicate register. Do not visit the 442286425Sdim // users of it. 443286425Sdim if (!isPredReg(NewOutR)) { 444286425Sdim Register R(NewOutR); 445286425Sdim PredGPRs.insert(R); 446286425Sdim processPredicateGPR(R); 447286425Sdim } 448286425Sdim return true; 449286425Sdim} 450286425Sdim 451286425Sdimbool HexagonGenPredicate::eliminatePredCopies(MachineFunction &MF) { 452341825Sdim LLVM_DEBUG(dbgs() << __func__ << "\n"); 453286425Sdim const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass; 454286425Sdim bool Changed = false; 455286425Sdim VectOfInst Erase; 456286425Sdim 457286425Sdim // First, replace copies 458286425Sdim // IntR = PredR1 459286425Sdim // PredR2 = IntR 460286425Sdim // with 461286425Sdim // PredR2 = PredR1 462286425Sdim // Such sequences can be generated when a copy-into-pred is generated from 463286425Sdim // a gpr register holding a result of a convertible instruction. After 464286425Sdim // the convertible instruction is converted, its predicate result will be 465286425Sdim // copied back into the original gpr. 466286425Sdim 467309124Sdim for (MachineBasicBlock &MBB : MF) { 468309124Sdim for (MachineInstr &MI : MBB) { 469309124Sdim if (MI.getOpcode() != TargetOpcode::COPY) 470286425Sdim continue; 471309124Sdim Register DR = MI.getOperand(0); 472309124Sdim Register SR = MI.getOperand(1); 473286425Sdim if (!TargetRegisterInfo::isVirtualRegister(DR.R)) 474286425Sdim continue; 475286425Sdim if (!TargetRegisterInfo::isVirtualRegister(SR.R)) 476286425Sdim continue; 477286425Sdim if (MRI->getRegClass(DR.R) != PredRC) 478286425Sdim continue; 479286425Sdim if (MRI->getRegClass(SR.R) != PredRC) 480286425Sdim continue; 481286425Sdim assert(!DR.S && !SR.S && "Unexpected subregister"); 482286425Sdim MRI->replaceRegWith(DR.R, SR.R); 483309124Sdim Erase.insert(&MI); 484286425Sdim Changed = true; 485286425Sdim } 486286425Sdim } 487286425Sdim 488286425Sdim for (VectOfInst::iterator I = Erase.begin(), E = Erase.end(); I != E; ++I) 489286425Sdim (*I)->eraseFromParent(); 490286425Sdim 491286425Sdim return Changed; 492286425Sdim} 493286425Sdim 494286425Sdimbool HexagonGenPredicate::runOnMachineFunction(MachineFunction &MF) { 495327952Sdim if (skipFunction(MF.getFunction())) 496309124Sdim return false; 497309124Sdim 498286425Sdim TII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo(); 499286425Sdim TRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); 500286425Sdim MRI = &MF.getRegInfo(); 501286425Sdim PredGPRs.clear(); 502286425Sdim PUsers.clear(); 503286425Sdim G2P.clear(); 504286425Sdim 505286425Sdim bool Changed = false; 506286425Sdim collectPredicateGPR(MF); 507286425Sdim for (SetOfReg::iterator I = PredGPRs.begin(), E = PredGPRs.end(); I != E; ++I) 508286425Sdim processPredicateGPR(*I); 509286425Sdim 510286425Sdim bool Again; 511286425Sdim do { 512286425Sdim Again = false; 513286425Sdim VectOfInst Processed, Copy; 514286425Sdim 515327952Sdim using iterator = VectOfInst::iterator; 516327952Sdim 517286425Sdim Copy = PUsers; 518286425Sdim for (iterator I = Copy.begin(), E = Copy.end(); I != E; ++I) { 519286425Sdim MachineInstr *MI = *I; 520286425Sdim bool Done = convertToPredForm(MI); 521286425Sdim if (Done) { 522286425Sdim Processed.insert(MI); 523286425Sdim Again = true; 524286425Sdim } 525286425Sdim } 526286425Sdim Changed |= Again; 527286425Sdim 528286425Sdim auto Done = [Processed] (MachineInstr *MI) -> bool { 529286425Sdim return Processed.count(MI); 530286425Sdim }; 531286425Sdim PUsers.remove_if(Done); 532286425Sdim } while (Again); 533286425Sdim 534286425Sdim Changed |= eliminatePredCopies(MF); 535286425Sdim return Changed; 536286425Sdim} 537286425Sdim 538286425SdimFunctionPass *llvm::createHexagonGenPredicate() { 539286425Sdim return new HexagonGenPredicate(); 540286425Sdim} 541