blob: 253f09d12839d1c707c7445c0639a2733445e110 [file] [log] [blame]
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +00001//===- HexagonGatherPacketize.cpp -----------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9// This pass ensures that producer and consumer of VTMP are paired in a bundle.
10//===----------------------------------------------------------------------===//
11
12#define DEBUG_TYPE "gather-packetize"
13
14#include "HexagonTargetMachine.h"
15#include "llvm/CodeGen/MachineFunctionPass.h"
Matthias Braunf8422972017-12-13 02:51:04 +000016#include "llvm/CodeGen/MachineInstrBundle.h"
Krzysztof Parzyszeka8ab1b72017-12-11 18:57:54 +000017#include "llvm/Support/CommandLine.h"
18#include "llvm/Support/Debug.h"
19using namespace llvm;
20
21cl::opt<bool> EnableGatherPacketize(
22 "hexagon-enable-gather-packetize", cl::Hidden, cl::init(true),
23 cl::desc("Generate gather packets before packetization"));
24
25namespace llvm {
26FunctionPass *createHexagonGatherPacketize();
27void initializeHexagonGatherPacketizePass(PassRegistry &);
28}
29
30namespace {
31class HexagonGatherPacketize : public MachineFunctionPass {
32public:
33 static char ID;
34 HexagonGatherPacketize() : MachineFunctionPass(ID) {
35 PassRegistry &Registry = *PassRegistry::getPassRegistry();
36 initializeHexagonGatherPacketizePass(Registry);
37 }
38
39 StringRef getPassName() const override {
40 return "Hexagon Gather Packetize Code";
41 }
42 bool runOnMachineFunction(MachineFunction &Fn) override;
43};
44
45char HexagonGatherPacketize::ID = 0;
46
47static inline bool isVtmpDef(const MachineInstr &MI) {
48 for (const MachineOperand &MO : MI.operands())
49 if (MO.isReg() && MO.isDef() && MO.isImplicit() &&
50 (MO.getReg() == Hexagon::VTMP)) {
51 return true;
52 }
53 return false;
54}
55
56static inline bool isVtmpUse(const MachineInstr &MI) {
57 return (MI.mayStore() && (MI.getOperand(2)).isReg() &&
58 ((MI.getOperand(2)).getReg() == Hexagon::VTMP));
59}
60
61bool HexagonGatherPacketize::runOnMachineFunction(MachineFunction &Fn) {
62 if (!EnableGatherPacketize)
63 return false;
64 auto &ST = Fn.getSubtarget<HexagonSubtarget>();
65 bool HasV65 = ST.hasV65TOps();
66 bool UseHVX = ST.useHVXOps();
67 if (!(HasV65 & UseHVX))
68 return false;
69
70 for (auto &MBB : Fn) {
71 bool VtmpDef = false;
72 MachineBasicBlock::iterator MII, MIE, DefMII;
73 for (MII = MBB.begin(), MIE = MBB.end(); MII != MIE; ++MII) {
74 MachineInstr &MI = *MII;
75 if (VtmpDef) {
76 if (!isVtmpUse(MI))
77 continue;
78 MBB.splice(std::next(DefMII), &MBB, MII);
79 finalizeBundle(MBB, DefMII.getInstrIterator(),
80 std::next(MII).getInstrIterator());
81 VtmpDef = false;
82 continue;
83 }
84 if (!(isVtmpDef(MI)))
85 continue;
86 VtmpDef = true;
87 DefMII = MII;
88 }
89 assert(!VtmpDef && "VTMP producer and consumer not in same block");
90 }
91 return true;
92}
93}
94
95//===----------------------------------------------------------------------===//
96// Public Constructor Functions
97//===----------------------------------------------------------------------===//
98
99INITIALIZE_PASS(HexagonGatherPacketize, "hexagon-gather-packetize",
100 "Hexagon gather packetize Code", false, false)
101
102FunctionPass *llvm::createHexagonGatherPacketize() {
103 return new HexagonGatherPacketize();
104}