1 //===----- PPCQPXLoadSplat.cpp - QPX Load Splat Simplification ------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // The QPX vector registers overlay the scalar floating-point registers, and
11 // any scalar floating-point loads splat their value across all vector lanes.
12 // Thus, if we have a scalar load followed by a splat, we can remove the splat
13 // (i.e. replace the load with a load-and-splat pseudo instruction).
15 // This pass must run after anything that might do store-to-load forwarding.
17 //===----------------------------------------------------------------------===//
20 #include "PPCInstrBuilder.h"
21 #include "PPCInstrInfo.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/Statistic.h"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/Support/MathExtras.h"
26 #include "llvm/Target/TargetMachine.h"
27 #include "llvm/Target/TargetSubtargetInfo.h"
30 #define DEBUG_TYPE "ppc-qpx-load-splat"
32 STATISTIC(NumSimplified, "Number of QPX load splats simplified");
35 void initializePPCQPXLoadSplatPass(PassRegistry&);
39 struct PPCQPXLoadSplat : public MachineFunctionPass {
41 PPCQPXLoadSplat() : MachineFunctionPass(ID) {
42 initializePPCQPXLoadSplatPass(*PassRegistry::getPassRegistry());
45 bool runOnMachineFunction(MachineFunction &Fn) override;
47 StringRef getPassName() const override {
48 return "PowerPC QPX Load Splat Simplification";
51 char PPCQPXLoadSplat::ID = 0;
54 INITIALIZE_PASS(PPCQPXLoadSplat, "ppc-qpx-load-splat",
55 "PowerPC QPX Load Splat Simplification",
58 FunctionPass *llvm::createPPCQPXLoadSplatPass() {
59 return new PPCQPXLoadSplat();
62 bool PPCQPXLoadSplat::runOnMachineFunction(MachineFunction &MF) {
63 if (skipFunction(*MF.getFunction()))
66 bool MadeChange = false;
67 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
69 for (auto MFI = MF.begin(), MFIE = MF.end(); MFI != MFIE; ++MFI) {
70 MachineBasicBlock *MBB = &*MFI;
71 SmallVector<MachineInstr *, 4> Splats;
73 for (auto MBBI = MBB->rbegin(); MBBI != MBB->rend(); ++MBBI) {
74 MachineInstr *MI = &*MBBI;
76 if (MI->hasUnmodeledSideEffects() || MI->isCall()) {
81 // We're looking for a sequence like this:
82 // %F0<def> = LFD 0, %X3<kill>, %QF0<imp-def>; mem:LD8[%a](tbaa=!2)
83 // %QF1<def> = QVESPLATI %QF0<kill>, 0, %RM<imp-use>
85 for (auto SI = Splats.begin(); SI != Splats.end();) {
86 MachineInstr *SMI = *SI;
87 unsigned SplatReg = SMI->getOperand(0).getReg();
88 unsigned SrcReg = SMI->getOperand(1).getReg();
90 if (MI->modifiesRegister(SrcReg, TRI)) {
91 switch (MI->getOpcode()) {
93 SI = Splats.erase(SI);
105 if (SplatReg != SrcReg) {
106 // We need to change the load to define the scalar subregister of
107 // the QPX splat source register.
108 unsigned SubRegIndex =
109 TRI->getSubRegIndex(SrcReg, MI->getOperand(0).getReg());
110 unsigned SplatSubReg = TRI->getSubReg(SplatReg, SubRegIndex);
112 // Substitute both the explicit defined register, and also the
113 // implicit def of the containing QPX register.
114 MI->getOperand(0).setReg(SplatSubReg);
115 MI->substituteRegister(SrcReg, SplatReg, 0, *TRI);
118 SI = Splats.erase(SI);
120 // If SMI is directly after MI, then MBBI's base iterator is
121 // pointing at SMI. Adjust MBBI around the call to erase SMI to
122 // avoid invalidating MBBI.
124 SMI->eraseFromParent();
133 // If this instruction defines the splat register, then we cannot move
134 // the previous definition above it. If it reads from the splat
135 // register, then it must already be alive from some previous
136 // definition, and if the splat register is different from the source
137 // register, then this definition must not be the load for which we're
139 if (MI->modifiesRegister(SplatReg, TRI) ||
140 (SrcReg != SplatReg &&
141 MI->readsRegister(SplatReg, TRI))) {
142 SI = Splats.erase(SI);
149 if (MI->getOpcode() != PPC::QVESPLATI &&
150 MI->getOpcode() != PPC::QVESPLATIs &&
151 MI->getOpcode() != PPC::QVESPLATIb)
153 if (MI->getOperand(2).getImm() != 0)
156 // If there are other uses of the scalar value after this, replacing
157 // those uses might be non-trivial.
158 if (!MI->getOperand(1).isKill())
161 Splats.push_back(MI);