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 IdExp
* id
= new IdExp
;
214 id
->symbol
= new Symbol
;
215 id
->symbol
->name
= node
.symbol
->name
+ "_" + nextId();;
216 id
->symbol
->type
= unreferencedType(node
.type
);
217 id
->type
= id
->symbol
->type
;
220 LoadVar
* lv
= new LoadVar
;
221 lv
->to
= id
->symbol
->name
;
223 simplifications_
.push_back(lv
);
226 replacement_
= &node
;
230 SimplifyVisitor::visit(DereferenceExp
& node
)
232 node
.exp
->accept(*this);
233 node
.exp
= replacement_
;
235 LoadVar
* lv
= new LoadVar
;
238 simplifications_
.push_back(lv
);
240 IdExp
* id
= new IdExp
;
241 id
->symbol
= new Symbol
;
242 id
->symbol
->name
= lv
->to
;
243 id
->symbol
->type
= node
.type
;
244 id
->symbol
->address
= new RegisterAddress
;
245 id
->type
= node
.type
;
250 SimplifyVisitor::visit(CallExp
& node
)
252 BOOST_FOREACH (Exp
*& exp
, (*node
.args
))
263 * develop the cast, and simplify it
266 SimplifyVisitor::visit(CastExp
& node
)
268 node
.exp
->accept(*this);
269 node
.exp
= replacement_
;
271 if (!castToBestType(node
.type
, node
.exp
->type
))
278 SimplifyVisitor::visit(Label
& node
)
280 simplifications_
.push_back(&node
);
284 SimplifyVisitor::visit(Goto
& node
)
286 simplifications_
.push_back(&node
);
290 SimplifyVisitor::visit(Return
& node
)
292 node
.exp
->accept(*this);
293 node
.exp
= replacement_
;
294 simplifications_
.push_back(&node
);
298 SimplifyVisitor::visit(If
& node
)
300 node
.branch
->cond
->accept(*this);
301 assert(replacement_
);
302 node
.branch
->cond
= replacement_
;
304 simplifications_
.push_back(node
.branch
);
306 node
.branch
->trueLabel
= new Label
;
307 node
.branch
->trueLabel
->name
= std::string("if_true_") + nextId();
308 node
.branch
->falseLabel
= new Label
;
309 node
.branch
->falseLabel
->name
= std::string("if_false_") + nextId();
310 node
.endLabel
= new Label
;
311 node
.endLabel
->name
= std::string("if_end_") + nextId();
313 simplifications_
.push_back(node
.branch
->trueLabel
);
314 node
.trueBlock
->accept(*this);
315 Goto
* gotoNode
= new Goto
;
316 gotoNode
->label
= node
.endLabel
->name
;
318 simplifications_
.push_back(node
.branch
->falseLabel
);
319 node
.falseBlock
->accept(*this);
320 simplifications_
.push_back(node
.endLabel
);
324 SimplifyVisitor::visit(While
& node
)
327 assert(node
.branch
->cond
);
329 node
.beginLabel
= new Label
;
330 node
.beginLabel
->name
= std::string("do_while_1_") + nextId();
331 node
.branch
->trueLabel
= new Label
;
332 node
.branch
->trueLabel
->name
= std::string("do_while_2_") + nextId();
333 node
.branch
->falseLabel
= new Label
;
334 node
.branch
->falseLabel
->name
= std::string("do_while_3_") + nextId();
336 simplifications_
.push_back(node
.beginLabel
);
337 node
.branch
->cond
->accept(*this);
338 node
.branch
->cond
= replacement_
;
339 simplifications_
.push_back(node
.branch
);
340 simplifications_
.push_back(node
.branch
->trueLabel
);
341 node
.block
->accept(*this);
342 node
.block
= replacement_
;
344 Goto
* gt
= new Goto
;
345 gt
->label
= node
.beginLabel
->name
;
346 simplifications_
.push_back(gt
);
347 simplifications_
.push_back(node
.branch
->falseLabel
);
351 SimplifyVisitor::visit(DoWhile
& node
)
354 assert(node
.branch
->cond
);
356 node
.branch
->trueLabel
= new Label
;
357 node
.branch
->trueLabel
->name
= std::string("do_while_1_") + nextId();
358 node
.branch
->falseLabel
= new Label
;
359 node
.branch
->falseLabel
->name
= std::string("do_while_2_") + nextId();
360 simplifications_
.push_back(node
.branch
->trueLabel
);
362 node
.block
->accept(*this);
363 node
.block
= replacement_
;
364 node
.branch
->cond
->accept(*this);
365 node
.branch
->cond
= replacement_
;
368 simplifications_
.push_back(node
.branch
);
369 simplifications_
.push_back(node
.branch
->falseLabel
);