LLVM  9.0.0svn
PPCQPXLoadSplat.cpp
Go to the documentation of this file.
1 //===----- PPCQPXLoadSplat.cpp - QPX Load Splat Simplification ------------===//
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 // The QPX vector registers overlay the scalar floating-point registers, and
10 // any scalar floating-point loads splat their value across all vector lanes.
11 // Thus, if we have a scalar load followed by a splat, we can remove the splat
12 // (i.e. replace the load with a load-and-splat pseudo instruction).
13 //
14 // This pass must run after anything that might do store-to-load forwarding.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #include "PPC.h"
19 #include "PPCInstrBuilder.h"
20 #include "PPCInstrInfo.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/Statistic.h"
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "ppc-qpx-load-splat"
30 
31 STATISTIC(NumSimplified, "Number of QPX load splats simplified");
32 
33 namespace llvm {
35 }
36 
37 namespace {
38  struct PPCQPXLoadSplat : public MachineFunctionPass {
39  static char ID;
40  PPCQPXLoadSplat() : MachineFunctionPass(ID) {
42  }
43 
44  bool runOnMachineFunction(MachineFunction &Fn) override;
45 
46  StringRef getPassName() const override {
47  return "PowerPC QPX Load Splat Simplification";
48  }
49  };
50  char PPCQPXLoadSplat::ID = 0;
51 }
52 
53 INITIALIZE_PASS(PPCQPXLoadSplat, "ppc-qpx-load-splat",
54  "PowerPC QPX Load Splat Simplification",
55  false, false)
56 
58  return new PPCQPXLoadSplat();
59 }
60 
61 bool PPCQPXLoadSplat::runOnMachineFunction(MachineFunction &MF) {
62  if (skipFunction(MF.getFunction()))
63  return false;
64 
65  bool MadeChange = false;
67 
68  for (auto MFI = MF.begin(), MFIE = MF.end(); MFI != MFIE; ++MFI) {
69  MachineBasicBlock *MBB = &*MFI;
71 
72  for (auto MBBI = MBB->rbegin(); MBBI != MBB->rend(); ++MBBI) {
73  MachineInstr *MI = &*MBBI;
74 
75  if (MI->hasUnmodeledSideEffects() || MI->isCall()) {
76  Splats.clear();
77  continue;
78  }
79 
80  // We're looking for a sequence like this:
81  // %f0 = LFD 0, killed %x3, implicit-def %qf0; mem:LD8[%a](tbaa=!2)
82  // %qf1 = QVESPLATI killed %qf0, 0, implicit %rm
83 
84  for (auto SI = Splats.begin(); SI != Splats.end();) {
85  MachineInstr *SMI = *SI;
86  unsigned SplatReg = SMI->getOperand(0).getReg();
87  unsigned SrcReg = SMI->getOperand(1).getReg();
88 
89  if (MI->modifiesRegister(SrcReg, TRI)) {
90  switch (MI->getOpcode()) {
91  default:
92  SI = Splats.erase(SI);
93  continue;
94  case PPC::LFS:
95  case PPC::LFD:
96  case PPC::LFSU:
97  case PPC::LFDU:
98  case PPC::LFSUX:
99  case PPC::LFDUX:
100  case PPC::LFSX:
101  case PPC::LFDX:
102  case PPC::LFIWAX:
103  case PPC::LFIWZX:
104  if (SplatReg != SrcReg) {
105  // We need to change the load to define the scalar subregister of
106  // the QPX splat source register.
107  unsigned SubRegIndex =
108  TRI->getSubRegIndex(SrcReg, MI->getOperand(0).getReg());
109  unsigned SplatSubReg = TRI->getSubReg(SplatReg, SubRegIndex);
110 
111  // Substitute both the explicit defined register, and also the
112  // implicit def of the containing QPX register.
113  MI->getOperand(0).setReg(SplatSubReg);
114  MI->substituteRegister(SrcReg, SplatReg, 0, *TRI);
115  }
116 
117  SI = Splats.erase(SI);
118 
119  // If SMI is directly after MI, then MBBI's base iterator is
120  // pointing at SMI. Adjust MBBI around the call to erase SMI to
121  // avoid invalidating MBBI.
122  ++MBBI;
123  SMI->eraseFromParent();
124  --MBBI;
125 
126  ++NumSimplified;
127  MadeChange = true;
128  continue;
129  }
130  }
131 
132  // If this instruction defines the splat register, then we cannot move
133  // the previous definition above it. If it reads from the splat
134  // register, then it must already be alive from some previous
135  // definition, and if the splat register is different from the source
136  // register, then this definition must not be the load for which we're
137  // searching.
138  if (MI->modifiesRegister(SplatReg, TRI) ||
139  (SrcReg != SplatReg &&
140  MI->readsRegister(SplatReg, TRI))) {
141  SI = Splats.erase(SI);
142  continue;
143  }
144 
145  ++SI;
146  }
147 
148  if (MI->getOpcode() != PPC::QVESPLATI &&
149  MI->getOpcode() != PPC::QVESPLATIs &&
150  MI->getOpcode() != PPC::QVESPLATIb)
151  continue;
152  if (MI->getOperand(2).getImm() != 0)
153  continue;
154 
155  // If there are other uses of the scalar value after this, replacing
156  // those uses might be non-trivial.
157  if (!MI->getOperand(1).isKill())
158  continue;
159 
160  Splats.push_back(MI);
161  }
162  }
163 
164  return MadeChange;
165 }
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:632
This class represents lattice values for constants.
Definition: AllocatorList.h:23
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void push_back(const T &Elt)
Definition: SmallVector.h:211
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const
For a given register pair, return the sub-register index if the second register is a sub-register of ...
unsigned getReg() const
getReg - Returns the register number.
void initializePPCQPXLoadSplatPass(PassRegistry &)
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:408
reverse_iterator rend()
reverse_iterator rbegin()
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
INITIALIZE_PASS(PPCQPXLoadSplat, "ppc-qpx-load-splat", "PowerPC QPX Load Splat Simplification", false, false) FunctionPass *llvm
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
QVESPLATI = This corresponds to the QPX qvesplati instruction.
iterator erase(const_iterator CI)
Definition: SmallVector.h:437
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
int64_t getImm() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
Representation of each machine instruction.
Definition: MachineInstr.h:63
FunctionPass * createPPCQPXLoadSplatPass()
void setReg(unsigned Reg)
Change the register this operand corresponds to.
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:413
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...