LLVM  9.0.0svn
SystemZShortenInst.cpp
Go to the documentation of this file.
1 //===-- SystemZShortenInst.cpp - Instruction-shortening pass --------------===//
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 tries to replace instructions with shorter forms. For example,
10 // IILF can be replaced with LLILL or LLILH if the constant fits and if the
11 // other 32 bits of the GR64 destination are not live.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "SystemZTargetMachine.h"
20 
21 using namespace llvm;
22 
23 #define DEBUG_TYPE "systemz-shorten-inst"
24 
25 namespace {
26 class SystemZShortenInst : public MachineFunctionPass {
27 public:
28  static char ID;
29  SystemZShortenInst(const SystemZTargetMachine &tm);
30 
31  StringRef getPassName() const override {
32  return "SystemZ Instruction Shortening";
33  }
34 
35  bool processBlock(MachineBasicBlock &MBB);
36  bool runOnMachineFunction(MachineFunction &F) override;
37  MachineFunctionProperties getRequiredProperties() const override {
40  }
41 
42 private:
43  bool shortenIIF(MachineInstr &MI, unsigned LLIxL, unsigned LLIxH);
44  bool shortenOn0(MachineInstr &MI, unsigned Opcode);
45  bool shortenOn01(MachineInstr &MI, unsigned Opcode);
46  bool shortenOn001(MachineInstr &MI, unsigned Opcode);
47  bool shortenOn001AddCC(MachineInstr &MI, unsigned Opcode);
48  bool shortenFPConv(MachineInstr &MI, unsigned Opcode);
49 
50  const SystemZInstrInfo *TII;
51  const TargetRegisterInfo *TRI;
52  LivePhysRegs LiveRegs;
53 };
54 
55 char SystemZShortenInst::ID = 0;
56 } // end anonymous namespace
57 
59  return new SystemZShortenInst(TM);
60 }
61 
62 SystemZShortenInst::SystemZShortenInst(const SystemZTargetMachine &tm)
63  : MachineFunctionPass(ID), TII(nullptr) {}
64 
65 // Tie operands if MI has become a two-address instruction.
68  !MI.getOperand(0).isTied())
69  MI.tieOperands(0, 1);
70 }
71 
72 // MI loads one word of a GPR using an IIxF instruction and LLIxL and LLIxH
73 // are the halfword immediate loads for the same word. Try to use one of them
74 // instead of IIxF.
75 bool SystemZShortenInst::shortenIIF(MachineInstr &MI, unsigned LLIxL,
76  unsigned LLIxH) {
77  unsigned Reg = MI.getOperand(0).getReg();
78  // The new opcode will clear the other half of the GR64 reg, so
79  // cancel if that is live.
80  unsigned thisSubRegIdx =
81  (SystemZ::GRH32BitRegClass.contains(Reg) ? SystemZ::subreg_h32
82  : SystemZ::subreg_l32);
83  unsigned otherSubRegIdx =
84  (thisSubRegIdx == SystemZ::subreg_l32 ? SystemZ::subreg_h32
85  : SystemZ::subreg_l32);
86  unsigned GR64BitReg =
87  TRI->getMatchingSuperReg(Reg, thisSubRegIdx, &SystemZ::GR64BitRegClass);
88  unsigned OtherReg = TRI->getSubReg(GR64BitReg, otherSubRegIdx);
89  if (LiveRegs.contains(OtherReg))
90  return false;
91 
92  uint64_t Imm = MI.getOperand(1).getImm();
93  if (SystemZ::isImmLL(Imm)) {
94  MI.setDesc(TII->get(LLIxL));
96  return true;
97  }
98  if (SystemZ::isImmLH(Imm)) {
99  MI.setDesc(TII->get(LLIxH));
101  MI.getOperand(1).setImm(Imm >> 16);
102  return true;
103  }
104  return false;
105 }
106 
107 // Change MI's opcode to Opcode if register operand 0 has a 4-bit encoding.
108 bool SystemZShortenInst::shortenOn0(MachineInstr &MI, unsigned Opcode) {
109  if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16) {
110  MI.setDesc(TII->get(Opcode));
111  return true;
112  }
113  return false;
114 }
115 
116 // Change MI's opcode to Opcode if register operands 0 and 1 have a
117 // 4-bit encoding.
118 bool SystemZShortenInst::shortenOn01(MachineInstr &MI, unsigned Opcode) {
119  if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
120  SystemZMC::getFirstReg(MI.getOperand(1).getReg()) < 16) {
121  MI.setDesc(TII->get(Opcode));
122  return true;
123  }
124  return false;
125 }
126 
127 // Change MI's opcode to Opcode if register operands 0, 1 and 2 have a
128 // 4-bit encoding and if operands 0 and 1 are tied. Also ties op 0
129 // with op 1, if MI becomes 2-address.
130 bool SystemZShortenInst::shortenOn001(MachineInstr &MI, unsigned Opcode) {
131  if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
132  MI.getOperand(1).getReg() == MI.getOperand(0).getReg() &&
133  SystemZMC::getFirstReg(MI.getOperand(2).getReg()) < 16) {
134  MI.setDesc(TII->get(Opcode));
135  tieOpsIfNeeded(MI);
136  return true;
137  }
138  return false;
139 }
140 
141 // Calls shortenOn001 if CCLive is false. CC def operand is added in
142 // case of success.
143 bool SystemZShortenInst::shortenOn001AddCC(MachineInstr &MI, unsigned Opcode) {
144  if (!LiveRegs.contains(SystemZ::CC) && shortenOn001(MI, Opcode)) {
146  .addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead);
147  return true;
148  }
149  return false;
150 }
151 
152 // MI is a vector-style conversion instruction with the operand order:
153 // destination, source, exact-suppress, rounding-mode. If both registers
154 // have a 4-bit encoding then change it to Opcode, which has operand order:
155 // destination, rouding-mode, source, exact-suppress.
156 bool SystemZShortenInst::shortenFPConv(MachineInstr &MI, unsigned Opcode) {
157  if (SystemZMC::getFirstReg(MI.getOperand(0).getReg()) < 16 &&
158  SystemZMC::getFirstReg(MI.getOperand(1).getReg()) < 16) {
159  MachineOperand Dest(MI.getOperand(0));
160  MachineOperand Src(MI.getOperand(1));
161  MachineOperand Suppress(MI.getOperand(2));
163  MI.RemoveOperand(3);
164  MI.RemoveOperand(2);
165  MI.RemoveOperand(1);
166  MI.RemoveOperand(0);
167  MI.setDesc(TII->get(Opcode));
169  .add(Dest)
170  .add(Mode)
171  .add(Src)
172  .add(Suppress);
173  return true;
174  }
175  return false;
176 }
177 
178 // Process all instructions in MBB. Return true if something changed.
179 bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) {
180  bool Changed = false;
181 
182  // Set up the set of live registers at the end of MBB (live out)
183  LiveRegs.clear();
184  LiveRegs.addLiveOuts(MBB);
185 
186  // Iterate backwards through the block looking for instructions to change.
187  for (auto MBBI = MBB.rbegin(), MBBE = MBB.rend(); MBBI != MBBE; ++MBBI) {
188  MachineInstr &MI = *MBBI;
189  switch (MI.getOpcode()) {
190  case SystemZ::IILF:
191  Changed |= shortenIIF(MI, SystemZ::LLILL, SystemZ::LLILH);
192  break;
193 
194  case SystemZ::IIHF:
195  Changed |= shortenIIF(MI, SystemZ::LLIHL, SystemZ::LLIHH);
196  break;
197 
198  case SystemZ::WFADB:
199  Changed |= shortenOn001AddCC(MI, SystemZ::ADBR);
200  break;
201 
202  case SystemZ::WFASB:
203  Changed |= shortenOn001AddCC(MI, SystemZ::AEBR);
204  break;
205 
206  case SystemZ::WFDDB:
207  Changed |= shortenOn001(MI, SystemZ::DDBR);
208  break;
209 
210  case SystemZ::WFDSB:
211  Changed |= shortenOn001(MI, SystemZ::DEBR);
212  break;
213 
214  case SystemZ::WFIDB:
215  Changed |= shortenFPConv(MI, SystemZ::FIDBRA);
216  break;
217 
218  case SystemZ::WFISB:
219  Changed |= shortenFPConv(MI, SystemZ::FIEBRA);
220  break;
221 
222  case SystemZ::WLDEB:
223  Changed |= shortenOn01(MI, SystemZ::LDEBR);
224  break;
225 
226  case SystemZ::WLEDB:
227  Changed |= shortenFPConv(MI, SystemZ::LEDBRA);
228  break;
229 
230  case SystemZ::WFMDB:
231  Changed |= shortenOn001(MI, SystemZ::MDBR);
232  break;
233 
234  case SystemZ::WFMSB:
235  Changed |= shortenOn001(MI, SystemZ::MEEBR);
236  break;
237 
238  case SystemZ::WFLCDB:
239  Changed |= shortenOn01(MI, SystemZ::LCDFR);
240  break;
241 
242  case SystemZ::WFLCSB:
243  Changed |= shortenOn01(MI, SystemZ::LCDFR_32);
244  break;
245 
246  case SystemZ::WFLNDB:
247  Changed |= shortenOn01(MI, SystemZ::LNDFR);
248  break;
249 
250  case SystemZ::WFLNSB:
251  Changed |= shortenOn01(MI, SystemZ::LNDFR_32);
252  break;
253 
254  case SystemZ::WFLPDB:
255  Changed |= shortenOn01(MI, SystemZ::LPDFR);
256  break;
257 
258  case SystemZ::WFLPSB:
259  Changed |= shortenOn01(MI, SystemZ::LPDFR_32);
260  break;
261 
262  case SystemZ::WFSQDB:
263  Changed |= shortenOn01(MI, SystemZ::SQDBR);
264  break;
265 
266  case SystemZ::WFSQSB:
267  Changed |= shortenOn01(MI, SystemZ::SQEBR);
268  break;
269 
270  case SystemZ::WFSDB:
271  Changed |= shortenOn001AddCC(MI, SystemZ::SDBR);
272  break;
273 
274  case SystemZ::WFSSB:
275  Changed |= shortenOn001AddCC(MI, SystemZ::SEBR);
276  break;
277 
278  case SystemZ::WFCDB:
279  Changed |= shortenOn01(MI, SystemZ::CDBR);
280  break;
281 
282  case SystemZ::WFCSB:
283  Changed |= shortenOn01(MI, SystemZ::CEBR);
284  break;
285 
286  case SystemZ::VL32:
287  // For z13 we prefer LDE over LE to avoid partial register dependencies.
288  Changed |= shortenOn0(MI, SystemZ::LDE32);
289  break;
290 
291  case SystemZ::VST32:
292  Changed |= shortenOn0(MI, SystemZ::STE);
293  break;
294 
295  case SystemZ::VL64:
296  Changed |= shortenOn0(MI, SystemZ::LD);
297  break;
298 
299  case SystemZ::VST64:
300  Changed |= shortenOn0(MI, SystemZ::STD);
301  break;
302  }
303 
304  LiveRegs.stepBackward(MI);
305  }
306 
307  return Changed;
308 }
309 
310 bool SystemZShortenInst::runOnMachineFunction(MachineFunction &F) {
311  if (skipFunction(F.getFunction()))
312  return false;
313 
315  TII = ST.getInstrInfo();
316  TRI = ST.getRegisterInfo();
317  LiveRegs.init(*TRI);
318 
319  bool Changed = false;
320  for (auto &MBB : F)
321  Changed |= processBlock(MBB);
322 
323  return Changed;
324 }
SI Whole Quad Mode
unsigned getFirstReg(unsigned Reg)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
unsigned getReg() const
getReg - Returns the register number.
unsigned Reg
unsigned const TargetRegisterInfo * TRI
F(f)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:408
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:405
FunctionPass * createSystemZShortenInstPass(SystemZTargetMachine &TM)
reverse_iterator rend()
reverse_iterator rbegin()
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void setImm(int64_t immVal)
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...
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static bool isImmLH(uint64_t Val)
Definition: SystemZ.h:165
const SystemZInstrInfo * getInstrInfo() const override
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specific constraint if it is set.
Definition: MCInstrDesc.h:187
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
MachineOperand class - Representation of each machine instruction operand.
unsigned getRegAsGR64(unsigned Reg)
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:253
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
Definition: MachineInstr.h:63
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Definition: LivePhysRegs.h:48
void setReg(unsigned Reg)
Change the register this operand corresponds to.
static void tieOpsIfNeeded(MachineInstr &MI)
static bool isImmLL(uint64_t Val)
Definition: SystemZ.h:160
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...
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:413
const SystemZRegisterInfo * getRegisterInfo() const override
Properties which a MachineFunction may have at a given point in time.
void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.