Skip to content

Commit 88dfe9e

Browse files
增加窥孔优化:取余数优化
1 parent ca297cc commit 88dfe9e

19 files changed

+275
-173
lines changed

Block.cpp

+13-7
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void Block::useDefScan() {
2626
if (i.op == MIDADD || i.op == MIDSUB || i.op == MIDMULT
2727
|| i.op == MIDDIV || i.op == MIDLSS || i.op == MIDLEQ
2828
|| i.op == MIDGRE || i.op == MIDGEQ || i.op == MIDEQL
29-
|| i.op == MIDNEQ||i.op==MIDARRAYGET) {
29+
|| i.op == MIDNEQ||i.op==MIDARRAYGET||i.op==MIDREM) {
3030
use.erase(i.target);
3131
def.insert(i.target);
3232
if (!i.isImmediate1) {
@@ -97,7 +97,7 @@ vector<vector<int>>Block::conflictEdgeAnalyze(){
9797
if (i.op == MIDADD || i.op == MIDSUB || i.op == MIDMULT
9898
|| i.op == MIDDIV || i.op == MIDLSS || i.op == MIDLEQ
9999
|| i.op == MIDGRE || i.op == MIDGEQ || i.op == MIDEQL
100-
|| i.op == MIDNEQ || i.op == MIDARRAYGET) {
100+
|| i.op == MIDNEQ || i.op == MIDARRAYGET||i.op==MIDREM) {
101101
localActive.erase(i.target);
102102
if (!i.isImmediate1) {
103103
localActive.insert(i.operand1);
@@ -190,6 +190,16 @@ void Block::eliminateDeadCode() {
190190
v=eliminator.eliminateDeadCode(v);
191191
}
192192

193+
void Block::blockOptimize() {
194+
BlockOptimization bop(activeOut);
195+
v = bop.propagationInBlock(v);
196+
}
197+
198+
void Block::peepholeOptimize() {
199+
PeepHoleOptimization opt;
200+
v = opt.peepHoleOptimization(v);
201+
}
202+
193203
set<int>Block::setUnion(set<int> a, set<int> b) {
194204
set<int>res;
195205
for (int i : a) {
@@ -258,10 +268,6 @@ ostream& operator<<(ostream& out, Block b) {
258268
return out;
259269
}
260270

261-
void Block::blockOptimize() {
262-
BlockOptimization bop(activeOut);
263-
v = bop.propagationInBlock(v);
264-
}
265271

266272
void Block::activeVariableAnalyzePerLine() {
267273
set<int>localActive = activeOut;
@@ -272,7 +278,7 @@ void Block::activeVariableAnalyzePerLine() {
272278
if (i.op == MIDADD || i.op == MIDSUB || i.op == MIDMULT
273279
|| i.op == MIDDIV || i.op == MIDLSS || i.op == MIDLEQ
274280
|| i.op == MIDGRE || i.op == MIDGEQ || i.op == MIDEQL
275-
|| i.op == MIDNEQ || i.op == MIDARRAYGET) {
281+
|| i.op == MIDNEQ || i.op == MIDARRAYGET||i.op==MIDREM) {
276282
localActive.erase(i.target);
277283
if (!i.isImmediate1) {
278284
localActive.insert(i.operand1);

Block.h

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include"DagMap.h"
66
#include"DeadCodeEliminator.h"
77
#include"BlockOptimization.h"
8+
#include"PeepHoleOptimization.h"
89
using namespace std;
910

1011
class Block {
@@ -34,4 +35,5 @@ class Block {
3435
void eliminateDeadCode();
3536
void blockOptimize();
3637
void activeVariableAnalyzePerLine();
38+
void peepholeOptimize();
3739
};

BlockOptimization.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ vector<MidCode>BlockOptimization::propagationInBlock(vector<MidCode>& v) {
5656
case MIDGEQ:
5757
case MIDEQL:
5858
case MIDNEQ:
59+
case MIDREM:
5960
{
6061
MidCode tmp = c;
6162
//如果两个立即数都是常量的话

C0Compiler.rar

285 KB
Binary file not shown.

C0Compiler.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
<ClCompile Include="MidCode.cpp" />
148148
<ClCompile Include="MidCodeFrameWork.cpp" />
149149
<ClCompile Include="MipsTranslator.cpp" />
150+
<ClCompile Include="PeepHoleOptimization.cpp" />
150151
<ClCompile Include="SubSymbolTable.cpp" />
151152
<ClCompile Include="SymbolTable.cpp" />
152153
</ItemGroup>
@@ -164,6 +165,7 @@
164165
<ClInclude Include="MidCodeContainer.h" />
165166
<ClInclude Include="MidCodeFramework.h" />
166167
<ClInclude Include="MipsTranslator.h" />
168+
<ClInclude Include="PeepHoleOptimization.h" />
167169
<ClInclude Include="SubSymbolTable.h" />
168170
<ClInclude Include="SymbolTable.h" />
169171
</ItemGroup>

C0Compiler.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@
104104
<ClCompile Include="BlockOptimization.cpp">
105105
<Filter>源文件\BackEnd</Filter>
106106
</ClCompile>
107+
<ClCompile Include="PeepHoleOptimization.cpp">
108+
<Filter>源文件\BackEnd</Filter>
109+
</ClCompile>
107110
</ItemGroup>
108111
<ItemGroup>
109112
<ClInclude Include="LexicalAnalyzer.h">
@@ -151,6 +154,9 @@
151154
<ClInclude Include="BlockOptimization.h">
152155
<Filter>头文件\BackEnd</Filter>
153156
</ClInclude>
157+
<ClInclude Include="PeepHoleOptimization.h">
158+
<Filter>头文件\BackEnd</Filter>
159+
</ClInclude>
154160
</ItemGroup>
155161
<ItemGroup>
156162
<Image Include="Annotation 2019-09-26 123820.jpg">

DagMap.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ void DagMap::handleMidCode(MidCode c){
114114
case MIDGEQ:
115115
case MIDEQL:
116116
case MIDNEQ:
117+
case MIDREM:
117118
case MIDARRAYGET:
118119
{
119120
DagNode* node1 = getNodeByVar(c.operand1, c.isImmediate1);
@@ -372,6 +373,7 @@ MidCode DagMap::nodeToMidCode(DagNode* node) {
372373
case MIDNEQ:
373374
case MIDARRAYGET:
374375
case MIDARRAYWRITE:
376+
case MIDREM:
375377
{
376378
MidCode res;
377379
res.op = node->op;

DeadCodeEliminator.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ vector<MidCode> DeadCodeEliminator::eliminateDeadCode(vector<MidCode>& v) {
1616
if (i.op == MIDADD || i.op == MIDSUB || i.op == MIDMULT
1717
|| i.op == MIDDIV || i.op == MIDLSS || i.op == MIDLEQ
1818
|| i.op == MIDGRE || i.op == MIDGEQ || i.op == MIDEQL
19-
|| i.op == MIDNEQ || i.op == MIDARRAYGET) {
19+
|| i.op == MIDNEQ || i.op == MIDARRAYGET||i.op==MIDREM) {
2020
SymbolEntry* entry = MidCode::table->getSymbolById(i.target);
2121
if (localActive.find(i.target) == localActive.end()
2222
&& (i.target < 0 || entry->scope != "")) {

FlowGraph.cpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ FlowGraph::FlowGraph(MidCodeContainer& c) {
1414
Block* oldBlock = block;
1515
block = new Block(functionId);
1616
graph.push_back(oldBlock);
17-
addLink(oldBlock, block);
17+
if (!(i != 0 && (c.v[i - 1].op == MIDGOTO || c.v[i - 1].op == MIDRET))) {
18+
addLink(oldBlock, block);
19+
}
1820
}
1921
else if (i != 0 &&( c.v[i - 1].op == MIDGOTO||c.v[i-1].op==MIDRET)) {
2022
Block* oldBlock = block;
@@ -52,12 +54,20 @@ void FlowGraph::addLink(Block* from, Block* to) {
5254
}
5355

5456
void FlowGraph::optimize() {
57+
5558
activeVariableAnalyze();
5659
DAGoptimize();
60+
5761
activeVariableAnalyze();
5862
blockOptimize();
63+
5964
activeVariableAnalyze();
6065
eliminateDeadCode();
66+
67+
activeVariableAnalyze();
68+
activeVariablePerLine();
69+
peepholeOptimize();
70+
6171
activeVariableAnalyze();
6272
variableSummary();
6373
activeVariablePerLine();
@@ -124,6 +134,7 @@ void FlowGraph::variableSummary() {
124134
case MIDGEQ:
125135
case MIDEQL:
126136
case MIDNEQ:
137+
case MIDREM:
127138
if (!j.isImmediate1 && j.operand1 < -1) {
128139
tmpVariable.insert(j.operand1);
129140
}
@@ -271,4 +282,10 @@ ostream& operator<<(ostream& out, FlowGraph& f) {
271282
out << (*i);
272283
}
273284
return out;
274-
}
285+
}
286+
287+
void FlowGraph::peepholeOptimize() {
288+
for (Block* i : graph) {
289+
i->peepholeOptimize();
290+
}
291+
}

FlowGraph.h

+1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ class FlowGraph {
2525
void eliminateDeadCode();
2626
void blockOptimize();
2727
void activeVariablePerLine();
28+
void peepholeOptimize();
2829
};

GrammarAnalyzer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ void GrammarAnalyzer::parameterList(SymbolEntry* entry) {
749749

750750
/*<复合语句>*/
751751
void GrammarAnalyzer::compoundSentence(){
752-
inlineable = true;
752+
inlineable = true;
753753
if (currentScope == "main") {
754754
inlineable = false;
755755
}

MidCode.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ ostream& operator<<(ostream& out, MidCode c) {
5050
ops[MIDGEQ] = ">=";
5151
ops[MIDEQL] = "==";
5252
ops[MIDNEQ] = "!=";
53+
ops[MIDREM] = "mod";
5354
if (c.labelNo < -1) {
5455
out << "_label" << -(c.labelNo) << ": ";
5556
}
@@ -92,6 +93,7 @@ ostream& operator<<(ostream& out, MidCode c) {
9293
case MIDGEQ:
9394
case MIDEQL:
9495
case MIDNEQ:
96+
case MIDREM:
9597
out << MidCode::getOperandName(c.target,false);
9698
out << " " << "=" << " ";
9799
out << MidCode::getOperandName(c.operand1, c.isImmediate1);

MidCode.h

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum MidCodeOp {
4141
MIDREADINTEGER,//SYSCALL5 target-读入整数的id
4242
MIDREADCHAR,//SYSCALL12 target-读入字符的id
4343
MIDNOP,//对付跳转使用的,优化时候就都干掉了,什么都不要什么都不做
44+
MIDREM,//取余数 xinzeng
4445
};
4546
/*再这里记录一下*/
4647
class MidCode {

MipsTranslator.cpp

+40
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,46 @@ void MipsTranslator::translate(MidCode c) {
906906
specialVarwriteback(c.target, false);
907907
break;
908908
}
909+
case MIDREM:
910+
{
911+
if (c.isImmediate2) {
912+
vector<int>conflictVar;
913+
if (!c.isImmediate1) { conflictVar.push_back(c.operand1); }
914+
int target = loadOperand(c.target, false, conflictVar, {}, &(c.activeVariable));
915+
916+
conflictVar.clear();
917+
conflictVar.push_back(c.target);
918+
int operand1 = loadOperand(c.operand1, c.isImmediate1, conflictVar,
919+
{ target }, &(c.activeVariable));
920+
921+
out << "rem " << name[target] << "," << name[operand1] << "," << c.operand2;
922+
out << "#" << c << endl;
923+
specialVarwriteback(c.target, false);
924+
break;
925+
}
926+
vector<int>conflictVar;
927+
if (!c.isImmediate1) { conflictVar.push_back(c.operand1); }
928+
if (!c.isImmediate2) { conflictVar.push_back(c.operand2); }
929+
int target = loadOperand(c.target, false, conflictVar, {}, &(c.activeVariable));
930+
931+
conflictVar.clear();
932+
conflictVar.push_back(c.target);
933+
if (!c.isImmediate2) { conflictVar.push_back(c.operand2); }
934+
int operand1 = loadOperand(c.operand1, c.isImmediate1, conflictVar,
935+
{ target }, &(c.activeVariable));
936+
937+
conflictVar.clear();
938+
conflictVar.push_back(c.target);
939+
if (!c.isImmediate1) { conflictVar.push_back(c.operand1); }
940+
int operand2 = loadOperand(c.operand2, c.isImmediate2, conflictVar,
941+
{ target,operand1 }, &(c.activeVariable));
942+
943+
out << "div " << name[operand1] << "," << name[operand2]<<endl;
944+
out << "mfhi " << name[target]<<endl;
945+
out << "#" << c << endl;
946+
specialVarwriteback(c.target, false);
947+
break;
948+
}
909949
case MIDNEGATE:
910950
{
911951
vector<int>conflictVar;

PeepHoleOptimization.cpp

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include"PeepHoleOptimization.h"
2+
vector<MidCode> PeepHoleOptimization::peepHoleOptimization(vector<MidCode>& v) {
3+
vector<MidCode>res;
4+
/*针对取余操作的优化*/
5+
for (int i = 0; i < v.size(); i++) {
6+
if (i > (int)(v.size()) - 3) {
7+
res.push_back(v[i]);
8+
continue;
9+
}
10+
if (v[i].op == MIDDIV && v[i + 1].op == MIDMULT && v[i+2].op == MIDSUB) {
11+
int a0 = v[i].operand1;
12+
bool a1 = v[i].isImmediate1;
13+
int b0 = v[i].operand2;
14+
bool b1 = v[i].isImmediate2;
15+
int c0 = v[i].target;
16+
bool c1 = false;
17+
if (!(v[i + 1].operand1 == c0 && v[i + 1].isImmediate1 == c1)) {
18+
res.push_back(v[i]);
19+
continue;
20+
}
21+
if (!(v[i + 1].operand2 == b0 && v[i + 1].isImmediate2 == b1)) {
22+
res.push_back(v[i]);
23+
continue;
24+
}
25+
int d0 = v[i+1].target;
26+
bool d1 = false;
27+
if (!(v[i + 2].operand1 == a0 && v[i + 2].isImmediate1 == a1)) {
28+
res.push_back(v[i]);
29+
continue;
30+
}
31+
if (!(v[i + 2].operand2 == d0 && v[i + 2].isImmediate2 == d1)) {
32+
res.push_back(v[i]);
33+
continue;
34+
}
35+
/*因为这里会取消对c d的赋值,所以必须保证以后cd不再有人使用*/
36+
if (!c1 && v[i + 2].activeVariable.find(c0) != v[i + 2].activeVariable.end()) {
37+
res.push_back(v[i]);
38+
continue;
39+
}
40+
if (!d1 && v[i + 2].activeVariable.find(d0) != v[i + 2].activeVariable.end()) {
41+
res.push_back(v[i]);
42+
continue;
43+
}
44+
MidCode tmp = MidCode::generateMidCode(MIDREM, v[i + 2].target,
45+
a0, a1, b0, b1, v[i].labelNo);
46+
i += 2;
47+
res.push_back(tmp);
48+
}
49+
else {
50+
res.push_back(v[i]);
51+
continue;
52+
}
53+
}
54+
return res;
55+
}

PeepHoleOptimization.h

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#pragma once
2+
#include"MidCode.h"
3+
class PeepHoleOptimization {
4+
public:
5+
vector<MidCode>peepHoleOptimization(vector<MidCode>& v);
6+
};

0 commit comments

Comments
 (0)