@@ -75,6 +75,10 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s,
75
75
76
76
case Stmt::ForStmtClass:
77
77
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));
78
82
79
83
case Stmt::OMPScopeDirectiveClass:
80
84
case Stmt::OMPErrorDirectiveClass:
@@ -97,8 +101,6 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s,
97
101
case Stmt::SYCLKernelCallStmtClass:
98
102
case Stmt::IfStmtClass:
99
103
case Stmt::SwitchStmtClass:
100
- case Stmt::WhileStmtClass:
101
- case Stmt::DoStmtClass:
102
104
case Stmt::CoroutineBodyStmtClass:
103
105
case Stmt::CoreturnStmtClass:
104
106
case Stmt::CXXTryStmtClass:
@@ -387,3 +389,110 @@ mlir::LogicalResult CIRGenFunction::emitForStmt(const ForStmt &s) {
387
389
terminateBody (builder, forOp.getBody (), getLoc (s.getEndLoc ()));
388
390
return mlir::success ();
389
391
}
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