1414#include " mlir/Pass/Pass.h"
1515#include " mlir/Support/LLVM.h"
1616#include " llvm/ADT/STLExtras.h"
17+ #include " llvm/ADT/MapVector.h"
1718#include " llvm/Support/Casting.h"
1819#include " llvm/Support/Error.h"
1920#include " llvm/Support/raw_ostream.h"
@@ -25,9 +26,6 @@ using namespace mlir;
2526#define GEN_PASS_DEF_TransformCtrlToDataFlow
2627#include " NeuraDialect/NeuraPasses.h.inc"
2728
28- // TODO: Needs to enbale a deterministic ctrol to data flow transformation
29- // https://github.com/coredac/dataflow/issues/64
30-
3129// Inserts `grant_once` for every predicated value defined in the entry block
3230// that is used outside of the block (i.e., a live-out).
3331void GrantPredicateInEntryBlock (Block *entry_block, OpBuilder &builder) {
@@ -115,15 +113,16 @@ struct ControlFlowInfo {
115113 SmallVector<Value> passed_values; // Values passed to the target block.
116114 bool is_back_edge;
117115 };
118- std::vector <std::unique_ptr<Edge>> all_edges; // All edges in the function.
119- DenseMap <Block *, SmallVector<Edge *>>
116+ SmallVector <std::unique_ptr<Edge>> all_edges; // All edges in the function.
117+ llvm::MapVector <Block *, SmallVector<Edge *>>
120118 incoming_edges; // Incoming edges for each block.
121- DenseMap <Block *, SmallVector<Edge *>>
119+ llvm::MapVector <Block *, SmallVector<Edge *>>
122120 outgoing_edges; // Outgoing edges for each block.
123121
124- DenseMap<Block *, SmallVector<Edge *>> back_edges;
125- DenseMap<Block *, SmallVector<Edge *>> forward_edges;
126- DenseSet<Block *> blocks_with_back_edges; // Blocks with backward edges.
122+ llvm::MapVector<Block *, SmallVector<Edge *>> back_edges;
123+ llvm::MapVector<Block *, SmallVector<Edge *>> forward_edges;
124+ llvm::SmallVector<Block *>
125+ blocks_with_back_edges; // Blocks with backward edges.
127126
128127 Edge *createEdge () {
129128 all_edges.push_back (std::make_unique<Edge>());
@@ -235,13 +234,13 @@ void buildControlFlowInfo(func::FuncOp &func, ControlFlowInfo &ctrl_info,
235234 // Handles back edges.
236235 if (true_edge->is_back_edge ) {
237236 ctrl_info.back_edges [&block].push_back (true_edge);
238- ctrl_info.blocks_with_back_edges .insert (&block);
237+ ctrl_info.blocks_with_back_edges .push_back (&block);
239238 } else {
240239 ctrl_info.forward_edges [&block].push_back (true_edge);
241240 }
242241 if (false_edge->is_back_edge ) {
243242 ctrl_info.back_edges [&block].push_back (false_edge);
244- ctrl_info.blocks_with_back_edges .insert (&block);
243+ ctrl_info.blocks_with_back_edges .push_back (&block);
245244 } else {
246245 ctrl_info.forward_edges [&block].push_back (false_edge);
247246 }
@@ -267,7 +266,7 @@ void buildControlFlowInfo(func::FuncOp &func, ControlFlowInfo &ctrl_info,
267266 // Handles back edges.
268267 if (edge->is_back_edge ) {
269268 ctrl_info.back_edges [&block].push_back (edge);
270- ctrl_info.blocks_with_back_edges .insert (&block);
269+ ctrl_info.blocks_with_back_edges .push_back (&block);
271270 } else {
272271 ctrl_info.forward_edges [&block].push_back (edge);
273272 }
@@ -282,7 +281,7 @@ void buildControlFlowInfo(func::FuncOp &func, ControlFlowInfo &ctrl_info,
282281}
283282
284283Value getPrecessedCondition (Value condition, bool is_not_condition,
285- DenseMap <Value, Value> &condition_cache,
284+ llvm::MapVector <Value, Value> &condition_cache,
286285 OpBuilder &builder) {
287286 if (!is_not_condition) {
288287 return condition;
@@ -302,8 +301,8 @@ Value getPrecessedCondition(Value condition, bool is_not_condition,
302301}
303302
304303void createReserveAndPhiOps (func::FuncOp &func, ControlFlowInfo &ctrl_info,
305- DenseMap <BlockArgument, Value> &arg_to_reserve,
306- DenseMap <BlockArgument, Value> &arg_to_phi_result,
304+ llvm::MapVector <BlockArgument, Value> &arg_to_reserve,
305+ llvm::MapVector <BlockArgument, Value> &arg_to_phi_result,
307306 OpBuilder &builder) {
308307 DominanceInfo dom_info (func);
309308
@@ -318,16 +317,17 @@ void createReserveAndPhiOps(func::FuncOp &func, ControlFlowInfo &ctrl_info,
318317 // Type 6: Forward br edges without values.
319318 // For Backward edges without values, they can be transformed into type 1 or 2
320319
321- DenseMap<BlockArgument, SmallVector<ControlFlowInfo::Edge *>>
320+ // Uses llvm::MapVector instead of DenseMap to maintain insertion order.
321+ llvm::MapVector<BlockArgument, SmallVector<ControlFlowInfo::Edge *>>
322322 backward_value_edges;
323- DenseMap <BlockArgument, SmallVector<ControlFlowInfo::Edge *>>
323+ llvm::MapVector <BlockArgument, SmallVector<ControlFlowInfo::Edge *>>
324324 forward_value_edges;
325- DenseMap <Block *, SmallVector<ControlFlowInfo::Edge *>>
325+ llvm::MapVector <Block *, SmallVector<ControlFlowInfo::Edge *>>
326326 block_conditional_edges;
327327
328- DenseMap <Value, Value> condition_cache;
328+ llvm::MapVector <Value, Value> condition_cache;
329329
330- DenseMap <BlockArgument, SmallVector<Value>> arg_to_phi_operands;
330+ llvm::MapVector <BlockArgument, SmallVector<Value>> arg_to_phi_operands;
331331
332332 for (auto &edge : ctrl_info.all_edges ) {
333333 Block *target = edge->target ;
@@ -431,8 +431,6 @@ void createReserveAndPhiOps(func::FuncOp &func, ControlFlowInfo &ctrl_info,
431431 // ================================================
432432 // Step 4: Creates phi operations for each block argument.
433433 // ================================================
434- DenseSet<BlockArgument> args_needing_phi;
435-
436434 for (auto &arg_to_phi_pair : arg_to_phi_operands) {
437435 BlockArgument arg = arg_to_phi_pair.first ;
438436 auto &phi_operands = arg_to_phi_pair.second ;
@@ -501,7 +499,8 @@ void createReserveAndPhiOps(func::FuncOp &func, ControlFlowInfo &ctrl_info,
501499
502500 if (target->getArguments ().empty ()) {
503501 // Grants predicate for all the live-in values in the target block.
504- DenseSet<Value> live_in_values;
502+ // Uses SetVector instead of DenseSet to maintain insertion order.
503+ SetVector<Value> live_in_values;
505504 for (Operation &op : target->getOperations ()) {
506505 for (Value operand : op.getOperands ()) {
507506 if (operand.getDefiningOp () &&
@@ -562,8 +561,8 @@ void transformControlFlowToDataFlow(func::FuncOp &func,
562561 assertLiveOutValuesDominatedByBlockArgs (func);
563562
564563 // Creates reserve and phi operations for each block argument.
565- DenseMap <BlockArgument, Value> arg_to_reserve;
566- DenseMap <BlockArgument, Value> arg_to_phi_result;
564+ llvm::MapVector <BlockArgument, Value> arg_to_reserve;
565+ llvm::MapVector <BlockArgument, Value> arg_to_phi_result;
567566 createReserveAndPhiOps (func, ctrl_info, arg_to_reserve, arg_to_phi_result,
568567 builder);
569568
0 commit comments