SystemZElimCompare.cpp revision 263508
167754Smsmith//===-- SystemZElimCompare.cpp - Eliminate comparison instructions --------===// 267754Smsmith// 367754Smsmith// The LLVM Compiler Infrastructure 477424Smsmith// 5123315Snjl// This file is distributed under the University of Illinois Open Source 667754Smsmith// License. See LICENSE.TXT for details. 767754Smsmith// 867754Smsmith//===----------------------------------------------------------------------===// 967754Smsmith// 1067754Smsmith// This pass: 1167754Smsmith// (1) tries to remove compares if CC already contains the required information 1267754Smsmith// (2) fuses compares and branches into COMPARE AND BRANCH instructions 13114237Snjl// 1470243Smsmith//===----------------------------------------------------------------------===// 1567754Smsmith 1667754Smsmith#define DEBUG_TYPE "systemz-elim-compare" 1767754Smsmith 1867754Smsmith#include "SystemZTargetMachine.h" 1967754Smsmith#include "llvm/ADT/Statistic.h" 2067754Smsmith#include "llvm/CodeGen/MachineFunctionPass.h" 2167754Smsmith#include "llvm/CodeGen/MachineInstrBuilder.h" 2267754Smsmith#include "llvm/IR/Function.h" 2367754Smsmith#include "llvm/Support/CommandLine.h" 2467754Smsmith#include "llvm/Support/MathExtras.h" 2567754Smsmith#include "llvm/Target/TargetInstrInfo.h" 2667754Smsmith#include "llvm/Target/TargetMachine.h" 2767754Smsmith#include "llvm/Target/TargetRegisterInfo.h" 2867754Smsmith 2967754Smsmithusing namespace llvm; 3067754Smsmith 3167754SmsmithSTATISTIC(BranchOnCounts, "Number of branch-on-count instructions"); 3267754SmsmithSTATISTIC(EliminatedComparisons, "Number of eliminated comparisons"); 3367754SmsmithSTATISTIC(FusedComparisons, "Number of fused compare-and-branch instructions"); 3467754Smsmith 3567754Smsmithnamespace { 3667754Smsmith // Represents the references to a particular register in one or more 3767754Smsmith // instructions. 3867754Smsmith struct Reference { 3967754Smsmith Reference() 4067754Smsmith : Def(false), Use(false), IndirectDef(false), IndirectUse(false) {} 4167754Smsmith 4267754Smsmith Reference &operator|=(const Reference &Other) { 4367754Smsmith Def |= Other.Def; 4467754Smsmith IndirectDef |= Other.IndirectDef; 4567754Smsmith Use |= Other.Use; 4667754Smsmith IndirectUse |= Other.IndirectUse; 4767754Smsmith return *this; 4867754Smsmith } 4967754Smsmith 5067754Smsmith operator bool() const { return Def || Use; } 5167754Smsmith 5267754Smsmith // True if the register is defined or used in some form, either directly or 5367754Smsmith // via a sub- or super-register. 5467754Smsmith bool Def; 5567754Smsmith bool Use; 5667754Smsmith 5767754Smsmith // True if the register is defined or used indirectly, by a sub- or 5867754Smsmith // super-register. 5967754Smsmith bool IndirectDef; 6067754Smsmith bool IndirectUse; 6167754Smsmith }; 6267754Smsmith 6367754Smsmith class SystemZElimCompare : public MachineFunctionPass { 6467754Smsmith public: 6567754Smsmith static char ID; 6667754Smsmith SystemZElimCompare(const SystemZTargetMachine &tm) 6767754Smsmith : MachineFunctionPass(ID), TII(0), TRI(0) {} 6867754Smsmith 6967754Smsmith virtual const char *getPassName() const { 7067754Smsmith return "SystemZ Comparison Elimination"; 7167754Smsmith } 7267754Smsmith 7367754Smsmith bool processBlock(MachineBasicBlock *MBB); 7467754Smsmith bool runOnMachineFunction(MachineFunction &F); 7567754Smsmith 7667754Smsmith private: 7767754Smsmith Reference getRegReferences(MachineInstr *MI, unsigned Reg); 7867754Smsmith bool convertToBRCT(MachineInstr *MI, MachineInstr *Compare, 7967754Smsmith SmallVectorImpl<MachineInstr *> &CCUsers); 8067754Smsmith bool convertToLoadAndTest(MachineInstr *MI); 8167754Smsmith bool adjustCCMasksForInstr(MachineInstr *MI, MachineInstr *Compare, 8267754Smsmith SmallVectorImpl<MachineInstr *> &CCUsers); 8367754Smsmith bool optimizeCompareZero(MachineInstr *Compare, 8467754Smsmith SmallVectorImpl<MachineInstr *> &CCUsers); 8567754Smsmith bool fuseCompareAndBranch(MachineInstr *Compare, 8667754Smsmith SmallVectorImpl<MachineInstr *> &CCUsers); 8767754Smsmith 8867754Smsmith const SystemZInstrInfo *TII; 8967754Smsmith const TargetRegisterInfo *TRI; 9067754Smsmith }; 9167754Smsmith 9267754Smsmith char SystemZElimCompare::ID = 0; 9367754Smsmith} // end of anonymous namespace 9467754Smsmith 9567754SmsmithFunctionPass *llvm::createSystemZElimComparePass(SystemZTargetMachine &TM) { 9667754Smsmith return new SystemZElimCompare(TM); 9767754Smsmith} 9867754Smsmith 9967754Smsmith// Return true if CC is live out of MBB. 10067754Smsmithstatic bool isCCLiveOut(MachineBasicBlock *MBB) { 10167754Smsmith for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), 10267754Smsmith SE = MBB->succ_end(); SI != SE; ++SI) 10367754Smsmith if ((*SI)->isLiveIn(SystemZ::CC)) 10467754Smsmith return true; 10567754Smsmith return false; 10667754Smsmith} 10767754Smsmith 10867754Smsmith// Return true if any CC result of MI would reflect the value of subreg 10967754Smsmith// SubReg of Reg. 11067754Smsmithstatic bool resultTests(MachineInstr *MI, unsigned Reg, unsigned SubReg) { 11167754Smsmith if (MI->getNumOperands() > 0 && 11267754Smsmith MI->getOperand(0).isReg() && 11367754Smsmith MI->getOperand(0).isDef() && 11467754Smsmith MI->getOperand(0).getReg() == Reg && 11567754Smsmith MI->getOperand(0).getSubReg() == SubReg) 11667754Smsmith return true; 11767754Smsmith 11877424Smsmith switch (MI->getOpcode()) { 11967754Smsmith case SystemZ::LR: 12067754Smsmith case SystemZ::LGR: 12167754Smsmith case SystemZ::LGFR: 12267754Smsmith case SystemZ::LTR: 12367754Smsmith case SystemZ::LTGR: 124104470Siwasaki case SystemZ::LTGFR: 125123315Snjl case SystemZ::LER: 12667754Smsmith case SystemZ::LDR: 12767754Smsmith case SystemZ::LXR: 12877424Smsmith case SystemZ::LTEBR: 12991116Smsmith case SystemZ::LTDBR: 13067754Smsmith case SystemZ::LTXBR: 13167754Smsmith if (MI->getOperand(1).getReg() == Reg && 13267754Smsmith MI->getOperand(1).getSubReg() == SubReg) 13367754Smsmith return true; 13477424Smsmith } 13567754Smsmith 13667754Smsmith return false; 13777424Smsmith} 13867754Smsmith 13977424Smsmith// Describe the references to Reg in MI, including sub- and super-registers. 14067754SmsmithReference SystemZElimCompare::getRegReferences(MachineInstr *MI, unsigned Reg) { 14167754Smsmith Reference Ref; 14267754Smsmith for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 14371867Smsmith const MachineOperand &MO = MI->getOperand(I); 14467754Smsmith if (MO.isReg()) { 14567754Smsmith if (unsigned MOReg = MO.getReg()) { 14667754Smsmith if (MOReg == Reg || TRI->regsOverlap(MOReg, Reg)) { 14767754Smsmith if (MO.isUse()) { 14877424Smsmith Ref.Use = true; 14967754Smsmith Ref.IndirectUse |= (MOReg != Reg); 15067754Smsmith } 15167754Smsmith if (MO.isDef()) { 15277424Smsmith Ref.Def = true; 15367754Smsmith Ref.IndirectDef |= (MOReg != Reg); 15467754Smsmith } 15591116Smsmith } 15667754Smsmith } 15767754Smsmith } 15867754Smsmith } 15967754Smsmith return Ref; 16082367Smsmith} 16167754Smsmith 16267754Smsmith// Compare compares the result of MI against zero. If MI is an addition 16367754Smsmith// of -1 and if CCUsers is a single branch on nonzero, eliminate the addition 16467754Smsmith// and convert the branch to a BRCT(G). Return true on success. 16567754Smsmithbool 16667754SmsmithSystemZElimCompare::convertToBRCT(MachineInstr *MI, MachineInstr *Compare, 16767754Smsmith SmallVectorImpl<MachineInstr *> &CCUsers) { 16867754Smsmith // Check whether we have an addition of -1. 16999679Siwasaki unsigned Opcode = MI->getOpcode(); 17067754Smsmith unsigned BRCT; 17177424Smsmith if (Opcode == SystemZ::AHI) 17267754Smsmith BRCT = SystemZ::BRCT; 17367754Smsmith else if (Opcode == SystemZ::AGHI) 17467754Smsmith BRCT = SystemZ::BRCTG; 17567754Smsmith else 17667754Smsmith return false; 17767754Smsmith if (MI->getOperand(2).getImm() != -1) 17867754Smsmith return false; 17977424Smsmith 18067754Smsmith // Check whether we have a single JLH. 18167754Smsmith if (CCUsers.size() != 1) 18291116Smsmith return false; 18367754Smsmith MachineInstr *Branch = CCUsers[0]; 18499679Siwasaki if (Branch->getOpcode() != SystemZ::BRC || 18599679Siwasaki Branch->getOperand(0).getImm() != SystemZ::CCMASK_ICMP || 18677424Smsmith Branch->getOperand(1).getImm() != SystemZ::CCMASK_CMP_NE) 18777424Smsmith return false; 18877424Smsmith 18977424Smsmith // We already know that there are no references to the register between 19077424Smsmith // MI and Compare. Make sure that there are also no references between 19167754Smsmith // Compare and Branch. 19267754Smsmith unsigned SrcReg = Compare->getOperand(0).getReg(); 19399146Siwasaki MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch; 19477424Smsmith for (++MBBI; MBBI != MBBE; ++MBBI) 19567754Smsmith if (getRegReferences(MBBI, SrcReg)) 19667754Smsmith return false; 19767754Smsmith 19867754Smsmith // The transformation is OK. Rebuild Branch as a BRCT(G). 19967754Smsmith MachineOperand Target(Branch->getOperand(2)); 20077424Smsmith Branch->RemoveOperand(2); 20167754Smsmith Branch->RemoveOperand(1); 20267754Smsmith Branch->RemoveOperand(0); 20367754Smsmith Branch->setDesc(TII->get(BRCT)); 20477424Smsmith MachineInstrBuilder(*Branch->getParent()->getParent(), Branch) 20567754Smsmith .addOperand(MI->getOperand(0)) 20667754Smsmith .addOperand(MI->getOperand(1)) 20767754Smsmith .addOperand(Target) 20867754Smsmith .addReg(SystemZ::CC, RegState::ImplicitDefine); 20967754Smsmith MI->removeFromParent(); 21067754Smsmith return true; 21167754Smsmith} 21267754Smsmith 21367754Smsmith// If MI is a load instruction, try to convert it into a LOAD AND TEST. 21477424Smsmith// Return true on success. 21567754Smsmithbool SystemZElimCompare::convertToLoadAndTest(MachineInstr *MI) { 21667754Smsmith unsigned Opcode = TII->getLoadAndTest(MI->getOpcode()); 21767754Smsmith if (!Opcode) 21877424Smsmith return false; 21967754Smsmith 22077424Smsmith MI->setDesc(TII->get(Opcode)); 22177424Smsmith MachineInstrBuilder(*MI->getParent()->getParent(), MI) 22267754Smsmith .addReg(SystemZ::CC, RegState::ImplicitDefine); 22367754Smsmith return true; 22467754Smsmith} 22591116Smsmith 22667754Smsmith// The CC users in CCUsers are testing the result of a comparison of some 22767754Smsmith// value X against zero and we know that any CC value produced by MI 22867754Smsmith// would also reflect the value of X. Try to adjust CCUsers so that 22967754Smsmith// they test the result of MI directly, returning true on success. 23067754Smsmith// Leave everything unchanged on failure. 23167754Smsmithbool SystemZElimCompare:: 23299679SiwasakiadjustCCMasksForInstr(MachineInstr *MI, MachineInstr *Compare, 23367754Smsmith SmallVectorImpl<MachineInstr *> &CCUsers) { 234107325Siwasaki int Opcode = MI->getOpcode(); 23567754Smsmith const MCInstrDesc &Desc = TII->get(Opcode); 23677424Smsmith unsigned MIFlags = Desc.TSFlags; 23767754Smsmith 23867754Smsmith // See which compare-style condition codes are available. 23967754Smsmith unsigned ReusableCCMask = SystemZII::getCompareZeroCCMask(MIFlags); 24067754Smsmith 24167754Smsmith // For unsigned comparisons with zero, only equality makes sense. 24267754Smsmith unsigned CompareFlags = Compare->getDesc().TSFlags; 24367754Smsmith if (CompareFlags & SystemZII::IsLogical) 24477424Smsmith ReusableCCMask &= SystemZ::CCMASK_CMP_EQ; 24567754Smsmith 24677424Smsmith if (ReusableCCMask == 0) 24767754Smsmith return false; 24867754Smsmith 24967754Smsmith unsigned CCValues = SystemZII::getCCValues(MIFlags); 25077424Smsmith assert((ReusableCCMask & ~CCValues) == 0 && "Invalid CCValues"); 25167754Smsmith 25267754Smsmith // Now check whether these flags are enough for all users. 25367754Smsmith SmallVector<MachineOperand *, 4> AlterMasks; 25477424Smsmith for (unsigned int I = 0, E = CCUsers.size(); I != E; ++I) { 25567754Smsmith MachineInstr *MI = CCUsers[I]; 25667754Smsmith 25767754Smsmith // Fail if this isn't a use of CC that we understand. 25867754Smsmith unsigned Flags = MI->getDesc().TSFlags; 25977424Smsmith unsigned FirstOpNum; 26067754Smsmith if (Flags & SystemZII::CCMaskFirst) 26167754Smsmith FirstOpNum = 0; 26267754Smsmith else if (Flags & SystemZII::CCMaskLast) 26367754Smsmith FirstOpNum = MI->getNumExplicitOperands() - 2; 26467754Smsmith else 26577424Smsmith return false; 26677424Smsmith 26767754Smsmith // Check whether the instruction predicate treats all CC values 26867754Smsmith // outside of ReusableCCMask in the same way. In that case it 26967754Smsmith // doesn't matter what those CC values mean. 27067754Smsmith unsigned CCValid = MI->getOperand(FirstOpNum).getImm(); 27167754Smsmith unsigned CCMask = MI->getOperand(FirstOpNum + 1).getImm(); 27267754Smsmith unsigned OutValid = ~ReusableCCMask & CCValid; 27367754Smsmith unsigned OutMask = ~ReusableCCMask & CCMask; 27467754Smsmith if (OutMask != 0 && OutMask != OutValid) 27567754Smsmith return false; 27677424Smsmith 27767754Smsmith AlterMasks.push_back(&MI->getOperand(FirstOpNum)); 27867754Smsmith AlterMasks.push_back(&MI->getOperand(FirstOpNum + 1)); 27999146Siwasaki } 28077424Smsmith 28167754Smsmith // All users are OK. Adjust the masks for MI. 28267754Smsmith for (unsigned I = 0, E = AlterMasks.size(); I != E; I += 2) { 28367754Smsmith AlterMasks[I]->setImm(CCValues); 28467754Smsmith unsigned CCMask = AlterMasks[I + 1]->getImm(); 28567754Smsmith if (CCMask & ~ReusableCCMask) 28667754Smsmith AlterMasks[I + 1]->setImm((CCMask & ReusableCCMask) | 28767754Smsmith (CCValues & ~ReusableCCMask)); 28867754Smsmith } 28967754Smsmith 29067754Smsmith // CC is now live after MI. 29167754Smsmith int CCDef = MI->findRegisterDefOperandIdx(SystemZ::CC, false, true, TRI); 29267754Smsmith assert(CCDef >= 0 && "Couldn't find CC set"); 29367754Smsmith MI->getOperand(CCDef).setIsDead(false); 29467754Smsmith 29599679Siwasaki // Clear any intervening kills of CC. 29667754Smsmith MachineBasicBlock::iterator MBBI = MI, MBBE = Compare; 29767754Smsmith for (++MBBI; MBBI != MBBE; ++MBBI) 29867754Smsmith MBBI->clearRegisterKills(SystemZ::CC, TRI); 29967754Smsmith 30067754Smsmith return true; 30167754Smsmith} 30267754Smsmith 30367754Smsmith// Return true if Compare is a comparison against zero. 30477424Smsmithstatic bool isCompareZero(MachineInstr *Compare) { 30577424Smsmith switch (Compare->getOpcode()) { 30667754Smsmith case SystemZ::LTEBRCompare: 30767754Smsmith case SystemZ::LTDBRCompare: 30867754Smsmith case SystemZ::LTXBRCompare: 30967754Smsmith return true; 31067754Smsmith 31167754Smsmith default: 31277424Smsmith return (Compare->getNumExplicitOperands() == 2 && 31367754Smsmith Compare->getOperand(1).isImm() && 31482367Smsmith Compare->getOperand(1).getImm() == 0); 31583174Smsmith } 31677424Smsmith} 31767754Smsmith 31867754Smsmith// Try to optimize cases where comparison instruction Compare is testing 31967754Smsmith// a value against zero. Return true on success and if Compare should be 32067754Smsmith// deleted as dead. CCUsers is the list of instructions that use the CC 32199679Siwasaki// value produced by Compare. 32267754Smsmithbool SystemZElimCompare:: 32399679SiwasakioptimizeCompareZero(MachineInstr *Compare, 32477424Smsmith SmallVectorImpl<MachineInstr *> &CCUsers) { 32567754Smsmith if (!isCompareZero(Compare)) 32682367Smsmith return false; 32782367Smsmith 32867754Smsmith // Search back for CC results that are based on the first operand. 32967754Smsmith unsigned SrcReg = Compare->getOperand(0).getReg(); 33067754Smsmith unsigned SrcSubReg = Compare->getOperand(0).getSubReg(); 33167754Smsmith MachineBasicBlock *MBB = Compare->getParent(); 33267754Smsmith MachineBasicBlock::iterator MBBI = Compare, MBBE = MBB->begin(); 33367754Smsmith Reference CCRefs; 33467754Smsmith Reference SrcRefs; 335100966Siwasaki while (MBBI != MBBE) { 33667754Smsmith --MBBI; 337123315Snjl MachineInstr *MI = MBBI; 33867754Smsmith if (resultTests(MI, SrcReg, SrcSubReg)) { 33967754Smsmith // Try to remove both MI and Compare by converting a branch to BRCT(G). 340100966Siwasaki // We don't care in this case whether CC is modified between MI and 34167754Smsmith // Compare. 34267754Smsmith if (!CCRefs.Use && !SrcRefs && convertToBRCT(MI, Compare, CCUsers)) { 34367754Smsmith BranchOnCounts += 1; 34467754Smsmith return true; 34567754Smsmith } 346123315Snjl // Try to eliminate Compare by reusing a CC result from MI. 347123315Snjl if ((!CCRefs && convertToLoadAndTest(MI)) || 34867754Smsmith (!CCRefs.Def && adjustCCMasksForInstr(MI, Compare, CCUsers))) { 34977424Smsmith EliminatedComparisons += 1; 35099679Siwasaki return true; 35199679Siwasaki } 35267754Smsmith } 35367754Smsmith SrcRefs |= getRegReferences(MI, SrcReg); 35499146Siwasaki if (SrcRefs.Def) 35599146Siwasaki return false; 35699146Siwasaki CCRefs |= getRegReferences(MI, SystemZ::CC); 35799146Siwasaki if (CCRefs.Use && CCRefs.Def) 35899146Siwasaki return false; 35999146Siwasaki } 36099146Siwasaki return false; 36199146Siwasaki} 36299146Siwasaki 36399146Siwasaki// Try to fuse comparison instruction Compare into a later branch. 36499146Siwasaki// Return true on success and if Compare is therefore redundant. 36599146Siwasakibool SystemZElimCompare:: 36687031SmsmithfuseCompareAndBranch(MachineInstr *Compare, 36791116Smsmith SmallVectorImpl<MachineInstr *> &CCUsers) { 36887031Smsmith // See whether we have a comparison that can be fused. 36977424Smsmith unsigned FusedOpcode = TII->getCompareAndBranch(Compare->getOpcode(), 370107325Siwasaki Compare); 371107325Siwasaki if (!FusedOpcode) 372107325Siwasaki return false; 37367754Smsmith 37487031Smsmith // See whether we have a single branch with which to fuse. 37599679Siwasaki if (CCUsers.size() != 1) 37667754Smsmith return false; 37799146Siwasaki MachineInstr *Branch = CCUsers[0]; 37867754Smsmith if (Branch->getOpcode() != SystemZ::BRC) 37967754Smsmith return false; 38067754Smsmith 38167754Smsmith // Make sure that the operands are available at the branch. 38267754Smsmith unsigned SrcReg = Compare->getOperand(0).getReg(); 38387031Smsmith unsigned SrcReg2 = (Compare->getOperand(1).isReg() ? 38467754Smsmith Compare->getOperand(1).getReg() : 0); 38567754Smsmith MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch; 38667754Smsmith for (++MBBI; MBBI != MBBE; ++MBBI) 38767754Smsmith if (MBBI->modifiesRegister(SrcReg, TRI) || 38867754Smsmith (SrcReg2 && MBBI->modifiesRegister(SrcReg2, TRI))) 389104470Siwasaki return false; 390104470Siwasaki 391104470Siwasaki // Read the branch mask and target. 392104470Siwasaki MachineOperand CCMask(MBBI->getOperand(1)); 393104470Siwasaki MachineOperand Target(MBBI->getOperand(2)); 394104470Siwasaki assert((CCMask.getImm() & ~SystemZ::CCMASK_ICMP) == 0 && 395104470Siwasaki "Invalid condition-code mask for integer comparison"); 396104470Siwasaki 397104470Siwasaki // Clear out all current operands. 398104470Siwasaki int CCUse = MBBI->findRegisterUseOperandIdx(SystemZ::CC, false, TRI); 399104470Siwasaki assert(CCUse >= 0 && "BRC must use CC"); 400104470Siwasaki Branch->RemoveOperand(CCUse); 401104470Siwasaki Branch->RemoveOperand(2); 402104470Siwasaki Branch->RemoveOperand(1); 403104470Siwasaki Branch->RemoveOperand(0); 404104470Siwasaki 405104470Siwasaki // Rebuild Branch as a fused compare and branch. 406104470Siwasaki Branch->setDesc(TII->get(FusedOpcode)); 407104470Siwasaki MachineInstrBuilder(*Branch->getParent()->getParent(), Branch) 408104470Siwasaki .addOperand(Compare->getOperand(0)) 409104470Siwasaki .addOperand(Compare->getOperand(1)) 410104470Siwasaki .addOperand(CCMask) 411104470Siwasaki .addOperand(Target) 412104470Siwasaki .addReg(SystemZ::CC, RegState::ImplicitDefine); 413104470Siwasaki 414104470Siwasaki // Clear any intervening kills of SrcReg and SrcReg2. 415104470Siwasaki MBBI = Compare; 416104470Siwasaki for (++MBBI; MBBI != MBBE; ++MBBI) { 417107325Siwasaki MBBI->clearRegisterKills(SrcReg, TRI); 418104470Siwasaki if (SrcReg2) 419104470Siwasaki MBBI->clearRegisterKills(SrcReg2, TRI); 420104470Siwasaki } 421104470Siwasaki FusedComparisons += 1; 422114237Snjl return true; 423114237Snjl} 424104470Siwasaki 425104470Siwasaki// Process all comparison instructions in MBB. Return true if something 426107325Siwasaki// changed. 427104470Siwasakibool SystemZElimCompare::processBlock(MachineBasicBlock *MBB) { 428104470Siwasaki bool Changed = false; 429104470Siwasaki 430104470Siwasaki // Walk backwards through the block looking for comparisons, recording 431104470Siwasaki // all CC users as we go. The subroutines can delete Compare and 432104470Siwasaki // instructions before it. 433104470Siwasaki bool CompleteCCUsers = !isCCLiveOut(MBB); 434104470Siwasaki SmallVector<MachineInstr *, 4> CCUsers; 435104470Siwasaki MachineBasicBlock::iterator MBBI = MBB->end(); 436104470Siwasaki while (MBBI != MBB->begin()) { 437104470Siwasaki MachineInstr *MI = --MBBI; 438104470Siwasaki if (CompleteCCUsers && 439104470Siwasaki MI->isCompare() && 440123315Snjl (optimizeCompareZero(MI, CCUsers) || 441123315Snjl fuseCompareAndBranch(MI, CCUsers))) { 442104470Siwasaki ++MBBI; 443104470Siwasaki MI->removeFromParent(); 444104470Siwasaki Changed = true; 445104470Siwasaki CCUsers.clear(); 446104470Siwasaki CompleteCCUsers = true; 447104470Siwasaki continue; 448104470Siwasaki } 449104470Siwasaki 450104470Siwasaki Reference CCRefs(getRegReferences(MI, SystemZ::CC)); 451104470Siwasaki if (CCRefs.Def) { 452104470Siwasaki CCUsers.clear(); 453104470Siwasaki CompleteCCUsers = !CCRefs.IndirectDef; 454104470Siwasaki } 455104470Siwasaki if (CompleteCCUsers && CCRefs.Use) 456104470Siwasaki CCUsers.push_back(MI); 457104470Siwasaki } 458104470Siwasaki return Changed; 459104470Siwasaki} 460104470Siwasaki 461104470Siwasakibool SystemZElimCompare::runOnMachineFunction(MachineFunction &F) { 462104470Siwasaki TII = static_cast<const SystemZInstrInfo *>(F.getTarget().getInstrInfo()); 463104470Siwasaki TRI = &TII->getRegisterInfo(); 464104470Siwasaki 465104470Siwasaki bool Changed = false; 466104470Siwasaki for (MachineFunction::iterator MFI = F.begin(), MFE = F.end(); 467104470Siwasaki MFI != MFE; ++MFI) 468104470Siwasaki Changed |= processBlock(MFI); 469104470Siwasaki 470104470Siwasaki return Changed; 471104470Siwasaki} 472104470Siwasaki