LLVM  14.0.0git
SystemZPostRewrite.cpp
Go to the documentation of this file.
1 //==---- SystemZPostRewrite.cpp - Select pseudos after RegAlloc ---*- C++ -*-=//
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 file contains a pass that is run immediately after VirtRegRewriter
10 // but before MachineCopyPropagation. The purpose is to lower pseudos to
11 // target instructions before any later pass might substitute a register for
12 // another.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "SystemZ.h"
17 #include "SystemZInstrInfo.h"
18 #include "SystemZSubtarget.h"
19 #include "llvm/ADT/Statistic.h"
22 using namespace llvm;
23 
24 #define SYSTEMZ_POSTREWRITE_NAME "SystemZ Post Rewrite pass"
25 
26 #define DEBUG_TYPE "systemz-postrewrite"
27 STATISTIC(MemFoldCopies, "Number of copies inserted before folded mem ops.");
28 STATISTIC(LOCRMuxJumps, "Number of LOCRMux jump-sequences (lower is better)");
29 
30 namespace llvm {
32 }
33 
34 namespace {
35 
36 class SystemZPostRewrite : public MachineFunctionPass {
37 public:
38  static char ID;
39  SystemZPostRewrite() : MachineFunctionPass(ID) {
41  }
42 
43  const SystemZInstrInfo *TII;
44 
45  bool runOnMachineFunction(MachineFunction &Fn) override;
46 
47  StringRef getPassName() const override { return SYSTEMZ_POSTREWRITE_NAME; }
48 
49 private:
50  void selectLOCRMux(MachineBasicBlock &MBB,
53  unsigned LowOpcode,
54  unsigned HighOpcode);
55  void selectSELRMux(MachineBasicBlock &MBB,
58  unsigned LowOpcode,
59  unsigned HighOpcode);
60  bool expandCondMove(MachineBasicBlock &MBB,
62  MachineBasicBlock::iterator &NextMBBI);
64  MachineBasicBlock::iterator &NextMBBI);
65  bool selectMBB(MachineBasicBlock &MBB);
66 };
67 
68 char SystemZPostRewrite::ID = 0;
69 
70 } // end anonymous namespace
71 
72 INITIALIZE_PASS(SystemZPostRewrite, "systemz-post-rewrite",
73  SYSTEMZ_POSTREWRITE_NAME, false, false)
74 
75 /// Returns an instance of the Post Rewrite pass.
77  return new SystemZPostRewrite();
78 }
79 
80 // MI is a load-register-on-condition pseudo instruction. Replace it with
81 // LowOpcode if source and destination are both low GR32s and HighOpcode if
82 // source and destination are both high GR32s. Otherwise, a branch sequence
83 // is created.
84 void SystemZPostRewrite::selectLOCRMux(MachineBasicBlock &MBB,
87  unsigned LowOpcode,
88  unsigned HighOpcode) {
89  Register DestReg = MBBI->getOperand(0).getReg();
90  Register SrcReg = MBBI->getOperand(2).getReg();
91  bool DestIsHigh = SystemZ::isHighReg(DestReg);
92  bool SrcIsHigh = SystemZ::isHighReg(SrcReg);
93 
94  if (!DestIsHigh && !SrcIsHigh)
95  MBBI->setDesc(TII->get(LowOpcode));
96  else if (DestIsHigh && SrcIsHigh)
97  MBBI->setDesc(TII->get(HighOpcode));
98  else
99  expandCondMove(MBB, MBBI, NextMBBI);
100 }
101 
102 // MI is a select pseudo instruction. Replace it with LowOpcode if source
103 // and destination are all low GR32s and HighOpcode if source and destination
104 // are all high GR32s. Otherwise, a branch sequence is created.
105 void SystemZPostRewrite::selectSELRMux(MachineBasicBlock &MBB,
107  MachineBasicBlock::iterator &NextMBBI,
108  unsigned LowOpcode,
109  unsigned HighOpcode) {
110  Register DestReg = MBBI->getOperand(0).getReg();
111  Register Src1Reg = MBBI->getOperand(1).getReg();
112  Register Src2Reg = MBBI->getOperand(2).getReg();
113  bool DestIsHigh = SystemZ::isHighReg(DestReg);
114  bool Src1IsHigh = SystemZ::isHighReg(Src1Reg);
115  bool Src2IsHigh = SystemZ::isHighReg(Src2Reg);
116 
117  // If sources and destination aren't all high or all low, we may be able to
118  // simplify the operation by moving one of the sources to the destination
119  // first. But only if this doesn't clobber the other source.
120  if (DestReg != Src1Reg && DestReg != Src2Reg) {
121  if (DestIsHigh != Src1IsHigh) {
122  BuildMI(*MBBI->getParent(), MBBI, MBBI->getDebugLoc(),
123  TII->get(SystemZ::COPY), DestReg)
124  .addReg(MBBI->getOperand(1).getReg(), getRegState(MBBI->getOperand(1)));
125  MBBI->getOperand(1).setReg(DestReg);
126  Src1Reg = DestReg;
127  Src1IsHigh = DestIsHigh;
128  } else if (DestIsHigh != Src2IsHigh) {
129  BuildMI(*MBBI->getParent(), MBBI, MBBI->getDebugLoc(),
130  TII->get(SystemZ::COPY), DestReg)
131  .addReg(MBBI->getOperand(2).getReg(), getRegState(MBBI->getOperand(2)));
132  MBBI->getOperand(2).setReg(DestReg);
133  Src2Reg = DestReg;
134  Src2IsHigh = DestIsHigh;
135  }
136  }
137 
138  // If the destination (now) matches one source, prefer this to be first.
139  if (DestReg != Src1Reg && DestReg == Src2Reg) {
140  TII->commuteInstruction(*MBBI, false, 1, 2);
141  std::swap(Src1Reg, Src2Reg);
142  std::swap(Src1IsHigh, Src2IsHigh);
143  }
144 
145  if (!DestIsHigh && !Src1IsHigh && !Src2IsHigh)
146  MBBI->setDesc(TII->get(LowOpcode));
147  else if (DestIsHigh && Src1IsHigh && Src2IsHigh)
148  MBBI->setDesc(TII->get(HighOpcode));
149  else
150  // Given the simplification above, we must already have a two-operand case.
151  expandCondMove(MBB, MBBI, NextMBBI);
152 }
153 
154 // Replace MBBI by a branch sequence that performs a conditional move of
155 // operand 2 to the destination register. Operand 1 is expected to be the
156 // same register as the destination.
157 bool SystemZPostRewrite::expandCondMove(MachineBasicBlock &MBB,
159  MachineBasicBlock::iterator &NextMBBI) {
160  MachineFunction &MF = *MBB.getParent();
161  const BasicBlock *BB = MBB.getBasicBlock();
162  MachineInstr &MI = *MBBI;
163  DebugLoc DL = MI.getDebugLoc();
164  Register DestReg = MI.getOperand(0).getReg();
165  Register SrcReg = MI.getOperand(2).getReg();
166  unsigned CCValid = MI.getOperand(3).getImm();
167  unsigned CCMask = MI.getOperand(4).getImm();
168  assert(DestReg == MI.getOperand(1).getReg() &&
169  "Expected destination and first source operand to be the same.");
170 
171  LivePhysRegs LiveRegs(TII->getRegisterInfo());
172  LiveRegs.addLiveOuts(MBB);
173  for (auto I = std::prev(MBB.end()); I != MBBI; --I)
174  LiveRegs.stepBackward(*I);
175 
176  // Splice MBB at MI, moving the rest of the block into RestMBB.
178  MF.insert(std::next(MachineFunction::iterator(MBB)), RestMBB);
179  RestMBB->splice(RestMBB->begin(), &MBB, MI, MBB.end());
180  RestMBB->transferSuccessors(&MBB);
181  for (auto I = LiveRegs.begin(); I != LiveRegs.end(); ++I)
182  RestMBB->addLiveIn(*I);
183 
184  // Create a new block MoveMBB to hold the move instruction.
186  MF.insert(std::next(MachineFunction::iterator(MBB)), MoveMBB);
187  MoveMBB->addLiveIn(SrcReg);
188  for (auto I = LiveRegs.begin(); I != LiveRegs.end(); ++I)
189  MoveMBB->addLiveIn(*I);
190 
191  // At the end of MBB, create a conditional branch to RestMBB if the
192  // condition is false, otherwise fall through to MoveMBB.
193  BuildMI(&MBB, DL, TII->get(SystemZ::BRC))
194  .addImm(CCValid).addImm(CCMask ^ CCValid).addMBB(RestMBB);
195  MBB.addSuccessor(RestMBB);
196  MBB.addSuccessor(MoveMBB);
197 
198  // In MoveMBB, emit an instruction to move SrcReg into DestReg,
199  // then fall through to RestMBB.
200  BuildMI(*MoveMBB, MoveMBB->end(), DL, TII->get(SystemZ::COPY), DestReg)
201  .addReg(MI.getOperand(2).getReg(), getRegState(MI.getOperand(2)));
202  MoveMBB->addSuccessor(RestMBB);
203 
204  NextMBBI = MBB.end();
205  MI.eraseFromParent();
206  LOCRMuxJumps++;
207  return true;
208 }
209 
210 /// If MBBI references a pseudo instruction that should be selected here,
211 /// do it and return true. Otherwise return false.
212 bool SystemZPostRewrite::selectMI(MachineBasicBlock &MBB,
214  MachineBasicBlock::iterator &NextMBBI) {
215  MachineInstr &MI = *MBBI;
216  unsigned Opcode = MI.getOpcode();
217 
218  // Note: If this could be done during regalloc in foldMemoryOperandImpl()
219  // while also updating the LiveIntervals, there would be no need for the
220  // MemFoldPseudo to begin with.
221  int TargetMemOpcode = SystemZ::getTargetMemOpcode(Opcode);
222  if (TargetMemOpcode != -1) {
223  MI.setDesc(TII->get(TargetMemOpcode));
224  MI.tieOperands(0, 1);
225  Register DstReg = MI.getOperand(0).getReg();
226  MachineOperand &SrcMO = MI.getOperand(1);
227  if (DstReg != SrcMO.getReg()) {
228  BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(SystemZ::COPY), DstReg)
229  .addReg(SrcMO.getReg());
230  SrcMO.setReg(DstReg);
231  MemFoldCopies++;
232  }
233  return true;
234  }
235 
236  switch (Opcode) {
237  case SystemZ::LOCRMux:
238  selectLOCRMux(MBB, MBBI, NextMBBI, SystemZ::LOCR, SystemZ::LOCFHR);
239  return true;
240  case SystemZ::SELRMux:
241  selectSELRMux(MBB, MBBI, NextMBBI, SystemZ::SELR, SystemZ::SELFHR);
242  return true;
243  }
244 
245  return false;
246 }
247 
248 /// Iterate over the instructions in basic block MBB and select any
249 /// pseudo instructions. Return true if anything was modified.
250 bool SystemZPostRewrite::selectMBB(MachineBasicBlock &MBB) {
251  bool Modified = false;
252 
254  while (MBBI != E) {
255  MachineBasicBlock::iterator NMBBI = std::next(MBBI);
256  Modified |= selectMI(MBB, MBBI, NMBBI);
257  MBBI = NMBBI;
258  }
259 
260  return Modified;
261 }
262 
263 bool SystemZPostRewrite::runOnMachineFunction(MachineFunction &MF) {
264  TII = static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
265 
266  bool Modified = false;
267  for (auto &MBB : MF)
268  Modified |= selectMBB(MBB);
269 
270  return Modified;
271 }
272 
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
INITIALIZE_PASS
INITIALIZE_PASS(SystemZPostRewrite, "systemz-post-rewrite", SYSTEMZ_POSTREWRITE_NAME, false, false) FunctionPass *llvm
Returns an instance of the Post Rewrite pass.
Definition: SystemZPostRewrite.cpp:72
llvm::MachineBasicBlock::getBasicBlock
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
Definition: MachineBasicBlock.h:202
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:92
Statistic.h
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::LivePhysRegs
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Definition: LivePhysRegs.h:48
llvm::initializeSystemZPostRewritePass
void initializeSystemZPostRewritePass(PassRegistry &)
llvm::MachineFunction::insert
void insert(iterator MBBI, MachineBasicBlock *MBB)
Definition: MachineFunction.h:827
llvm::SystemZInstrInfo
Definition: SystemZInstrInfo.h:174
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
llvm::MachineBasicBlock::addSuccessor
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Definition: MachineBasicBlock.cpp:746
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:146
SystemZInstrInfo.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
LoopDeletionResult::Modified
@ Modified
llvm::SystemZ::isHighReg
bool isHighReg(unsigned int Reg)
Definition: SystemZRegisterInfo.h:34
SystemZ.h
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::getRegState
unsigned getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
Definition: MachineInstrBuilder.h:528
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::SystemZTargetMachine
Definition: SystemZTargetMachine.h:27
llvm::MachineFunction::CreateMachineBasicBlock
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Definition: MachineFunction.cpp:414
MachineFunctionPass.h
SYSTEMZ_POSTREWRITE_NAME
#define SYSTEMZ_POSTREWRITE_NAME
Definition: SystemZPostRewrite.cpp:24
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:225
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineFunction
Definition: MachineFunction.h:230
SystemZSubtarget.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MachineBasicBlock::splice
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
Definition: MachineBasicBlock.h:950
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition: AArch64SLSHardening.cpp:75
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::SystemZ::getTargetMemOpcode
int getTargetMemOpcode(uint16_t Opcode)
llvm::MachineBasicBlock::transferSuccessors
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
Definition: MachineBasicBlock.cpp:865
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineBasicBlock::addLiveIn
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
Definition: MachineBasicBlock.h:367
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::ilist_iterator
Iterator for intrusive lists based on ilist_node.
Definition: ilist_iterator.h:57
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
llvm::MachineOperand::setReg
void setReg(Register Reg)
Change the register this operand corresponds to.
Definition: MachineOperand.cpp:55
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::createSystemZPostRewritePass
FunctionPass * createSystemZPostRewritePass(SystemZTargetMachine &TM)
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37