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