summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonGatherPacketize.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonGatherPacketize.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonGatherPacketize.cpp103
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();
+}
OpenPOWER on IntegriCloud