1 //===----- PPCQPXLoadSplat.cpp - QPX Load Splat Simplification ------------===//
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 // 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).
14 // This pass must run after anything that might do store-to-load forwarding.
16 //===----------------------------------------------------------------------===//
19 #include "PPCInstrBuilder.h"
20 #include "PPCInstrInfo.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/Statistic.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/TargetSubtargetInfo.h"
25 #include "llvm/Support/MathExtras.h"
26 #include "llvm/Target/TargetMachine.h"
29 #define DEBUG_TYPE "ppc-qpx-load-splat"
31 STATISTIC(NumSimplified
, "Number of QPX load splats simplified");
34 struct PPCQPXLoadSplat
: public MachineFunctionPass
{
36 PPCQPXLoadSplat() : MachineFunctionPass(ID
) {
37 initializePPCQPXLoadSplatPass(*PassRegistry::getPassRegistry());
40 bool runOnMachineFunction(MachineFunction
&Fn
) override
;
42 StringRef
getPassName() const override
{
43 return "PowerPC QPX Load Splat Simplification";
46 char PPCQPXLoadSplat::ID
= 0;
49 INITIALIZE_PASS(PPCQPXLoadSplat
, "ppc-qpx-load-splat",
50 "PowerPC QPX Load Splat Simplification",
53 FunctionPass
*llvm::createPPCQPXLoadSplatPass() {
54 return new PPCQPXLoadSplat();
57 bool PPCQPXLoadSplat::runOnMachineFunction(MachineFunction
&MF
) {
58 if (skipFunction(MF
.getFunction()))
61 bool MadeChange
= false;
62 const TargetRegisterInfo
*TRI
= MF
.getSubtarget().getRegisterInfo();
64 for (auto MFI
= MF
.begin(), MFIE
= MF
.end(); MFI
!= MFIE
; ++MFI
) {
65 MachineBasicBlock
*MBB
= &*MFI
;
66 SmallVector
<MachineInstr
*, 4> Splats
;
68 for (auto MBBI
= MBB
->rbegin(); MBBI
!= MBB
->rend(); ++MBBI
) {
69 MachineInstr
*MI
= &*MBBI
;
71 if (MI
->hasUnmodeledSideEffects() || MI
->isCall()) {
76 // We're looking for a sequence like this:
77 // %f0 = LFD 0, killed %x3, implicit-def %qf0; mem:LD8[%a](tbaa=!2)
78 // %qf1 = QVESPLATI killed %qf0, 0, implicit %rm
80 for (auto SI
= Splats
.begin(); SI
!= Splats
.end();) {
81 MachineInstr
*SMI
= *SI
;
82 Register SplatReg
= SMI
->getOperand(0).getReg();
83 Register SrcReg
= SMI
->getOperand(1).getReg();
85 if (MI
->modifiesRegister(SrcReg
, TRI
)) {
86 switch (MI
->getOpcode()) {
88 SI
= Splats
.erase(SI
);
100 if (SplatReg
!= SrcReg
) {
101 // We need to change the load to define the scalar subregister of
102 // the QPX splat source register.
103 unsigned SubRegIndex
=
104 TRI
->getSubRegIndex(SrcReg
, MI
->getOperand(0).getReg());
105 Register SplatSubReg
= TRI
->getSubReg(SplatReg
, SubRegIndex
);
107 // Substitute both the explicit defined register, and also the
108 // implicit def of the containing QPX register.
109 MI
->getOperand(0).setReg(SplatSubReg
);
110 MI
->substituteRegister(SrcReg
, SplatReg
, 0, *TRI
);
113 SI
= Splats
.erase(SI
);
115 // If SMI is directly after MI, then MBBI's base iterator is
116 // pointing at SMI. Adjust MBBI around the call to erase SMI to
117 // avoid invalidating MBBI.
119 SMI
->eraseFromParent();
128 // If this instruction defines the splat register, then we cannot move
129 // the previous definition above it. If it reads from the splat
130 // register, then it must already be alive from some previous
131 // definition, and if the splat register is different from the source
132 // register, then this definition must not be the load for which we're
134 if (MI
->modifiesRegister(SplatReg
, TRI
) ||
135 (SrcReg
!= SplatReg
&&
136 MI
->readsRegister(SplatReg
, TRI
))) {
137 SI
= Splats
.erase(SI
);
144 if (MI
->getOpcode() != PPC::QVESPLATI
&&
145 MI
->getOpcode() != PPC::QVESPLATIs
&&
146 MI
->getOpcode() != PPC::QVESPLATIb
)
148 if (MI
->getOperand(2).getImm() != 0)
151 // If there are other uses of the scalar value after this, replacing
152 // those uses might be non-trivial.
153 if (!MI
->getOperand(1).isKill())
156 Splats
.push_back(MI
);