#ifndef LLVM_CODEGEN_DFAPACKETIZER_H
#define LLVM_CODEGEN_DFAPACKETIZER_H
-#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include <map>
namespace llvm {
class MachineLoopInfo;
class MachineDominatorTree;
class InstrItineraryData;
-class ScheduleDAGInstrs;
+class DefaultVLIWScheduler;
class SUnit;
+// --------------------------------------------------------------------
+// Definitions shared between DFAPacketizer.cpp and DFAPacketizerEmitter.cpp
+
+// DFA_MAX_RESTERMS * DFA_MAX_RESOURCES must fit within sizeof DFAInput.
+// This is verified in DFAPacketizer.cpp:DFAPacketizer::DFAPacketizer.
+//
+// e.g. terms x resource bit combinations that fit in uint32_t:
+// 4 terms x 8 bits = 32 bits
+// 3 terms x 10 bits = 30 bits
+// 2 terms x 16 bits = 32 bits
+//
+// e.g. terms x resource bit combinations that fit in uint64_t:
+// 8 terms x 8 bits = 64 bits
+// 7 terms x 9 bits = 63 bits
+// 6 terms x 10 bits = 60 bits
+// 5 terms x 12 bits = 60 bits
+// 4 terms x 16 bits = 64 bits <--- current
+// 3 terms x 21 bits = 63 bits
+// 2 terms x 32 bits = 64 bits
+//
+#define DFA_MAX_RESTERMS 4 // The max # of AND'ed resource terms.
+#define DFA_MAX_RESOURCES 16 // The max # of resource bits in one term.
+
+typedef uint64_t DFAInput;
+typedef int64_t DFAStateInput;
+#define DFA_TBLTYPE "int64_t" // For generating DFAStateInputTable.
+// --------------------------------------------------------------------
+
class DFAPacketizer {
private:
- typedef std::pair<unsigned, unsigned> UnsignPair;
+ typedef std::pair<unsigned, DFAInput> UnsignPair;
+
const InstrItineraryData *InstrItins;
int CurrentState;
- const int (*DFAStateInputTable)[2];
+ const DFAStateInput (*DFAStateInputTable)[2];
const unsigned *DFAStateEntryTable;
// CachedTable is a map from <FromState, Input> to ToState.
DenseMap<UnsignPair, unsigned> CachedTable;
// ReadTable - Read the DFA transition table and update CachedTable.
- void ReadTable(unsigned int state);
+ void ReadTable(unsigned state);
public:
- DFAPacketizer(const InstrItineraryData *I, const int (*SIT)[2],
+ DFAPacketizer(const InstrItineraryData *I, const DFAStateInput (*SIT)[2],
const unsigned *SET);
// Reset the current state to make all resources available.
CurrentState = 0;
}
+ // getInsnInput - Return the DFAInput for an instruction class.
+ DFAInput getInsnInput(unsigned InsnClass);
+
+ // getInsnInput - Return the DFAInput for an instruction class input vector.
+ static DFAInput getInsnInput(const std::vector<unsigned> &InsnClass);
+
// canReserveResources - Check if the resources occupied by a MCInstrDesc
// are available in the current state.
bool canReserveResources(const llvm::MCInstrDesc *MID);
// reserveResources - Reserve the resources occupied by a machine
// instruction and change the current state to reflect that change.
void reserveResources(llvm::MachineInstr *MI);
+
+ const InstrItineraryData *getInstrItins() const { return InstrItins; }
};
// VLIWPacketizerList - Implements a simple VLIW packetizer using DFA. The
// and machine resource is marked as taken. If any dependency is found, a target
// API call is made to prune the dependence.
class VLIWPacketizerList {
- const TargetMachine &TM;
- const MachineFunction &MF;
+protected:
+ MachineFunction &MF;
const TargetInstrInfo *TII;
// The VLIW Scheduler.
- ScheduleDAGInstrs *VLIWScheduler;
+ DefaultVLIWScheduler *VLIWScheduler;
-protected:
// Vector of instructions assigned to the current packet.
std::vector<MachineInstr*> CurrentPacketMIs;
// DFA resource tracker.
DFAPacketizer *ResourceTracker;
- // Scheduling units.
- std::vector<SUnit> SUnits;
+
+ // Generate MI -> SU map.
+ std::map<MachineInstr*, SUnit*> MIToSUnit;
public:
- VLIWPacketizerList(
- MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT,
- bool IsPostRA);
+ VLIWPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI);
virtual ~VLIWPacketizerList();
DFAPacketizer *getResourceTracker() {return ResourceTracker;}
// addToPacket - Add MI to the current packet.
- void addToPacket(MachineInstr *MI);
+ virtual MachineBasicBlock::iterator addToPacket(MachineInstr *MI) {
+ MachineBasicBlock::iterator MII = MI;
+ CurrentPacketMIs.push_back(MI);
+ ResourceTracker->reserveResources(MI);
+ return MII;
+ }
- // endPacket - End the current packet.
- void endPacket(MachineBasicBlock *MBB, MachineInstr *I);
+ // End the current packet and reset the state of the packetizer.
+ // Overriding this function allows the target-specific packetizer
+ // to perform custom finalization.
+ virtual void endPacket(MachineBasicBlock *MBB, MachineInstr *MI);
+
+ // initPacketizerState - perform initialization before packetizing
+ // an instruction. This function is supposed to be overrided by
+ // the target dependent packetizer.
+ virtual void initPacketizerState() { return; }
// ignorePseudoInstruction - Ignore bundling of pseudo instructions.
- bool ignorePseudoInstruction(MachineInstr *I, MachineBasicBlock *MBB);
+ virtual bool ignorePseudoInstruction(const MachineInstr *I,
+ const MachineBasicBlock *MBB) {
+ return false;
+ }
- // isSoloInstruction - return true if instruction I must end previous
- // packet.
- bool isSoloInstruction(MachineInstr *I);
+ // isSoloInstruction - return true if instruction MI can not be packetized
+ // with any other instruction, which means that MI itself is a packet.
+ virtual bool isSoloInstruction(const MachineInstr *MI) {
+ return true;
+ }
// isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ
// together.
virtual bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
return false;
}
+
};
}