LLVM API Documentation

DFAPacketizer.h
Go to the documentation of this file.
00001 //=- llvm/CodeGen/DFAPacketizer.h - DFA Packetizer for VLIW ---*- C++ -*-=====//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 // This class implements a deterministic finite automaton (DFA) based
00010 // packetizing mechanism for VLIW architectures. It provides APIs to
00011 // determine whether there exists a legal mapping of instructions to
00012 // functional unit assignments in a packet. The DFA is auto-generated from
00013 // the target's Schedule.td file.
00014 //
00015 // A DFA consists of 3 major elements: states, inputs, and transitions. For
00016 // the packetizing mechanism, the input is the set of instruction classes for
00017 // a target. The state models all possible combinations of functional unit
00018 // consumption for a given set of instructions in a packet. A transition
00019 // models the addition of an instruction to a packet. In the DFA constructed
00020 // by this class, if an instruction can be added to a packet, then a valid
00021 // transition exists from the corresponding state. Invalid transitions
00022 // indicate that the instruction cannot be added to the current packet.
00023 //
00024 //===----------------------------------------------------------------------===//
00025 
00026 #ifndef LLVM_CODEGEN_DFAPACKETIZER_H
00027 #define LLVM_CODEGEN_DFAPACKETIZER_H
00028 
00029 #include "llvm/ADT/DenseMap.h"
00030 #include "llvm/CodeGen/MachineBasicBlock.h"
00031 #include <map>
00032 
00033 namespace llvm {
00034 
00035 class MCInstrDesc;
00036 class MachineInstr;
00037 class MachineLoopInfo;
00038 class MachineDominatorTree;
00039 class InstrItineraryData;
00040 class DefaultVLIWScheduler;
00041 class SUnit;
00042 
00043 class DFAPacketizer {
00044 private:
00045   typedef std::pair<unsigned, unsigned> UnsignPair;
00046   const InstrItineraryData *InstrItins;
00047   int CurrentState;
00048   const int (*DFAStateInputTable)[2];
00049   const unsigned *DFAStateEntryTable;
00050 
00051   // CachedTable is a map from <FromState, Input> to ToState.
00052   DenseMap<UnsignPair, unsigned> CachedTable;
00053 
00054   // ReadTable - Read the DFA transition table and update CachedTable.
00055   void ReadTable(unsigned int state);
00056 
00057 public:
00058   DFAPacketizer(const InstrItineraryData *I, const int (*SIT)[2],
00059                 const unsigned *SET);
00060 
00061   // Reset the current state to make all resources available.
00062   void clearResources() {
00063     CurrentState = 0;
00064   }
00065 
00066   // canReserveResources - Check if the resources occupied by a MCInstrDesc
00067   // are available in the current state.
00068   bool canReserveResources(const llvm::MCInstrDesc *MID);
00069 
00070   // reserveResources - Reserve the resources occupied by a MCInstrDesc and
00071   // change the current state to reflect that change.
00072   void reserveResources(const llvm::MCInstrDesc *MID);
00073 
00074   // canReserveResources - Check if the resources occupied by a machine
00075   // instruction are available in the current state.
00076   bool canReserveResources(llvm::MachineInstr *MI);
00077 
00078   // reserveResources - Reserve the resources occupied by a machine
00079   // instruction and change the current state to reflect that change.
00080   void reserveResources(llvm::MachineInstr *MI);
00081 
00082   const InstrItineraryData *getInstrItins() const { return InstrItins; }
00083 };
00084 
00085 // VLIWPacketizerList - Implements a simple VLIW packetizer using DFA. The
00086 // packetizer works on machine basic blocks. For each instruction I in BB, the
00087 // packetizer consults the DFA to see if machine resources are available to
00088 // execute I. If so, the packetizer checks if I depends on any instruction J in
00089 // the current packet. If no dependency is found, I is added to current packet
00090 // and machine resource is marked as taken. If any dependency is found, a target
00091 // API call is made to prune the dependence.
00092 class VLIWPacketizerList {
00093 protected:
00094   const TargetMachine &TM;
00095   const MachineFunction &MF;
00096   const TargetInstrInfo *TII;
00097 
00098   // The VLIW Scheduler.
00099   DefaultVLIWScheduler *VLIWScheduler;
00100 
00101   // Vector of instructions assigned to the current packet.
00102   std::vector<MachineInstr*> CurrentPacketMIs;
00103   // DFA resource tracker.
00104   DFAPacketizer *ResourceTracker;
00105 
00106   // Generate MI -> SU map.
00107   std::map<MachineInstr*, SUnit*> MIToSUnit;
00108 
00109 public:
00110   VLIWPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, bool IsPostRA);
00111 
00112   virtual ~VLIWPacketizerList();
00113 
00114   // PacketizeMIs - Implement this API in the backend to bundle instructions.
00115   void PacketizeMIs(MachineBasicBlock *MBB,
00116                     MachineBasicBlock::iterator BeginItr,
00117                     MachineBasicBlock::iterator EndItr);
00118 
00119   // getResourceTracker - return ResourceTracker
00120   DFAPacketizer *getResourceTracker() {return ResourceTracker;}
00121 
00122   // addToPacket - Add MI to the current packet.
00123   virtual MachineBasicBlock::iterator addToPacket(MachineInstr *MI) {
00124     MachineBasicBlock::iterator MII = MI;
00125     CurrentPacketMIs.push_back(MI);
00126     ResourceTracker->reserveResources(MI);
00127     return MII;
00128   }
00129 
00130   // endPacket - End the current packet.
00131   void endPacket(MachineBasicBlock *MBB, MachineInstr *MI);
00132 
00133   // initPacketizerState - perform initialization before packetizing
00134   // an instruction. This function is supposed to be overrided by
00135   // the target dependent packetizer.
00136   virtual void initPacketizerState() { return; }
00137 
00138   // ignorePseudoInstruction - Ignore bundling of pseudo instructions.
00139   virtual bool ignorePseudoInstruction(MachineInstr *I,
00140                                        MachineBasicBlock *MBB) {
00141     return false;
00142   }
00143 
00144   // isSoloInstruction - return true if instruction MI can not be packetized
00145   // with any other instruction, which means that MI itself is a packet.
00146   virtual bool isSoloInstruction(MachineInstr *MI) {
00147     return true;
00148   }
00149 
00150   // isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ
00151   // together.
00152   virtual bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
00153     return false;
00154   }
00155 
00156   // isLegalToPruneDependencies - Is it legal to prune dependece between SUI
00157   // and SUJ.
00158   virtual bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
00159     return false;
00160   }
00161 
00162 };
00163 }
00164 
00165 #endif