blob: dcffec7a3b1a67a8bea9d543619243147f3ba041 [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"
16#include "llvm/Support/CommandLine.h"
17#include "llvm/Support/Debug.h"
18using namespace llvm;
19
20cl::opt<bool> EnableGatherPacketize(
21 "hexagon-enable-gather-packetize", cl::Hidden, cl::init(true),
22 cl::desc("Generate gather packets before packetization"));
23
24namespace llvm {
25FunctionPass *createHexagonGatherPacketize();
26void initializeHexagonGatherPacketizePass(PassRegistry &);
27}
28
29namespace {
30class HexagonGatherPacketize : public MachineFunctionPass {
31public:
32 static char ID;
33 HexagonGatherPacketize() : MachineFunctionPass(ID) {
34 PassRegistry &Registry = *PassRegistry::getPassRegistry();
35 initializeHexagonGatherPacketizePass(Registry);
36 }
37
38 StringRef getPassName() const override {
39 return "Hexagon Gather Packetize Code";
40 }
41 bool runOnMachineFunction(MachineFunction &Fn) override;
42};
43
44char HexagonGatherPacketize::ID = 0;
45
46static inline bool isVtmpDef(const MachineInstr &MI) {
47 for (const MachineOperand &MO : MI.operands())
48 if (MO.isReg() && MO.isDef() && MO.isImplicit() &&
49 (MO.getReg() == Hexagon::VTMP)) {
50 return true;
51 }
52 return false;
53}
54
55static inline bool isVtmpUse(const MachineInstr &MI) {
56 return (MI.mayStore() && (MI.getOperand(2)).isReg() &&
57 ((MI.getOperand(2)).getReg() == Hexagon::VTMP));
58}
59
60bool HexagonGatherPacketize::runOnMachineFunction(MachineFunction &Fn) {
61 if (!EnableGatherPacketize)
62 return false;
63 auto &ST = Fn.getSubtarget<HexagonSubtarget>();
64 bool HasV65 = ST.hasV65TOps();
65 bool UseHVX = ST.useHVXOps();
66 if (!(HasV65 & UseHVX))
67 return false;
68
69 for (auto &MBB : Fn) {
70 bool VtmpDef = false;
71 MachineBasicBlock::iterator MII, MIE, DefMII;
72 for (MII = MBB.begin(), MIE = MBB.end(); MII != MIE; ++MII) {
73 MachineInstr &MI = *MII;
74 if (VtmpDef) {
75 if (!isVtmpUse(MI))
76 continue;
77 MBB.splice(std::next(DefMII), &MBB, MII);
78 finalizeBundle(MBB, DefMII.getInstrIterator(),
79 std::next(MII).getInstrIterator());
80 VtmpDef = false;
81 continue;
82 }
83 if (!(isVtmpDef(MI)))
84 continue;
85 VtmpDef = true;
86 DefMII = MII;
87 }
88 assert(!VtmpDef && "VTMP producer and consumer not in same block");
89 }
90 return true;
91}
92}
93
94//===----------------------------------------------------------------------===//
95// Public Constructor Functions
96//===----------------------------------------------------------------------===//
97
98INITIALIZE_PASS(HexagonGatherPacketize, "hexagon-gather-packetize",
99 "Hexagon gather packetize Code", false, false)
100
101FunctionPass *llvm::createHexagonGatherPacketize() {
102 return new HexagonGatherPacketize();
103}