Skip to content
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

IR: Optimize runtime of optimization passes #670

Merged
merged 24 commits into from Jan 22, 2021
Merged
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e847f94
RA: rework ConstrainedRAPass::CalculateNodeInterference
skmp Jan 19, 2021
77d072e
RA: Switch active set to also use BucketList
skmp Jan 19, 2021
91ddc1d
RCLSE: Optimize FindMemberInfo to be O(1)
skmp Jan 19, 2021
6380ab6
RA: Optimize register conflict handling
skmp Jan 19, 2021
af94e24
RA: Simplify and optimize data structures
skmp Jan 19, 2021
900fc6d
ConstProp: Switch maps to unordred_maps
skmp Jan 19, 2021
56ca731
DSE: Merge Flag/GPR/FPR passes for perf
skmp Jan 19, 2021
997650b
DSE: Merge logic more for perf
skmp Jan 19, 2021
6bdf785
DSE: Optimize map lookups
skmp Jan 19, 2021
f3e19ef
DSE: No need to loop to find branching op
skmp Jan 19, 2021
9c760ff
RA: Get OP_JUMP/CONDJUMP without loop in CalculatePrecessors
skmp Jan 19, 2021
10b6fb0
RA: Rename CalculatePrecessors to CalculatePredecessors
skmp Jan 19, 2021
47ee9af
ConstProp: Keep pools in heap
skmp Jan 19, 2021
c3682f9
RA: Fix several bugs, get rid of virtual registers, remove unused com…
skmp Jan 19, 2021
e7e6b66
RA: Cleanups
skmp Jan 19, 2021
a9332e6
JIT/x64: Fix VAddV
skmp Jan 19, 2021
9f3ce47
RA: Expire ending intervals before starting new ones
skmp Jan 19, 2021
d3fc85e
RA: Make spans at least 1 offset long
skmp Jan 20, 2021
8aef9cb
RA: Exit after first spill per iteration is found
skmp Jan 20, 2021
9c462eb
ConsProp: Revert to ordered set for identical codegen
skmp Jan 20, 2021
ac1036a
IR: Sync Invalid class with RA
skmp Jan 20, 2021
0e7db64
RA: Run compation after spilling, not before
skmp Jan 20, 2021
00ca576
IRCompaction: Only memset in debug
skmp Jan 21, 2021
0546da7
Address review feedback
skmp Jan 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
111 changes: 94 additions & 17 deletions External/FEXCore/Source/Interface/IR/Passes/RegisterAllocationPass.cpp
Expand Up @@ -304,6 +304,51 @@ namespace FEXCore::IR {

std::vector<uint32_t> PhysicalRegisterCount;
std::vector<uint32_t> TopRAPressure;

#define INFO_MAKE(id, Class, StartEnd) ((id) | (Class << 24) | (StartEnd << 31))

#define INFO_IDCLASS(info) (info & 0x7fff'ffff)
#define INFO_ID(info) (info & 0xff'ffff)
#define INFO_CLASS(info) (info & 0x7f00'0000)
#define INFO_IS_END(info) (info & 0x8000'0000)

struct BucketList {
static constexpr const unsigned Size = 6;

uint32_t Items[Size];
std::unique_ptr<BucketList> Next;

BucketList() {
Items[0] = 0;
#ifndef NDEBUG
for (int i = 1; i < Size; i++)
Items[i] = 0xDEADBEEF;
#endif
}

void Append(uint32_t Val) {
auto that = this;

while (that->Next) {
that = that->Next.get();
}

int i;
for (i = 0; i < Size; i++) {
if (that->Items[i] == 0) {
that->Items[i] = Val;
break;
}
}

if (i < (Size-1)) {
that->Items[i+1] = 0;
} else {
that->Next = std::make_unique<BucketList>();
}
}
};
std::vector<BucketList> SpanStartEnd;

RegisterGraph *Graph;
FEXCore::IR::Pass* CompactionPass;
Expand Down Expand Up @@ -790,28 +835,60 @@ namespace FEXCore::IR {
uint32_t NodeCount = IR->GetSSACount();

// Now that we have all the live ranges calculated we need to add them to our interference graph

auto GetClass = [](uint64_t RegAndClass) {
uint32_t Class = RegAndClass >> 32;

if (Class == IR::GPRPairClass.Val)
return IR::GPRClass.Val;
else
return Class;
};

SpanStartEnd.resize(NodeCount);
for (uint32_t i = 0; i < NodeCount; ++i) {
for (uint32_t j = i + 1; j < NodeCount; ++j) {
if (!(LiveRanges[i].Begin >= LiveRanges[j].End ||
LiveRanges[j].Begin >= LiveRanges[i].End)) {

auto GetClass = [](uint64_t RegAndClass) {
uint32_t Class = RegAndClass >> 32;

if (Class == IR::GPRPairClass.Val)
return IR::GPRClass.Val;
else
return Class;
};

if (GetClass(Graph->Nodes[i].Head.RegAndClass) == GetClass(Graph->Nodes[j].Head.RegAndClass))
{
AddInterference(i, j);
AddInterference(j, i);
if (LiveRanges[i].Begin != 4294967295) {
auto Class = GetClass(Graph->Nodes[i].Head.RegAndClass);
SpanStartEnd[LiveRanges[i].Begin].Append(INFO_MAKE(i, Class, false));
SpanStartEnd[LiveRanges[i].End ].Append(INFO_MAKE(i, Class, true));
}
}

std::set<uint32_t> Active;
for (int OpNodeId = 0; OpNodeId < IR->GetSSACount(); OpNodeId++) {
auto OpHeader = IR->GetNode(OrderedNodeWrapper::WrapOffset(OpNodeId * sizeof(IR::OrderedNode)))->Op(IR->GetData());

auto Bucket = &SpanStartEnd[OpNodeId];
int i = 0;
for(;;) {
auto EdgeInfo = Bucket->Items[i];
if (EdgeInfo == 0)
break;

if (INFO_IS_END(EdgeInfo)) {
// Ends here
Active.erase(INFO_IDCLASS(EdgeInfo));
} else {
// Starts here
for (auto ActiveInfo: Active) {
if (INFO_CLASS(ActiveInfo) == INFO_CLASS(EdgeInfo)) {
AddInterference(INFO_ID(ActiveInfo), INFO_ID(EdgeInfo));
AddInterference(INFO_ID(EdgeInfo), INFO_ID(ActiveInfo));
}
}
Active.insert(EdgeInfo);
}

if (++i == Bucket->Size) {
LogMan::Throw::A(Bucket->Next != nullptr, "Interference bug");
Bucket = Bucket->Next.get();
i = 0;
}
}
}

LogMan::Throw::A(Active.size() == 0, "Interference bug");
SpanStartEnd.clear();
}

void ConstrainedRAPass::AllocateVirtualRegisters() {
Expand Down