diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/PowerPC/PPCQPXLoadSplat.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Target/PowerPC/PPCQPXLoadSplat.cpp | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCQPXLoadSplat.cpp b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCQPXLoadSplat.cpp deleted file mode 100644 index 6e9042643820..000000000000 --- a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCQPXLoadSplat.cpp +++ /dev/null @@ -1,161 +0,0 @@ -//===----- PPCQPXLoadSplat.cpp - QPX Load Splat Simplification ------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// The QPX vector registers overlay the scalar floating-point registers, and -// any scalar floating-point loads splat their value across all vector lanes. -// Thus, if we have a scalar load followed by a splat, we can remove the splat -// (i.e. replace the load with a load-and-splat pseudo instruction). -// -// This pass must run after anything that might do store-to-load forwarding. -// -//===----------------------------------------------------------------------===// - -#include "PPC.h" -#include "PPCInstrBuilder.h" -#include "PPCInstrInfo.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/TargetSubtargetInfo.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Target/TargetMachine.h" -using namespace llvm; - -#define DEBUG_TYPE "ppc-qpx-load-splat" - -STATISTIC(NumSimplified, "Number of QPX load splats simplified"); - -namespace { - struct PPCQPXLoadSplat : public MachineFunctionPass { - static char ID; - PPCQPXLoadSplat() : MachineFunctionPass(ID) { - initializePPCQPXLoadSplatPass(*PassRegistry::getPassRegistry()); - } - - bool runOnMachineFunction(MachineFunction &Fn) override; - - StringRef getPassName() const override { - return "PowerPC QPX Load Splat Simplification"; - } - }; - char PPCQPXLoadSplat::ID = 0; -} - -INITIALIZE_PASS(PPCQPXLoadSplat, "ppc-qpx-load-splat", - "PowerPC QPX Load Splat Simplification", - false, false) - -FunctionPass *llvm::createPPCQPXLoadSplatPass() { - return new PPCQPXLoadSplat(); -} - -bool PPCQPXLoadSplat::runOnMachineFunction(MachineFunction &MF) { - if (skipFunction(MF.getFunction())) - return false; - - bool MadeChange = false; - const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); - - for (auto MFI = MF.begin(), MFIE = MF.end(); MFI != MFIE; ++MFI) { - MachineBasicBlock *MBB = &*MFI; - SmallVector<MachineInstr *, 4> Splats; - - for (auto MBBI = MBB->rbegin(); MBBI != MBB->rend(); ++MBBI) { - MachineInstr *MI = &*MBBI; - - if (MI->hasUnmodeledSideEffects() || MI->isCall()) { - Splats.clear(); - continue; - } - - // We're looking for a sequence like this: - // %f0 = LFD 0, killed %x3, implicit-def %qf0; mem:LD8[%a](tbaa=!2) - // %qf1 = QVESPLATI killed %qf0, 0, implicit %rm - - for (auto SI = Splats.begin(); SI != Splats.end();) { - MachineInstr *SMI = *SI; - Register SplatReg = SMI->getOperand(0).getReg(); - Register SrcReg = SMI->getOperand(1).getReg(); - - if (MI->modifiesRegister(SrcReg, TRI)) { - switch (MI->getOpcode()) { - default: - SI = Splats.erase(SI); - continue; - case PPC::LFS: - case PPC::LFD: - case PPC::LFSU: - case PPC::LFDU: - case PPC::LFSUX: - case PPC::LFDUX: - case PPC::LFSX: - case PPC::LFDX: - case PPC::LFIWAX: - case PPC::LFIWZX: - if (SplatReg != SrcReg) { - // We need to change the load to define the scalar subregister of - // the QPX splat source register. - unsigned SubRegIndex = - TRI->getSubRegIndex(SrcReg, MI->getOperand(0).getReg()); - Register SplatSubReg = TRI->getSubReg(SplatReg, SubRegIndex); - - // Substitute both the explicit defined register, and also the - // implicit def of the containing QPX register. - MI->getOperand(0).setReg(SplatSubReg); - MI->substituteRegister(SrcReg, SplatReg, 0, *TRI); - } - - SI = Splats.erase(SI); - - // If SMI is directly after MI, then MBBI's base iterator is - // pointing at SMI. Adjust MBBI around the call to erase SMI to - // avoid invalidating MBBI. - ++MBBI; - SMI->eraseFromParent(); - --MBBI; - - ++NumSimplified; - MadeChange = true; - continue; - } - } - - // If this instruction defines the splat register, then we cannot move - // the previous definition above it. If it reads from the splat - // register, then it must already be alive from some previous - // definition, and if the splat register is different from the source - // register, then this definition must not be the load for which we're - // searching. - if (MI->modifiesRegister(SplatReg, TRI) || - (SrcReg != SplatReg && - MI->readsRegister(SplatReg, TRI))) { - SI = Splats.erase(SI); - continue; - } - - ++SI; - } - - if (MI->getOpcode() != PPC::QVESPLATI && - MI->getOpcode() != PPC::QVESPLATIs && - MI->getOpcode() != PPC::QVESPLATIb) - continue; - if (MI->getOperand(2).getImm() != 0) - continue; - - // If there are other uses of the scalar value after this, replacing - // those uses might be non-trivial. - if (!MI->getOperand(1).isKill()) - continue; - - Splats.push_back(MI); - } - } - - return MadeChange; -} |