Skip to content

Commit

Permalink
Added dominated check elimination
Browse files Browse the repository at this point in the history
  • Loading branch information
techie-mike committed Apr 17, 2024
1 parent 8f91d90 commit 3f02789
Show file tree
Hide file tree
Showing 11 changed files with 380 additions and 11 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set(COMPILER_SOURCES
${CMAKE_SOURCE_DIR}/src/optimizations/peepholes.cpp
${CMAKE_SOURCE_DIR}/src/optimizations/constant_folding.cpp
${CMAKE_SOURCE_DIR}/src/optimizations/inlining.cpp
${CMAKE_SOURCE_DIR}/src/optimizations/checks_elimination.cpp
)

add_library(CompilerLibBase ${COMPILER_SOURCES})
Expand Down
38 changes: 37 additions & 1 deletion src/inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,18 @@ void ParameterInst::DumpInputs(std::ostream &out) {

void Inst::ReplaceAllUsers(Inst *from) {
ReplaceDataUsers(from);
ReplaceCtrUser(from);
UpdateCtrConnection(from);
}

void Inst::UpdateCtrConnection(Inst *from) {
// ASSERT(HasSingleDataUser());
auto c_user = from->GetControlUser();
if (c_user == nullptr) {
return;
}
auto c_input = from->GetControlInput();
c_user->SetControlInput(c_input);
from->SetControlUser(nullptr);
}

void Inst::ReplaceCtrUser(Inst *from) {
Expand All @@ -401,4 +412,29 @@ void DynamicInputs::DeleteInput(Inst *inst) {
inputs_.erase(it);
}

RegionInst *FindRegion(Inst *inst) {
ASSERT(inst->HasControlProp());
while (!inst->IsRegion()) {
inst = inst->GetControlInput();
}
return inst->CastToRegion();
}

bool Inst::IsDominated(Inst *other) {
ASSERT(HasControlProp() && other->HasControlProp());
auto *our_region = FindRegion(this);
auto *other_region = FindRegion(other);

if (our_region == other_region) {
auto *inst = other;
while (inst != other_region && inst != this) {
inst = inst->GetControlInput();
}
return inst == this;
}
// Insts in different regions
return our_region->IsDominated(other_region);
}


}
21 changes: 21 additions & 0 deletions src/inst.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ class Inst
void ReplaceDataUsers(Inst *from);
void ReplaceAllUsers(Inst *from);
void ReplaceCtrUser(Inst *from);
void UpdateCtrConnection(Inst *from);

bool IsDominated(Inst *other);

private:
auto StartIteratorDataUsers() {
Expand Down Expand Up @@ -711,4 +714,22 @@ class CallInst : public ControlProp<DynamicInputs>
std::string name_func_;
};

class NullCheckInst : public ControlProp<FixedInputs<2>>
{
public:
using Base = ControlProp<FixedInputs<2>>;
NullCheckInst():
Base(Opcode::NullCheck) {};
// Need to add check type of input
};

class BoundsCheckInst : public ControlProp<FixedInputs<3>>
{
public:
using Base = ControlProp<FixedInputs<3>>;
BoundsCheckInst():
Base(Opcode::BoundsCheck) {};
// Need to add check type of input
};

}
15 changes: 9 additions & 6 deletions src/opcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ namespace compiler {
ACTION( Phi , PhiInst ) \
ACTION( Return , ReturnInst ) \
ACTION( Parameter , ParameterInst ) \
ACTION( NullCheck , NullCheckInst ) \
ACTION( BoundsCheck , BoundsCheckInst ) \
ACTION( Call , CallInst )

#define REGIONS_OPCODE_LIST(ACTION) \
Expand Down Expand Up @@ -96,12 +98,13 @@ constexpr std::array<const char *const, static_cast<size_t>(ConditionCode::NUM_C

//===================================================================

#define TYPE_LIST(ACTION) \
ACTION( BOOL , b ) \
ACTION( INT32 , i32 ) \
ACTION( UINT32 , u32 ) \
ACTION( INT64 , i64 ) \
ACTION( UINT64 , u64 )
#define TYPE_LIST(ACTION) \
ACTION( BOOL , b ) \
ACTION( INT32 , i32 ) \
ACTION( UINT32 , u32 ) \
ACTION( INT64 , i64 ) \
ACTION( UINT64 , u64 ) \
ACTION( REFERENCE, ref )

enum class Type {
NONE = 0,
Expand Down
3 changes: 2 additions & 1 deletion src/optimizations/analysis/rpo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ void RpoRegions::AddInstInVector(Inst *inst) {
RpoInsts::RpoInsts(Graph *graph):
graph_ (graph) {}

void RpoInsts::Run() {
RpoInsts* RpoInsts::Run() {
auto end = graph_->GetInstByIndex(1);
auto marker = Marker(graph_);
DFSInsts(end, marker);
return this;
}

void RpoInsts::DFSInsts(Inst *inst, Marker &marker) {
Expand Down
2 changes: 1 addition & 1 deletion src/optimizations/analysis/rpo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class RpoInsts
public:
RpoInsts(Graph *graph);

void Run();
RpoInsts* Run();
void DFSInsts(Inst *inst, Marker &marker);
std::vector<Inst *> &GetVector();

Expand Down
53 changes: 53 additions & 0 deletions src/optimizations/checks_elimination.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "checks_elimination.h"
#include "analysis/domtree.h"
#include "analysis/rpo.h"

namespace compiler {

void ChecksElimination::Run() {
DomTreeSlow(graph_).Run();
auto rpo_vector = RpoInsts(graph_).Run()->GetVector();

VisitChecks(rpo_vector);
}

void ChecksElimination::VisitChecks(std::vector<Inst *> &rpo_vector) {
for (auto inst : rpo_vector) {
switch (inst->GetOpcode()) {
case Opcode::NullCheck:
VisitNullCheck(inst);
break;
case Opcode::BoundsCheck:
VisitBoundCheck(inst);
break;
default:
break;
}
}
}

void ChecksElimination::VisitNullCheck(Inst *inst) {
auto* input = inst->GetDataInput(0);
for (auto* user : input->GetDataUsers()) {
if (user->GetOpcode() == Opcode::NullCheck &&
user != inst &&
user->IsDominated(inst)) {
user->ReplaceAllUsers(inst);
}
}
}

void ChecksElimination::VisitBoundCheck(Inst *inst) {
auto* checked_value = inst->GetDataInput(0);
auto* up_bound = inst->GetDataInput(1);
for (auto* user : checked_value->GetDataUsers()) {
if (user->GetOpcode() == Opcode::BoundsCheck &&
user != inst &&
user->GetDataInput(1) == up_bound &&
user->IsDominated(inst)) {
user->ReplaceAllUsers(inst);
}
}
}

}
27 changes: 27 additions & 0 deletions src/optimizations/checks_elimination.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include "vector"

namespace compiler {

class Graph;
class Inst;

class ChecksElimination
{
public:
ChecksElimination(Graph *graph):
graph_(graph) {};

void Run();

private:
void VisitChecks(std::vector<Inst *> &rpo);
void VisitNullCheck(Inst *inst);
void VisitBoundCheck(Inst *inst);

private:
Graph *graph_;
};

}
22 changes: 21 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,27 @@ add_custom_target(
COMMAND inlining_test
)

add_executable(
checks_elimination
checks_elimination_tests.cpp
graph_comparator.cpp
)

target_link_libraries(
checks_elimination
${ALL_LIBS_FOR_TESTS}
)

target_include_directories(checks_elimination PUBLIC "${CMAKE_SOURCE_DIR}/src")

gtest_discover_tests(checks_elimination)

add_custom_target(
checks_elimination_gtest
COMMAND checks_elimination
)

add_custom_target(
tests
DEPENDS graph_tests_gtest analysis_tests_gtest peepholes_tests_gtest
DEPENDS graph_tests_gtest analysis_tests_gtest peepholes_tests_gtest checks_elimination_gtest
)
Loading

0 comments on commit 3f02789

Please sign in to comment.