@@ -75,6 +75,10 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s,
7575
7676 case Stmt::ForStmtClass:
7777 return emitForStmt (cast<ForStmt>(*s));
78+ case Stmt::WhileStmtClass:
79+ return emitWhileStmt (cast<WhileStmt>(*s));
80+ case Stmt::DoStmtClass:
81+ return emitDoStmt (cast<DoStmt>(*s));
7882
7983 case Stmt::OMPScopeDirectiveClass:
8084 case Stmt::OMPErrorDirectiveClass:
@@ -97,8 +101,6 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s,
97101 case Stmt::SYCLKernelCallStmtClass:
98102 case Stmt::IfStmtClass:
99103 case Stmt::SwitchStmtClass:
100- case Stmt::WhileStmtClass:
101- case Stmt::DoStmtClass:
102104 case Stmt::CoroutineBodyStmtClass:
103105 case Stmt::CoreturnStmtClass:
104106 case Stmt::CXXTryStmtClass:
@@ -387,3 +389,110 @@ mlir::LogicalResult CIRGenFunction::emitForStmt(const ForStmt &s) {
387389 terminateBody (builder, forOp.getBody (), getLoc (s.getEndLoc ()));
388390 return mlir::success ();
389391}
392+
393+ mlir::LogicalResult CIRGenFunction::emitDoStmt (const DoStmt &s) {
394+ cir::DoWhileOp doWhileOp;
395+
396+ // TODO: pass in array of attributes.
397+ auto doStmtBuilder = [&]() -> mlir::LogicalResult {
398+ mlir::LogicalResult loopRes = mlir::success ();
399+ assert (!cir::MissingFeatures::loopInfoStack ());
400+ // From LLVM: if there are any cleanups between here and the loop-exit
401+ // scope, create a block to stage a loop exit along.
402+ // We probably already do the right thing because of ScopeOp, but make
403+ // sure we handle all cases.
404+ assert (!cir::MissingFeatures::requiresCleanups ());
405+
406+ doWhileOp = builder.createDoWhile (
407+ getLoc (s.getSourceRange ()),
408+ /* condBuilder=*/
409+ [&](mlir::OpBuilder &b, mlir::Location loc) {
410+ assert (!cir::MissingFeatures::createProfileWeightsForLoop ());
411+ assert (!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic ());
412+ // C99 6.8.5p2/p4: The first substatement is executed if the
413+ // expression compares unequal to 0. The condition must be a
414+ // scalar type.
415+ mlir::Value condVal = evaluateExprAsBool (s.getCond ());
416+ builder.createCondition (condVal);
417+ },
418+ /* bodyBuilder=*/
419+ [&](mlir::OpBuilder &b, mlir::Location loc) {
420+ // The scope of the do-while loop body is a nested scope.
421+ if (emitStmt (s.getBody (), /* useCurrentScope=*/ false ).failed ())
422+ loopRes = mlir::failure ();
423+ emitStopPoint (&s);
424+ });
425+ return loopRes;
426+ };
427+
428+ mlir::LogicalResult res = mlir::success ();
429+ mlir::Location scopeLoc = getLoc (s.getSourceRange ());
430+ builder.create <cir::ScopeOp>(scopeLoc, /* scopeBuilder=*/
431+ [&](mlir::OpBuilder &b, mlir::Location loc) {
432+ LexicalScope lexScope{
433+ *this , loc, builder.getInsertionBlock ()};
434+ res = doStmtBuilder ();
435+ });
436+
437+ if (res.failed ())
438+ return res;
439+
440+ terminateBody (builder, doWhileOp.getBody (), getLoc (s.getEndLoc ()));
441+ return mlir::success ();
442+ }
443+
444+ mlir::LogicalResult CIRGenFunction::emitWhileStmt (const WhileStmt &s) {
445+ cir::WhileOp whileOp;
446+
447+ // TODO: pass in array of attributes.
448+ auto whileStmtBuilder = [&]() -> mlir::LogicalResult {
449+ mlir::LogicalResult loopRes = mlir::success ();
450+ assert (!cir::MissingFeatures::loopInfoStack ());
451+ // From LLVM: if there are any cleanups between here and the loop-exit
452+ // scope, create a block to stage a loop exit along.
453+ // We probably already do the right thing because of ScopeOp, but make
454+ // sure we handle all cases.
455+ assert (!cir::MissingFeatures::requiresCleanups ());
456+
457+ whileOp = builder.createWhile (
458+ getLoc (s.getSourceRange ()),
459+ /* condBuilder=*/
460+ [&](mlir::OpBuilder &b, mlir::Location loc) {
461+ assert (!cir::MissingFeatures::createProfileWeightsForLoop ());
462+ assert (!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic ());
463+ mlir::Value condVal;
464+ // If the for statement has a condition scope,
465+ // emit the local variable declaration.
466+ if (s.getConditionVariable ())
467+ emitDecl (*s.getConditionVariable ());
468+ // C99 6.8.5p2/p4: The first substatement is executed if the
469+ // expression compares unequal to 0. The condition must be a
470+ // scalar type.
471+ condVal = evaluateExprAsBool (s.getCond ());
472+ builder.createCondition (condVal);
473+ },
474+ /* bodyBuilder=*/
475+ [&](mlir::OpBuilder &b, mlir::Location loc) {
476+ // The scope of the while loop body is a nested scope.
477+ if (emitStmt (s.getBody (), /* useCurrentScope=*/ false ).failed ())
478+ loopRes = mlir::failure ();
479+ emitStopPoint (&s);
480+ });
481+ return loopRes;
482+ };
483+
484+ mlir::LogicalResult res = mlir::success ();
485+ mlir::Location scopeLoc = getLoc (s.getSourceRange ());
486+ builder.create <cir::ScopeOp>(scopeLoc, /* scopeBuilder=*/
487+ [&](mlir::OpBuilder &b, mlir::Location loc) {
488+ LexicalScope lexScope{
489+ *this , loc, builder.getInsertionBlock ()};
490+ res = whileStmtBuilder ();
491+ });
492+
493+ if (res.failed ())
494+ return res;
495+
496+ terminateBody (builder, whileOp.getBody (), getLoc (s.getEndLoc ()));
497+ return mlir::success ();
498+ }
0 commit comments