-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AIE NFC] Postpipeliner cleanups and refactorings #253
Open
martien-de-jong
wants to merge
9
commits into
aie-public
Choose a base branch
from
martien.smallfixes
base: aie-public
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
8baa1cf
[AIE] Pack NodeInfo in a class with additional information
03951f0
[AIE] Push Earliest with local resource contention
3cd1db1
[AIE] Specify maxii relative to MinII
37d1a95
[AIE] Compute MinEarliest, MaxEarliest and MinLatest
505d73f
[AIE] Don't print edges to ExitSU
11bc08e
[AIE] Maintain II in the pipeliner strategy
6636a0a
[AIE] Add conv2d-bf16 test with feasible register allocation
7f4c316
[AIE] Bail out if RecMII not met.
95dbddf
[AIE] Reject NStages=1 pipelines
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -323,7 +323,7 @@ bool PostPipeliner::computeLoopCarriedParameters() { | |
} | ||
|
||
// Save the static values for ease of reset | ||
for (auto &N : Info) { | ||
for (auto &N : Info.Nodes) { | ||
N.StaticEarliest = N.Earliest; | ||
N.StaticLatest = N.Latest; | ||
} | ||
|
@@ -343,24 +343,23 @@ int PostPipeliner::computeMinScheduleLength() const { | |
return MinLength; | ||
} | ||
|
||
void dumpGraph(int NInstr, const std::vector<NodeInfo> &Info, | ||
ScheduleDAGInstrs *DAG) { | ||
void dumpGraph(const ScheduleInfo &Info, ScheduleDAGInstrs *DAG) { | ||
dbgs() << "digraph {\n"; | ||
|
||
for (int K = 0; K < NInstr; K++) { | ||
for (int K = 0; K < Info.NInstr; K++) { | ||
auto &SU = DAG->SUnits[K]; | ||
for (auto &Dep : SU.Succs) { | ||
auto *Succ = Dep.getSUnit(); | ||
int S = Succ->NodeNum; | ||
if (S % NInstr == K) { | ||
if (S % Info.NInstr == K) { | ||
continue; | ||
} | ||
|
||
dbgs() << "\tSU" << K << " -> " | ||
<< "SU" << S; | ||
|
||
if (S >= NInstr) { | ||
dbgs() << "_" << S % NInstr; | ||
if (S >= Info.NInstr) { | ||
dbgs() << "_" << S % Info.NInstr; | ||
} | ||
if (Dep.getKind() == SDep::Data) { | ||
dbgs() << " [color=red] "; | ||
|
@@ -476,7 +475,7 @@ bool PostPipeliner::scheduleFirstIteration(PostPipelinerStrategy &Strategy) { | |
} | ||
|
||
namespace { | ||
void dumpEarliestChain(const std::vector<NodeInfo> &Info, int N) { | ||
void dumpEarliestChain(const ScheduleInfo &Info, int N) { | ||
auto Prev = Info[N].LastEarliestPusher; | ||
if (Prev) { | ||
dumpEarliestChain(Info, *Prev); | ||
|
@@ -515,8 +514,7 @@ bool PostPipeliner::scheduleOtherIterations() { | |
|
||
class DefaultStrategy : public PostPipelinerStrategy { | ||
public: | ||
DefaultStrategy(ScheduleDAGMI &DAG, std::vector<NodeInfo> &Info, | ||
int LatestBias) | ||
DefaultStrategy(ScheduleDAGMI &DAG, ScheduleInfo &Info, int LatestBias) | ||
: PostPipelinerStrategy(DAG, Info, LatestBias) {} | ||
bool better(const SUnit &A, const SUnit &B) override { | ||
return Info[A.NodeNum].Latest < Info[B.NodeNum].Latest; | ||
|
@@ -525,6 +523,7 @@ class DefaultStrategy : public PostPipelinerStrategy { | |
|
||
class ConfigStrategy : public PostPipelinerStrategy { | ||
bool TopDown = true; | ||
bool Alternate = false; | ||
|
||
public: | ||
enum PriorityComponent { | ||
|
@@ -552,6 +551,13 @@ class ConfigStrategy : public PostPipelinerStrategy { | |
} | ||
return "Size - Illegal"; | ||
} | ||
struct Configuration { | ||
int ExtraStages = 0; | ||
bool TopDown = true; | ||
bool Alternate = false; | ||
int Runs = 0; | ||
ArrayRef<PriorityComponent> Components; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not own the list of components? Does that help a lot with memory usage? |
||
}; | ||
|
||
private: | ||
std::string Name; | ||
|
@@ -597,6 +603,12 @@ class ConfigStrategy : public PostPipelinerStrategy { | |
return false; | ||
} | ||
|
||
int earliest(const SUnit &N) override { return Info[N.NodeNum].Earliest; } | ||
|
||
int latest(const SUnit &N) override { | ||
return Info[N.NodeNum].Latest + LatestBias; | ||
} | ||
|
||
void selected(const SUnit &N) override { | ||
// Promote the critical path | ||
NodeInfo *Pushed = &Info[N.NodeNum]; | ||
|
@@ -628,75 +640,71 @@ class ConfigStrategy : public PostPipelinerStrategy { | |
PredSiblingScheduled.insert(PDep.getSUnit()->NodeNum); | ||
} | ||
} | ||
if (Alternate) { | ||
TopDown = !TopDown; | ||
} | ||
} | ||
|
||
public: | ||
std::string name() override { return Name; } | ||
ConfigStrategy(ScheduleDAGInstrs &DAG, std::vector<NodeInfo> &Info, | ||
int Length, bool TopDown, | ||
ConfigStrategy(ScheduleDAGInstrs &DAG, ScheduleInfo &Info, int Length, | ||
bool TopDown, bool Alternate, | ||
ArrayRef<PriorityComponent> Components) | ||
: PostPipelinerStrategy(DAG, Info, Length), TopDown(TopDown) { | ||
Name = "Config_" + std::to_string(Length) + "_" + std::to_string(TopDown); | ||
: PostPipelinerStrategy(DAG, Info, Length), TopDown(TopDown), | ||
Alternate(Alternate) { | ||
Name = "Config_" + std::to_string(Length) + "_" + std::to_string(TopDown) + | ||
"_" + std::to_string(Alternate); | ||
for (auto Comp : Components) { | ||
Name += "_" + getPriorityName(Comp); | ||
Priority.emplace_back(Comp); | ||
} | ||
} | ||
}; | ||
|
||
static const struct { | ||
int ExtraStages; | ||
bool TopDown; | ||
bool Rerun; | ||
ConfigStrategy::PriorityComponent Components[3]; | ||
} Strategies[] = { | ||
static const ConfigStrategy::PriorityComponent | ||
NodeNum[] = {ConfigStrategy::NodeNum}, | ||
Latest[] = {ConfigStrategy::Latest}, | ||
Critical[] = {ConfigStrategy::Critical}, | ||
CriticalLCDLatest[] = {ConfigStrategy::Critical, ConfigStrategy::LCDLatest}; | ||
|
||
static const ConfigStrategy::Configuration Strategies[] = { | ||
// Loosely speaking, a lower value of the first parameter targets | ||
// a lower stage count, which benefits code size. | ||
// Rerurn is only useful for heuristics that use it, e.g. Critical | ||
{1, true, false, {ConfigStrategy::NodeNum}}, | ||
{1, true, false, {ConfigStrategy::Latest}}, | ||
{1, true, true, {ConfigStrategy::Critical}}, | ||
{1, true, true, {ConfigStrategy::Critical, ConfigStrategy::LCDLatest}}, | ||
{0, false, true, {ConfigStrategy::Critical, ConfigStrategy::LCDLatest}}, | ||
{1, false, true, {ConfigStrategy::Critical, ConfigStrategy::LCDLatest}}, | ||
// Runs>1 is only useful for heuristics that use it, e.g. Critical | ||
// {ExtraStages, TopDown, Alternate, Runs, Components} | ||
{1, true, false, 1, NodeNum}, | ||
{1, true, false, 1, Latest}, | ||
{1, true, false, 2, Critical}, | ||
{1, true, false, 2, CriticalLCDLatest}, | ||
{0, false, false, 2, CriticalLCDLatest}, | ||
{1, false, false, 2, CriticalLCDLatest}, | ||
// This is pure bottom up | ||
{1, false, false, {ConfigStrategy::NodeNum}}, | ||
{1, false, false, 1, NodeNum}, | ||
}; | ||
|
||
bool PostPipeliner::tryHeuristics() { | ||
int MinLength = computeMinScheduleLength(); | ||
|
||
DEBUG_SUMMARY(dbgs() << "-- MinLength=" << MinLength << "\n"); | ||
|
||
int HeuristicIndex = 0; | ||
for (auto &[ExtraStages, TopDown, Rerun, Components] : Strategies) { | ||
for (const auto &Config : Strategies) { | ||
if (Heuristic >= 0 && Heuristic != HeuristicIndex++) { | ||
continue; | ||
} | ||
ConfigStrategy S(*DAG, Info, MinLength + ExtraStages * II, TopDown, | ||
Components); | ||
ConfigStrategy S(*DAG, Info, MinLength + Config.ExtraStages * II, | ||
Config.TopDown, Config.Alternate, Config.Components); | ||
resetSchedule(/*FullReset=*/true); | ||
DEBUG_SUMMARY(dbgs() << "--- Strategy " << S.name() << "\n"); | ||
if (scheduleFirstIteration(S) && scheduleOtherIterations()) { | ||
DEBUG_SUMMARY(dbgs() << " Strategy " << S.name() << " found II=" << II | ||
for (int Run = 0; Run < Config.Runs; Run++) { | ||
DEBUG_SUMMARY(dbgs() << "--- Strategy " << S.name() << " run=" << Run | ||
<< "\n"); | ||
return true; | ||
} | ||
|
||
DEBUG_SUMMARY(dbgs() << " failed\n"); | ||
if (!Rerun) { | ||
continue; | ||
} | ||
|
||
// Rerun with dynamic information retained | ||
resetSchedule(/*FullReset=*/false); | ||
DEBUG_SUMMARY(dbgs() << "--- Strategy " << S.name() | ||
<< " with critical path"); | ||
if (scheduleFirstIteration(S) && scheduleOtherIterations()) { | ||
DEBUG_SUMMARY(dbgs() << " found II=" << II << "\n"); | ||
return true; | ||
if (scheduleFirstIteration(S) && scheduleOtherIterations()) { | ||
DEBUG_SUMMARY(dbgs() << " Strategy " << S.name() << " run=" << Run | ||
<< " found II=" << II << "\n"); | ||
return true; | ||
} | ||
resetSchedule(/*FullReset=*/false); | ||
} | ||
DEBUG_SUMMARY(dbgs() << " failed\n"); | ||
DEBUG_SUMMARY(dbgs() << " Strategy " << S.name() << " failed\n"); | ||
} | ||
DEBUG_SUMMARY(dbgs() << "=== II=" << II << " Failed ===\n"); | ||
return false; | ||
|
@@ -718,12 +726,11 @@ bool PostPipeliner::schedule(ScheduleDAGMI &TheDAG, int InitiationInterval) { | |
Depth = NCopies * II + HR.getPipelineDepth(); | ||
Scoreboard.reset(Depth); | ||
|
||
Info.clear(); | ||
Info.resize(NTotalInstrs); | ||
Info.init(NInstr, NCopies); | ||
|
||
LLVM_DEBUG(for (int I = 0; I < NInstr; | ||
I++) { dbgs() << I << " " << *DAG->SUnits[I].getInstr(); }); | ||
LLVM_DEBUG(dumpGraph(NInstr, Info, DAG)); | ||
LLVM_DEBUG(dumpGraph(Info, DAG)); | ||
|
||
computeLoopCarriedParameters(); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,14 +90,27 @@ class NodeInfo { | |
void reset(bool FullReset); | ||
}; | ||
|
||
class ScheduleInfo { | ||
public: | ||
std::vector<NodeInfo> Nodes; | ||
int NInstr; | ||
void init(int NOrig, int NCopies) { | ||
NInstr = NOrig; | ||
Nodes.clear(); | ||
Nodes.resize(NInstr * NCopies); | ||
} | ||
NodeInfo &operator[](int N) { return Nodes[N]; } | ||
const NodeInfo &operator[](int N) const { return Nodes[N]; } | ||
}; | ||
|
||
class PostPipelinerStrategy { | ||
protected: | ||
ScheduleDAGInstrs &DAG; | ||
std::vector<NodeInfo> &Info; | ||
ScheduleInfo &Info; | ||
int LatestBias = 0; | ||
|
||
public: | ||
PostPipelinerStrategy(ScheduleDAGInstrs &DAG, std::vector<NodeInfo> &Info, | ||
PostPipelinerStrategy(ScheduleDAGInstrs &DAG, ScheduleInfo &Info, | ||
int LatestBias) | ||
: DAG(DAG), Info(Info), LatestBias(LatestBias) {}; | ||
virtual ~PostPipelinerStrategy() {}; | ||
|
@@ -139,9 +152,10 @@ class PostPipeliner { | |
int FirstUnscheduled = 0; | ||
int LastUnscheduled = -1; | ||
|
||
/// Holds the cycle of each SUnit. The following should hold: | ||
/// Holds the schuling information for each instruction. The following | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
/// should hold: | ||
/// Cycle(N) mod II == Cycle(N % NInstr) mod II | ||
std::vector<NodeInfo> Info; | ||
ScheduleInfo Info; | ||
|
||
// The scoreboard and its depth | ||
ResourceScoreboard<FuncUnitWrapper> Scoreboard; | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to document those fields, especially
Alternate