Skip to content

Commit

Permalink
Hexagon V60/HVX DFA scheduler support
Browse files Browse the repository at this point in the history
Extended DFA tablegen to:
  - added "-debug-only dfa-emitter" support to llvm-tblgen

  - defined CVI_PIPE* resources for the V60 vector coprocessor

  - allow specification of multiple required resources
    - supports ANDs of ORs
    - e.g. [SLOT2, SLOT3], [CVI_MPY0, CVI_MPY1] means:
           (SLOT2 OR SLOT3) AND (CVI_MPY0 OR CVI_MPY1)

  - added support for combo resources
    - allows specifying ORs of ANDs
    - e.g. [CVI_XLSHF, CVI_MPY01] means:
           (CVI_XLANE AND CVI_SHIFT) OR (CVI_MPY0 AND CVI_MPY1)

  - increased DFA input size from 32-bit to 64-bit
    - allows for a maximum of 4 AND'ed terms of 16 resources

  - supported expressions now include:

    expression     => term [AND term] [AND term] [AND term]
    term           => resource [OR resource]*
    resource       => one_resource | combo_resource
    combo_resource => (one_resource [AND one_resource]*)

Author: Dan Palermo <dpalermo@codeaurora.org>

kparzysz: Verified AMDGPU codegen to be unchanged on all llc
tests, except those dealing with instruction encodings.

Reapply the previous patch, this time without circular dependencies.

llvm-svn: 253793
  • Loading branch information
Krzysztof Parzyszek committed Nov 21, 2015
1 parent a5ea528 commit b465572
Show file tree
Hide file tree
Showing 6 changed files with 668 additions and 120 deletions.
18 changes: 14 additions & 4 deletions llvm/include/llvm/CodeGen/DFAPacketizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define LLVM_CODEGEN_DFAPACKETIZER_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/DFAPacketizerDefs.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include <map>

Expand All @@ -42,27 +43,36 @@ class SUnit;

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.
void clearResources() {
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) {
return getDFAInsnInput(InsnClass);
}

// canReserveResources - Check if the resources occupied by a MCInstrDesc
// are available in the current state.
bool canReserveResources(const llvm::MCInstrDesc *MID);
Expand Down
63 changes: 63 additions & 0 deletions llvm/include/llvm/CodeGen/DFAPacketizerDefs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//=- llvm/CodeGen/DFAPacketizerDefs.h - DFA Packetizer for VLIW ---*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Common definitions used by TableGen and the DFAPacketizer in CodeGen.
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_DFAPACKETIZERDEFS_H
#define LLVM_CODEGEN_DFAPACKETIZERDEFS_H

#include <vector>

namespace llvm {

// 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.

namespace {
DFAInput addDFAFuncUnits(DFAInput Inp, unsigned FuncUnits) {
return (Inp << DFA_MAX_RESOURCES) | FuncUnits;
}

/// Return the DFAInput for an instruction class input vector.
/// This function is used in both DFAPacketizer.cpp and in
/// DFAPacketizerEmitter.cpp.
DFAInput getDFAInsnInput(const std::vector<unsigned> &InsnClass) {
DFAInput InsnInput = 0;
assert ((InsnClass.size() <= DFA_MAX_RESTERMS) &&
"Exceeded maximum number of DFA terms");
for (auto U : InsnClass)
InsnInput = addDFAFuncUnits(InsnInput, U);
return InsnInput;
}
}

}

#endif
16 changes: 16 additions & 0 deletions llvm/include/llvm/Target/TargetItinerary.td
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,19 @@ class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp,
// info. Subtargets using NoItineraries can bypass the scheduler's
// expensive HazardRecognizer because no reservation table is needed.
def NoItineraries : ProcessorItineraries<[], [], []>;

//===----------------------------------------------------------------------===//
// Combo Function Unit data - This is a map of combo function unit names to
// the list of functional units that are included in the combination.
//
class ComboFuncData<FuncUnit ComboFunc, list<FuncUnit> funclist> {
FuncUnit TheComboFunc = ComboFunc;
list<FuncUnit> FuncList = funclist;
}

//===----------------------------------------------------------------------===//
// Combo Function Units - This is a list of all combo function unit data.
class ComboFuncUnits<list<ComboFuncData> cfd> {
list<ComboFuncData> CFD = cfd;
}

36 changes: 27 additions & 9 deletions llvm/lib/CodeGen/DFAPacketizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@
#include "llvm/Target/TargetInstrInfo.h"
using namespace llvm;

DFAPacketizer::DFAPacketizer(const InstrItineraryData *I, const int (*SIT)[2],
DFAPacketizer::DFAPacketizer(const InstrItineraryData *I,
const DFAStateInput (*SIT)[2],
const unsigned *SET):
InstrItins(I), CurrentState(0), DFAStateInputTable(SIT),
DFAStateEntryTable(SET) {}
DFAStateEntryTable(SET) {
// Make sure DFA types are large enough for the number of terms & resources.
assert((DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <= (8 * sizeof(DFAInput))
&& "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAInput");
assert((DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <= (8 * sizeof(DFAStateInput))
&& "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAStateInput");
}


//
Expand All @@ -60,26 +67,37 @@ void DFAPacketizer::ReadTable(unsigned int state) {
DFAStateInputTable[i][1];
}

//
// getInsnInput - Return the DFAInput for an instruction class.
//
DFAInput DFAPacketizer::getInsnInput(unsigned InsnClass) {
// Note: this logic must match that in DFAPacketizerDefs.h for input vectors.
DFAInput InsnInput = 0;
unsigned i = 0;
for (const InstrStage *IS = InstrItins->beginStage(InsnClass),
*IE = InstrItins->endStage(InsnClass); IS != IE; ++IS, ++i) {
InsnInput = addDFAFuncUnits(InsnInput, IS->getUnits());
assert ((i < DFA_MAX_RESTERMS) && "Exceeded maximum number of DFA inputs");
}
return InsnInput;
}

// canReserveResources - Check if the resources occupied by a MCInstrDesc
// are available in the current state.
bool DFAPacketizer::canReserveResources(const llvm::MCInstrDesc *MID) {
unsigned InsnClass = MID->getSchedClass();
const llvm::InstrStage *IS = InstrItins->beginStage(InsnClass);
unsigned FuncUnits = IS->getUnits();
UnsignPair StateTrans = UnsignPair(CurrentState, FuncUnits);
DFAInput InsnInput = getInsnInput(InsnClass);
UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
ReadTable(CurrentState);
return (CachedTable.count(StateTrans) != 0);
}


// reserveResources - Reserve the resources occupied by a MCInstrDesc and
// change the current state to reflect that change.
void DFAPacketizer::reserveResources(const llvm::MCInstrDesc *MID) {
unsigned InsnClass = MID->getSchedClass();
const llvm::InstrStage *IS = InstrItins->beginStage(InsnClass);
unsigned FuncUnits = IS->getUnits();
UnsignPair StateTrans = UnsignPair(CurrentState, FuncUnits);
DFAInput InsnInput = getInsnInput(InsnClass);
UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
ReadTable(CurrentState);
assert(CachedTable.count(StateTrans) != 0);
CurrentState = CachedTable[StateTrans];
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonScheduleV60.td
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ def CVI_XLSHF : FuncUnit;
def CVI_MPY01 : FuncUnit;
def CVI_ALL : FuncUnit;

// Combined functional unit data.
def HexagonComboFuncsV60 :
ComboFuncUnits<[
ComboFuncData<CVI_XLSHF , [CVI_XLANE, CVI_SHIFT]>,
ComboFuncData<CVI_MPY01 , [CVI_MPY0, CVI_MPY1]>,
ComboFuncData<CVI_ALL , [CVI_ST, CVI_XLANE, CVI_SHIFT,
CVI_MPY0, CVI_MPY1, CVI_LD]>
]>;

// Note: When adding additional vector scheduling classes, add the
// corresponding methods to the class HexagonInstrInfo.
def CVI_VA : InstrItinClass;
Expand Down
Loading

0 comments on commit b465572

Please sign in to comment.