1 //===-- SystemZElimCompare.cpp - Eliminate comparison instructions --------===//
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
7 //===----------------------------------------------------------------------===//
10 // (1) tries to remove compares if CC already contains the required information
11 // (2) fuses compares and branches into COMPARE AND BRANCH instructions
13 //===----------------------------------------------------------------------===//
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"
35 #define DEBUG_TYPE "systemz-elim-compare"
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");
44 // Represents the references to a particular register in one or more
47 Reference() = default;
49 Reference
&operator|=(const Reference
&Other
) {
55 explicit operator bool() const { return Def
|| Use
; }
57 // True if the register is defined or used in some form, either directly or
58 // via a sub- or super-register.
63 class SystemZElimCompare
: public MachineFunctionPass
{
67 SystemZElimCompare(const SystemZTargetMachine
&tm
)
68 : MachineFunctionPass(ID
) {}
70 StringRef
getPassName() const override
{
71 return "SystemZ Comparison Elimination";
74 bool processBlock(MachineBasicBlock
&MBB
);
75 bool runOnMachineFunction(MachineFunction
&F
) override
;
77 MachineFunctionProperties
getRequiredProperties() const override
{
78 return MachineFunctionProperties().set(
79 MachineFunctionProperties::Property::NoVRegs
);
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
);
98 const SystemZInstrInfo
*TII
= nullptr;
99 const TargetRegisterInfo
*TRI
= nullptr;
102 char SystemZElimCompare::ID
= 0;
104 } // end anonymous namespace
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
))
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()) {
129 if (MI
.getOperand(1).getReg() == Reg
)
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
)
143 return (preservesValueOf(MI
, Reg
));
146 // Describe the references to Reg or any of its aliases in MI.
147 Reference
SystemZElimCompare::getRegReferences(MachineInstr
&MI
, unsigned Reg
) {
149 if (MI
.isDebugInstr())
152 for (unsigned I
= 0, E
= MI
.getNumOperands(); I
!= E
; ++I
) {
153 const MachineOperand
&MO
= MI
.getOperand(I
);
155 if (unsigned MOReg
= MO
.getReg()) {
156 if (TRI
->regsOverlap(MOReg
, Reg
)) {
168 // Return true if this is a load and test which can be optimized the
169 // same way as compare instruction.
170 static 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();
179 // Return the source register of Compare, which is the unknown value
181 static unsigned getCompareSourceReg(MachineInstr
&Compare
) {
183 if (Compare
.isCompare())
184 reg
= Compare
.getOperand(0).getReg();
185 else if (isLoadAndTestAsCmp(Compare
))
186 reg
= Compare
.getOperand(1).getReg();
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(
196 MachineInstr
&MI
, MachineInstr
&Compare
,
197 SmallVectorImpl
<MachineInstr
*> &CCUsers
) {
198 // Check whether we have an addition of -1.
199 unsigned Opcode
= MI
.getOpcode();
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
;
209 if (MI
.getOperand(2).getImm() != -1)
212 // Check whether we have a single JLH.
213 if (CCUsers
.size() != 1)
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
)
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
))
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();
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
,
251 SmallVectorImpl
<MachineInstr
*> &CCUsers
) {
252 unsigned LATOpcode
= TII
->getLoadAndTrap(MI
.getOpcode());
256 // Check whether we have a single CondTrap that traps on zero.
257 if (CCUsers
.size() != 1)
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
)
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
))
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();
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
,
291 SmallVectorImpl
<MachineInstr
*> &CCUsers
) {
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
))
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())
302 MIB
.setMemRefs(MI
.memoperands());
303 MI
.eraseFromParent();
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
,
316 SmallVectorImpl
<MachineInstr
*> &CCUsers
,
318 int Opcode
= (ConvOpc
? ConvOpc
: MI
.getOpcode());
319 const MCInstrDesc
&Desc
= TII
->get(Opcode
);
320 unsigned MIFlags
= Desc
.TSFlags
;
322 // See which compare-style condition codes are available.
323 unsigned ReusableCCMask
= SystemZII::getCompareZeroCCMask(MIFlags
);
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
;
330 if (ReusableCCMask
== 0)
333 unsigned CCValues
= SystemZII::getCCValues(MIFlags
);
334 assert((ReusableCCMask
& ~CCValues
) == 0 && "Invalid CCValues");
336 bool MIEquivalentToCmp
=
337 (ReusableCCMask
== CCValues
&&
338 CCValues
== SystemZII::getCCValues(CompareFlags
));
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
];
346 // Fail if this isn't a use of CC that we understand.
347 unsigned Flags
= MI
->getDesc().TSFlags
;
349 if (Flags
& SystemZII::CCMaskFirst
)
351 else if (Flags
& SystemZII::CCMaskLast
)
352 FirstOpNum
= MI
->getNumExplicitOperands() - 2;
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
)
366 AlterMasks
.push_back(&MI
->getOperand(FirstOpNum
));
367 AlterMasks
.push_back(&MI
->getOperand(FirstOpNum
+ 1));
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
));
380 // CC is now live after MI.
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);
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
) {
396 // Clear any intervening kills of CC.
398 MachineBasicBlock::iterator MBBI
= MI
, MBBE
= Compare
;
399 for (++MBBI
; MBBI
!= MBBE
; ++MBBI
)
400 MBBI
->clearRegisterKills(SystemZ::CC
, TRI
);
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
:
415 if (isLoadAndTestAsCmp(Compare
))
417 return Compare
.getNumExplicitOperands() == 2 &&
418 Compare
.getOperand(1).isImm() && Compare
.getOperand(1).getImm() == 0;
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
))
431 // Search back for CC results that are based on the first operand.
432 unsigned SrcReg
= getCompareSourceReg(Compare
);
433 MachineBasicBlock
&MBB
= *Compare
.getParent();
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
)) {
449 if (convertToLoadAndTrap(MI
, Compare
, CCUsers
)) {
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;
461 SrcRefs
|= getRegReferences(MI
, SrcReg
);
464 CCRefs
|= getRegReferences(MI
, SystemZ::CC
);
465 if (CCRefs
.Use
&& CCRefs
.Def
)
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();
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;
483 if (getRegReferences(MI
, SrcReg
).Def
)
485 if (getRegReferences(MI
, SystemZ::CC
))
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)
499 MachineInstr
*Branch
= CCUsers
[0];
500 SystemZII::FusedCompareType Type
;
501 switch (Branch
->getOpcode()) {
503 Type
= SystemZII::CompareAndBranch
;
505 case SystemZ::CondReturn
:
506 Type
= SystemZII::CompareAndReturn
;
508 case SystemZ::CallBCR
:
509 Type
= SystemZII::CompareAndSibcall
;
511 case SystemZ::CondTrap
:
512 Type
= SystemZII::CompareAndTrap
;
518 // See whether we have a comparison that can be fused.
519 unsigned FusedOpcode
=
520 TII
->getFusedCompare(Compare
.getOpcode(), Type
, &Compare
);
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();
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
)))
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();
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);
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
)
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
));
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
);
579 if (Type
== SystemZII::CompareAndSibcall
)
580 MIB
.addRegMask(RegMask
);
582 // Clear any intervening kills of SrcReg and SrcReg2.
584 for (++MBBI
; MBBI
!= MBBE
; ++MBBI
) {
585 MBBI
->clearRegisterKills(SrcReg
, TRI
);
587 MBBI
->clearRegisterKills(SrcReg2
, TRI
);
589 FusedComparisons
+= 1;
593 // Process all comparison instructions in MBB. Return true if something
595 bool SystemZElimCompare::processBlock(MachineBasicBlock
&MBB
) {
596 bool Changed
= false;
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
))) {
610 MI
.eraseFromParent();
616 if (MI
.definesRegister(SystemZ::CC
)) {
618 CompleteCCUsers
= true;
620 if (MI
.readsRegister(SystemZ::CC
) && CompleteCCUsers
)
621 CCUsers
.push_back(&MI
);
626 bool SystemZElimCompare::runOnMachineFunction(MachineFunction
&F
) {
627 if (skipFunction(F
.getFunction()))
630 TII
= static_cast<const SystemZInstrInfo
*>(F
.getSubtarget().getInstrInfo());
631 TRI
= &TII
->getRegisterInfo();
633 bool Changed
= false;
635 Changed
|= processBlock(MBB
);
640 FunctionPass
*llvm::createSystemZElimComparePass(SystemZTargetMachine
&TM
) {
641 return new SystemZElimCompare(TM
);