1//===- HexagonPacketizer.h - VLIW packetizer --------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONVLIWPACKETIZER_H
10#define LLVM_LIB_TARGET_HEXAGON_HEXAGONVLIWPACKETIZER_H
11
12#include "llvm/CodeGen/DFAPacketizer.h"
13#include "llvm/CodeGen/MachineBasicBlock.h"
14#include "llvm/CodeGen/ScheduleDAG.h"
15#include <vector>
16
17namespace llvm {
18
19class HexagonInstrInfo;
20class HexagonRegisterInfo;
21class MachineBranchProbabilityInfo;
22class MachineFunction;
23class MachineInstr;
24class MachineLoopInfo;
25class TargetRegisterClass;
26
27class HexagonPacketizerList : public VLIWPacketizerList {
28  // Vector of instructions assigned to the packet that has just been created.
29  std::vector<MachineInstr *> OldPacketMIs;
30
31  // Has the instruction been promoted to a dot-new instruction.
32  bool PromotedToDotNew;
33
34  // Has the instruction been glued to allocframe.
35  bool GlueAllocframeStore;
36
37  // Has the feeder instruction been glued to new value jump.
38  bool GlueToNewValueJump;
39
40  // This holds the offset value, when pruning the dependences.
41  int64_t ChangedOffset;
42
43  // Check if there is a dependence between some instruction already in this
44  // packet and this instruction.
45  bool Dependence;
46
47  // Only check for dependence if there are resources available to
48  // schedule this instruction.
49  bool FoundSequentialDependence;
50
51  bool MemShufDisabled = false;
52
53  // Track MIs with ignored dependence.
54  std::vector<MachineInstr*> IgnoreDepMIs;
55
56  // Set to true if the packet contains an instruction that stalls with an
57  // instruction from the previous packet.
58  bool PacketStalls = false;
59  // Set to the number of cycles of stall a given instruction will incur
60  // because of dependence on instruction in previous packet.
61  unsigned int PacketStallCycles = 0;
62
63  // Set to true if the packet has a duplex pair of sub-instructions.
64  bool PacketHasDuplex = false;
65
66  // Set to true if the packet has a instruction that can only be executed
67  // in SLOT0.
68  bool PacketHasSLOT0OnlyInsn = false;
69
70protected:
71  /// A handle to the branch probability pass.
72  const MachineBranchProbabilityInfo *MBPI;
73  const MachineLoopInfo *MLI;
74
75private:
76  const HexagonInstrInfo *HII;
77  const HexagonRegisterInfo *HRI;
78  const bool Minimal;
79
80public:
81  HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI,
82                        AAResults *AA, const MachineBranchProbabilityInfo *MBPI,
83                        bool Minimal);
84
85  // initPacketizerState - initialize some internal flags.
86  void initPacketizerState() override;
87
88  // ignorePseudoInstruction - Ignore bundling of pseudo instructions.
89  bool ignorePseudoInstruction(const MachineInstr &MI,
90                               const MachineBasicBlock *MBB) override;
91
92  // isSoloInstruction - return true if instruction MI can not be packetized
93  // with any other instruction, which means that MI itself is a packet.
94  bool isSoloInstruction(const MachineInstr &MI) override;
95
96  // isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ
97  // together.
98  bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) override;
99
100  // isLegalToPruneDependencies - Is it legal to prune dependece between SUI
101  // and SUJ.
102  bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) override;
103
104  bool foundLSInPacket();
105  MachineBasicBlock::iterator addToPacket(MachineInstr &MI) override;
106  void endPacket(MachineBasicBlock *MBB,
107                 MachineBasicBlock::iterator MI) override;
108  bool shouldAddToPacket(const MachineInstr &MI) override;
109
110  void unpacketizeSoloInstrs(MachineFunction &MF);
111
112protected:
113  bool getmemShufDisabled() {
114    return MemShufDisabled;
115  };
116  void setmemShufDisabled(bool val) {
117    MemShufDisabled = val;
118  };
119  bool isCallDependent(const MachineInstr &MI, SDep::Kind DepType,
120                       unsigned DepReg);
121  bool promoteToDotCur(MachineInstr &MI, SDep::Kind DepType,
122                       MachineBasicBlock::iterator &MII,
123                       const TargetRegisterClass *RC);
124  bool canPromoteToDotCur(const MachineInstr &MI, const SUnit *PacketSU,
125                          unsigned DepReg, MachineBasicBlock::iterator &MII,
126                          const TargetRegisterClass *RC);
127  void cleanUpDotCur();
128
129  bool promoteToDotNew(MachineInstr &MI, SDep::Kind DepType,
130                       MachineBasicBlock::iterator &MII,
131                       const TargetRegisterClass *RC);
132  bool canPromoteToDotNew(const MachineInstr &MI, const SUnit *PacketSU,
133                          unsigned DepReg, MachineBasicBlock::iterator &MII,
134                          const TargetRegisterClass *RC);
135  bool canPromoteToNewValue(const MachineInstr &MI, const SUnit *PacketSU,
136                            unsigned DepReg, MachineBasicBlock::iterator &MII);
137  bool canPromoteToNewValueStore(const MachineInstr &MI,
138                                 const MachineInstr &PacketMI, unsigned DepReg);
139  bool demoteToDotOld(MachineInstr &MI);
140  bool useCallersSP(MachineInstr &MI);
141  void useCalleesSP(MachineInstr &MI);
142  bool updateOffset(SUnit *SUI, SUnit *SUJ);
143  void undoChangedOffset(MachineInstr &MI);
144  bool arePredicatesComplements(MachineInstr &MI1, MachineInstr &MI2);
145  bool restrictingDepExistInPacket(MachineInstr&, unsigned);
146  bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC);
147  bool isCurifiable(MachineInstr &MI);
148  bool cannotCoexist(const MachineInstr &MI, const MachineInstr &MJ);
149
150  bool isPromotedToDotNew() const {
151    return PromotedToDotNew;
152  }
153
154  bool tryAllocateResourcesForConstExt(bool Reserve);
155  bool canReserveResourcesForConstExt();
156  void reserveResourcesForConstExt();
157  bool hasDeadDependence(const MachineInstr &I, const MachineInstr &J);
158  bool hasControlDependence(const MachineInstr &I, const MachineInstr &J);
159  bool hasRegMaskDependence(const MachineInstr &I, const MachineInstr &J);
160  bool hasDualStoreDependence(const MachineInstr &I, const MachineInstr &J);
161  bool producesStall(const MachineInstr &MI);
162  unsigned int calcStall(const MachineInstr &MI);
163};
164
165} // end namespace llvm
166
167#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONVLIWPACKETIZER_H
168