]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/Hexagon/HexagonGatherPacketize.cpp
MFC r345805: Unify SCSI_STATUS_BUSY retry handling with other cases.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / Hexagon / HexagonGatherPacketize.cpp
1 //===- 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/CodeGen/MachineInstrBundle.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/Debug.h"
19 using namespace llvm;
20
21 cl::opt<bool> EnableGatherPacketize(
22     "hexagon-enable-gather-packetize", cl::Hidden, cl::init(true),
23     cl::desc("Generate gather packets before packetization"));
24
25 namespace llvm {
26 FunctionPass *createHexagonGatherPacketize();
27 void initializeHexagonGatherPacketizePass(PassRegistry &);
28 }
29
30 namespace {
31 class HexagonGatherPacketize : public MachineFunctionPass {
32 public:
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
45 char HexagonGatherPacketize::ID = 0;
46
47 static 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
56 static inline bool isVtmpUse(const MachineInstr &MI) {
57   return (MI.mayStore() && (MI.getOperand(2)).isReg() &&
58           ((MI.getOperand(2)).getReg() == Hexagon::VTMP));
59 }
60
61 bool HexagonGatherPacketize::runOnMachineFunction(MachineFunction &Fn) {
62   if (!EnableGatherPacketize)
63     return false;
64   auto &ST = Fn.getSubtarget<HexagonSubtarget>();
65   bool HasV65 = ST.hasV65Ops();
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
99 INITIALIZE_PASS(HexagonGatherPacketize, "hexagon-gather-packetize",
100                 "Hexagon gather packetize Code", false, false)
101
102 FunctionPass *llvm::createHexagonGatherPacketize() {
103   return new HexagonGatherPacketize();
104 }