Commit f0997107 authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Using SCF While loop



All the loop constructs have now been converted to Affine/SCF

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 7ae612a7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ QCOR_EXPECT_TRUE(i == 10);
  auto mlir2 = qcor::mlir_compile(while_stmt, "while_stmt",
                                 qcor::OutputType::MLIR, false);
  std::cout << mlir2 << "\n";
  // We're using SCF while loop:
  EXPECT_TRUE(mlir2.find("scf.while") != std::string::npos);
  EXPECT_FALSE(qcor::execute(while_stmt, "while_stmt"));

    const std::string decrement = R"#(OPENQASM 3;
+27 −43
Original line number Diff line number Diff line
@@ -408,52 +408,36 @@ void qasm3_visitor::createWhileLoop(
  auto loop_signature = context->loopSignature();
  auto program_block = context->programBlock();
  assert(loop_signature->booleanExpression());
  auto main_block = builder.saveInsertionPoint();
  auto cachedBuilder = builder;
  mlir::scf::WhileOp whileOp = builder.create<mlir::scf::WhileOp>(
      location, mlir::TypeRange() /*resultTypes*/,
      mlir::ValueRange() /*operands*/);

  // FIXME: convert to mlir::scf::WhileOp (should be easy since it's
  // conditioned on an i1 value)
  // this is a while loop
  auto while_expr = loop_signature->booleanExpression();

  // Create a new scope for the for loop
  symbol_table.enter_new_scope();

  auto currRegion = builder.getBlock()->getParent();

  auto savept = builder.saveInsertionPoint();
  auto headerBlock = builder.createBlock(currRegion, currRegion->end());
  auto bodyBlock = builder.createBlock(currRegion, currRegion->end());
  auto exitBlock = builder.createBlock(currRegion, currRegion->end());

  builder.restoreInsertionPoint(savept);
  builder.create<mlir::BranchOp>(location, headerBlock);
  mlir::Block *before = builder.createBlock(&whileOp.before(), {}, {});
  mlir::Block *after = builder.createBlock(&whileOp.after(), {}, {});

  builder.setInsertionPointToEnd(headerBlock);
  // Build the "before" region:
  // In a "while" loop, this region computes the condition. 
  builder.setInsertionPointToStart(&whileOp.before().front());
  qasm3_expression_generator exp_generator(builder, symbol_table, file_name);
  exp_generator.visit(while_expr);
  auto expr_value = exp_generator.current_value;
  builder.create<mlir::CondBranchOp>(location, expr_value, bodyBlock,
                                     exitBlock);

  builder.setInsertionPointToStart(bodyBlock);
  current_loop_exit_block = exitBlock;
  current_loop_header_block = headerBlock;

  exp_generator.visit(loop_signature->booleanExpression());
  mlir::Value cond = exp_generator.current_value;
  builder.create<mlir::scf::ConditionOp>(location, cond, before->getArguments());
  builder.setInsertionPointToStart(&whileOp.after().front());

  // Build the "after" region:
  // In a "while" loop, this region is the loop body.
  builder.setInsertionPointToStart(&whileOp.after().front());
  {
    symbol_table.enter_new_scope();
    visitChildren(program_block);

  current_loop_header_block = nullptr;
  current_loop_exit_block = nullptr;

  builder.create<mlir::BranchOp>(location, headerBlock);
  builder.setInsertionPointToStart(exitBlock);

    symbol_table.exit_scope();

  // This is where we do some manipulation of
  // the basic blocks, lets store the current last block
  // so that finalize_mlirgen() can add return and deallocs
  // correctly

  symbol_table.set_last_created_block(exitBlock);
    // 'After' block must end with a yield op.
    builder.create<mlir::scf::YieldOp>(location);
  }

  builder = cachedBuilder;
  builder.restoreInsertionPoint(main_block);
}
} // namespace qcor
 No newline at end of file