From 9f8a55f9a7bca24fd577397d4a50f92f5a436893 Mon Sep 17 00:00:00 2001 From: Krishnam Tibrewala Date: Mon, 23 Sep 2024 02:27:52 -0700 Subject: [PATCH] [AIEX] NFC: Refactor Alternate Descriptor codebase --- llvm/lib/Target/AIE/AIEAlternateDescriptor.h | 71 ++++++++++++++++++++ llvm/lib/Target/AIE/AIEBundle.h | 10 +-- llvm/lib/Target/AIE/AIEHazardRecognizer.cpp | 14 ++-- llvm/lib/Target/AIE/AIEHazardRecognizer.h | 8 +-- llvm/lib/Target/AIE/AIEMachineScheduler.cpp | 5 +- llvm/unittests/Target/AIE/BundleTest.cpp | 2 +- 6 files changed, 87 insertions(+), 23 deletions(-) create mode 100644 llvm/lib/Target/AIE/AIEAlternateDescriptor.h diff --git a/llvm/lib/Target/AIE/AIEAlternateDescriptor.h b/llvm/lib/Target/AIE/AIEAlternateDescriptor.h new file mode 100644 index 000000000000..cbf7a42669ee --- /dev/null +++ b/llvm/lib/Target/AIE/AIEAlternateDescriptor.h @@ -0,0 +1,71 @@ +//== AIEAlternateDescriptor.h - Define Alternate descriptor Class *-C++-*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// (c) Copyright 2024 Advanced Micro Devices, Inc. or its affiliates +// +//===----------------------------------------------------------------------===// +// +// This file declares the AIEngine Alternate instruction descriptor class +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_AIEALTERNATEDESCRIPTOR_H +#define LLVM_SUPPORT_AIEALTERNATEDESCRIPTOR_H + +#include "AIEBaseSubtarget.h" +#include "MCTargetDesc/AIEMCFormats.h" + +#include + +namespace llvm { + +using MIAltDescsMap = std::unordered_map; + +class AIEAlternateDescriptor { + MIAltDescsMap AlternateDescs; + +public: + AIEAlternateDescriptor() = default; + ~AIEAlternateDescriptor() = default; + + // Construct an alternate descriptor with the given alternate descriptors. + AIEAlternateDescriptor(const MIAltDescsMap &AltDescs) + : AlternateDescs(AltDescs) {} + + // Set the alternate descriptor for the given multi-opcode instruction. + void setAlternateDescriptor(MachineInstr *MI, const MCInstrDesc *AltDesc) { + AlternateDescs[MI] = AltDesc; + } + + // Return the alternate descriptor for the given multi-opcode instruction. + std::optional + getAlternateDescriptor(MachineInstr *MI) const { + if (auto It = AlternateDescs.find(MI); It != AlternateDescs.end()) + return It->second; + return std::nullopt; + } + + const MCInstrDesc *getDesc(MachineInstr *MI) { + return getAlternateDescriptor(MI).value_or(&MI->getDesc()); + } + + // Return the alternate opcode for the given multi-opcode instruction. + std::optional getAlternateOpcode(MachineInstr *MI) const { + if (auto It = AlternateDescs.find(MI); It != AlternateDescs.end()) + return It->second->getOpcode(); + return std::nullopt; + } + + unsigned getOpcode(MachineInstr *MI) const { + return getAlternateOpcode(MI).value_or(MI->getDesc().getOpcode()); + } + + void clear() { AlternateDescs.clear(); } +}; + +} // end namespace llvm + +#endif // LLVM_SUPPORT_AIEALTERNATEDESCRIPTOR_H diff --git a/llvm/lib/Target/AIE/AIEBundle.h b/llvm/lib/Target/AIE/AIEBundle.h index c5b2c8f941d9..324c174b0c60 100644 --- a/llvm/lib/Target/AIE/AIEBundle.h +++ b/llvm/lib/Target/AIE/AIEBundle.h @@ -50,7 +50,7 @@ template class Bundle { : FormatInterface(FormatInterface) { bool ComputeSlots = (FormatInterface != nullptr); for (I *Instr : Instrs) { - add(Instr, std::nullopt, ComputeSlots); + add(Instr, Instr->getOpcode(), ComputeSlots); } } @@ -98,8 +98,7 @@ template class Bundle { /// Add an instruction to the bundle /// \param Instr Instruction to add /// \pre canAdd(Instr); - void add(I *Instr, std::optional SelectedOpcode = std::nullopt, - bool ComputeSlots = true) { + void add(I *Instr, unsigned OpCode, bool ComputeSlots = true) { if (isNoHazardMetaInstruction(Instr->getOpcode())) { MetaInstrs.push_back(Instr); return; @@ -113,8 +112,7 @@ template class Bundle { if (!ComputeSlots) return; - MCSlotKind FinalSlot = FormatInterface->getSlotKind( - SelectedOpcode ? *SelectedOpcode : Instr->getOpcode()); + MCSlotKind FinalSlot = FormatInterface->getSlotKind(OpCode); if (FinalSlot == MCSlotKind()) { assert(Instrs.size() == 1 && "Tried to add an unknown slot instruction in a valid Bundle"); @@ -127,6 +125,8 @@ template class Bundle { OccupiedSlots |= NewSlots; } + void add(I *Instr) { add(Instr, Instr->getOpcode()); } + /// return the minimum size valid format for this bundle, if any const VLIWFormat *getFormatOrNull(unsigned Size = 0) const { assert(!isStandalone()); diff --git a/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp b/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp index 9cb4a95996b8..2ff69b6bab21 100644 --- a/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp +++ b/llvm/lib/Target/AIE/AIEHazardRecognizer.cpp @@ -292,7 +292,7 @@ void AIEHazardRecognizer::Reset() { LLVM_DEBUG(dbgs() << "Reset hazard recognizer\n"); ReservedCycles = 0; Scoreboard.reset(); - SelectedAltOpcodes.clear(); + SelectedAltDescs.clear(); } ScheduleHazardRecognizer::HazardType @@ -324,7 +324,8 @@ AIEHazardRecognizer::getHazardType(SUnit *SU, int DeltaCycles) { // Check if there is NoHazard, If there is a Hazard or NoopHazard check // for the next possible Opcode. if (Haz == NoHazard) { - SelectedAltOpcodes[MI] = AltInstOpcode; + SelectedAltDescs.setAlternateDescriptor( + MI, const_cast(&TII->get(AltInstOpcode))); return NoHazard; } } @@ -385,7 +386,7 @@ void AIEHazardRecognizer::EmitInstruction(SUnit *SU, int DeltaCycles) { // If the instruction has multiple options, find the opcode that was selected // and use the latter to update the scoreboard. - unsigned SelectedOpcode = getSelectedAltOpcode(MI).value_or(MI->getOpcode()); + unsigned SelectedOpcode = SelectedAltDescs.getOpcode(MI); if (!AIE::MachineBundle::isNoHazardMetaInstruction(SelectedOpcode)) emitInScoreboard(TII->get(SelectedOpcode), getMemoryBanks(MI), MI->operands(), MI->getMF()->getRegInfo(), DeltaCycles); @@ -603,13 +604,6 @@ unsigned AIEHazardRecognizer::computeScoreboardDepth() const { return std::max(Depth, UserScoreboardDepth.getValue()); } -std::optional -AIEHazardRecognizer::getSelectedAltOpcode(MachineInstr *MI) const { - if (auto It = SelectedAltOpcodes.find(MI); It != SelectedAltOpcodes.end()) - return It->second; - return std::nullopt; -} - MemoryBankBits AIEHazardRecognizer::getMemoryBanks(const MachineInstr *MI) const { if (!(MI->mayLoad() || MI->mayStore())) diff --git a/llvm/lib/Target/AIE/AIEHazardRecognizer.h b/llvm/lib/Target/AIE/AIEHazardRecognizer.h index 55eeb6accaf5..107eaa70d63a 100644 --- a/llvm/lib/Target/AIE/AIEHazardRecognizer.h +++ b/llvm/lib/Target/AIE/AIEHazardRecognizer.h @@ -13,6 +13,7 @@ #ifndef LLVM_LIB_TARGET_AIE_AIEHAZARDRECOGNIZER_H #define LLVM_LIB_TARGET_AIE_AIEHAZARDRECOGNIZER_H +#include "AIEAlternateDescriptor.h" #include "AIEBaseSubtarget.h" #include "AIEBundle.h" #include "MCTargetDesc/AIEMCFormats.h" @@ -107,6 +108,8 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer { ~AIEHazardRecognizer() override {} + AIEAlternateDescriptor SelectedAltDescs; + void Reset() override; HazardType getHazardType(SUnit *SU, int DeltaCycles) override; void EmitInstruction(SUnit *) override; @@ -153,10 +156,6 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer { // Dump the scoreboard void dumpScoreboard() const; - /// For instructions with multiple "alternative opcodes", this will return - /// the opcode selected during scheduling. - std::optional getSelectedAltOpcode(MachineInstr *MI) const; - /// The instructions with memory bank attribute return the address space /// number MemoryBankBits getMemoryBanks(const MachineInstr *MI) const; @@ -202,7 +201,6 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer { private: ResourceScoreboard Scoreboard; - std::map SelectedAltOpcodes; const AIEBaseInstrInfo *TII; const InstrItineraryData *ItinData; static int NumInstrsScheduled; diff --git a/llvm/lib/Target/AIE/AIEMachineScheduler.cpp b/llvm/lib/Target/AIE/AIEMachineScheduler.cpp index 4a31318a01cc..427cfa9837ea 100644 --- a/llvm/lib/Target/AIE/AIEMachineScheduler.cpp +++ b/llvm/lib/Target/AIE/AIEMachineScheduler.cpp @@ -163,7 +163,8 @@ llvm::AIE::computeAndFinalizeBundles(SchedBoundary &Zone) { bumpCycleForBundles(EmitCycle, Bundles, CurrBundle); LLVM_DEBUG(dbgs() << " Add to CurrBundle: " << MI); - CurrBundle.add(&MI, HazardRec.getSelectedAltOpcode(&MI), ComputeSlots); + CurrBundle.add(&MI, HazardRec.SelectedAltDescs.getOpcode(&MI), + ComputeSlots); } }; @@ -629,7 +630,7 @@ void AIEPostRASchedStrategy::materializeMultiOpcodeInstrs() { const AIEHazardRecognizer &HazardRec) { // Materialize instructions with multiple opcode options if (std::optional AltOpcode = - HazardRec.getSelectedAltOpcode(&MI)) { + HazardRec.SelectedAltDescs.getAlternateOpcode(&MI)) { MI.setDesc(TII->get(*AltOpcode)); } }; diff --git a/llvm/unittests/Target/AIE/BundleTest.cpp b/llvm/unittests/Target/AIE/BundleTest.cpp index e0f7ad823f71..8fe68d30a73e 100644 --- a/llvm/unittests/Target/AIE/BundleTest.cpp +++ b/llvm/unittests/Target/AIE/BundleTest.cpp @@ -241,7 +241,7 @@ TEST(Bundle, AddUnknowns) { // Test we can create a bundle of two unknown instructions // when not computing VLIW formats. B.add(Unknown); - B.add(Unknown, std::nullopt, /*ComputeSlots=*/false); + B.add(Unknown, Unknown->getOpcode(), /*ComputeSlots=*/false); EXPECT_EQ(B.size(), unsigned(2)); }