2 #include <boost/foreach.hpp>
4 #include <core/assert.hh>
5 #include "simplify-visitor.hh"
6 #include "type-checker-visitor.hh"
10 /// @defgroup Visitors
12 * @class SimplifyVisitor
15 * <b>Algorithm</b><br>
17 * - for every instruction
18 * - split the instruction in 3 address instruction
21 SimplifyVisitor::SimplifyVisitor()
29 SimplifyVisitor::~SimplifyVisitor()
34 SimplifyVisitor::nextId()
37 ss
<< "r" << ++nextId_
;
42 SimplifyVisitor::currentId() const
50 SimplifyVisitor::visit(Block
& block
)
52 std::vector
<Node
*> backup
= simplifications_
;
53 simplifications_
.clear();
55 BOOST_FOREACH (Node
* node
, (*block
.statements
))
61 *block
.statements
= simplifications_
;
62 simplifications_
= backup
;
65 #define SIMPLIFY_BINARY_EXP(Type) \
69 * - Create a new id. \
70 * - Create a new assign exp to id. \
71 * - Create a IdExp and tell replace the parent's child with it. \
74 SimplifyVisitor::visit(Type & node) \
77 node.left->accept(*this); \
78 node.left = replacement_; \
80 node.right->accept(*this); \
81 node.right = replacement_; \
83 std::string name = nextId(); \
85 TmpResultExp * tmpRes = new TmpResultExp(); \
86 tmpRes->name = name; \
87 tmpRes->type = node.type; \
88 assert(tmpRes->type); \
89 replacement_ = tmpRes; \
91 AssignExp * assign = new AssignExp(); \
92 assign->dest = new Symbol(); \
93 assign->dest->name = name; \
94 assign->dest->type = node.type; \
95 assign->value = &node; \
96 assign->type = node.type; \
97 simplifications_.push_back(assign); \
100 SIMPLIFY_BINARY_EXP(EqExp
)
101 SIMPLIFY_BINARY_EXP(NeqExp
)
102 SIMPLIFY_BINARY_EXP(LtExp
)
103 SIMPLIFY_BINARY_EXP(LtEqExp
)
104 SIMPLIFY_BINARY_EXP(GtExp
)
105 SIMPLIFY_BINARY_EXP(GtEqExp
)
107 SIMPLIFY_BINARY_EXP(AddExp
)
108 SIMPLIFY_BINARY_EXP(SubExp
)
109 SIMPLIFY_BINARY_EXP(MulExp
)
110 SIMPLIFY_BINARY_EXP(DivExp
)
111 SIMPLIFY_BINARY_EXP(ModExp
)
113 SIMPLIFY_BINARY_EXP(AndExp
)
114 SIMPLIFY_BINARY_EXP(OrExp
)
115 SIMPLIFY_BINARY_EXP(XorExp
)
117 SIMPLIFY_BINARY_EXP(AndAndExp
)
118 SIMPLIFY_BINARY_EXP(OrOrExp
)
120 SIMPLIFY_BINARY_EXP(ShlExp
)
121 SIMPLIFY_BINARY_EXP(AShrExp
)
122 SIMPLIFY_BINARY_EXP(LShrExp
)
125 SimplifyVisitor::visit(AssignExp
& node
)
128 node
.value
->accept(*this);
129 node
.value
= replacement_
;
131 StoreVar
* sv
= new StoreVar();
132 sv
->name
= node
.dest
->name
;
133 sv
->value
= replacement_
;
134 simplifications_
.push_back(sv
);
140 SimplifyVisitor::visit(NumberExp
& node
)
142 replacement_
= &node
;
146 SimplifyVisitor::visit(IdExp
& node
)
148 LoadVar
* lv
= new LoadVar();
149 lv
->name
= node
.name
;
151 lv
->type
= node
.type
;
152 simplifications_
.push_back(lv
);
154 TmpResultExp
* tre
= new TmpResultExp();
156 tre
->type
= node
.type
;
163 * develop the cast, and simplify it
166 SimplifyVisitor::visit(CastExp
& node
)
168 node
.exp
->accept(*this);
169 node
.exp
= replacement_
;
171 if (!TypeCheckerVisitor::findCast(node
.type
, node
.exp
->type
))
174 AssignExp
* assign
= new AssignExp();
175 assign
->value
= &node
;
176 assign
->dest
= new Symbol();
177 assign
->dest
->name
= nextId();
178 assign
->dest
->type
= node
.type
;
179 assign
->type
= node
.type
;
180 simplifications_
.push_back(assign
);
182 TmpResultExp
* tre
= new TmpResultExp();
183 tre
->name
= assign
->dest
->name
;
184 tre
->type
= node
.type
;
189 SimplifyVisitor::visit(Label
& node
)
191 simplifications_
.push_back(&node
);
195 SimplifyVisitor::visit(Goto
& node
)
197 simplifications_
.push_back(&node
);
201 SimplifyVisitor::visit(If
& node
)
206 node
.cond
->accept(*this);
207 assert(replacement_
);
208 node
.cond
= replacement_
;
210 simplifications_
.push_back(&node
);
212 #define EXPAND_BLOCK(True) \
214 Label * True##Label = new Label; \
215 True##Label->name = std::string(#True "Label_") + nextId(); \
216 simplifications_.push_back(True##Label); \
218 node.if##True->accept(*this); \
219 if (node.if##True->nodeType == Block::nodeTypeId()) { \
220 BOOST_FOREACH(Node * elt, \
221 *reinterpret_cast<Block *>(node.if##True)->statements) \
222 simplifications_.push_back(elt); \
224 node.if##True = True##Label; \
229 node
.endLabel
= new Label
;
230 node
.endLabel
->name
= std::string("EndLabel_") + nextId();
231 Goto
* gotoNode
= new Goto
;
232 gotoNode
->label
= node
.endLabel
->name
;
233 simplifications_
.push_back(gotoNode
);
236 simplifications_
.push_back(node
.endLabel
);