Back to home page

EIC code displayed by LXR

 
 

    


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