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

Added code for continue handling



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent dc467701
Loading
Loading
Loading
Loading
+25 −12
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ antlrcpp::Any qasm3_visitor::visitControlDirective(
  // For example, with a for loop: we need to wrap the whole body in a break check
  // **and** each subsequent block after the *break/continue* point
  if (stmt == "break") {
    // builder.create<mlir::BranchOp>(location, current_loop_exit_block);

    mlir::Region *region = builder.getInsertionBlock()->getParent();
    auto parent_op = region->getParentOp();
    mlir::scf::IfOp parentIfOp =
@@ -40,27 +38,42 @@ antlrcpp::Any qasm3_visitor::visitControlDirective(

    // Store false to both the break and continue:
    // i.e., bypass the whole for loop and the rest of the loop body:
    // (1) This bool will bypass the whole for loop body:
    builder.create<mlir::StoreOp>(
        location,
        get_or_create_constant_integer_value(0, location, builder.getI1Type(),
                                             symbol_table, builder),
        cond1);
    // (2) This bool will bypass rest of the loop body (after this point)
    builder.create<mlir::StoreOp>(
        location,
        get_or_create_constant_integer_value(0, location, builder.getI1Type(),
                                             symbol_table, builder),
        cond2);
  } else if (stmt == "continue") {
    // TODO: Handle this case.
    if (current_loop_incrementor_block) {
      builder.create<mlir::BranchOp>(location, current_loop_incrementor_block);
    } else if (current_loop_header_block) {
      // this is a while loop
      builder.create<mlir::BranchOp>(location, current_loop_header_block);
    } else {
      printErrorMessage(
          "Something went wrong with continue, no valid block to branch to.");
    mlir::Region *region = builder.getInsertionBlock()->getParent();
    auto parent_op = region->getParentOp();
    mlir::scf::IfOp parentIfOp =
        mlir::dyn_cast_or_null<mlir::scf::IfOp>(parent_op);
    if (!parentIfOp) {
      // We can handle this as well, but it's really a programmers' bug.
      // Hence, just let them know.
      printErrorMessage("Illegal break directive: unconditional break.");
    }

    // Set an attribute so that we can detect this after handling this.
    parentIfOp->setAttr("control-directive",
                        mlir::IntegerAttr::get(builder.getIntegerType(1), 1));
    assert(!for_loop_control_vars.empty());
    auto [cond1, cond2] = for_loop_control_vars.top();

    // Just bypass rest of the loop body (after this point)
    // i.e., not disable the whol loop.
    builder.create<mlir::StoreOp>(
        location,
        get_or_create_constant_integer_value(0, location, builder.getI1Type(),
                                             symbol_table, builder),
        cond2);
  } else {
    printErrorMessage("we do not yet support the " + stmt +
                      " control directive.");