| 1 | //===--- HexagonHazardRecognizer.h - Hexagon Post RA Hazard Recognizer ----===// |
| 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 | // This file defines the hazard recognizer for scheduling on Hexagon. |
| 9 | //===----------------------------------------------------------------------===// |
| 10 | |
| 11 | #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONPROFITRECOGNIZER_H |
| 12 | #define LLVM_LIB_TARGET_HEXAGON_HEXAGONPROFITRECOGNIZER_H |
| 13 | |
| 14 | #include "HexagonInstrInfo.h" |
| 15 | #include "HexagonSubtarget.h" |
| 16 | #include "llvm/ADT/SmallSet.h" |
| 17 | #include "llvm/CodeGen/DFAPacketizer.h" |
| 18 | #include "llvm/CodeGen/ScheduleHazardRecognizer.h" |
| 19 | |
| 20 | namespace llvm { |
| 21 | |
| 22 | class HexagonHazardRecognizer : public ScheduleHazardRecognizer { |
| 23 | DFAPacketizer *Resources; |
| 24 | const HexagonInstrInfo *TII; |
| 25 | unsigned PacketNum = 0; |
| 26 | // If the packet contains a potential dot cur instruction. This is |
| 27 | // used for the scheduling priority function. |
| 28 | SUnit *UsesDotCur = nullptr; |
| 29 | // The packet number when a dor cur is emitted. If its use is not generated |
| 30 | // in the same packet, then try to wait another cycle before emitting. |
| 31 | int DotCurPNum = -1; |
| 32 | // Does the packet contain a load. Used to restrict another load, if possible. |
| 33 | bool UsesLoad = false; |
| 34 | // Check if we should prefer a vector store that will become a .new version. |
| 35 | // The .new store uses different resources than a normal store, and the |
| 36 | // packetizer will not generate the .new if the regular store does not have |
| 37 | // resources available (even if the .new version does). To help, the schedule |
| 38 | // attempts to schedule the .new as soon as possible in the packet. |
| 39 | SUnit *PrefVectorStoreNew = nullptr; |
| 40 | // The set of registers defined by instructions in the current packet. |
| 41 | SmallSet<unsigned, 8> RegDefs; |
| 42 | |
| 43 | // Return true if the instruction is a store that is converted to a new value |
| 44 | // store because its value is defined in the same packet. |
| 45 | bool isNewStore(MachineInstr &MI); |
| 46 | |
| 47 | public: |
| 48 | HexagonHazardRecognizer(const InstrItineraryData *II, |
| 49 | const HexagonInstrInfo *HII, |
| 50 | const HexagonSubtarget &ST) |
| 51 | : Resources(ST.createDFAPacketizer(IID: II)), TII(HII) { } |
| 52 | |
| 53 | ~HexagonHazardRecognizer() override { |
| 54 | if (Resources) |
| 55 | delete Resources; |
| 56 | } |
| 57 | |
| 58 | /// This callback is invoked when a new block of instructions is about to be |
| 59 | /// scheduled. The hazard state is set to an initialized state. |
| 60 | void Reset() override; |
| 61 | |
| 62 | /// Return the hazard type of emitting this node. There are three |
| 63 | /// possible results. Either: |
| 64 | /// * NoHazard: it is legal to issue this instruction on this cycle. |
| 65 | /// * Hazard: issuing this instruction would stall the machine. If some |
| 66 | /// other instruction is available, issue it first. |
| 67 | HazardType getHazardType(SUnit *SU, int stalls) override; |
| 68 | |
| 69 | /// This callback is invoked when an instruction is emitted to be scheduled, |
| 70 | /// to advance the hazard state. |
| 71 | void EmitInstruction(SUnit *) override; |
| 72 | |
| 73 | /// This callback may be invoked if getHazardType returns NoHazard. If, even |
| 74 | /// though there is no hazard, it would be better to schedule another |
| 75 | /// available instruction, this callback should return true. |
| 76 | bool ShouldPreferAnother(SUnit *) override; |
| 77 | |
| 78 | /// This callback is invoked whenever the next top-down instruction to be |
| 79 | /// scheduled cannot issue in the current cycle, either because of latency |
| 80 | /// or resource conflicts. This should increment the internal state of the |
| 81 | /// hazard recognizer so that previously "Hazard" instructions will now not |
| 82 | /// be hazards. |
| 83 | void AdvanceCycle() override; |
| 84 | }; |
| 85 | |
| 86 | } // end namespace llvm |
| 87 | |
| 88 | #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONPROFITRECOGNIZER_H |
| 89 | |