Skip to content

Commit

Permalink
[AIEX] Extend Itinerary based of RegClass for multiple Operand
Browse files Browse the repository at this point in the history
  • Loading branch information
krishnamtibrewala authored and martien-de-jong committed Sep 20, 2024
1 parent 46f23e1 commit 562ccea
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 35 deletions.
10 changes: 7 additions & 3 deletions llvm/include/llvm/Target/Target.td
Original file line number Diff line number Diff line change
Expand Up @@ -583,11 +583,15 @@ class EncodingByHwMode<list<HwMode> Ms = [], list<InstructionEncoding> Ts = []>
list<InstructionEncoding> Objects = Ts;
}

class OperandRegClass<int OperIdx, RegisterClass Reg> {
RegisterClass RegClass = Reg;
int OperandIdx = OperIdx;
}

// Allows to specify instrution Itineraries based on RegClass used
class ItinRegClassPair<InstrItinClass Itin, RegisterClass Reg, int OperIdx = 0> {
class ItinRegClassPair<InstrItinClass Itin, list<OperandRegClass> RegType> {
InstrItinClass Itinerary = Itin;
RegisterClass Regclass = Reg;
int OperandIdx = OperIdx;
list<OperandRegClass> RegTypeList = RegType;
}

//===----------------------------------------------------------------------===//
Expand Down
22 changes: 11 additions & 11 deletions llvm/lib/Target/AIE/AIE2GenInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,9 @@ let Itinerary = II_JZ, hasDelaySlot = true in {
}

let Itinerary = II_MOVA, isMoveImm = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
let ItineraryRegPairs = [ItinRegClassPair<II_MOVA_R,eR>, ItinRegClassPair<II_MOVA_P,eP>,
ItinRegClassPair<II_MOVA_M,eM>, ItinRegClassPair<II_MOVA_DC,eDC>,
ItinRegClassPair<II_MOVA_DJ,eDJ>, ItinRegClassPair<II_MOVA_DN,eDN>] in {
let ItineraryRegPairs = [ItinRegClassPair<II_MOVA_R,[OperandRegClass<0, eR>]>, ItinRegClassPair<II_MOVA_P,[OperandRegClass<0, eP>]>,
ItinRegClassPair<II_MOVA_M,[OperandRegClass<0, eM>]>, ItinRegClassPair<II_MOVA_DC,[OperandRegClass<0, eDC>]>,
ItinRegClassPair<II_MOVA_DJ,[OperandRegClass<0, eDJ>]>, ItinRegClassPair<II_MOVA_DN,[OperandRegClass<0, eDN>]>] in {
def MOVA_lda_cg : AIE2_lda_cg_inst_lda<(outs OP_mLdaCg:$mLdaCg),
(ins simm11:$c11s), "mova", "$mLdaCg, $c11s">;
}
Expand Down Expand Up @@ -538,10 +538,10 @@ let Itinerary = II_PADD_3D in {

// MOV & MOVXM instruction have identical itineraries, they differ only in slot usage
let Itinerary = II_MOV, isMoveImm = 1, isReMaterializable = 1 in {
let ItineraryRegPairs = [ItinRegClassPair<II_MOV_RS,eR>, ItinRegClassPair<II_MOV_P,eP>,
ItinRegClassPair<II_MOV_M,eM>, ItinRegClassPair<II_MOV_RS,eS>,
ItinRegClassPair<II_MOV_DC,eDC>, ItinRegClassPair<II_MOV_DJ,eDJ>,
ItinRegClassPair<II_MOV_DN,eDN>] in {
let ItineraryRegPairs = [ItinRegClassPair<II_MOV_RS,[OperandRegClass<0, eR>]>, ItinRegClassPair<II_MOV_P,[OperandRegClass<0, eP>]>,
ItinRegClassPair<II_MOV_M,[OperandRegClass<0, eM>]>, ItinRegClassPair<II_MOV_RS,[OperandRegClass<0, eS>]>,
ItinRegClassPair<II_MOV_DC,[OperandRegClass<0, eDC>]>, ItinRegClassPair<II_MOV_DJ,[OperandRegClass<0, eDJ>]>,
ItinRegClassPair<II_MOV_DN,[OperandRegClass<0, eDN>]>] in {
// MOVXM is quite expensive in code size, and will block an extra slot, so we don't
// mark it as isAsCheapAsAMove
let isAsCheapAsAMove = 0 in {
Expand All @@ -556,10 +556,10 @@ let Itinerary = II_MOV, isMoveImm = 1, isReMaterializable = 1 in {
}

let Itinerary = II_MOV_SCL, isMoveReg = 1 in {
let ItineraryRegPairs = [ItinRegClassPair<II_MOV_SCL_RS,eR>, ItinRegClassPair<II_MOV_SCL_P,eP>,
ItinRegClassPair<II_MOV_SCL_M,eM>, ItinRegClassPair<II_MOV_SCL_RS,eS>,
ItinRegClassPair<II_MOV_SCL_DC,eDC>, ItinRegClassPair<II_MOV_SCL_DJ,eDJ>,
ItinRegClassPair<II_MOV_SCL_DN,eDN>] in {
let ItineraryRegPairs = [ItinRegClassPair<II_MOV_SCL_RS,[OperandRegClass<0, eR>]>, ItinRegClassPair<II_MOV_SCL_P,[OperandRegClass<0, eP>]>,
ItinRegClassPair<II_MOV_SCL_M,[OperandRegClass<0, eM>]>, ItinRegClassPair<II_MOV_SCL_RS,[OperandRegClass<0, eS>]>,
ItinRegClassPair<II_MOV_SCL_DC,[OperandRegClass<0, eDC>]>, ItinRegClassPair<II_MOV_SCL_DJ,[OperandRegClass<0, eDJ>]>,
ItinRegClassPair<II_MOV_SCL_DN,[OperandRegClass<0, eDN>]>] in {
def MOV_mv_scl : AIE2_mv_scl_inst_mv<(outs OP_mMvSclDst:$mMvSclDst),
(ins OP_mMvSclSrc:$mMvSclSrc), "mov", "$mMvSclDst, $mMvSclSrc">;
}
Expand Down
55 changes: 50 additions & 5 deletions llvm/test/TableGen/aie-variable-instr-itinerary.td
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,39 @@ class MOVInstruction : TestInstruction {
let Itinerary = II_MOV in
def MOV_instr : MOVInstruction<>;

let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,GPR>] in
let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,[OperandRegClass<0, GPR>]>] in
def MOV_instr_GPR : MOVInstruction<>;

let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_PTR,PTR>] in
let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_PTR,[OperandRegClass<0, PTR>]>] in
def MOV_instr_PTR : MOVInstruction<>;

let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,GPR, 1>, ItinRegClassPair<II_MOV_PTR,PTR, 1>] in
let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,[OperandRegClass<1, GPR>]>, ItinRegClassPair<II_MOV_PTR,[OperandRegClass<1, PTR>]>] in
def MOV_instr_GPR_PTR : MOVInstruction<>;

let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,[OperandRegClass<0, GPR>,OperandRegClass<1, PTR>]>] in
def MOV_instr_GP : MOVInstruction<>;

let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,GPR>] in {
let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,[OperandRegClass<0, PTR>,OperandRegClass<1, GPR>]>] in
def MOV_instr_PG : MOVInstruction<>;

let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,[OperandRegClass<0, GPR>,OperandRegClass<1, PTR>]>, ItinRegClassPair<II_MOV_PTR,[OperandRegClass<1, GPR>,OperandRegClass<0, PTR>]>] in
def MOV_instr_GP_PG : MOVInstruction<>;

let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,[OperandRegClass<0, GPR>]>] in {
def MOV_instr_GPR_1 : MOVInstruction<>;
def MOV_instr_GPR_2 : MOVInstruction<>;
}

let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,GPR, 1>, ItinRegClassPair<II_MOV_PTR,PTR, 1>] in {
let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,[OperandRegClass<1, GPR>]>, ItinRegClassPair<II_MOV_PTR,[OperandRegClass<1, PTR>]>] in {
def MOV_instr_GPR_PTR_1 : MOVInstruction<>;
def MOV_instr_GPR_PTR_2 : MOVInstruction<>;
}

let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,[OperandRegClass<0, GPR>,OperandRegClass<1, PTR>]>, ItinRegClassPair<II_MOV_PTR,[OperandRegClass<1, GPR>,OperandRegClass<0, PTR>]>] in {
def MOV_instr_GP_PG_1 : MOVInstruction<>;
def MOV_instr_GP_PG_2 : MOVInstruction<>;
}

// CHECK: unsigned TestAIEInstrInfo::getSchedClass(
// CHECK-NEXT: const MCInstrDesc &Desc,
// CHECK-NEXT: iterator_range<const MachineOperand *> Operands,
Expand Down Expand Up @@ -92,6 +105,29 @@ let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,GPR, 1>
// CHECK-NEXT: << Desc.getOpcode() << "\n");
// CHECK-NEXT: return Desc.getSchedClass();
// CHECK-NEXT: }
// CHECK-NEXT: case TestAIE::MOV_instr_GP:
// CHECK-NEXT: {
// CHECK-NEXT: if (checkRCForOperand(TestAIE::GPRRegClass,0) &&
// CHECK-NEXT: checkRCForOperand(TestAIE::PTRRegClass,1))
// CHECK-NEXT: return TestAIE::Sched::II_MOV_GPR;
// CHECK-NEXT: LLVM_DEBUG(dbgs() << "No matching RegClass found for instruction: "
// CHECK-NEXT: << Desc.getOpcode() << "\n");
// CHECK-NEXT: return Desc.getSchedClass();
// CHECK-NEXT: }
// CHECK-NEXT: case TestAIE::MOV_instr_GP_PG:
// CHECK-NEXT: case TestAIE::MOV_instr_GP_PG_1:
// CHECK-NEXT: case TestAIE::MOV_instr_GP_PG_2:
// CHECK-NEXT: {
// CHECK-NEXT: if (checkRCForOperand(TestAIE::GPRRegClass,0) &&
// CHECK-NEXT: checkRCForOperand(TestAIE::PTRRegClass,1))
// CHECK-NEXT: return TestAIE::Sched::II_MOV_GPR;
// CHECK-NEXT: if (checkRCForOperand(TestAIE::GPRRegClass,1) &&
// CHECK-NEXT: checkRCForOperand(TestAIE::PTRRegClass,0))
// CHECK-NEXT: return TestAIE::Sched::II_MOV_PTR;
// CHECK-NEXT: LLVM_DEBUG(dbgs() << "No matching RegClass found for instruction: "
// CHECK-NEXT: << Desc.getOpcode() << "\n");
// CHECK-NEXT: return Desc.getSchedClass();
// CHECK-NEXT: }
// CHECK-NEXT: case TestAIE::MOV_instr_GPR_PTR:
// CHECK-NEXT: case TestAIE::MOV_instr_GPR_PTR_1:
// CHECK-NEXT: case TestAIE::MOV_instr_GPR_PTR_2:
Expand All @@ -104,6 +140,15 @@ let Itinerary = II_MOV, ItineraryRegPairs = [ItinRegClassPair<II_MOV_GPR,GPR, 1>
// CHECK-NEXT: << Desc.getOpcode() << "\n");
// CHECK-NEXT: return Desc.getSchedClass();
// CHECK-NEXT: }
// CHECK-NEXT: case TestAIE::MOV_instr_PG:
// CHECK-NEXT: {
// CHECK-NEXT: if (checkRCForOperand(TestAIE::PTRRegClass,0) &&
// CHECK-NEXT: checkRCForOperand(TestAIE::GPRRegClass,1))
// CHECK-NEXT: return TestAIE::Sched::II_MOV_GPR;
// CHECK-NEXT: LLVM_DEBUG(dbgs() << "No matching RegClass found for instruction: "
// CHECK-NEXT: << Desc.getOpcode() << "\n");
// CHECK-NEXT: return Desc.getSchedClass();
// CHECK-NEXT: }
// CHECK-NEXT: case TestAIE::MOV_instr_PTR:
// CHECK-NEXT: {
// CHECK-NEXT: if (checkRCForOperand(TestAIE::PTRRegClass,0))
Expand Down
54 changes: 38 additions & 16 deletions llvm/utils/TableGen/AIEVariableInstrItineraryEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ namespace {

class AIEVariableInstrItineraryEmitter {

std::map<std::vector<std::tuple<llvm::StringRef, llvm::StringRef, unsigned>>,
std::vector<llvm::StringRef>>
std::map<
std::vector<std::tuple<
llvm::StringRef, std::vector<std::pair<llvm::StringRef, unsigned>>>>,
std::vector<llvm::StringRef>>
UniqueRegItineraryOpIdx;

public:
Expand Down Expand Up @@ -81,9 +83,18 @@ void AIEVariableInstrItineraryEmitter::emitAltItineraryInfo(raw_ostream &OS) {
for (const auto &Instr : Instrs)
OS << " case " << CurrentNamespace << "::" << Instr << ":\n";
OS << " {\n";
for (const auto &[RegClass, Itinerary, OpIdx] : RegItineraryPairs) {
OS << " if (checkRCForOperand(" << CurrentNamespace << "::" << RegClass
<< "RegClass," << OpIdx << "))\n";
for (const auto &[Itinerary, RegClassList] : RegItineraryPairs) {
assert(!RegClassList.empty() && "RegClassList cannot be empty");
OS << " if (";
unsigned Count = 0;
for (const auto &[RegClass, OpIdx] : RegClassList) {
if (Count)
OS << " &&\n ";
OS << "checkRCForOperand(" << CurrentNamespace << "::" << RegClass
<< "RegClass," << OpIdx << ")";
Count++;
}
OS << ")\n";
OS << " return " << CurrentNamespace << "::" << "Sched"
<< "::" << Itinerary << ";\n";
}
Expand Down Expand Up @@ -111,21 +122,32 @@ void AIEVariableInstrItineraryEmitter::run(raw_ostream &OS) {
std::vector<Record *> AltItinary =
R->getValueAsListOfDefs("ItineraryRegPairs");
if (AltItinary.size()) {
int FirstOperandIdx = AltItinary[0]->getValueAsInt("OperandIdx");
for (const auto AltItinerary : AltItinary)
if (FirstOperandIdx != AltItinerary->getValueAsInt("OperandIdx"))
llvm_unreachable("All alternate itineraries for an instruction must "
"have the same operand index");

std::vector<std::tuple<llvm::StringRef, llvm::StringRef, unsigned>>
std::vector<std::tuple<llvm::StringRef,
std::vector<std::pair<llvm::StringRef, unsigned>>>>
RegItineraryPairs;
for (const auto AltItinerary : AltItinary) {
std::vector<Record *> OpRegType =
AltItinerary->getValueAsListOfDefs("RegTypeList");
std::vector<std::pair<llvm::StringRef, unsigned>> OperandRegClass;

auto checkUnique = [&OperandRegClass](unsigned OpIdx) {
return !std::any_of(
OperandRegClass.begin(), OperandRegClass.end(),
[OpIdx](const auto &Operand) { return Operand.second == OpIdx; });
};

for (const auto RegType : OpRegType) {
unsigned OpIdx = RegType->getValueAsInt("OperandIdx");
assert(checkUnique(OpIdx) && "OperandIdx must be unique");
OperandRegClass.push_back(std::make_pair(
RegType->getValueAsDef("RegClass")->getName(), OpIdx));
}

assert(!OperandRegClass.empty() && "OperandRegClass cannot be empty");
RegItineraryPairs.push_back(
std::make_tuple(AltItinerary->getValueAsDef("Regclass")->getName(),
AltItinerary->getValueAsDef("Itinerary")->getName(),
FirstOperandIdx));
std::make_tuple(AltItinerary->getValueAsDef("Itinerary")->getName(),
OperandRegClass));
}

UniqueRegItineraryOpIdx[RegItineraryPairs].push_back(R->getName());
}
}
Expand Down

0 comments on commit 562ccea

Please sign in to comment.