|
|
|||
File indexing completed on 2026-05-10 08:43:28
0001 //===- llvm/CodeGen/DFAPacketizer.h - DFA Packetizer for VLIW ---*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // This class implements a deterministic finite automaton (DFA) based 0009 // packetizing mechanism for VLIW architectures. It provides APIs to 0010 // determine whether there exists a legal mapping of instructions to 0011 // functional unit assignments in a packet. The DFA is auto-generated from 0012 // the target's Schedule.td file. 0013 // 0014 // A DFA consists of 3 major elements: states, inputs, and transitions. For 0015 // the packetizing mechanism, the input is the set of instruction classes for 0016 // a target. The state models all possible combinations of functional unit 0017 // consumption for a given set of instructions in a packet. A transition 0018 // models the addition of an instruction to a packet. In the DFA constructed 0019 // by this class, if an instruction can be added to a packet, then a valid 0020 // transition exists from the corresponding state. Invalid transitions 0021 // indicate that the instruction cannot be added to the current packet. 0022 // 0023 //===----------------------------------------------------------------------===// 0024 0025 #ifndef LLVM_CODEGEN_DFAPACKETIZER_H 0026 #define LLVM_CODEGEN_DFAPACKETIZER_H 0027 0028 #include "llvm/CodeGen/MachineBasicBlock.h" 0029 #include "llvm/CodeGen/ScheduleDAGInstrs.h" 0030 #include "llvm/CodeGen/ScheduleDAGMutation.h" 0031 #include "llvm/Support/Automaton.h" 0032 #include <cstdint> 0033 #include <map> 0034 #include <memory> 0035 #include <utility> 0036 #include <vector> 0037 0038 namespace llvm { 0039 0040 class ScheduleDAGMutation; 0041 class InstrItineraryData; 0042 class MachineFunction; 0043 class MachineInstr; 0044 class MachineLoopInfo; 0045 class MCInstrDesc; 0046 class SUnit; 0047 class TargetInstrInfo; 0048 0049 // This class extends ScheduleDAGInstrs and overrides the schedule method 0050 // to build the dependence graph. 0051 class DefaultVLIWScheduler : public ScheduleDAGInstrs { 0052 private: 0053 AAResults *AA; 0054 /// Ordered list of DAG postprocessing steps. 0055 std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations; 0056 0057 public: 0058 DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI, 0059 AAResults *AA); 0060 0061 // Actual scheduling work. 0062 void schedule() override; 0063 0064 /// DefaultVLIWScheduler takes ownership of the Mutation object. 0065 void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) { 0066 Mutations.push_back(std::move(Mutation)); 0067 } 0068 0069 protected: 0070 void postProcessDAG(); 0071 }; 0072 0073 class DFAPacketizer { 0074 private: 0075 const InstrItineraryData *InstrItins; 0076 Automaton<uint64_t> A; 0077 /// For every itinerary, an "action" to apply to the automaton. This removes 0078 /// the redundancy in actions between itinerary classes. 0079 ArrayRef<unsigned> ItinActions; 0080 0081 public: 0082 DFAPacketizer(const InstrItineraryData *InstrItins, Automaton<uint64_t> a, 0083 ArrayRef<unsigned> ItinActions) 0084 : InstrItins(InstrItins), A(std::move(a)), ItinActions(ItinActions) { 0085 // Start off with resource tracking disabled. 0086 A.enableTranscription(false); 0087 } 0088 0089 // Reset the current state to make all resources available. 0090 void clearResources() { 0091 A.reset(); 0092 } 0093 0094 // Set whether this packetizer should track not just whether instructions 0095 // can be packetized, but also which functional units each instruction ends up 0096 // using after packetization. 0097 void setTrackResources(bool Track) { 0098 A.enableTranscription(Track); 0099 } 0100 0101 // Check if the resources occupied by a MCInstrDesc are available in 0102 // the current state. 0103 bool canReserveResources(const MCInstrDesc *MID); 0104 0105 // Reserve the resources occupied by a MCInstrDesc and change the current 0106 // state to reflect that change. 0107 void reserveResources(const MCInstrDesc *MID); 0108 0109 // Check if the resources occupied by a machine instruction are available 0110 // in the current state. 0111 bool canReserveResources(MachineInstr &MI); 0112 0113 // Reserve the resources occupied by a machine instruction and change the 0114 // current state to reflect that change. 0115 void reserveResources(MachineInstr &MI); 0116 0117 // Return the resources used by the InstIdx'th instruction added to this 0118 // packet. The resources are returned as a bitvector of functional units. 0119 // 0120 // Note that a bundle may be packed in multiple valid ways. This function 0121 // returns one arbitary valid packing. 0122 // 0123 // Requires setTrackResources(true) to have been called. 0124 unsigned getUsedResources(unsigned InstIdx); 0125 0126 const InstrItineraryData *getInstrItins() const { return InstrItins; } 0127 }; 0128 0129 // VLIWPacketizerList implements a simple VLIW packetizer using DFA. The 0130 // packetizer works on machine basic blocks. For each instruction I in BB, 0131 // the packetizer consults the DFA to see if machine resources are available 0132 // to execute I. If so, the packetizer checks if I depends on any instruction 0133 // in the current packet. If no dependency is found, I is added to current 0134 // packet and the machine resource is marked as taken. If any dependency is 0135 // found, a target API call is made to prune the dependence. 0136 class VLIWPacketizerList { 0137 protected: 0138 MachineFunction &MF; 0139 const TargetInstrInfo *TII; 0140 AAResults *AA; 0141 0142 // The VLIW Scheduler. 0143 DefaultVLIWScheduler *VLIWScheduler; 0144 // Vector of instructions assigned to the current packet. 0145 std::vector<MachineInstr*> CurrentPacketMIs; 0146 // DFA resource tracker. 0147 DFAPacketizer *ResourceTracker; 0148 // Map: MI -> SU. 0149 std::map<MachineInstr*, SUnit*> MIToSUnit; 0150 0151 public: 0152 // The AAResults parameter can be nullptr. 0153 VLIWPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, 0154 AAResults *AA); 0155 VLIWPacketizerList &operator=(const VLIWPacketizerList &other) = delete; 0156 VLIWPacketizerList(const VLIWPacketizerList &other) = delete; 0157 virtual ~VLIWPacketizerList(); 0158 0159 // Implement this API in the backend to bundle instructions. 0160 void PacketizeMIs(MachineBasicBlock *MBB, 0161 MachineBasicBlock::iterator BeginItr, 0162 MachineBasicBlock::iterator EndItr); 0163 0164 // Return the ResourceTracker. 0165 DFAPacketizer *getResourceTracker() {return ResourceTracker;} 0166 0167 // addToPacket - Add MI to the current packet. 0168 virtual MachineBasicBlock::iterator addToPacket(MachineInstr &MI) { 0169 CurrentPacketMIs.push_back(&MI); 0170 ResourceTracker->reserveResources(MI); 0171 return MI; 0172 } 0173 0174 // End the current packet and reset the state of the packetizer. 0175 // Overriding this function allows the target-specific packetizer 0176 // to perform custom finalization. 0177 virtual void endPacket(MachineBasicBlock *MBB, 0178 MachineBasicBlock::iterator MI); 0179 0180 // Perform initialization before packetizing an instruction. This 0181 // function is supposed to be overrided by the target dependent packetizer. 0182 virtual void initPacketizerState() {} 0183 0184 // Check if the given instruction I should be ignored by the packetizer. 0185 virtual bool ignorePseudoInstruction(const MachineInstr &I, 0186 const MachineBasicBlock *MBB) { 0187 return false; 0188 } 0189 0190 // Return true if instruction MI can not be packetized with any other 0191 // instruction, which means that MI itself is a packet. 0192 virtual bool isSoloInstruction(const MachineInstr &MI) { return true; } 0193 0194 // Check if the packetizer should try to add the given instruction to 0195 // the current packet. One reasons for which it may not be desirable 0196 // to include an instruction in the current packet could be that it 0197 // would cause a stall. 0198 // If this function returns "false", the current packet will be ended, 0199 // and the instruction will be added to the next packet. 0200 virtual bool shouldAddToPacket(const MachineInstr &MI) { return true; } 0201 0202 // Check if it is legal to packetize SUI and SUJ together. 0203 virtual bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { 0204 return false; 0205 } 0206 0207 // Check if it is legal to prune dependece between SUI and SUJ. 0208 virtual bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) { 0209 return false; 0210 } 0211 0212 // Add a DAG mutation to be done before the packetization begins. 0213 void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation); 0214 0215 bool alias(const MachineInstr &MI1, const MachineInstr &MI2, 0216 bool UseTBAA = true) const; 0217 0218 private: 0219 bool alias(const MachineMemOperand &Op1, const MachineMemOperand &Op2, 0220 bool UseTBAA = true) const; 0221 }; 0222 0223 } // end namespace llvm 0224 0225 #endif // LLVM_CODEGEN_DFAPACKETIZER_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|