Skip to content

Commit

Permalink
Added Sub peephole
Browse files Browse the repository at this point in the history
+ Test
  • Loading branch information
techie-mike committed Mar 18, 2024
1 parent cac075d commit 17a2dff
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 7 deletions.
7 changes: 5 additions & 2 deletions src/inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ void Inst::SetDataInput(id_t index, Inst *inst) {
if (HasControlProp()) {
index++;
}
// For dynamic inputs
if (index != NumAllInputs() && GetRawInput(index) != nullptr) {
GetRawInput(index)->DeleteDataUser(this);
}
SetRawInput(index, inst);
inst->AddDataUser(this);
}
Expand Down Expand Up @@ -268,9 +272,8 @@ ConstantInst *Inst::CastToConstant() {

void Inst::ReplaceDataUsers(Inst *from) {
ASSERT(!HasControlProp());
for (auto it = from->StartIteratorDataUsers(); it != from->GetRawUsers().end(); it++) {
for (auto it = from->StartIteratorDataUsers(); it != from->GetRawUsers().end(); it = from->StartIteratorDataUsers()) {
auto user = *it;
AddDataUser(user);
for (id_t i = 0; i < user->NumDataInputs(); i++) {
if (user->GetDataInput(i) == from) {
user->SetDataInput(i, this);
Expand Down
19 changes: 14 additions & 5 deletions src/inst.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ class Inst
void AddDataUser(Inst *inst);
void DeleteDataUser(Inst *inst);

bool HasSingleDataUser() {
return NumDataUsers() == 1;
}

Inst *GetSingleDataUser() {
ASSERT(HasSingleDataUser());
return GetRawUsers().back();
}

const std::list<Inst *> GetDataUsers();

virtual void DumpInputs([[maybe_unused]] std::ostream &out) {};
Expand Down Expand Up @@ -205,11 +214,11 @@ class Inst

private:
bool inst_placed_ = false;
id_t id_;
LinearNumber linear_number_;
LifeNumber life_number_;
Opcode opc_;
Type type_;
id_t id_ {};
LinearNumber linear_number_ {};
LifeNumber life_number_ {};
Opcode opc_ {};
Type type_ {};

protected:
Inst *prev_ = nullptr;
Expand Down
44 changes: 44 additions & 0 deletions src/optimizations/peepholes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ void Peepholes::VisitSub(Inst *inst) {
if (ConstFoldingBinaryOp(graph_, inst)) {
return;
}
// Some optimization may be applied, so we don't go out from function
TryOptimizeSubSub(inst);

if (TryOptimizeSubZero(inst)) {
return;
Expand All @@ -60,6 +62,13 @@ void Peepholes::VisitOr(Inst *inst) {
}
}

// 1. Constant 0x0 -> v3
// 2. ... -> v3
// 3. Sub v2, v1 -> v4
// ==========>>==========
// 1. Constant 0x0
// 2. ... -> v4
// 3. Sub v2, v1
bool Peepholes::TryOptimizeSubZero(Inst *inst) {
auto input0 = inst->GetDataInput(0);
auto input1 = inst->GetDataInput(1);
Expand All @@ -71,6 +80,41 @@ bool Peepholes::TryOptimizeSubZero(Inst *inst) {
return false;
}

// Optimize sub of sub
// 1. Constant ... -> v3
// 2. Constant ... -> v3
// 3. ... -> v4
// 4. Sub v3, v1 -> v3
// 5. Sub v4, v2 -> v6
// ==========>>==========
// 1. Constant ... -> v3
// 2. Constant ...
// 6. Constant /v1+v2/ -> v5
// 3. ... -> v4
// 4. Sub v3, v1
// 5. Sub v3, v6 -> v6
bool Peepholes::TryOptimizeSubSub(Inst *inst) {
auto input0 = inst->GetDataInput(0);
auto input1 = inst->GetDataInput(1);

if (!input1->IsConst() || !inst->HasSingleDataUser()) {
return false;
}

auto single_user = inst->GetSingleDataUser();
if (single_user->GetOpcode() != Opcode::Sub || !single_user->GetDataInput(1)->IsConst()) {
return false;
}

auto const_near = input1->CastToConstant()->GetImm();
auto const_far = single_user->GetDataInput(1)->CastToConstant()->GetImm();
// Overflow is ok
auto new_const = graph_->CreateConstantInst(const_near + const_far);
single_user->SetDataInput(1, new_const);
single_user->SetDataInput(0, input0);
return true;
}

bool Peepholes::TryOptimizeShlAfterShr(Inst *inst) {
auto input0 = inst->GetDataInput(0);
auto input1 = inst->GetDataInput(1);
Expand Down
1 change: 1 addition & 0 deletions src/optimizations/peepholes.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Peepholes {

// Cases of optimization
bool TryOptimizeSubZero(Inst *inst);
bool TryOptimizeSubSub(Inst *inst);
bool TryOptimizeShlAfterShr(Inst *inst);
bool TryOptimizeOrZero(Inst *inst);

Expand Down
38 changes: 38 additions & 0 deletions tests/peepholes_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,44 @@ TEST(PeepholesTest, ShrAfterShr) {
GraphComparator(true_graph, graph).Compare();
}

TEST(PeepholesTest, SubSub) {
// Before
auto ic = IrConstructor();
ic.CreateInst<Opcode::Start>(0);
ic.CreateInst<Opcode::End>(1);
ic.CreateInst<Opcode::Parameter>(2);
ic.CreateInst<Opcode::Constant>(3).Imm(10);
ic.CreateInst<Opcode::Constant>(4).Imm(15);
ic.CreateInst<Opcode::Sub>(5).DataInputs(2, 3);
ic.CreateInst<Opcode::Sub>(6).DataInputs(5, 4);
ic.CreateInst<Opcode::Return>(7).CtrlInput(0).DataInputs(6);
ic.CreateInst<Opcode::Jump>(8).CtrlInput(7).JmpTo(1);

auto graph = ic.GetFinalGraph();
auto ph = Peepholes(graph);
ph.Run();

// After
auto ic_true = IrConstructor();
ic_true.CreateInst<Opcode::Start>(0);
ic_true.CreateInst<Opcode::Parameter>(2);
ic_true.CreateInst<Opcode::Constant>(3).Imm(10);
ic_true.CreateInst<Opcode::Constant>(4).Imm(15);
ic_true.CreateInst<Opcode::Constant>(9).Imm(25);

ic_true.CreateInst<Opcode::Sub>(5).DataInputs(2, 3);
ic_true.CreateInst<Opcode::Sub>(6).DataInputs(2, 9);
ic_true.CreateInst<Opcode::Return>(7).CtrlInput(0).DataInputs(6);
ic_true.CreateInst<Opcode::Jump>(8).CtrlInput(7).JmpTo(1);

ic_true.CreateInst<Opcode::End>(1);

auto true_graph = ic_true.GetFinalGraph();

GraphComparator(true_graph, graph).Compare();
}



TEST(ConstFoldingTest, Sub) {
// Before
Expand Down

0 comments on commit 17a2dff

Please sign in to comment.