diff --git a/include/ir/Module.hh b/include/ir/Module.hh index 088a5e538c87d45f266f686600d4006c2b0edc7d..fd5ede85623e39944b43ae997a45cba5d72354b5 100644 --- a/include/ir/Module.hh +++ b/include/ir/Module.hh @@ -15,7 +15,7 @@ class Module { unordered_set<Function*> externFunctions; LinkedList<Function*> functions; BasicBlock* currBasicBlock; - + unordered_map<string, Function*> libFunctions; public: Module(); @@ -32,13 +32,15 @@ class Module { AllocaInst* addAllocaInst(Type* type, string name); BinaryOpInst* addBinaryOpInst(OpTag opType, Value* op1, Value* op2, string name); - BranchInst* addBranchInst(Value* cond, BasicBlock* trueBlock, BasicBlock* falseBlock); + BranchInst* addBranchInst(Value* cond, BasicBlock* trueBlock, + BasicBlock* falseBlock); CallInst* addCallInst(Function* func, string name); CallInst* addCallInst(Function* func, vector<Value*>& params, string name); IcmpInst* addIcmpInst(OpTag opType, Value* op1, Value* op2, string name); FcmpInst* addFcmpInst(OpTag opType, Value* op1, Value* op2, string name); FptosiInst* addFptosiInst(Value* src, string name); - GetElemPtrInst* addGetElemPtrInst(Value* ptr, Value* idx1, Value* idx2, string name); + GetElemPtrInst* addGetElemPtrInst(Value* ptr, Value* idx1, Value* idx2, + string name); GetElemPtrInst* addGetElemPtrInst(Value* ptr, Value* idx1, string name); JumpInst* addJumpInst(BasicBlock* block); LoadInst* addLoadInst(Value* addr, string name); @@ -56,7 +58,9 @@ class Module { LinkedList<Function*>* getFunctions() { return &functions; } unordered_set<Function*>* getexternFunctions() { return &externFunctions; } - + void addLibFunction(Function* func) { libFunctions[func->getName()] = func; } + Function* getLibFunction(string name) { return libFunctions[name]; } + void buildCFG(); void irOptimize(); diff --git a/src/asm/Machine.cc b/src/asm/Machine.cc index e710a49c5b0f939bf647c79a9ea8b5c12f1b6626..b59b1a5f0f44e9afe45e95907f2f126e7702b22d 100644 --- a/src/asm/Machine.cc +++ b/src/asm/Machine.cc @@ -610,11 +610,15 @@ vector<MFunction *> MModule::getFunctions() { std::ostream &operator<<(std::ostream &os, const MModule &obj) { bool gen_memset = false; + bool gen_multimod = false; for (const auto &ef : *obj.externFunctions) { if (ef->getName() == "memset") { gen_memset = true; continue; } + if (ef->getName() == "antpie_multimod") { + gen_multimod = true; + } os << ".extern " << ef->getName() << endl; } @@ -632,6 +636,9 @@ std::ostream &operator<<(std::ostream &os, const MModule &obj) { if (gen_memset) { os << memset_code << endl; } - +#include "multimod.hh" + if (gen_multimod) { + os << multimod_code << endl; + } return os; } \ No newline at end of file diff --git a/src/asm/multimod.hh b/src/asm/multimod.hh new file mode 100644 index 0000000000000000000000000000000000000000..bbf6ee32bc30c2b70578d9c4714310b2700a5c69 --- /dev/null +++ b/src/asm/multimod.hh @@ -0,0 +1,20 @@ +// int multimod(int x, int y, int m) + +#include <string> + +std::string multimod_code = + "antpie_multimod:\n" + " mul a3, a1, a0\n" + " fcvt.d.l fa5, a0\n" + " fcvt.d.l fa4, a1\n" + " fmul.d fa5, fa5, fa4\n" + " fcvt.d.l fa4, a2\n" + " fdiv.d fa5, fa5, fa4\n" + " fcvt.l.d a0, fa5, rtz\n" + " mul a0, a0, a2\n" + " sub a3, a3, a0\n" + " rem a0, a3, a2\n" + " srai a1, a0, 63\n" + " and a1, a1, a2\n" + " addw a0, a0, a1\n" + " ret\n"; \ No newline at end of file diff --git a/src/frontend/MySysYParserVisitor.cc b/src/frontend/MySysYParserVisitor.cc index 93f118b552b7b74b7cb75af89b6add5221d8c91d..eb4509ffe7aa1de1b9cef49c8caf76cc0186e6ad 100644 --- a/src/frontend/MySysYParserVisitor.cc +++ b/src/frontend/MySysYParserVisitor.cc @@ -1124,8 +1124,17 @@ void MySysYParserVisitor::init_extern_function() { function = new Function(funcType, true, "_sysy_stoptime"); current->put("stoptime", function); + // int antpie_multimod(int x, int y, int m) + vector<Argument*> mmArgs = {new Argument("x", i32Type), + new Argument("y", i32Type), + new Argument("m", i32Type)}; + funcType = Type::getFuncType(i32Type, mmArgs); + function = new Function(funcType, true, "antpie_multimod"); + externFunctions.push_back(function); + for (Function* function : externFunctions) { current->put(function->getName(), function); + module.addLibFunction(function); } } diff --git a/src/ir/Module.cc b/src/ir/Module.cc index 53c4182c68daf869afd2fe6e55259a6e3c9516e4..80d4440c9ecd0bec8520f13cefcf6b8002626b3b 100644 --- a/src/ir/Module.cc +++ b/src/ir/Module.cc @@ -311,9 +311,14 @@ void Module::irOptimize() { optimizations.pushBack(new LoopSimplify(false)); optimizations.pushBack(new LoopInvariantCodeMotion()); optimizations.pushBack(new Reassociate()); + optimizations.pushBack(new GEPSimplify()); + + optimizations.pushBack(new StrengthReduction()); optimizations.pushBack(new TailRecursionElimination()); optimizations.pushBack(new MergeBlock()); + optimizations.pushBack(new LoadElimination()); + optimizations.pushBack(new ConstantFolding()); optimizations.pushBack(new CFGSimplify()); optimizations.pushBack(new DeadCodeElimination()); @@ -322,6 +327,7 @@ void Module::irOptimize() { // if (dynamic_cast<Reassociate*>(pass)) printIR(std::cout); pass->runOnModule(this); + // if (dynamic_cast<Reassociate*>(pass)) printIR(std::cout); } for (Function* func : functions) { diff --git a/src/opt/Reassociate.cc b/src/opt/Reassociate.cc index 7af38108f5e5907d724cf07024db07286a3b97fa..6fbc5945666a9b7ded48aa8058063a29d79c56bb 100644 --- a/src/opt/Reassociate.cc +++ b/src/opt/Reassociate.cc @@ -58,7 +58,11 @@ bool Reassociate::runOnBasicBlock(BasicBlock* block) { break; } } - + unordered_map<const Value*, int> idx; + int i = 0; + for (auto arg : args) { + idx[arg] = i++; + } if (!flag) { changed = true; std::sort(args.begin(), args.end(), @@ -67,7 +71,10 @@ bool Reassociate::runOnBasicBlock(BasicBlock* block) { return true; if (rhs->isa(VT_INTCONST) && !lhs->isa(VT_INTCONST)) return false; - return lhs < rhs; + if (lhs->isa(VT_PHI) && !rhs->isa(VT_PHI)) return false; + if (!lhs->isa(VT_PHI) && rhs->isa(VT_PHI)) return true; + + return idx[lhs] < idx[rhs]; }); int constValue = 0; int initValue = 0;