2 #include <boost/foreach.hpp>
4 #include <core/assert.hh>
5 #include <ast/cast-tables.hh>
6 #include "simplify-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::makeTmpResult(Exp
& node
)
52 if (node
.type
->nodeType
== VoidType::nodeTypeId())
55 simplifications_
.push_back(&node
);
59 AssignExp
* assign
= new AssignExp();
60 assign
->value
= &node
;
61 assign
->dest
= new Symbol();
62 assign
->dest
->name
= nextId();
63 assign
->dest
->type
= node
.type
;
64 assign
->type
= node
.type
;
65 simplifications_
.push_back(assign
);
67 TmpResultExp
* tre
= new TmpResultExp();
68 tre
->name
= assign
->dest
->name
;
69 tre
->type
= node
.type
;
74 SimplifyVisitor::visit(Block
& block
)
76 std::vector
<Node
*> backup
= simplifications_
;
77 simplifications_
.clear();
79 BOOST_FOREACH (Node
* node
, (*block
.statements
))
85 *block
.statements
= simplifications_
;
86 simplifications_
= backup
;
90 SimplifyVisitor::visit(Exp
& /*node*/)
92 assert_msg(false, "unimplemented visit method");
96 SimplifyVisitor::visit(VoidExp
& node
)
101 #define SIMPLIFY_UNARY_EXP(Type) \
104 * - Simplify childs \
105 * - Create a new id. \
106 * - Create a new assign exp to id. \
107 * - Create a IdExp and tell replace the parent's child with it. \
110 SimplifyVisitor::visit(Type & node) \
113 node.exp->accept(*this); \
114 node.exp = replacement_; \
116 makeTmpResult(node); \
119 SIMPLIFY_UNARY_EXP(NotExp
)
120 SIMPLIFY_UNARY_EXP(BangExp
)
121 SIMPLIFY_UNARY_EXP(NegExp
)
123 #define SIMPLIFY_BINARY_EXP(Type) \
126 * - Simplify childs \
127 * - Create a new id. \
128 * - Create a new assign exp to id. \
129 * - Create a IdExp and tell replace the parent's child with it. \
132 SimplifyVisitor::visit(Type & node) \
135 node.left->accept(*this); \
136 node.left = replacement_; \
137 assert(node.right); \
138 node.right->accept(*this); \
139 node.right = replacement_; \
141 makeTmpResult(node); \
144 SIMPLIFY_BINARY_EXP(EqExp
)
145 SIMPLIFY_BINARY_EXP(NeqExp
)
146 SIMPLIFY_BINARY_EXP(LtExp
)
147 SIMPLIFY_BINARY_EXP(LtEqExp
)
148 SIMPLIFY_BINARY_EXP(GtExp
)
149 SIMPLIFY_BINARY_EXP(GtEqExp
)
151 SIMPLIFY_BINARY_EXP(AddExp
)
152 SIMPLIFY_BINARY_EXP(SubExp
)
153 SIMPLIFY_BINARY_EXP(MulExp
)
154 SIMPLIFY_BINARY_EXP(DivExp
)
155 SIMPLIFY_BINARY_EXP(ModExp
)
157 SIMPLIFY_BINARY_EXP(AndExp
)
158 SIMPLIFY_BINARY_EXP(OrExp
)
159 SIMPLIFY_BINARY_EXP(XorExp
)
161 SIMPLIFY_BINARY_EXP(AndAndExp
)
162 SIMPLIFY_BINARY_EXP(OrOrExp
)
164 SIMPLIFY_BINARY_EXP(ShlExp
)
165 SIMPLIFY_BINARY_EXP(AShrExp
)
166 SIMPLIFY_BINARY_EXP(LShrExp
)
169 SimplifyVisitor::visit(AssignExp
& node
)
172 node
.value
->accept(*this);
173 node
.value
= replacement_
;
175 StoreVar
* sv
= new StoreVar();
176 sv
->name
= node
.dest
->name
;
177 sv
->value
= replacement_
;
178 simplifications_
.push_back(sv
);
184 SimplifyVisitor::visit(NumberExp
& node
)
186 replacement_
= &node
;
190 SimplifyVisitor::visit(IdExp
& node
)
192 LoadVar
* lv
= new LoadVar();
193 lv
->name
= node
.name
;
195 lv
->type
= node
.type
;
196 simplifications_
.push_back(lv
);
198 TmpResultExp
* tre
= new TmpResultExp();
200 tre
->type
= node
.type
;
206 SimplifyVisitor::visit(CallExp
& node
)
208 BOOST_FOREACH (Exp
*& exp
, (*node
.args
))
219 * develop the cast, and simplify it
222 SimplifyVisitor::visit(CastExp
& node
)
224 node
.exp
->accept(*this);
225 node
.exp
= replacement_
;
227 if (!castToBestType(node
.type
, node
.exp
->type
))
234 SimplifyVisitor::visit(Label
& node
)
236 simplifications_
.push_back(&node
);
240 SimplifyVisitor::visit(Goto
& node
)
242 simplifications_
.push_back(&node
);
246 SimplifyVisitor::visit(Return
& node
)
248 node
.exp
->accept(*this);
249 node
.exp
= replacement_
;
250 simplifications_
.push_back(&node
);
254 SimplifyVisitor::visit(If
& node
)
256 node
.branch
->cond
->accept(*this);
257 assert(replacement_
);
258 node
.branch
->cond
= replacement_
;
260 simplifications_
.push_back(node
.branch
);
262 node
.branch
->trueLabel
= new Label
;
263 node
.branch
->trueLabel
->name
= std::string("if_true_") + nextId();
264 node
.branch
->falseLabel
= new Label
;
265 node
.branch
->falseLabel
->name
= std::string("if_false_") + nextId();
266 node
.endLabel
= new Label
;
267 node
.endLabel
->name
= std::string("if_end_") + nextId();
269 simplifications_
.push_back(node
.branch
->trueLabel
);
270 node
.trueBlock
->accept(*this);
271 Goto
* gotoNode
= new Goto
;
272 gotoNode
->label
= node
.endLabel
->name
;
274 simplifications_
.push_back(node
.branch
->falseLabel
);
275 node
.falseBlock
->accept(*this);
276 simplifications_
.push_back(node
.endLabel
);
280 SimplifyVisitor::visit(While
& node
)
283 assert(node
.branch
->cond
);
285 node
.beginLabel
= new Label
;
286 node
.beginLabel
->name
= std::string("do_while_1_") + nextId();
287 node
.branch
->trueLabel
= new Label
;
288 node
.branch
->trueLabel
->name
= std::string("do_while_2_") + nextId();
289 node
.branch
->falseLabel
= new Label
;
290 node
.branch
->falseLabel
->name
= std::string("do_while_3_") + nextId();
292 simplifications_
.push_back(node
.beginLabel
);
293 node
.branch
->cond
->accept(*this);
294 node
.branch
->cond
= replacement_
;
295 simplifications_
.push_back(node
.branch
);
296 simplifications_
.push_back(node
.branch
->trueLabel
);
297 node
.block
->accept(*this);
298 node
.block
= replacement_
;
300 Goto
* gt
= new Goto
;
301 gt
->label
= node
.beginLabel
->name
;
302 simplifications_
.push_back(gt
);
303 simplifications_
.push_back(node
.branch
->falseLabel
);
307 SimplifyVisitor::visit(DoWhile
& node
)
310 assert(node
.branch
->cond
);
312 node
.branch
->trueLabel
= new Label
;
313 node
.branch
->trueLabel
->name
= std::string("do_while_1_") + nextId();
314 node
.branch
->falseLabel
= new Label
;
315 node
.branch
->falseLabel
->name
= std::string("do_while_2_") + nextId();
316 simplifications_
.push_back(node
.branch
->trueLabel
);
318 node
.block
->accept(*this);
319 node
.block
= replacement_
;
320 node
.branch
->cond
->accept(*this);
321 node
.branch
->cond
= replacement_
;
324 simplifications_
.push_back(node
.branch
);
325 simplifications_
.push_back(node
.branch
->falseLabel
);