1 //==-- SystemZExpandPseudo.cpp - Expand pseudo instructions -------*- C++ -*-=//
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 //===----------------------------------------------------------------------===//
9 // This file contains a pass that expands pseudo instructions into target
10 // instructions to allow proper scheduling and other late optimizations. This
11 // pass should be run after register allocation but before the post-regalloc
14 //===----------------------------------------------------------------------===//
17 #include "SystemZInstrInfo.h"
18 #include "SystemZSubtarget.h"
19 #include "llvm/CodeGen/LivePhysRegs.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #define SYSTEMZ_EXPAND_PSEUDO_NAME "SystemZ pseudo instruction expansion pass"
27 void initializeSystemZExpandPseudoPass(PassRegistry
&);
31 class SystemZExpandPseudo
: public MachineFunctionPass
{
34 SystemZExpandPseudo() : MachineFunctionPass(ID
) {
35 initializeSystemZExpandPseudoPass(*PassRegistry::getPassRegistry());
38 const SystemZInstrInfo
*TII
;
40 bool runOnMachineFunction(MachineFunction
&Fn
) override
;
42 StringRef
getPassName() const override
{ return SYSTEMZ_EXPAND_PSEUDO_NAME
; }
45 bool expandMBB(MachineBasicBlock
&MBB
);
46 bool expandMI(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
47 MachineBasicBlock::iterator
&NextMBBI
);
48 bool expandLOCRMux(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
49 MachineBasicBlock::iterator
&NextMBBI
);
51 char SystemZExpandPseudo::ID
= 0;
54 INITIALIZE_PASS(SystemZExpandPseudo
, "systemz-expand-pseudo",
55 SYSTEMZ_EXPAND_PSEUDO_NAME
, false, false)
57 /// Returns an instance of the pseudo instruction expansion pass.
58 FunctionPass
*llvm::createSystemZExpandPseudoPass(SystemZTargetMachine
&TM
) {
59 return new SystemZExpandPseudo();
62 // MI is a load-register-on-condition pseudo instruction that could not be
63 // handled as a single hardware instruction. Replace it by a branch sequence.
64 bool SystemZExpandPseudo::expandLOCRMux(MachineBasicBlock
&MBB
,
65 MachineBasicBlock::iterator MBBI
,
66 MachineBasicBlock::iterator
&NextMBBI
) {
67 MachineFunction
&MF
= *MBB
.getParent();
68 const BasicBlock
*BB
= MBB
.getBasicBlock();
69 MachineInstr
&MI
= *MBBI
;
70 DebugLoc DL
= MI
.getDebugLoc();
71 Register DestReg
= MI
.getOperand(0).getReg();
72 Register SrcReg
= MI
.getOperand(2).getReg();
73 unsigned CCValid
= MI
.getOperand(3).getImm();
74 unsigned CCMask
= MI
.getOperand(4).getImm();
76 LivePhysRegs
LiveRegs(TII
->getRegisterInfo());
77 LiveRegs
.addLiveOuts(MBB
);
78 for (auto I
= std::prev(MBB
.end()); I
!= MBBI
; --I
)
79 LiveRegs
.stepBackward(*I
);
81 // Splice MBB at MI, moving the rest of the block into RestMBB.
82 MachineBasicBlock
*RestMBB
= MF
.CreateMachineBasicBlock(BB
);
83 MF
.insert(std::next(MachineFunction::iterator(MBB
)), RestMBB
);
84 RestMBB
->splice(RestMBB
->begin(), &MBB
, MI
, MBB
.end());
85 RestMBB
->transferSuccessors(&MBB
);
86 for (auto I
= LiveRegs
.begin(); I
!= LiveRegs
.end(); ++I
)
87 RestMBB
->addLiveIn(*I
);
89 // Create a new block MoveMBB to hold the move instruction.
90 MachineBasicBlock
*MoveMBB
= MF
.CreateMachineBasicBlock(BB
);
91 MF
.insert(std::next(MachineFunction::iterator(MBB
)), MoveMBB
);
92 MoveMBB
->addLiveIn(SrcReg
);
93 for (auto I
= LiveRegs
.begin(); I
!= LiveRegs
.end(); ++I
)
94 MoveMBB
->addLiveIn(*I
);
96 // At the end of MBB, create a conditional branch to RestMBB if the
97 // condition is false, otherwise fall through to MoveMBB.
98 BuildMI(&MBB
, DL
, TII
->get(SystemZ::BRC
))
99 .addImm(CCValid
).addImm(CCMask
^ CCValid
).addMBB(RestMBB
);
100 MBB
.addSuccessor(RestMBB
);
101 MBB
.addSuccessor(MoveMBB
);
103 // In MoveMBB, emit an instruction to move SrcReg into DestReg,
104 // then fall through to RestMBB.
105 TII
->copyPhysReg(*MoveMBB
, MoveMBB
->end(), DL
, DestReg
, SrcReg
,
106 MI
.getOperand(2).isKill());
107 MoveMBB
->addSuccessor(RestMBB
);
109 NextMBBI
= MBB
.end();
110 MI
.eraseFromParent();
114 /// If MBBI references a pseudo instruction that should be expanded here,
115 /// do the expansion and return true. Otherwise return false.
116 bool SystemZExpandPseudo::expandMI(MachineBasicBlock
&MBB
,
117 MachineBasicBlock::iterator MBBI
,
118 MachineBasicBlock::iterator
&NextMBBI
) {
119 MachineInstr
&MI
= *MBBI
;
120 switch (MI
.getOpcode()) {
121 case SystemZ::LOCRMux
:
122 return expandLOCRMux(MBB
, MBBI
, NextMBBI
);
129 /// Iterate over the instructions in basic block MBB and expand any
130 /// pseudo instructions. Return true if anything was modified.
131 bool SystemZExpandPseudo::expandMBB(MachineBasicBlock
&MBB
) {
132 bool Modified
= false;
134 MachineBasicBlock::iterator MBBI
= MBB
.begin(), E
= MBB
.end();
136 MachineBasicBlock::iterator NMBBI
= std::next(MBBI
);
137 Modified
|= expandMI(MBB
, MBBI
, NMBBI
);
144 bool SystemZExpandPseudo::runOnMachineFunction(MachineFunction
&MF
) {
145 TII
= static_cast<const SystemZInstrInfo
*>(MF
.getSubtarget().getInstrInfo());
147 bool Modified
= false;
149 Modified
|= expandMBB(MBB
);