LLVM  10.0.0svn
SystemZElimCompare.cpp
Go to the documentation of this file.
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"
29 #include "llvm/MC/MCInstrDesc.h"
30 #include <cassert>
31 #include <cstdint>
32 
33 using namespace llvm;
34 
35 #define DEBUG_TYPE "systemz-elim-compare"
36 
37 STATISTIC(BranchOnCounts, "Number of branch-on-count instructions");
38 STATISTIC(LoadAndTraps, "Number of load-and-trap instructions");
39 STATISTIC(EliminatedComparisons, "Number of eliminated comparisons");
40 STATISTIC(FusedComparisons, "Number of fused compare-and-branch instructions");
41 
42 namespace {
43 
44 // Represents the references to a particular register in one or more
45 // instructions.
46 struct 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 
63 class SystemZElimCompare : public MachineFunctionPass {
64 public:
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 {
80  }
81 
82 private:
83  Reference getRegReferences(MachineInstr &MI, unsigned Reg);
84  bool convertToBRCT(MachineInstr &MI, MachineInstr &Compare,
86  bool convertToLoadAndTrap(MachineInstr &MI, MachineInstr &Compare,
88  bool convertToLoadAndTest(MachineInstr &MI, MachineInstr &Compare,
90  bool adjustCCMasksForInstr(MachineInstr &MI, MachineInstr &Compare,
92  unsigned ConvOpc = 0);
93  bool optimizeCompareZero(MachineInstr &Compare,
95  bool fuseCompareOperations(MachineInstr &Compare,
97 
98  const SystemZInstrInfo *TII = nullptr;
99  const TargetRegisterInfo *TRI = nullptr;
100 };
101 
102 char SystemZElimCompare::ID = 0;
103 
104 } // end anonymous namespace
105 
106 // Return true if CC is live out of MBB.
107 static 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.
115 static 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.
138 static 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.
147 Reference 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 (Register 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.
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.
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.
195 bool SystemZElimCompare::convertToBRCT(
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);
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.
249 bool SystemZElimCompare::convertToLoadAndTrap(
250  MachineInstr &MI, MachineInstr &Compare,
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);
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));
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.
289 bool SystemZElimCompare::convertToLoadAndTest(
290  MachineInstr &MI, MachineInstr &Compare,
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.
314 bool SystemZElimCompare::adjustCCMasksForInstr(
315  MachineInstr &MI, MachineInstr &Compare,
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.
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.
407 static 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.
426 bool 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;
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.
494 bool 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];
501  switch (Branch->getOpcode()) {
502  case SystemZ::BRC:
504  break;
505  case SystemZ::CondReturn:
507  break;
508  case SystemZ::CallBCR:
510  break;
511  case SystemZ::CondTrap:
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();
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 ||
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,
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.
595 bool 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);
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 
626 bool 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 
641  return new SystemZElimCompare(TM);
642 }
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand *> MMOs) const
const MachineInstrBuilder & add(const MachineOperand &MO) const
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:385
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:178
unsigned Reg
int findRegisterDefOperandIdx(Register Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a def of the specified register or -1 if it is not found...
static bool resultTests(MachineInstr &MI, unsigned Reg)
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
void setIsDead(bool Val=true)
F(f)
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:461
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const unsigned CCMASK_ICMP
Definition: SystemZ.h:46
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:414
A Use represents the edge between a Value definition and its users.
Definition: Use.h:55
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
The access may reference the value stored in memory.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:408
static bool isCompareZero(MachineInstr &Compare)
virtual const TargetInstrInfo * getInstrInfo() const
reverse_iterator rend()
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:518
static bool isCCLiveOut(MachineBasicBlock &MBB)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
Definition: MachineInstr.h:696
static bool preservesValueOf(MachineInstr &MI, unsigned Reg)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:52
bool isDebugInstr() const
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
static unsigned getCompareZeroCCMask(unsigned int Flags)
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:243
MachineOperand class - Representation of each machine instruction operand.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
const unsigned CCMASK_CMP_EQ
Definition: SystemZ.h:34
Promote Memory to Register
Definition: Mem2Reg.cpp:109
const unsigned CCMASK_CMP_NE
Definition: SystemZ.h:37
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
Target - Wrapper for Target specific information.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:256
MachineFunctionProperties & set(Property P)
static unsigned getCompareSourceReg(MachineInstr &Compare)
Representation of each machine instruction.
Definition: MachineInstr.h:64
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
#define I(x, y, z)
Definition: MD5.cpp:58
static unsigned getCCValues(unsigned int Flags)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
FunctionPass * createSystemZElimComparePass(SystemZTargetMachine &TM)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
static bool isLoadAndTestAsCmp(MachineInstr &MI)
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Properties which a MachineFunction may have at a given point in time.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19