Skip to content

Commit

Permalink
[AIEX] NFC: Refactor Alternate Descriptor codebase
Browse files Browse the repository at this point in the history
  • Loading branch information
krishnamtibrewala committed Oct 4, 2024
1 parent 4a65ca1 commit 0e2d85b
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 35 deletions.
14 changes: 13 additions & 1 deletion llvm/lib/Target/AIE/AIE2InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "AIE2TargetMachine.h"
#include "AIEHazardRecognizer.h"
#include "AIEMachineFunctionInfo.h"
#include "AIEMachineScheduler.h"
#include "AIETiedRegOperands.h"
#include "MCTargetDesc/AIE2MCTargetDesc.h"
#include "MCTargetDesc/AIEMCFormats.h"
Expand Down Expand Up @@ -912,12 +913,23 @@ ScheduleHazardRecognizer *AIE2InstrInfo::CreateTargetPostRAHazardRecognizer(
"Please use the MI scheduler instead: postmisched");
}

static AIEAlternateDescriptors &getSelectedAltDescs(const ScheduleDAGMI *DAG) {
if (DAG->hasVRegLiveness())
return static_cast<const AIEScheduleDAGMILive *>(DAG)
->getSchedImpl()
->getSelectedAltDescs();
return static_cast<const AIEScheduleDAGMI *>(DAG)
->getSchedImpl()
->getSelectedAltDescs();
}

ScheduleHazardRecognizer *
AIE2InstrInfo::CreateTargetMIHazardRecognizer(const InstrItineraryData *II,
const ScheduleDAGMI *DAG) const {
// AIE has a fully exposed pipeline, resource and format conflicts must be
// exactly modelled.
return new AIEHazardRecognizer(this, II, /*IsPreRA=*/DAG->hasVRegLiveness());
return new AIEHazardRecognizer(this, II, getSelectedAltDescs(DAG),
/*IsPreRA=*/DAG->hasVRegLiveness());
}

/// insertNoop - Insert a noop into the instruction stream at the specified
Expand Down
74 changes: 74 additions & 0 deletions llvm/lib/Target/AIE/AIEAlternateDescriptors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//== AIEAlternateDescriptors.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_AIEALTERNATEDESCRIPTORS_H
#define LLVM_SUPPORT_AIEALTERNATEDESCRIPTORS_H

#include "AIEBaseSubtarget.h"
#include "MCTargetDesc/AIEMCFormats.h"

#include <unordered_map>

namespace llvm {

using MIAltDescsMap = std::unordered_map<MachineInstr *, const MCInstrDesc *>;

class AIEAlternateDescriptors {
MIAltDescsMap AlternateDescs;

public:
AIEAlternateDescriptors() = default;
~AIEAlternateDescriptors() = default;

// Construct an alternate descriptor with the given alternate descriptors.
AIEAlternateDescriptors(const MIAltDescsMap &AltDescs)
: AlternateDescs(AltDescs) {}

// Set the alternate descriptor for the given multi-opcode instruction.
void setAlternateDescriptor(MachineInstr *MI, const unsigned AltInstOpcode) {
const AIEBaseSubtarget &STI = AIEBaseSubtarget::get(*MI->getMF());
const AIEBaseInstrInfo *TII = STI.getInstrInfo();

AlternateDescs[MI] = &TII->get(AltInstOpcode);
}

// Return the alternate descriptor for the given multi-opcode instruction.
std::optional<const MCInstrDesc *>
getSelectedDescriptor(MachineInstr *MI) const {
if (auto It = AlternateDescs.find(MI); It != AlternateDescs.end())
return It->second;
return std::nullopt;
}

const MCInstrDesc *getDesc(MachineInstr *MI) const {
return getSelectedDescriptor(MI).value_or(&MI->getDesc());
}

// Return the alternate opcode for the given multi-opcode instruction.
std::optional<unsigned> getSelectedOpcode(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 getSelectedOpcode(MI).value_or(MI->getDesc().getOpcode());
}

void clear() { AlternateDescs.clear(); }
};

} // end namespace llvm

#endif // LLVM_SUPPORT_AIEALTERNATEDESCRIPTOR_H
10 changes: 5 additions & 5 deletions llvm/lib/Target/AIE/AIEBundle.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ template <class I> class Bundle {
: FormatInterface(FormatInterface) {
bool ComputeSlots = (FormatInterface != nullptr);
for (I *Instr : Instrs) {
add(Instr, std::nullopt, ComputeSlots);
add(Instr, Instr->getOpcode(), ComputeSlots);
}
}

Expand Down Expand Up @@ -98,8 +98,7 @@ template <class I> class Bundle {
/// Add an instruction to the bundle
/// \param Instr Instruction to add
/// \pre canAdd(Instr);
void add(I *Instr, std::optional<unsigned> SelectedOpcode = std::nullopt,
bool ComputeSlots = true) {
void add(I *Instr, unsigned OpCode, bool ComputeSlots = true) {
if (isNoHazardMetaInstruction(Instr->getOpcode())) {
MetaInstrs.push_back(Instr);
return;
Expand All @@ -113,8 +112,7 @@ template <class I> 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");
Expand All @@ -127,6 +125,8 @@ template <class I> 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());
Expand Down
25 changes: 10 additions & 15 deletions llvm/lib/Target/AIE/AIEHazardRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,10 @@ static cl::opt<int>
int AIEHazardRecognizer::NumInstrsScheduled = 0;

AIEHazardRecognizer::AIEHazardRecognizer(
const AIEBaseInstrInfo *TII, const InstrItineraryData *II, bool IsPreRA,
const AIEBaseInstrInfo *TII, const InstrItineraryData *II,
AIEAlternateDescriptors &SelectedAlternateDescs, bool IsPreRA,
std::optional<unsigned> ScoreboardDepth)
: TII(TII), ItinData(II) {
: TII(TII), ItinData(II), SelectedAltDescs(SelectedAlternateDescs) {

int Depth = 0;
if (ScoreboardDepth.has_value()) {
Expand Down Expand Up @@ -213,11 +214,12 @@ AIEHazardRecognizer::AIEHazardRecognizer(
}
}

AIEHazardRecognizer::AIEHazardRecognizer(const TargetSubtargetInfo &Subtarget,
bool IsPreRA)
AIEHazardRecognizer::AIEHazardRecognizer(
const TargetSubtargetInfo &Subtarget,
AIEAlternateDescriptors &SelectedAlternateDescs, bool IsPreRA)
: AIEHazardRecognizer(
static_cast<const AIEBaseInstrInfo *>(Subtarget.getInstrInfo()),
Subtarget.getInstrItineraryData(), IsPreRA) {}
Subtarget.getInstrItineraryData(), SelectedAlternateDescs, IsPreRA) {}

namespace llvm {
void applyFormatOrdering(AIE::MachineBundle &Bundle, const VLIWFormat &Format,
Expand Down Expand Up @@ -292,7 +294,7 @@ void AIEHazardRecognizer::Reset() {
LLVM_DEBUG(dbgs() << "Reset hazard recognizer\n");
ReservedCycles = 0;
Scoreboard.clear();
SelectedAltOpcodes.clear();
SelectedAltDescs.clear();
}

ScheduleHazardRecognizer::HazardType
Expand Down Expand Up @@ -324,7 +326,7 @@ 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, AltInstOpcode);
return NoHazard;
}
}
Expand Down Expand Up @@ -385,7 +387,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);
Expand Down Expand Up @@ -616,13 +618,6 @@ unsigned AIEHazardRecognizer::computeScoreboardDepth() const {
return std::max(Depth, UserScoreboardDepth.getValue());
}

std::optional<unsigned>
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()))
Expand Down
14 changes: 8 additions & 6 deletions llvm/lib/Target/AIE/AIEHazardRecognizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#ifndef LLVM_LIB_TARGET_AIE_AIEHAZARDRECOGNIZER_H
#define LLVM_LIB_TARGET_AIE_AIEHAZARDRECOGNIZER_H

#include "AIEBaseAddrSpaceInfo.h"
#include "AIEAlternateDescriptors.h"
#include "AIEBaseSubtarget.h"
#include "AIEBundle.h"
#include "MCTargetDesc/AIEMCFormats.h"
Expand Down Expand Up @@ -103,9 +103,11 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer {
/// scheduling model. This is mostly used for testing, for other cases we
/// should trust the instruction itineraries.
AIEHazardRecognizer(const AIEBaseInstrInfo *TII, const InstrItineraryData *II,
AIEAlternateDescriptors &SelectedAlternateDescs,
bool IsPreRA,
std::optional<unsigned> ScoreboardDepth = std::nullopt);
AIEHazardRecognizer(const TargetSubtargetInfo &SubTarget,
AIEAlternateDescriptors &SelectedAlternateDescs,
bool IsPreRA = false);

~AIEHazardRecognizer() override {}
Expand Down Expand Up @@ -156,10 +158,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<unsigned> getSelectedAltOpcode(MachineInstr *MI) const;

/// The instructions with memory bank attribute return the address space
/// number
MemoryBankBits getMemoryBanks(const MachineInstr *MI) const;
Expand All @@ -182,6 +180,10 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer {
/// For efficiency, this size is rounded up to a power of two.
unsigned computeScoreboardDepth() const;

AIEAlternateDescriptors &getSelectedAltDescs() const {
return SelectedAltDescs;
}

ScheduleHazardRecognizer::HazardType
getHazardType(const ResourceScoreboard<FuncUnitWrapper> &TheScoreboard,
const MCInstrDesc &Desc, MemoryBankBits MemoryBanks,
Expand Down Expand Up @@ -209,9 +211,9 @@ class AIEHazardRecognizer : public ScheduleHazardRecognizer {

private:
ResourceScoreboard<FuncUnitWrapper> Scoreboard;
std::map<MachineInstr *, unsigned> SelectedAltOpcodes;
const AIEBaseInstrInfo *TII;
const InstrItineraryData *ItinData;
AIEAlternateDescriptors &SelectedAltDescs;
static int NumInstrsScheduled;
unsigned IssueLimit = 1;
unsigned ReservedCycles = 0;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/AIE/AIEHazardRecognizerPRAS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ using namespace llvm;

AIEHazardRecognizerPRAS::AIEHazardRecognizerPRAS(const AIEBaseInstrInfo *TII,
const InstrItineraryData *II)
: AIEHazardRecognizer(TII, II, /*IsPreRA=*/false),
: AIEHazardRecognizer(TII, II, PRASAlternateDescriptors,
/*IsPreRA=*/false),
CurrentBundle(TII->getFormatInterface()) {}

void AIEHazardRecognizerPRAS::StartBlock(MachineBasicBlock *MBB) {}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AIE/AIEHazardRecognizerPRAS.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class AIEHazardRecognizerPRAS : public AIEHazardRecognizer {
private:
std::vector<AIE::MachineBundle> Bundles;
AIE::MachineBundle CurrentBundle;
AIEAlternateDescriptors PRASAlternateDescriptors;
};

} // end namespace llvm
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/AIE/AIEInterBlockScheduling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ void InterBlockScheduling::enterFunction(MachineFunction *MF) {

// Get ourselves a hazard recognizer
const auto &Subtarget = MF->getSubtarget();
HR = std::make_unique<AIEHazardRecognizer>(Subtarget);
HR = std::make_unique<AIEHazardRecognizer>(Subtarget, SelectedAltDescs);

// And a native InstrInfo
TII = static_cast<const AIEBaseInstrInfo *>(Subtarget.getInstrInfo());
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AIE/AIEInterBlockScheduling.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ class InterBlockScheduling {
// A hazard recognizer to interpret itineraries
std::unique_ptr<AIEHazardRecognizer> HR;

AIEAlternateDescriptors SelectedAltDescs;
std::map<MachineBasicBlock *, BlockState> Blocks;
std::vector<MachineBasicBlock *> MBBSequence;
unsigned NextInOrder = 0;
Expand Down Expand Up @@ -393,6 +394,8 @@ class InterBlockScheduling {
void emitInterBlockBottom(const BlockState &BS) const;

bool tryPipeline(ScheduleDAGMI &DAG, MachineBasicBlock *BB);

AIEAlternateDescriptors &getSelectedAltDescs() { return SelectedAltDescs; }
};

} // end namespace llvm::AIE
Expand Down
11 changes: 9 additions & 2 deletions llvm/lib/Target/AIE/AIEMachineScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,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.getSelectedAltDescs().getOpcode(&MI),
ComputeSlots);
}
};

Expand Down Expand Up @@ -594,6 +595,7 @@ void AIEPostRASchedStrategy::leaveRegion(const SUnit &ExitSU) {
return;
}
materializeMultiOpcodeInstrs();
InterBlock.getSelectedAltDescs().clear();
if (IsBottomRegion) {
// This is the earliest point where we can destroy the recorded
// schedule in iterative scheduling. enterMBB and enterRegion are too early,
Expand Down Expand Up @@ -625,7 +627,7 @@ void AIEPostRASchedStrategy::materializeMultiOpcodeInstrs() {
const AIEHazardRecognizer &HazardRec) {
// Materialize instructions with multiple opcode options
if (std::optional<unsigned> AltOpcode =
HazardRec.getSelectedAltOpcode(&MI)) {
HazardRec.getSelectedAltDescs().getSelectedOpcode(&MI)) {
MI.setDesc(TII->get(*AltOpcode));
}
};
Expand Down Expand Up @@ -831,6 +833,7 @@ void AIEPreRASchedStrategy::leaveRegion(const SUnit &ExitSU) {
RegionBegin = nullptr;
RegionEnd = nullptr;
SUDelayerMap.clear();
SelectedAltDescs.clear();
}

PressureDiff estimatePressureDiff(const SUnit &SU,
Expand Down Expand Up @@ -1110,6 +1113,10 @@ void AIEScheduleDAGMI::releasePred(SUnit *SU, SDep *PredEdge) {
SchedImpl->releaseBottomNode(PredSU);
}

AIEPreRASchedStrategy *AIEScheduleDAGMILive::getSchedImpl() const {
return static_cast<AIEPreRASchedStrategy *>(SchedImpl.get());
}

void AIEScheduleDAGMILive::enterRegion(MachineBasicBlock *BB,
MachineBasicBlock::iterator Begin,
MachineBasicBlock::iterator End,
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/Target/AIE/AIEMachineScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ class AIEPostRASchedStrategy : public PostGenericScheduler {
const AIE::InterBlockScheduling &getInterBlock() const { return InterBlock; }
AIE::InterBlockScheduling &getInterBlock() { return InterBlock; }

AIEAlternateDescriptors &getSelectedAltDescs() {
return InterBlock.getSelectedAltDescs();
}

protected:
/// Apply a set of heuristics to a new candidate for PostRA scheduling.
///
Expand Down Expand Up @@ -166,6 +170,8 @@ class AIEPreRASchedStrategy : public GenericScheduler {
bool isAvailableNode(SUnit &SU, SchedBoundary &Zone,
bool VerifyReadyCycle) override;

AIEAlternateDescriptors &getSelectedAltDescs() { return SelectedAltDescs; }

protected:
/// Whether \p DelayedSU can be safely delayed without forming a cycle
/// of SUs delaying each other indefinitely.
Expand All @@ -192,6 +198,8 @@ class AIEPreRASchedStrategy : public GenericScheduler {
std::vector<unsigned> SUDelayerMap;

std::vector<unsigned> PSetThresholds;

AIEAlternateDescriptors SelectedAltDescs;
};

/// An extension to ScheduleDAGMI that provides callbacks on region entry/exit
Expand Down Expand Up @@ -230,6 +238,9 @@ class AIEScheduleDAGMILive final : public ScheduleDAGMILive {
unsigned RegionInstrs) override;

void exitRegion() override;

// Give dag mutators access to the scheduler state
AIEPreRASchedStrategy *getSchedImpl() const;
};

} // end namespace llvm
Expand Down
Loading

0 comments on commit 0e2d85b

Please sign in to comment.