Skip to content

Commit f405561

Browse files
committed
set up info about control-flow parent connections and ensure if conditions are kept on the block [ci skip]
1 parent bcc9f67 commit f405561

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

src/passes/Souperify.cpp

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
411425
struct Trace : public Visitor<Trace> {
412426
Builder& builder;
413427
SetLocal* set;

0 commit comments

Comments
 (0)