LLVM API Documentation
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