Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmake.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cmake -S . -B build
cmake --build build -j12
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ add_executable(sysyc
backend/llir.cc
backend/assembly.cc
opt/peephole.cc
opt/constprop.cc
)
target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(sysyc PRIVATE SysYParser)
Expand Down
135 changes: 133 additions & 2 deletions src/opt/constprop.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,134 @@
#include "constprop.h"
#include "../frontend/IR.h"
#include <unordered_map>
#include <string>

namespace transform {

}

void ConstProp::functionTransform(sysy::Function *func) {
for (auto &bb : func->getBasicBlocks()) {
this->curBB = bb.get();
this->constantPropagation(bb.get());
}
}

void ConstProp::moduleTransform() {
auto *funcs = this->module->getFunctions();
for (auto it = funcs->begin(); it != funcs->end(); ++it) {
this->functionTransform(it->second);
}
}

void ConstProp::constantPropagation(sysy::BasicBlock *bb) {
int flag;
std::unordered_map<std::string, std::string> valueMap;
std::unordered_map<std::string, std::string> valuechange;
for (auto &inst : bb->CoInst) {
if (inst.op == "li") { // Assuming 'li' is the instruction to load immediate constants.
valueMap[inst.fields[0]] = inst.fields[1]; // Store constant value with its register.
valuechange[inst.fields[0]] = "0";
}
else if(inst.op == "add" ){
for (int i=1;i<=2;i++){
flag = false;
if (inst.valid && !inst.fields.empty() && valueMap.find(inst.fields[i]) != valueMap.end() && valuechange[inst.fields[i]] == "0") {
inst.fields[i] = valueMap[inst.fields[i]];
flag = true;
}
else break;
}
if (flag){
int temp1 = std::stoll(inst.fields[1]);
int temp2 = std::stoll(inst.fields[2]);
valueMap[inst.fields[0]] = std::to_string(temp1 + temp2);
}
else{
valuechange[inst.fields[0]] = "1";
}
}
else if(inst.op == "sub" ){
for (int i=1;i<=2;i++){
flag = false;
if (inst.valid && !inst.fields.empty() && valueMap.find(inst.fields[i]) != valueMap.end() && valuechange[inst.fields[i]] == "0") {
inst.fields[i] = valueMap[inst.fields[i]];
flag = true;
}
else break;
}
if (flag){
int temp1 = std::stoll(inst.fields[1]);
int temp2 = std::stoll(inst.fields[2]);
valueMap[inst.fields[0]] = std::to_string(temp1 - temp2);
}
else{
valuechange[inst.fields[0]] = "1";
}
}
else if(inst.op == "mul" ){
for (int i=1;i<=2;i++){
flag = false;
if (inst.valid && !inst.fields.empty() && valueMap.find(inst.fields[i]) != valueMap.end() && valuechange[inst.fields[i]] == "0") {
inst.fields[i] = valueMap[inst.fields[i]];
flag = true;
}
else break;
}
if (flag){
int temp1 = std::stoll(inst.fields[1]);
int temp2 = std::stoll(inst.fields[2]);
valueMap[inst.fields[0]] = std::to_string(temp1 * temp2);
}
else{
valuechange[inst.fields[0]] = "1";
}
}
else if(inst.op == "div" ){
for (int i=1;i<=2;i++){
flag = false;
if (inst.valid && !inst.fields.empty() && valueMap.find(inst.fields[i]) != valueMap.end() && valuechange[inst.fields[i]] == "0") {
inst.fields[i] = valueMap[inst.fields[i]];
flag = true;
}
else break;
}
if (flag){
int temp1 = std::stoll(inst.fields[1]);
int temp2 = std::stoll(inst.fields[2]);
valueMap[inst.fields[0]] = std::to_string(temp1 / temp2);
}
else{
valuechange[inst.fields[0]] = "1";
}
}
else if (inst.op == "sw" ){
std::string temp;
auto nextInst = std::next(&inst);
if (inst.valid && !inst.fields.empty() && valueMap.find(inst.fields[0]) != valueMap.end() && valuechange[inst.fields[0]] == "0") {
// Replace uses of constants.
//inst.fields[0] = valueMap[inst.fields[0]];
temp = valueMap[inst.fields[0]];
}
if (nextInst->op == "lw"){
valueMap[nextInst->fields[0]] = temp;// Store constant value with its register.
valuechange[nextInst->fields[0]] = "0";
}
}
else if (inst.op == "lw" ){
continue;
}
// else if (inst.op == "addi" && inst.op == "ori" && inst.op == "subi" && inst.op == "slli" && inst.op == "sll" ){
// if (inst.valid && !inst.fields.empty() && valueMap.find(inst.fields[0]) != valueMap.end() && valuechange[inst.fields[0]] == "0") {
// // Replace uses of constants.
// valuechange[inst.fields[0]] = "1";
// }
// }
else{
if (inst.valid && !inst.fields.empty() && valueMap.find(inst.fields[0]) != valueMap.end() && valuechange[inst.fields[0]] == "0") {
// Replace uses of constants.
valuechange[inst.fields[0]] = "1";
}
}
}

}
} // namespace transform
21 changes: 21 additions & 0 deletions src/opt/constprop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "../frontend/IR.h"

namespace transform {

class ConstProp {
private:
sysy::Module *module;

public:
sysy::BasicBlock *curBB;

ConstProp(sysy::Module *module): module(module) {};

void moduleTransform();
void functionTransform(sysy::Function *func);
void constantPropagation(sysy::BasicBlock *bb);
//bool isConstantValue(sysy::RVInst *inst);
//void replaceConstantUses(sysy::RVInst *defInst, int constantValue);
}; // class ConstProp

} // namespace transform
6 changes: 6 additions & 0 deletions src/sysyc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "backend/llir.h"
#include "backend/assembly.h"
#include "opt/peephole.h"
#include "opt/constprop.h"

struct ArgsOptions {
std::string srcfile;
Expand All @@ -29,6 +30,7 @@ class TransformFlags {
{"--fpeephole", false},
{"--verbose", false},
{"--fparallel", false},
{"--fconstprop",false},
{"--opt", false}};
std::string srcfile;
void parseFlags(int argc, char** argv) {
Expand Down Expand Up @@ -57,6 +59,10 @@ class TransformFlags {
transform::Hole hole(this->module);
hole.moduleTransform();
}
if (this->flags["--fconstprop"]) {
transform::ConstProp constProp(this->module);
constProp.moduleTransform();
}
}
void emit() {
if (this->flags["--emit-ir"]) {
Expand Down
12 changes: 12 additions & 0 deletions test/17_constprop.sy
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
int main (){
int a = 30;
int b = 9 - a / 5;
int c;
c = b * 4;
if (c > 10) {
c = c - 10;
}else{
c = 100;
}
return c * (60 / a);
}