SystemZElimCompare.cpp revision 355940
1//===-- SystemZElimCompare.cpp - Eliminate comparison instructions --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass:
10// (1) tries to remove compares if CC already contains the required information
11// (2) fuses compares and branches into COMPARE AND BRANCH instructions
12//
13//===----------------------------------------------------------------------===//
14
15#include "SystemZ.h"
16#include "SystemZInstrInfo.h"
17#include "SystemZTargetMachine.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/Statistic.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/CodeGen/MachineBasicBlock.h"
22#include "llvm/CodeGen/MachineFunction.h"
23#include "llvm/CodeGen/MachineFunctionPass.h"
24#include "llvm/CodeGen/MachineInstr.h"
25#include "llvm/CodeGen/MachineInstrBuilder.h"
26#include "llvm/CodeGen/MachineOperand.h"
27#include "llvm/CodeGen/TargetRegisterInfo.h"
28#include "llvm/CodeGen/TargetSubtargetInfo.h"
29#include "llvm/MC/MCInstrDesc.h"
30#include <cassert>
31#include <cstdint>
32
33using namespace llvm;
34
35#define DEBUG_TYPE "systemz-elim-compare"
36
37STATISTIC(BranchOnCounts, "Number of branch-on-count instructions");
38STATISTIC(LoadAndTraps, "Number of load-and-trap instructions");
39STATISTIC(EliminatedComparisons, "Number of eliminated comparisons");
40STATISTIC(FusedComparisons, "Number of fused compare-and-branch instructions");
41
42namespace {
43
44// Represents the references to a particular register in one or more
45// instructions.
46struct Reference {
47  Reference() = default;
48
49  Reference &operator|=(const Reference &Other) {
50    Def |= Other.Def;
51    Use |= Other.Use;
52    return *this;
53  }
54
55  explicit operator bool() const { return Def || Use; }
56
57  // True if the register is defined or used in some form, either directly or
58  // via a sub- or super-register.
59  bool Def = false;
60  bool Use = false;
61};
62
63class SystemZElimCompare : public MachineFunctionPass {
64public:
65  static char ID;
66
67  SystemZElimCompare(const SystemZTargetMachine &tm)
68    : MachineFunctionPass(ID) {}
69
70  StringRef getPassName() const override {
71    return "SystemZ Comparison Elimination";
72  }
73
74  bool processBlock(MachineBasicBlock &MBB);
75  bool runOnMachineFunction(MachineFunction &F) override;
76
77  MachineFunctionProperties getRequiredProperties() const override {
78    return MachineFunctionProperties().set(
79        MachineFunctionProperties::Property::NoVRegs);
80  }
81
82private:
83  Reference getRegReferences(MachineInstr &MI, unsigned Reg);
84  bool convertToBRCT(MachineInstr &MI, MachineInstr &Compare,
85                     SmallVectorImpl<MachineInstr *> &CCUsers);
86  bool convertToLoadAndTrap(MachineInstr &MI, MachineInstr &Compare,
87                            SmallVectorImpl<MachineInstr *> &CCUsers);
88  bool convertToLoadAndTest(MachineInstr &MI, MachineInstr &Compare,
89                            SmallVectorImpl<MachineInstr *> &CCUsers);
90  bool adjustCCMasksForInstr(MachineInstr &MI, MachineInstr &Compare,
91                             SmallVectorImpl<MachineInstr *> &CCUsers,
92                             unsigned ConvOpc = 0);
93  bool optimizeCompareZero(MachineInstr &Compare,
94                           SmallVectorImpl<MachineInstr *> &CCUsers);
95  bool fuseCompareOperations(MachineInstr &Compare,
96                             SmallVectorImpl<MachineInstr *> &CCUsers);
97
98  const SystemZInstrInfo *TII = nullptr;
99  const TargetRegisterInfo *TRI = nullptr;
100};
101
102char SystemZElimCompare::ID = 0;
103
104} // end anonymous namespace
105
106// Return true if CC is live out of MBB.
107static bool isCCLiveOut(MachineBasicBlock &MBB) {
108  for (auto SI = MBB.succ_begin(), SE = MBB.succ_end(); SI != SE; ++SI)
109    if ((*SI)->isLiveIn(SystemZ::CC))
110      return true;
111  return false;
112}
113
114// Returns true if MI is an instruction whose output equals the value in Reg.
115static bool preservesValueOf(MachineInstr &MI, unsigned Reg) {
116  switch (MI.getOpcode()) {
117  case SystemZ::LR:
118  case SystemZ::LGR:
119  case SystemZ::LGFR:
120  case SystemZ::LTR:
121  case SystemZ::LTGR:
122  case SystemZ::LTGFR:
123  case SystemZ::LER:
124  case SystemZ::LDR:
125  case SystemZ::LXR:
126  case SystemZ::LTEBR:
127  case SystemZ::LTDBR:
128  case SystemZ::LTXBR:
129    if (MI.getOperand(1).getReg() == Reg)
130      return true;
131  }
132
133  return false;
134}
135
136// Return true if any CC result of MI would (perhaps after conversion)
137// reflect the value of Reg.
138static bool resultTests(MachineInstr &MI, unsigned Reg) {
139  if (MI.getNumOperands() > 0 && MI.getOperand(0).isReg() &&
140      MI.getOperand(0).isDef() && MI.getOperand(0).getReg() == Reg)
141    return true;
142
143  return (preservesValueOf(MI, Reg));
144}
145
146// Describe the references to Reg or any of its aliases in MI.
147Reference SystemZElimCompare::getRegReferences(MachineInstr &MI, unsigned Reg) {
148  Reference Ref;
149  if (MI.isDebugInstr())
150    return Ref;
151
152  for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
153    const MachineOperand &MO = MI.getOperand(I);
154    if (MO.isReg()) {
155      if (unsigned MOReg = MO.getReg()) {
156        if (TRI->regsOverlap(MOReg, Reg)) {
157          if (MO.isUse())
158            Ref.Use = true;
159          else if (MO.isDef())
160            Ref.Def = true;
161        }
162      }
163    }
164  }
165  return Ref;
166}
167
168// Return true if this is a load and test which can be optimized the
169// same way as compare instruction.
170static bool isLoadAndTestAsCmp(MachineInstr &MI) {
171  // If we during isel used a load-and-test as a compare with 0, the
172  // def operand is dead.
173  return (MI.getOpcode() == SystemZ::LTEBR ||
174          MI.getOpcode() == SystemZ::LTDBR ||
175          MI.getOpcode() == SystemZ::LTXBR) &&
176         MI.getOperand(0).isDead();
177}
178
179// Return the source register of Compare, which is the unknown value
180// being tested.
181static unsigned getCompareSourceReg(MachineInstr &Compare) {
182  unsigned reg = 0;
183  if (Compare.isCompare())
184    reg = Compare.getOperand(0).getReg();
185  else if (isLoadAndTestAsCmp(Compare))
186    reg = Compare.getOperand(1).getReg();
187  assert(reg);
188
189  return reg;
190}
191
192// Compare compares the result of MI against zero.  If MI is an addition
193// of -1 and if CCUsers is a single branch on nonzero, eliminate the addition
194// and convert the branch to a BRCT(G) or BRCTH.  Return true on success.
195bool SystemZElimCompare::convertToBRCT(
196    MachineInstr &MI, MachineInstr &Compare,
197    SmallVectorImpl<MachineInstr *> &CCUsers) {
198  // Check whether we have an addition of -1.
199  unsigned Opcode = MI.getOpcode();
200  unsigned BRCT;
201  if (Opcode == SystemZ::AHI)
202    BRCT = SystemZ::BRCT;
203  else if (Opcode == SystemZ::AGHI)
204    BRCT = SystemZ::BRCTG;
205  else if (Opcode == SystemZ::AIH)
206    BRCT = SystemZ::BRCTH;
207  else
208    return false;
209  if (MI.getOperand(2).getImm() != -1)
210    return false;
211
212  // Check whether we have a single JLH.
213  if (CCUsers.size() != 1)
214    return false;
215  MachineInstr *Branch = CCUsers[0];
216  if (Branch->getOpcode() != SystemZ::BRC ||
217      Branch->getOperand(0).getImm() != SystemZ::CCMASK_ICMP ||
218      Branch->getOperand(1).getImm() != SystemZ::CCMASK_CMP_NE)
219    return false;
220
221  // We already know that there are no references to the register between
222  // MI and Compare.  Make sure that there are also no references between
223  // Compare and Branch.
224  unsigned SrcReg = getCompareSourceReg(Compare);
225  MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch;
226  for (++MBBI; MBBI != MBBE; ++MBBI)
227    if (getRegReferences(*MBBI, SrcReg))
228      return false;
229
230  // The transformation is OK.  Rebuild Branch as a BRCT(G) or BRCTH.
231  MachineOperand Target(Branch->getOperand(2));
232  while (Branch->getNumOperands())
233    Branch->RemoveOperand(0);
234  Branch->setDesc(TII->get(BRCT));
235  MachineInstrBuilder MIB(*Branch->getParent()->getParent(), Branch);
236  MIB.add(MI.getOperand(0)).add(MI.getOperand(1)).add(Target);
237  // Add a CC def to BRCT(G), since we may have to split them again if the
238  // branch displacement overflows.  BRCTH has a 32-bit displacement, so
239  // this is not necessary there.
240  if (BRCT != SystemZ::BRCTH)
241    MIB.addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead);
242  MI.eraseFromParent();
243  return true;
244}
245
246// Compare compares the result of MI against zero.  If MI is a suitable load
247// instruction and if CCUsers is a single conditional trap on zero, eliminate
248// the load and convert the branch to a load-and-trap.  Return true on success.
249bool SystemZElimCompare::convertToLoadAndTrap(
250    MachineInstr &MI, MachineInstr &Compare,
251    SmallVectorImpl<MachineInstr *> &CCUsers) {
252  unsigned LATOpcode = TII->getLoadAndTrap(MI.getOpcode());
253  if (!LATOpcode)
254    return false;
255
256  // Check whether we have a single CondTrap that traps on zero.
257  if (CCUsers.size() != 1)
258    return false;
259  MachineInstr *Branch = CCUsers[0];
260  if (Branch->getOpcode() != SystemZ::CondTrap ||
261      Branch->getOperand(0).getImm() != SystemZ::CCMASK_ICMP ||
262      Branch->getOperand(1).getImm() != SystemZ::CCMASK_CMP_EQ)
263    return false;
264
265  // We already know that there are no references to the register between
266  // MI and Compare.  Make sure that there are also no references between
267  // Compare and Branch.
268  unsigned SrcReg = getCompareSourceReg(Compare);
269  MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch;
270  for (++MBBI; MBBI != MBBE; ++MBBI)
271    if (getRegReferences(*MBBI, SrcReg))
272      return false;
273
274  // The transformation is OK.  Rebuild Branch as a load-and-trap.
275  while (Branch->getNumOperands())
276    Branch->RemoveOperand(0);
277  Branch->setDesc(TII->get(LATOpcode));
278  MachineInstrBuilder(*Branch->getParent()->getParent(), Branch)
279      .add(MI.getOperand(0))
280      .add(MI.getOperand(1))
281      .add(MI.getOperand(2))
282      .add(MI.getOperand(3));
283  MI.eraseFromParent();
284  return true;
285}
286
287// If MI is a load instruction, try to convert it into a LOAD AND TEST.
288// Return true on success.
289bool SystemZElimCompare::convertToLoadAndTest(
290    MachineInstr &MI, MachineInstr &Compare,
291    SmallVectorImpl<MachineInstr *> &CCUsers) {
292
293  // Try to adjust CC masks for the LOAD AND TEST opcode that could replace MI.
294  unsigned Opcode = TII->getLoadAndTest(MI.getOpcode());
295  if (!Opcode || !adjustCCMasksForInstr(MI, Compare, CCUsers, Opcode))
296    return false;
297
298  // Rebuild to get the CC operand in the right place.
299  auto MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(Opcode));
300  for (const auto &MO : MI.operands())
301    MIB.add(MO);
302  MIB.setMemRefs(MI.memoperands());
303  MI.eraseFromParent();
304
305  return true;
306}
307
308// The CC users in CCUsers are testing the result of a comparison of some
309// value X against zero and we know that any CC value produced by MI would
310// also reflect the value of X.  ConvOpc may be used to pass the transfomed
311// opcode MI will have if this succeeds.  Try to adjust CCUsers so that they
312// test the result of MI directly, returning true on success.  Leave
313// everything unchanged on failure.
314bool SystemZElimCompare::adjustCCMasksForInstr(
315    MachineInstr &MI, MachineInstr &Compare,
316    SmallVectorImpl<MachineInstr *> &CCUsers,
317    unsigned ConvOpc) {
318  int Opcode = (ConvOpc ? ConvOpc : MI.getOpcode());
319  const MCInstrDesc &Desc = TII->get(Opcode);
320  unsigned MIFlags = Desc.TSFlags;
321
322  // See which compare-style condition codes are available.
323  unsigned ReusableCCMask = SystemZII::getCompareZeroCCMask(MIFlags);
324
325  // For unsigned comparisons with zero, only equality makes sense.
326  unsigned CompareFlags = Compare.getDesc().TSFlags;
327  if (CompareFlags & SystemZII::IsLogical)
328    ReusableCCMask &= SystemZ::CCMASK_CMP_EQ;
329
330  if (ReusableCCMask == 0)
331    return false;
332
333  unsigned CCValues = SystemZII::getCCValues(MIFlags);
334  assert((ReusableCCMask & ~CCValues) == 0 && "Invalid CCValues");
335
336  bool MIEquivalentToCmp =
337    (ReusableCCMask == CCValues &&
338     CCValues == SystemZII::getCCValues(CompareFlags));
339
340  if (!MIEquivalentToCmp) {
341    // Now check whether these flags are enough for all users.
342    SmallVector<MachineOperand *, 4> AlterMasks;
343    for (unsigned int I = 0, E = CCUsers.size(); I != E; ++I) {
344      MachineInstr *MI = CCUsers[I];
345
346      // Fail if this isn't a use of CC that we understand.
347      unsigned Flags = MI->getDesc().TSFlags;
348      unsigned FirstOpNum;
349      if (Flags & SystemZII::CCMaskFirst)
350        FirstOpNum = 0;
351      else if (Flags & SystemZII::CCMaskLast)
352        FirstOpNum = MI->getNumExplicitOperands() - 2;
353      else
354        return false;
355
356      // Check whether the instruction predicate treats all CC values
357      // outside of ReusableCCMask in the same way.  In that case it
358      // doesn't matter what those CC values mean.
359      unsigned CCValid = MI->getOperand(FirstOpNum).getImm();
360      unsigned CCMask = MI->getOperand(FirstOpNum + 1).getImm();
361      unsigned OutValid = ~ReusableCCMask & CCValid;
362      unsigned OutMask = ~ReusableCCMask & CCMask;
363      if (OutMask != 0 && OutMask != OutValid)
364        return false;
365
366      AlterMasks.push_back(&MI->getOperand(FirstOpNum));
367      AlterMasks.push_back(&MI->getOperand(FirstOpNum + 1));
368    }
369
370    // All users are OK.  Adjust the masks for MI.
371    for (unsigned I = 0, E = AlterMasks.size(); I != E; I += 2) {
372      AlterMasks[I]->setImm(CCValues);
373      unsigned CCMask = AlterMasks[I + 1]->getImm();
374      if (CCMask & ~ReusableCCMask)
375        AlterMasks[I + 1]->setImm((CCMask & ReusableCCMask) |
376                                  (CCValues & ~ReusableCCMask));
377    }
378  }
379
380  // CC is now live after MI.
381  if (!ConvOpc) {
382    int CCDef = MI.findRegisterDefOperandIdx(SystemZ::CC, false, true, TRI);
383    assert(CCDef >= 0 && "Couldn't find CC set");
384    MI.getOperand(CCDef).setIsDead(false);
385  }
386
387  // Check if MI lies before Compare.
388  bool BeforeCmp = false;
389  MachineBasicBlock::iterator MBBI = MI, MBBE = MI.getParent()->end();
390  for (++MBBI; MBBI != MBBE; ++MBBI)
391    if (MBBI == Compare) {
392      BeforeCmp = true;
393      break;
394    }
395
396  // Clear any intervening kills of CC.
397  if (BeforeCmp) {
398    MachineBasicBlock::iterator MBBI = MI, MBBE = Compare;
399    for (++MBBI; MBBI != MBBE; ++MBBI)
400      MBBI->clearRegisterKills(SystemZ::CC, TRI);
401  }
402
403  return true;
404}
405
406// Return true if Compare is a comparison against zero.
407static bool isCompareZero(MachineInstr &Compare) {
408  switch (Compare.getOpcode()) {
409  case SystemZ::LTEBRCompare:
410  case SystemZ::LTDBRCompare:
411  case SystemZ::LTXBRCompare:
412    return true;
413
414  default:
415    if (isLoadAndTestAsCmp(Compare))
416      return true;
417    return Compare.getNumExplicitOperands() == 2 &&
418           Compare.getOperand(1).isImm() && Compare.getOperand(1).getImm() == 0;
419  }
420}
421
422// Try to optimize cases where comparison instruction Compare is testing
423// a value against zero.  Return true on success and if Compare should be
424// deleted as dead.  CCUsers is the list of instructions that use the CC
425// value produced by Compare.
426bool SystemZElimCompare::optimizeCompareZero(
427    MachineInstr &Compare, SmallVectorImpl<MachineInstr *> &CCUsers) {
428  if (!isCompareZero(Compare))
429    return false;
430
431  // Search back for CC results that are based on the first operand.
432  unsigned SrcReg = getCompareSourceReg(Compare);
433  MachineBasicBlock &MBB = *Compare.getParent();
434  Reference CCRefs;
435  Reference SrcRefs;
436  for (MachineBasicBlock::reverse_iterator MBBI =
437         std::next(MachineBasicBlock::reverse_iterator(&Compare)),
438         MBBE = MBB.rend(); MBBI != MBBE;) {
439    MachineInstr &MI = *MBBI++;
440    if (resultTests(MI, SrcReg)) {
441      // Try to remove both MI and Compare by converting a branch to BRCT(G).
442      // or a load-and-trap instruction.  We don't care in this case whether
443      // CC is modified between MI and Compare.
444      if (!CCRefs.Use && !SrcRefs) {
445        if (convertToBRCT(MI, Compare, CCUsers)) {
446          BranchOnCounts += 1;
447          return true;
448        }
449        if (convertToLoadAndTrap(MI, Compare, CCUsers)) {
450          LoadAndTraps += 1;
451          return true;
452        }
453      }
454      // Try to eliminate Compare by reusing a CC result from MI.
455      if ((!CCRefs && convertToLoadAndTest(MI, Compare, CCUsers)) ||
456          (!CCRefs.Def && adjustCCMasksForInstr(MI, Compare, CCUsers))) {
457        EliminatedComparisons += 1;
458        return true;
459      }
460    }
461    SrcRefs |= getRegReferences(MI, SrcReg);
462    if (SrcRefs.Def)
463      break;
464    CCRefs |= getRegReferences(MI, SystemZ::CC);
465    if (CCRefs.Use && CCRefs.Def)
466      break;
467  }
468
469  // Also do a forward search to handle cases where an instruction after the
470  // compare can be converted, like
471  // LTEBRCompare %f0s, %f0s; %f2s = LER %f0s  =>  LTEBRCompare %f2s, %f0s
472  for (MachineBasicBlock::iterator MBBI =
473         std::next(MachineBasicBlock::iterator(&Compare)), MBBE = MBB.end();
474       MBBI != MBBE;) {
475    MachineInstr &MI = *MBBI++;
476    if (preservesValueOf(MI, SrcReg)) {
477      // Try to eliminate Compare by reusing a CC result from MI.
478      if (convertToLoadAndTest(MI, Compare, CCUsers)) {
479        EliminatedComparisons += 1;
480        return true;
481      }
482    }
483    if (getRegReferences(MI, SrcReg).Def)
484      return false;
485    if (getRegReferences(MI, SystemZ::CC))
486      return false;
487  }
488
489  return false;
490}
491
492// Try to fuse comparison instruction Compare into a later branch.
493// Return true on success and if Compare is therefore redundant.
494bool SystemZElimCompare::fuseCompareOperations(
495    MachineInstr &Compare, SmallVectorImpl<MachineInstr *> &CCUsers) {
496  // See whether we have a single branch with which to fuse.
497  if (CCUsers.size() != 1)
498    return false;
499  MachineInstr *Branch = CCUsers[0];
500  SystemZII::FusedCompareType Type;
501  switch (Branch->getOpcode()) {
502  case SystemZ::BRC:
503    Type = SystemZII::CompareAndBranch;
504    break;
505  case SystemZ::CondReturn:
506    Type = SystemZII::CompareAndReturn;
507    break;
508  case SystemZ::CallBCR:
509    Type = SystemZII::CompareAndSibcall;
510    break;
511  case SystemZ::CondTrap:
512    Type = SystemZII::CompareAndTrap;
513    break;
514  default:
515    return false;
516  }
517
518  // See whether we have a comparison that can be fused.
519  unsigned FusedOpcode =
520      TII->getFusedCompare(Compare.getOpcode(), Type, &Compare);
521  if (!FusedOpcode)
522    return false;
523
524  // Make sure that the operands are available at the branch.
525  // SrcReg2 is the register if the source operand is a register,
526  // 0 if the source operand is immediate, and the base register
527  // if the source operand is memory (index is not supported).
528  Register SrcReg = Compare.getOperand(0).getReg();
529  Register SrcReg2 =
530    Compare.getOperand(1).isReg() ? Compare.getOperand(1).getReg() : Register();
531  MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch;
532  for (++MBBI; MBBI != MBBE; ++MBBI)
533    if (MBBI->modifiesRegister(SrcReg, TRI) ||
534        (SrcReg2 && MBBI->modifiesRegister(SrcReg2, TRI)))
535      return false;
536
537  // Read the branch mask, target (if applicable), regmask (if applicable).
538  MachineOperand CCMask(MBBI->getOperand(1));
539  assert((CCMask.getImm() & ~SystemZ::CCMASK_ICMP) == 0 &&
540         "Invalid condition-code mask for integer comparison");
541  // This is only valid for CompareAndBranch.
542  MachineOperand Target(MBBI->getOperand(
543    Type == SystemZII::CompareAndBranch ? 2 : 0));
544  const uint32_t *RegMask;
545  if (Type == SystemZII::CompareAndSibcall)
546    RegMask = MBBI->getOperand(2).getRegMask();
547
548  // Clear out all current operands.
549  int CCUse = MBBI->findRegisterUseOperandIdx(SystemZ::CC, false, TRI);
550  assert(CCUse >= 0 && "BRC/BCR must use CC");
551  Branch->RemoveOperand(CCUse);
552  // Remove target (branch) or regmask (sibcall).
553  if (Type == SystemZII::CompareAndBranch ||
554      Type == SystemZII::CompareAndSibcall)
555    Branch->RemoveOperand(2);
556  Branch->RemoveOperand(1);
557  Branch->RemoveOperand(0);
558
559  // Rebuild Branch as a fused compare and branch.
560  // SrcNOps is the number of MI operands of the compare instruction
561  // that we need to copy over.
562  unsigned SrcNOps = 2;
563  if (FusedOpcode == SystemZ::CLT || FusedOpcode == SystemZ::CLGT)
564    SrcNOps = 3;
565  Branch->setDesc(TII->get(FusedOpcode));
566  MachineInstrBuilder MIB(*Branch->getParent()->getParent(), Branch);
567  for (unsigned I = 0; I < SrcNOps; I++)
568    MIB.add(Compare.getOperand(I));
569  MIB.add(CCMask);
570
571  if (Type == SystemZII::CompareAndBranch) {
572    // Only conditional branches define CC, as they may be converted back
573    // to a non-fused branch because of a long displacement.  Conditional
574    // returns don't have that problem.
575    MIB.add(Target).addReg(SystemZ::CC,
576                           RegState::ImplicitDefine | RegState::Dead);
577  }
578
579  if (Type == SystemZII::CompareAndSibcall)
580    MIB.addRegMask(RegMask);
581
582  // Clear any intervening kills of SrcReg and SrcReg2.
583  MBBI = Compare;
584  for (++MBBI; MBBI != MBBE; ++MBBI) {
585    MBBI->clearRegisterKills(SrcReg, TRI);
586    if (SrcReg2)
587      MBBI->clearRegisterKills(SrcReg2, TRI);
588  }
589  FusedComparisons += 1;
590  return true;
591}
592
593// Process all comparison instructions in MBB.  Return true if something
594// changed.
595bool SystemZElimCompare::processBlock(MachineBasicBlock &MBB) {
596  bool Changed = false;
597
598  // Walk backwards through the block looking for comparisons, recording
599  // all CC users as we go.  The subroutines can delete Compare and
600  // instructions before it.
601  bool CompleteCCUsers = !isCCLiveOut(MBB);
602  SmallVector<MachineInstr *, 4> CCUsers;
603  MachineBasicBlock::iterator MBBI = MBB.end();
604  while (MBBI != MBB.begin()) {
605    MachineInstr &MI = *--MBBI;
606    if (CompleteCCUsers && (MI.isCompare() || isLoadAndTestAsCmp(MI)) &&
607        (optimizeCompareZero(MI, CCUsers) ||
608         fuseCompareOperations(MI, CCUsers))) {
609      ++MBBI;
610      MI.eraseFromParent();
611      Changed = true;
612      CCUsers.clear();
613      continue;
614    }
615
616    if (MI.definesRegister(SystemZ::CC)) {
617      CCUsers.clear();
618      CompleteCCUsers = true;
619    }
620    if (MI.readsRegister(SystemZ::CC) && CompleteCCUsers)
621      CCUsers.push_back(&MI);
622  }
623  return Changed;
624}
625
626bool SystemZElimCompare::runOnMachineFunction(MachineFunction &F) {
627  if (skipFunction(F.getFunction()))
628    return false;
629
630  TII = static_cast<const SystemZInstrInfo *>(F.getSubtarget().getInstrInfo());
631  TRI = &TII->getRegisterInfo();
632
633  bool Changed = false;
634  for (auto &MBB : F)
635    Changed |= processBlock(MBB);
636
637  return Changed;
638}
639
640FunctionPass *llvm::createSystemZElimComparePass(SystemZTargetMachine &TM) {
641  return new SystemZElimCompare(TM);
642}
643