diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonGatherPacketize.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonGatherPacketize.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonGatherPacketize.cpp b/llvm/lib/Target/Hexagon/HexagonGatherPacketize.cpp new file mode 100644 index 00000000000..dcffec7a3b1 --- /dev/null +++ b/llvm/lib/Target/Hexagon/HexagonGatherPacketize.cpp @@ -0,0 +1,103 @@ +//===- HexagonGatherPacketize.cpp -----------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This pass ensures that producer and consumer of VTMP are paired in a bundle. +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "gather-packetize" + +#include "HexagonTargetMachine.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +using namespace llvm; + +cl::opt<bool> EnableGatherPacketize( + "hexagon-enable-gather-packetize", cl::Hidden, cl::init(true), + cl::desc("Generate gather packets before packetization")); + +namespace llvm { +FunctionPass *createHexagonGatherPacketize(); +void initializeHexagonGatherPacketizePass(PassRegistry &); +} + +namespace { +class HexagonGatherPacketize : public MachineFunctionPass { +public: + static char ID; + HexagonGatherPacketize() : MachineFunctionPass(ID) { + PassRegistry &Registry = *PassRegistry::getPassRegistry(); + initializeHexagonGatherPacketizePass(Registry); + } + + StringRef getPassName() const override { + return "Hexagon Gather Packetize Code"; + } + bool runOnMachineFunction(MachineFunction &Fn) override; +}; + +char HexagonGatherPacketize::ID = 0; + +static inline bool isVtmpDef(const MachineInstr &MI) { + for (const MachineOperand &MO : MI.operands()) + if (MO.isReg() && MO.isDef() && MO.isImplicit() && + (MO.getReg() == Hexagon::VTMP)) { + return true; + } + return false; +} + +static inline bool isVtmpUse(const MachineInstr &MI) { + return (MI.mayStore() && (MI.getOperand(2)).isReg() && + ((MI.getOperand(2)).getReg() == Hexagon::VTMP)); +} + +bool HexagonGatherPacketize::runOnMachineFunction(MachineFunction &Fn) { + if (!EnableGatherPacketize) + return false; + auto &ST = Fn.getSubtarget<HexagonSubtarget>(); + bool HasV65 = ST.hasV65TOps(); + bool UseHVX = ST.useHVXOps(); + if (!(HasV65 & UseHVX)) + return false; + + for (auto &MBB : Fn) { + bool VtmpDef = false; + MachineBasicBlock::iterator MII, MIE, DefMII; + for (MII = MBB.begin(), MIE = MBB.end(); MII != MIE; ++MII) { + MachineInstr &MI = *MII; + if (VtmpDef) { + if (!isVtmpUse(MI)) + continue; + MBB.splice(std::next(DefMII), &MBB, MII); + finalizeBundle(MBB, DefMII.getInstrIterator(), + std::next(MII).getInstrIterator()); + VtmpDef = false; + continue; + } + if (!(isVtmpDef(MI))) + continue; + VtmpDef = true; + DefMII = MII; + } + assert(!VtmpDef && "VTMP producer and consumer not in same block"); + } + return true; +} +} + +//===----------------------------------------------------------------------===// +// Public Constructor Functions +//===----------------------------------------------------------------------===// + +INITIALIZE_PASS(HexagonGatherPacketize, "hexagon-gather-packetize", + "Hexagon gather packetize Code", false, false) + +FunctionPass *llvm::createHexagonGatherPacketize() { + return new HexagonGatherPacketize(); +} |