Skip to content

Commit

Permalink
Added linear scan regalloc
Browse files Browse the repository at this point in the history
+ Added liveness analyzer
+ Improved linear order
+ Fixed GCM
  • Loading branch information
techie-mike committed Mar 5, 2024
1 parent a7be06b commit 49aaa48
Show file tree
Hide file tree
Showing 14 changed files with 951 additions and 43 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ jobs:
build:

runs-on: ubuntu-latest
env:
CC: gcc-9
CXX: g++-9

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -37,3 +40,4 @@ jobs:
cd build
valgrind tests/analysis_tests -s
valgrind tests/graph_tests -s
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ project(Compiler)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_FLAGS "-pedantic -Wall -Wextra -Werror -Wshadow")
set(CMAKE_CXX_FLAGS "-pedantic -Wall -Wextra -Werror -Wshadow -g")

set(ROOT_COMPILER ${CMAKE_SOURCE_DIR})
set(COMPILER_SOURCES
Expand All @@ -19,6 +19,7 @@ set(COMPILER_SOURCES
${CMAKE_SOURCE_DIR}/src/optimizations/gcm.cpp
${CMAKE_SOURCE_DIR}/src/optimizations/analysis/linear_order.cpp
${CMAKE_SOURCE_DIR}/src/optimizations/analysis/liveness_analyzer.cpp
${CMAKE_SOURCE_DIR}/src/optimizations/linear_scan.cpp
)

add_subdirectory(tests)
Expand Down
6 changes: 5 additions & 1 deletion src/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace compiler {

class LiveInterval;

class Graph
{
public:
Expand Down Expand Up @@ -130,13 +132,15 @@ class Graph
}

private:
bool unit_test_mode_;
bool unit_test_mode_ = false;
bool insts_placed_ = false;
uint32_t num_loops_ = 0;
Loop *root_loop_ = nullptr;
std::string name_method_;
std::vector<Inst *> all_inst_;
std::vector<RegionInst *> all_regions_;
LiveInterval *live_intervals_ = nullptr;
LinearNumber num_linear_inst_ = 0;
};

}
5 changes: 5 additions & 0 deletions src/inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,9 @@ RegionInst *Inst::CastToRegion() {
return static_cast<RegionInst *>(this);
}

IfInst *Inst::CastToIf() {
ASSERT(GetOpcode() == Opcode::If);
return static_cast<IfInst *>(this);
}

}
35 changes: 28 additions & 7 deletions src/inst.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ std::string CcToString(ConditionCode cc);
std::string TypeToString(Type type);

class RegionInst;
class IfInst;

class Inst
{
Expand Down Expand Up @@ -121,7 +122,7 @@ class Inst
virtual void DumpUsers(std::ostream &out);

uint32_t NumDataUsers();
std::list<Inst *> &GetRawUsers() {
std::list<Inst *> & GetRawUsers() {
return users_;
}

Expand All @@ -137,10 +138,14 @@ class Inst
return;
}

bool IsRegion() {
bool IsRegion() const {
return GetOpcode() == Opcode::Start || GetOpcode() == Opcode::Region || GetOpcode() == Opcode::End;
}

bool IsPhi() const {
return GetOpcode() == Opcode::Phi;
}

void SetPrev(Inst *inst) {
prev_ = inst;
}
Expand All @@ -158,8 +163,9 @@ class Inst
}

RegionInst *CastToRegion();
IfInst *CastToIf();

bool IsPlaced() {
bool IsPlaced() const {
return inst_placed_;
}

Expand Down Expand Up @@ -449,6 +455,21 @@ class RegionInst : public ControlProp<DynamicInputs>
return last_;
}

id_t GetIndexPredecessor(Inst* inst) {
id_t index = 0;
id_t num_inputs_succ_region = NumDataInputs();
for (index = 0; index < num_inputs_succ_region; index++) {
if (GetDataInput(index) == inst) {
return index;
}
}
UNREACHABLE();
}

LifeNumber GetLifeNumberEndOfRegion() {
return GetLast()->GetLifeNumber() + 2;
}

private:
void AddFirstInst(Inst *inst);

Expand Down Expand Up @@ -501,12 +522,12 @@ class IfInst : public ControlProp<FixedInputs<2>>
GetRawUsers().push_back(nullptr);
}

Inst *GetTrueBranch() {
return *(GetRawUsers().begin());
RegionInst *GetTrueBranch() {
return (*(GetRawUsers().begin()))->CastToRegion();
}

Inst *GetFalseBranch() {
return *(++GetRawUsers().begin());
RegionInst *GetFalseBranch() {
return (*(++GetRawUsers().begin()))->CastToRegion();
}

void SetTrueBranch(Inst *inst) {
Expand Down
76 changes: 72 additions & 4 deletions src/optimizations/analysis/linear_order.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,86 @@
#include "linear_order.h"
#include "rpo.h"
#include "analysis.h"
#include "loop_analysis.h"

namespace compiler {

void LinearOrder::Run() {
// TODO: Fix temporary solution
auto rpo = RpoRegions(graph_);
rpo.Run();
linear_order_ = rpo.GetVector();
if (!graph_->IsInstsPlaced()) {
UNREACHABLE();
}

LoopAnalysis(graph_).Run();
RecursiveOrder(graph_->GetStartRegion());
}

std::vector<RegionInst *> &LinearOrder::GetVector() {
return linear_order_;
}

void LinearOrder::RecursiveOrder(RegionInst *region) {
if (marker_.IsMarked(region)) {
return;
}
// If Region is loop header
if (region->IsLoopHeader() && !region->GetLoop()->IsIrreducible()) {
// Two case in this if:
// 1. If loop is reduceble, check preheaders is visited
// 2. If loop is irreduceble, don't check something
if (!region->GetLoop()->IsIrreducible() && !AllPreheadersIsVisited(region)) {
return;
}
} else {
if (!AllPrevIsVisited(region)) {
return;
}
}

linear_order_.push_back(region);
marker_.SetMarker(region);

if (region->GetOpcode() == Opcode::End) {
return;
}

auto last_inst = region->GetLast();
if (last_inst->GetOpcode() == Opcode::Jump) {
RecursiveOrder(last_inst->GetControlUser()->CastToRegion());
return;
}
ASSERT(last_inst->GetOpcode() == Opcode::If);
// TODO Change condition in IfInst, if false is jump back (region is already visited)
auto if_inst = last_inst->CastToIf();
RecursiveOrder(if_inst->GetFalseBranch());
RecursiveOrder(if_inst->GetTrueBranch());
}

void LinearOrder::AddRegionToOrder(RegionInst *region) {
linear_order_.push_back(region);
}

bool LinearOrder::AllPrevIsVisited(RegionInst *region) {
for (id_t i = 0; i < region->NumAllInputs(); i++) {
auto prev_region = GetRegionByInputRegion(region->GetRegionInput(i));
if (!marker_.IsMarked(prev_region)) {
return false;
}
}
return true;
}

bool LinearOrder::AllPreheadersIsVisited(RegionInst *region) {
auto backedges = region->GetLoop()->GetBackedges();
for (id_t i = 0; i < region->NumAllInputs(); i++) {
auto prev_region = GetRegionByInputRegion(region->GetRegionInput(i));
if (std::find(backedges.begin(), backedges.end(), prev_region) != backedges.end()) {
continue;
}
if (!marker_.IsMarked(prev_region)) {
return false;
}
}
return true;
}

}
11 changes: 10 additions & 1 deletion src/optimizations/analysis/linear_order.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "inst.h"
#include "marker.h"

namespace compiler {

Expand All @@ -9,14 +10,22 @@ class Graph;
class LinearOrder {
public:
LinearOrder(Graph *graph):
graph_(graph) {};
graph_(graph),
marker_(graph) {};

void Run();

std::vector<RegionInst *> &GetVector();

private:
void RecursiveOrder(RegionInst *region);
void AddRegionToOrder(RegionInst *region);
bool AllPrevIsVisited(RegionInst *region);
bool AllPreheadersIsVisited(RegionInst *region);

private:
Graph *graph_;
Marker marker_;
std::vector<RegionInst *> linear_order_;
};

Expand Down
Loading

0 comments on commit 49aaa48

Please sign in to comment.