@@ -153,6 +153,17 @@ struct Builder : public Visitor<Builder, bool> {
153153 // Connects a specific set to the data in its value.
154154 std::unordered_map<SetLocal*, Node*> setNodeMap;
155155
156+ // Maps a control-flo expression to the DataFlow Block for it. E.g.
157+ // for an if that is the block for the if condition.
158+ std::unordered_map<Expression*, Node*> expressionBlockMap;
159+
160+ // Maps each expression to its control-flow parent (or null if
161+ // there is none). We only map expressions we need to know about,
162+ // which are sets and control-flow constructs.
163+ std::unordered_map<Expression*, Expression*> parentMap;
164+
165+ Expression* parent = nullptr ;
166+
156167 // All the sets, in order of appearance.
157168 std::vector<SetLocal*> sets;
158169
@@ -204,45 +215,46 @@ struct Builder : public Visitor<Builder, bool> {
204215
205216 // Merge local state for multiple control flow paths
206217 // TODO: more than 2
207- void merge (const LocalState& aState, const LocalState& bState, Node* condition, LocalState& out) {
218+ void merge (const LocalState& aState, const LocalState& bState, Node* condition, Expression* expr, LocalState& out) {
208219 assert (out.size () == func->getNumLocals ());
209- // create a block only if necessary
210- Node* block = nullptr ;
220+ auto * block = addNode (Node::makeBlock (2 ));
221+ // FIXME: we need eqz neqz here
222+ block->addValue (addNode (Node::makeCond (block, 0 , condition, Literal (int32_t (1 )))));
223+ block->addValue (addNode (Node::makeCond (block, 1 , condition, Literal (int32_t (0 )))));
224+ expressionBlockMap[expr] = block;
211225 for (Index i = 0 ; i < func->getNumLocals (); i++) {
212226 auto a = aState[i];
213227 auto b = bState[i];
214228 if (a == b) {
215229 out[i] = a;
216230 } else {
217231 // We need to actually merge some stuff.
218- if (!block) {
219- block = addNode (Node::makeBlock (2 ));
220- }
221232 auto * phi = addNode (Node::makePhi (block));
222233 phi->addValue (a);
223234 phi->addValue (b);
224235 out[i] = phi;
225236 }
226237 }
227- if (block) {
228- // We have phis, so it make sense to create the Conds for the branches.
229- // FIXME: we need eqz neqz here
230- block->addValue (addNode (Node::makeCond (block, 0 , condition, Literal (int32_t (1 )))));
231- block->addValue (addNode (Node::makeCond (block, 1 , condition, Literal (int32_t (0 )))));
232- }
233238 }
234239
235240 // Visitors.
236241
237242 bool visitBlock (Block* curr) {
238243 // TODO: handle super-deep nesting
239244 // TODO: handle breaks to here
245+ auto * oldParent = parent;
246+ parentMap[curr] = oldParent;
247+ parent = curr;
240248 for (auto * child : curr->list ) {
241249 visit (child);
242250 }
251+ parent = oldParent;
243252 return true ;
244253 }
245254 bool visitIf (If* curr) {
255+ auto * oldParent = parent;
256+ parentMap[curr] = oldParent;
257+ parent = curr;
246258 // Set up the condition.
247259 // TODO: move this const-or-get logic to a helper, we'll need it elsewhere I am quite sure
248260 Node* condition;
@@ -262,10 +274,11 @@ struct Builder : public Visitor<Builder, bool> {
262274 localState = initialState;
263275 visit (curr->ifFalse );
264276 auto afterIfFalseState = localState; // TODO: optimize
265- merge (afterIfTrueState, afterIfFalseState, condition, localState);
277+ merge (afterIfTrueState, afterIfFalseState, condition, curr, localState);
266278 } else {
267- merge (initialState, afterIfTrueState, condition, localState);
279+ merge (initialState, afterIfTrueState, condition, curr, localState);
268280 }
281+ parent = oldParent;
269282 return true ;
270283 }
271284 bool visitLoop (Loop* curr) { return false ; }
@@ -282,6 +295,7 @@ struct Builder : public Visitor<Builder, bool> {
282295 }
283296 bool visitSetLocal (SetLocal* curr) {
284297 sets.push_back (curr);
298+ parentMap[curr] = parent;
285299 // If we are doing a copy, just do the copy.
286300 if (auto * get = curr->value ->dynCast <GetLocal>()) {
287301 setNodeMap[curr] = localState[curr->index ] = localState[get->index ];
@@ -407,7 +421,7 @@ struct Builder : public Visitor<Builder, bool> {
407421};
408422
409423// Generates a trace: all the information to generate a Souper LHS
410- // for a specific set whose value we want to infer.
424+ // for a specific set_local whose value we want to infer.
411425struct Trace : public Visitor <Trace> {
412426 Builder& builder;
413427 SetLocal* set;
0 commit comments