2 #include <boost/foreach.hpp>
4 #include <core/assert.hh>
5 #include <ast/cast-tables.hh>
6 #include <ast/clone.hh>
7 #include "simplify-visitor.hh"
11 /// @defgroup Visitors
13 * @class SimplifyVisitor
16 * <b>Algorithm</b><br>
18 * - for every instruction
19 * - split the instruction in 3 address instruction
22 SimplifyVisitor::SimplifyVisitor()
30 SimplifyVisitor::~SimplifyVisitor()
35 SimplifyVisitor::nextId()
38 ss
<< "$" << ++nextId_
;
43 SimplifyVisitor::currentId() const
51 SimplifyVisitor::makeTmpResult(Exp
& node
)
53 if (node
.type
->nodeType
== VoidType::nodeTypeId())
56 simplifications_
.push_back(&node
);
60 AssignExp
* assign
= new AssignExp();
61 assign
->value
= &node
;
62 assign
->dest
= new Symbol();
63 assign
->dest
->name
= nextId();
64 assign
->dest
->type
= node
.type
;
65 assign
->type
= node
.type
;
66 simplifications_
.push_back(assign
);
68 IdExp
* id
= new IdExp();
69 id
->symbol
= new Symbol
;
70 id
->symbol
->name
= assign
->dest
->name
;
71 id
->symbol
->type
= node
.type
;
77 SimplifyVisitor::visit(Block
& block
)
79 std::vector
<Node
*> backup
= simplifications_
;
80 simplifications_
.clear();
82 BOOST_FOREACH (Node
* node
, (*block
.statements
))
88 *block
.statements
= simplifications_
;
89 simplifications_
= backup
;
93 SimplifyVisitor::visit(Exp
& /*node*/)
95 assert_msg(false, "unimplemented visit method");
99 SimplifyVisitor::visit(VoidExp
& node
)
101 replacement_
= &node
;
104 #define SIMPLIFY_UNARY_EXP(Type) \
107 * - Simplify childs \
108 * - Create a new id. \
109 * - Create a new assign exp to id. \
110 * - Create a IdExp and tell replace the parent's child with it. \
113 SimplifyVisitor::visit(Type & node) \
116 node.exp->accept(*this); \
117 node.exp = replacement_; \
119 makeTmpResult(node); \
122 SIMPLIFY_UNARY_EXP(NotExp
)
123 SIMPLIFY_UNARY_EXP(BangExp
)
124 SIMPLIFY_UNARY_EXP(NegExp
)
126 #define SIMPLIFY_BINARY_EXP(Type) \
129 * - Simplify childs \
130 * - Create a new id. \
131 * - Create a new assign exp to id. \
132 * - Create a IdExp and tell replace the parent's child with it. \
135 SimplifyVisitor::visit(Type & node) \
138 node.left->accept(*this); \
139 node.left = replacement_; \
140 assert(node.right); \
141 node.right->accept(*this); \
142 node.right = replacement_; \
144 makeTmpResult(node); \
147 SIMPLIFY_BINARY_EXP(EqExp
)
148 SIMPLIFY_BINARY_EXP(NeqExp
)
149 SIMPLIFY_BINARY_EXP(LtExp
)
150 SIMPLIFY_BINARY_EXP(LtEqExp
)
151 SIMPLIFY_BINARY_EXP(GtExp
)
152 SIMPLIFY_BINARY_EXP(GtEqExp
)
154 SIMPLIFY_BINARY_EXP(AddExp
)
155 SIMPLIFY_BINARY_EXP(SubExp
)
156 SIMPLIFY_BINARY_EXP(MulExp
)
157 SIMPLIFY_BINARY_EXP(DivExp
)
158 SIMPLIFY_BINARY_EXP(ModExp
)
160 SIMPLIFY_BINARY_EXP(AndExp
)
161 SIMPLIFY_BINARY_EXP(OrExp
)
162 SIMPLIFY_BINARY_EXP(XorExp
)
164 SIMPLIFY_BINARY_EXP(AndAndExp
)
165 SIMPLIFY_BINARY_EXP(OrOrExp
)
167 SIMPLIFY_BINARY_EXP(ShlExp
)
168 SIMPLIFY_BINARY_EXP(AShrExp
)
169 SIMPLIFY_BINARY_EXP(LShrExp
)
172 SimplifyVisitor::visit(AssignExp
& node
)
176 assert(node
.dest
->address
);
178 node
.value
->accept(*this);
179 node
.value
= replacement_
;
181 if (node
.dest
->address
->nodeType
== MemoryAddress::nodeTypeId())
183 StoreVar
* sv
= new StoreVar();
184 sv
->name
= node
.dest
->name
;
185 sv
->value
= replacement_
;
186 simplifications_
.push_back(sv
);
190 /* update the address of the variable in the symbol table */
191 MemoryAddress
* addr
= reinterpret_cast<MemoryAddress
*> (node
.dest
->address
);
192 addr
->name
= node
.dest
->name
+ "_" + nextId();
194 node
.dest
= clone(node
.dest
);
195 IdExp
* id
= new IdExp
;
196 id
->symbol
= node
.dest
;
199 simplifications_
.push_back(&node
);
203 SimplifyVisitor::visit(NumberExp
& node
)
205 replacement_
= &node
;
209 SimplifyVisitor::visit(IdExp
& node
)
211 if (node
.symbol
->address
->nodeType
== MemoryAddress::nodeTypeId())
213 LoadVar
* lv
= new LoadVar
;
214 lv
->name
= node
.symbol
->name
;
215 lv
->to
= node
.symbol
->name
+ "_" + nextId();
216 lv
->type
= node
.symbol
->type
;
217 simplifications_
.push_back(lv
);
219 IdExp
* id
= new IdExp
;
220 id
->symbol
= new Symbol
;
221 id
->symbol
->name
= lv
->to
;
222 id
->symbol
->type
= node
.type
;
223 id
->type
= node
.type
;
227 replacement_
= &node
;
231 SimplifyVisitor::visit(CallExp
& node
)
233 BOOST_FOREACH (Exp
*& exp
, (*node
.args
))
244 * develop the cast, and simplify it
247 SimplifyVisitor::visit(CastExp
& node
)
249 node
.exp
->accept(*this);
250 node
.exp
= replacement_
;
252 if (!castToBestType(node
.type
, node
.exp
->type
))
259 SimplifyVisitor::visit(Label
& node
)
261 simplifications_
.push_back(&node
);
265 SimplifyVisitor::visit(Goto
& node
)
267 simplifications_
.push_back(&node
);
271 SimplifyVisitor::visit(Return
& node
)
273 node
.exp
->accept(*this);
274 node
.exp
= replacement_
;
275 simplifications_
.push_back(&node
);
279 SimplifyVisitor::visit(If
& node
)
281 node
.branch
->cond
->accept(*this);
282 assert(replacement_
);
283 node
.branch
->cond
= replacement_
;
285 simplifications_
.push_back(node
.branch
);
287 node
.branch
->trueLabel
= new Label
;
288 node
.branch
->trueLabel
->name
= std::string("if_true_") + nextId();
289 node
.branch
->falseLabel
= new Label
;
290 node
.branch
->falseLabel
->name
= std::string("if_false_") + nextId();
291 node
.endLabel
= new Label
;
292 node
.endLabel
->name
= std::string("if_end_") + nextId();
294 simplifications_
.push_back(node
.branch
->trueLabel
);
295 node
.trueBlock
->accept(*this);
296 Goto
* gotoNode
= new Goto
;
297 gotoNode
->label
= node
.endLabel
->name
;
299 simplifications_
.push_back(node
.branch
->falseLabel
);
300 node
.falseBlock
->accept(*this);
301 simplifications_
.push_back(node
.endLabel
);
305 SimplifyVisitor::visit(While
& node
)
308 assert(node
.branch
->cond
);
310 node
.beginLabel
= new Label
;
311 node
.beginLabel
->name
= std::string("do_while_1_") + nextId();
312 node
.branch
->trueLabel
= new Label
;
313 node
.branch
->trueLabel
->name
= std::string("do_while_2_") + nextId();
314 node
.branch
->falseLabel
= new Label
;
315 node
.branch
->falseLabel
->name
= std::string("do_while_3_") + nextId();
317 simplifications_
.push_back(node
.beginLabel
);
318 node
.branch
->cond
->accept(*this);
319 node
.branch
->cond
= replacement_
;
320 simplifications_
.push_back(node
.branch
);
321 simplifications_
.push_back(node
.branch
->trueLabel
);
322 node
.block
->accept(*this);
323 node
.block
= replacement_
;
325 Goto
* gt
= new Goto
;
326 gt
->label
= node
.beginLabel
->name
;
327 simplifications_
.push_back(gt
);
328 simplifications_
.push_back(node
.branch
->falseLabel
);
332 SimplifyVisitor::visit(DoWhile
& node
)
335 assert(node
.branch
->cond
);
337 node
.branch
->trueLabel
= new Label
;
338 node
.branch
->trueLabel
->name
= std::string("do_while_1_") + nextId();
339 node
.branch
->falseLabel
= new Label
;
340 node
.branch
->falseLabel
->name
= std::string("do_while_2_") + nextId();
341 simplifications_
.push_back(node
.branch
->trueLabel
);
343 node
.block
->accept(*this);
344 node
.block
= replacement_
;
345 node
.branch
->cond
->accept(*this);
346 node
.branch
->cond
= replacement_
;
349 simplifications_
.push_back(node
.branch
);
350 simplifications_
.push_back(node
.branch
->falseLabel
);