16#include "mlir/IR/Builders.h"
17#include "mlir/IR/Location.h"
18#include "mlir/Support/LLVM.h"
30 const Stmt *exprResult,
39 if (
const auto *ls = dyn_cast<LabelStmt>(exprResult)) {
40 if (cgf.
emitLabel(*ls->getDecl()).failed())
41 return mlir::failure();
42 exprResult = ls->getSubStmt();
43 }
else if (
const auto *as = dyn_cast<AttributedStmt>(exprResult)) {
46 exprResult = as->getSubStmt();
48 llvm_unreachable(
"Unknown value statement");
64 return mlir::success();
69 mlir::LogicalResult result = mlir::success();
70 const Stmt *exprResult =
s.body_back();
71 assert((!lastValue || (lastValue && exprResult)) &&
72 "If lastValue is not null then the CompoundStmt must have a "
75 for (
const Stmt *curStmt :
s.body()) {
76 const bool saveResult = lastValue && exprResult == curStmt;
79 result = mlir::failure();
81 if (
emitStmt(curStmt,
false).failed())
82 result = mlir::failure();
91 switch (
attr->getKind()) {
96 case attr::AlwaysInline:
97 case attr::NoConvergent:
100 case attr::HLSLControlFlowHint:
101 cgm.errorNYI(
s.getSourceRange(),
102 "Unimplemented statement attribute: ",
attr->getKind());
104 case attr::CXXAssume: {
106 if (
getLangOpts().CXXAssumptions && builder.getInsertionBlock() &&
109 cir::AssumeOp::create(builder,
getLoc(
s.getSourceRange()),
116 return emitStmt(
s.getSubStmt(),
true,
s.getAttrs());
124 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
125 mlir::OpBuilder::InsertPoint scopeInsPt;
126 cir::ScopeOp::create(
128 [&](mlir::OpBuilder &
b, mlir::Type &
type, mlir::Location loc) {
129 scopeInsPt =
b.saveInsertionPoint();
131 mlir::OpBuilder::InsertionGuard guard(builder);
132 builder.restoreInsertionPoint(scopeInsPt);
133 LexicalScope lexScope(*
this, scopeLoc, builder.getInsertionBlock());
144 bool useCurrentScope,
147 return mlir::success();
149 switch (
s->getStmtClass()) {
151 case Stmt::CXXCatchStmtClass:
152 case Stmt::SEHExceptStmtClass:
153 case Stmt::SEHFinallyStmtClass:
154 case Stmt::MSDependentExistsStmtClass:
155 case Stmt::UnresolvedSYCLKernelCallStmtClass:
156 llvm_unreachable(
"invalid statement class to emit generically");
157 case Stmt::BreakStmtClass:
158 case Stmt::NullStmtClass:
159 case Stmt::CompoundStmtClass:
160 case Stmt::ContinueStmtClass:
161 case Stmt::DeclStmtClass:
162 case Stmt::ReturnStmtClass:
163 llvm_unreachable(
"should have emitted these statements as simple");
165#define STMT(Type, Base)
166#define ABSTRACT_STMT(Op)
167#define EXPR(Type, Base) case Stmt::Type##Class:
168#include "clang/AST/StmtNodes.inc"
170 assert(builder.getInsertionBlock() &&
171 "expression emission must have an insertion point");
179 return mlir::success();
181 case Stmt::IfStmtClass:
183 case Stmt::SwitchStmtClass:
185 case Stmt::ForStmtClass:
187 case Stmt::WhileStmtClass:
189 case Stmt::DoStmtClass:
191 case Stmt::CXXTryStmtClass:
193 case Stmt::CXXForRangeStmtClass:
195 case Stmt::CoroutineBodyStmtClass:
197 case Stmt::IndirectGotoStmtClass:
199 case Stmt::CoreturnStmtClass:
201 case Stmt::OpenACCComputeConstructClass:
203 case Stmt::OpenACCLoopConstructClass:
205 case Stmt::OpenACCCombinedConstructClass:
207 case Stmt::OpenACCDataConstructClass:
209 case Stmt::OpenACCEnterDataConstructClass:
211 case Stmt::OpenACCExitDataConstructClass:
213 case Stmt::OpenACCHostDataConstructClass:
215 case Stmt::OpenACCWaitConstructClass:
217 case Stmt::OpenACCInitConstructClass:
219 case Stmt::OpenACCShutdownConstructClass:
221 case Stmt::OpenACCSetConstructClass:
223 case Stmt::OpenACCUpdateConstructClass:
225 case Stmt::OpenACCCacheConstructClass:
227 case Stmt::OpenACCAtomicConstructClass:
229 case Stmt::GCCAsmStmtClass:
230 case Stmt::MSAsmStmtClass:
232 case Stmt::OMPScopeDirectiveClass:
234 case Stmt::OMPErrorDirectiveClass:
236 case Stmt::OMPParallelDirectiveClass:
238 case Stmt::OMPTaskwaitDirectiveClass:
240 case Stmt::OMPTaskyieldDirectiveClass:
242 case Stmt::OMPBarrierDirectiveClass:
244 case Stmt::OMPMetaDirectiveClass:
246 case Stmt::OMPCanonicalLoopClass:
248 case Stmt::OMPSimdDirectiveClass:
250 case Stmt::OMPTileDirectiveClass:
252 case Stmt::OMPUnrollDirectiveClass:
254 case Stmt::OMPFuseDirectiveClass:
256 case Stmt::OMPForDirectiveClass:
258 case Stmt::OMPForSimdDirectiveClass:
260 case Stmt::OMPSectionsDirectiveClass:
262 case Stmt::OMPSectionDirectiveClass:
264 case Stmt::OMPSingleDirectiveClass:
266 case Stmt::OMPMasterDirectiveClass:
268 case Stmt::OMPCriticalDirectiveClass:
270 case Stmt::OMPParallelForDirectiveClass:
272 case Stmt::OMPParallelForSimdDirectiveClass:
275 case Stmt::OMPParallelMasterDirectiveClass:
277 case Stmt::OMPParallelSectionsDirectiveClass:
280 case Stmt::OMPTaskDirectiveClass:
282 case Stmt::OMPTaskgroupDirectiveClass:
284 case Stmt::OMPFlushDirectiveClass:
286 case Stmt::OMPDepobjDirectiveClass:
288 case Stmt::OMPScanDirectiveClass:
290 case Stmt::OMPOrderedDirectiveClass:
292 case Stmt::OMPAtomicDirectiveClass:
294 case Stmt::OMPTargetDirectiveClass:
296 case Stmt::OMPTeamsDirectiveClass:
298 case Stmt::OMPCancellationPointDirectiveClass:
301 case Stmt::OMPCancelDirectiveClass:
303 case Stmt::OMPTargetDataDirectiveClass:
305 case Stmt::OMPTargetEnterDataDirectiveClass:
308 case Stmt::OMPTargetExitDataDirectiveClass:
310 case Stmt::OMPTargetParallelDirectiveClass:
312 case Stmt::OMPTargetParallelForDirectiveClass:
315 case Stmt::OMPTaskLoopDirectiveClass:
317 case Stmt::OMPTaskLoopSimdDirectiveClass:
319 case Stmt::OMPMaskedTaskLoopDirectiveClass:
321 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
324 case Stmt::OMPMasterTaskLoopDirectiveClass:
326 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
329 case Stmt::OMPParallelGenericLoopDirectiveClass:
332 case Stmt::OMPParallelMaskedDirectiveClass:
334 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
337 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
340 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
343 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
346 case Stmt::OMPDistributeDirectiveClass:
348 case Stmt::OMPDistributeParallelForDirectiveClass:
351 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
354 case Stmt::OMPDistributeSimdDirectiveClass:
356 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
359 case Stmt::OMPTargetParallelForSimdDirectiveClass:
362 case Stmt::OMPTargetSimdDirectiveClass:
364 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
367 case Stmt::OMPTargetUpdateDirectiveClass:
369 case Stmt::OMPTeamsDistributeDirectiveClass:
372 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
375 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
378 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
381 case Stmt::OMPTeamsGenericLoopDirectiveClass:
384 case Stmt::OMPTargetTeamsDirectiveClass:
386 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
389 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
392 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
395 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
398 case Stmt::OMPInteropDirectiveClass:
400 case Stmt::OMPDispatchDirectiveClass:
402 case Stmt::OMPGenericLoopDirectiveClass:
404 case Stmt::OMPReverseDirectiveClass:
406 case Stmt::OMPInterchangeDirectiveClass:
408 case Stmt::OMPAssumeDirectiveClass:
410 case Stmt::OMPMaskedDirectiveClass:
412 case Stmt::OMPStripeDirectiveClass:
414 case Stmt::LabelStmtClass:
415 case Stmt::AttributedStmtClass:
416 case Stmt::GotoStmtClass:
417 case Stmt::DefaultStmtClass:
418 case Stmt::CaseStmtClass:
419 case Stmt::SEHLeaveStmtClass:
420 case Stmt::SYCLKernelCallStmtClass:
421 case Stmt::CapturedStmtClass:
422 case Stmt::ObjCAtTryStmtClass:
423 case Stmt::ObjCAtThrowStmtClass:
424 case Stmt::ObjCAtSynchronizedStmtClass:
425 case Stmt::ObjCForCollectionStmtClass:
426 case Stmt::ObjCAutoreleasePoolStmtClass:
427 case Stmt::SEHTryStmtClass:
428 case Stmt::ObjCAtCatchStmtClass:
429 case Stmt::ObjCAtFinallyStmtClass:
430 case Stmt::DeferStmtClass:
431 cgm.errorNYI(
s->getSourceRange(),
432 std::string(
"emitStmt: ") +
s->getStmtClassName());
433 return mlir::failure();
436 llvm_unreachable(
"Unexpected statement class");
440 bool useCurrentScope) {
441 switch (
s->getStmtClass()) {
443 return mlir::failure();
444 case Stmt::DeclStmtClass:
446 case Stmt::CompoundStmtClass:
450 case Stmt::GotoStmtClass:
452 case Stmt::ContinueStmtClass:
456 case Stmt::NullStmtClass:
459 case Stmt::LabelStmtClass:
461 case Stmt::CaseStmtClass:
462 case Stmt::DefaultStmtClass:
468 case Stmt::BreakStmtClass:
470 case Stmt::ReturnStmtClass:
472 case Stmt::AttributedStmtClass:
476 return mlir::success();
482 return mlir::failure();
492 mlir::Location loc) {
497 unsigned numBlocks = r.getBlocks().size();
498 for (
auto &block : r.getBlocks()) {
501 if (numBlocks != 1 && block.empty() && block.hasNoPredecessors() &&
502 block.hasNoSuccessors())
503 eraseBlocks.push_back(&block);
506 !block.back().hasTrait<mlir::OpTrait::IsTerminator>()) {
507 mlir::OpBuilder::InsertionGuard guardCase(builder);
508 builder.setInsertionPointToEnd(&block);
513 for (
auto *
b : eraseBlocks)
518 mlir::LogicalResult res = mlir::success();
521 const Stmt *constevalExecuted;
522 if (
s.isConsteval()) {
523 constevalExecuted =
s.isNegatedConsteval() ?
s.getThen() :
s.getElse();
524 if (!constevalExecuted) {
532 auto ifStmtBuilder = [&]() -> mlir::LogicalResult {
534 return emitStmt(constevalExecuted,
true);
537 if (
emitStmt(
s.getInit(),
true).failed())
538 return mlir::failure();
540 if (
s.getConditionVariable())
547 if (
s.isConstexpr()) {
552 if (
const Stmt *executed = condConstant ?
s.getThen() :
s.getElse())
556 return mlir::success();
568 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
569 cir::ScopeOp::create(builder, scopeLoc,
570 [&](mlir::OpBuilder &
b, mlir::Location loc) {
572 builder.getInsertionBlock()};
573 res = ifStmtBuilder();
580 assert(builder.getInsertionBlock() &&
"expected valid insertion point");
582 for (
const Decl *i :
s.decls())
585 return mlir::success();
589 mlir::Location loc =
getLoc(
s.getSourceRange());
590 const Expr *rv =
s.getRetValue();
593 bool createNewScope =
false;
594 if (
const auto *ewc = dyn_cast_or_null<ExprWithCleanups>(rv)) {
595 rv = ewc->getSubExpr();
596 createNewScope =
true;
599 auto handleReturnVal = [&]() {
601 s.getNRVOCandidate()->isNRVOVariable()) {
609 if (
auto nrvoFlag =
nrvoFlags[
s.getNRVOCandidate()])
610 builder.createFlagStore(loc,
true, nrvoFlag);
621 ->isReferenceType()) {
625 builder.CIRBaseBuilderTy::createStore(loc, result.
getValue(),
628 mlir::Value value =
nullptr;
633 builder.CIRBaseBuilderTy::createStore(loc, value, *
fnRetAlloca);
652 if (!createNewScope) {
655 mlir::Location scopeLoc =
660 mlir::OpBuilder::InsertPoint scopeBody;
661 cir::ScopeOp::create(builder, scopeLoc,
662 [&](mlir::OpBuilder &
b, mlir::Location loc) {
663 scopeBody =
b.saveInsertionPoint();
666 mlir::OpBuilder::InsertionGuard guard(builder);
667 builder.restoreInsertionPoint(scopeBody);
669 builder.getInsertionBlock()};
683 cir::AllocaOp retAlloca =
684 mlir::cast<cir::AllocaOp>(
fnRetAlloca->getDefiningOp());
685 auto value = cir::LoadOp::create(builder, loc, retAlloca.getAllocaType(),
688 cir::ReturnOp::create(builder, loc, {value});
690 cir::ReturnOp::create(builder, loc);
696 builder.createBlock(builder.getBlock()->getParent());
697 return mlir::success();
707 cir::GotoOp::create(builder,
getLoc(
s.getSourceRange()),
708 s.getLabel()->getName());
713 builder.createBlock(builder.getBlock()->getParent());
715 return mlir::success();
722 "If you jumping to a indirect branch should be alareadye emitted");
725 builder.createBlock(builder.getBlock()->getParent());
726 return mlir::success();
731 builder.createContinue(
getLoc(
s.getKwLoc()));
734 builder.createBlock(builder.getBlock()->getParent());
736 return mlir::success();
743 mlir::Block *currBlock = builder.getBlock();
744 mlir::Block *labelBlock = currBlock;
746 if (!currBlock->empty() || currBlock->isEntryBlock()) {
748 mlir::OpBuilder::InsertionGuard guard(builder);
749 labelBlock = builder.createBlock(builder.getBlock()->getParent());
754 builder.setInsertionPointToEnd(labelBlock);
757 builder.setInsertionPointToEnd(labelBlock);
759 cgm.mapBlockAddress(cir::BlockAddrInfoAttr::get(builder.getContext(),
760 func.getSymNameAttr(),
761 label.getLabelAttr()),
766 return mlir::success();
770 builder.createBreak(
getLoc(
s.getKwLoc()));
773 builder.createBlock(builder.getBlock()->getParent());
775 return mlir::success();
781 mlir::ArrayAttr value, CaseOpKind
kind,
782 bool buildingTopLevelCase) {
785 "only case or default stmt go here");
787 mlir::LogicalResult result = mlir::success();
789 mlir::Location loc =
getLoc(
stmt->getBeginLoc());
792 SubStmtKind subStmtKind = SubStmtKind::Other;
793 const Stmt *sub =
stmt->getSubStmt();
795 mlir::OpBuilder::InsertPoint insertPoint;
796 CaseOp::create(builder, loc, value,
kind, insertPoint);
799 mlir::OpBuilder::InsertionGuard guardSwitch(builder);
800 builder.restoreInsertionPoint(insertPoint);
803 subStmtKind = SubStmtKind::Default;
804 builder.createYield(loc);
806 subStmtKind = SubStmtKind::Case;
807 builder.createYield(loc);
812 insertPoint = builder.saveInsertionPoint();
847 if (subStmtKind == SubStmtKind::Case) {
849 }
else if (subStmtKind == SubStmtKind::Default) {
851 buildingTopLevelCase);
852 }
else if (buildingTopLevelCase) {
856 builder.restoreInsertionPoint(insertPoint);
864 bool buildingTopLevelCase) {
865 cir::CaseOpKind
kind;
866 mlir::ArrayAttr value;
867 llvm::APSInt intVal =
s.getLHS()->EvaluateKnownConstInt(
getContext());
872 if (
const Expr *rhs =
s.getRHS()) {
873 llvm::APSInt endVal = rhs->EvaluateKnownConstInt(
getContext());
874 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal),
875 cir::IntAttr::get(condType, endVal)});
876 kind = cir::CaseOpKind::Range;
878 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal)});
879 kind = cir::CaseOpKind::Equal;
883 buildingTopLevelCase);
888 bool buildingTopLevelCase) {
890 cir::CaseOpKind::Default, buildingTopLevelCase);
894 bool buildingTopLevelCase) {
896 "build switch case without specifying the type of the condition");
898 if (
s.getStmtClass() == Stmt::CaseStmtClass)
900 buildingTopLevelCase);
902 if (
s.getStmtClass() == Stmt::DefaultStmtClass)
904 buildingTopLevelCase);
906 llvm_unreachable(
"expect case or default stmt");
915 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
916 mlir::LogicalResult loopRes = mlir::success();
919 if (
emitStmt(
s.getInit(),
true).failed())
920 return mlir::failure();
921 if (
emitStmt(
s.getRangeStmt(),
true).failed())
922 return mlir::failure();
923 if (
emitStmt(
s.getBeginStmt(),
true).failed())
924 return mlir::failure();
925 if (
emitStmt(
s.getEndStmt(),
true).failed())
926 return mlir::failure();
935 forOp = builder.createFor(
938 [&](mlir::OpBuilder &
b, mlir::Location loc) {
939 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
940 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
941 mlir::Value condVal = evaluateExprAsBool(s.getCond());
942 builder.createCondition(condVal);
945 [&](mlir::OpBuilder &
b, mlir::Location loc) {
949 bool useCurrentScope = true;
950 if (emitStmt(s.getLoopVarStmt(), useCurrentScope).failed())
951 loopRes = mlir::failure();
952 if (emitStmt(s.getBody(), useCurrentScope).failed())
953 loopRes = mlir::failure();
957 [&](mlir::OpBuilder &
b, mlir::Location loc) {
959 if (emitStmt(s.getInc(), true).failed())
960 loopRes = mlir::failure();
961 builder.createYield(loc);
966 mlir::LogicalResult res = mlir::success();
967 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
968 cir::ScopeOp::create(builder, scopeLoc,
969 [&](mlir::OpBuilder &
b, mlir::Location loc) {
975 builder.getInsertionBlock()};
976 res = forStmtBuilder();
983 return mlir::success();
990 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
991 mlir::LogicalResult loopRes = mlir::success();
994 if (
emitStmt(
s.getInit(),
true).failed())
995 return mlir::failure();
1003 forOp = builder.createFor(
1006 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1007 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1008 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1009 mlir::Value condVal;
1013 if (s.getConditionVariable())
1014 emitDecl(*s.getConditionVariable());
1018 condVal = evaluateExprAsBool(s.getCond());
1020 condVal = cir::ConstantOp::create(b, loc, builder.getTrueAttr());
1022 builder.createCondition(condVal);
1025 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1028 if (
emitStmt(
s.getBody(),
false).failed())
1029 loopRes = mlir::failure();
1033 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1035 if (
emitStmt(
s.getInc(),
true).failed())
1036 loopRes = mlir::failure();
1037 builder.createYield(loc);
1042 auto res = mlir::success();
1043 auto scopeLoc = getLoc(
s.getSourceRange());
1044 cir::ScopeOp::create(builder, scopeLoc,
1045 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1046 LexicalScope lexScope{*
this, loc,
1047 builder.getInsertionBlock()};
1048 res = forStmtBuilder();
1055 return mlir::success();
1059 cir::DoWhileOp doWhileOp;
1062 auto doStmtBuilder = [&]() -> mlir::LogicalResult {
1063 mlir::LogicalResult loopRes = mlir::success();
1071 doWhileOp = builder.createDoWhile(
1074 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1075 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1076 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1080 mlir::Value condVal = evaluateExprAsBool(s.getCond());
1081 builder.createCondition(condVal);
1084 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1086 if (emitStmt(s.getBody(), false).failed())
1087 loopRes = mlir::failure();
1093 mlir::LogicalResult res = mlir::success();
1094 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1095 cir::ScopeOp::create(builder, scopeLoc,
1096 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1098 builder.getInsertionBlock()};
1099 res = doStmtBuilder();
1106 return mlir::success();
1110 cir::WhileOp whileOp;
1113 auto whileStmtBuilder = [&]() -> mlir::LogicalResult {
1114 mlir::LogicalResult loopRes = mlir::success();
1122 whileOp = builder.createWhile(
1125 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1126 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1127 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1128 mlir::Value condVal;
1131 if (s.getConditionVariable())
1132 emitDecl(*s.getConditionVariable());
1136 condVal = evaluateExprAsBool(s.getCond());
1137 builder.createCondition(condVal);
1140 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1142 if (emitStmt(s.getBody(), false).failed())
1143 loopRes = mlir::failure();
1149 mlir::LogicalResult res = mlir::success();
1150 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1151 cir::ScopeOp::create(builder, scopeLoc,
1152 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1154 builder.getInsertionBlock()};
1155 res = whileStmtBuilder();
1162 return mlir::success();
1180 mlir::Block *swtichBlock = builder.getBlock();
1183 builder.setInsertionPointToEnd(swtichBlock);
1189 return mlir::failure();
1196 return mlir::failure();
1199 return mlir::success();
1210 auto switchStmtBuilder = [&]() -> mlir::LogicalResult {
1212 if (
emitStmt(
s.getInit(),
true).failed())
1213 return mlir::failure();
1215 if (
s.getConditionVariable())
1216 emitDecl(*
s.getConditionVariable(),
true);
1226 mlir::LogicalResult res = mlir::success();
1227 swop = SwitchOp::create(
1228 builder,
getLoc(
s.getBeginLoc()), condV,
1230 [&](mlir::OpBuilder &
b, mlir::Location loc, mlir::OperationState &os) {
1231 curLexScope->setAsSwitch();
1233 condTypeStack.push_back(condV.getType());
1235 res = emitSwitchBody(s.getBody());
1237 condTypeStack.pop_back();
1244 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1245 mlir::LogicalResult res = mlir::success();
1246 cir::ScopeOp::create(builder, scopeLoc,
1247 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1249 builder.getInsertionBlock()};
1250 res = switchStmtBuilder();
1254 swop.collectCases(cases);
1255 for (
auto caseOp : cases)
1256 terminateBody(builder, caseOp.getCaseRegion(), caseOp.getLoc());
1259 swop.setAllEnumCasesCovered(
s.isAllEnumCasesCovered());
1273 cgm.errorNYI(loc,
"emitReturnOfRValue: complex return type");
1282 cir::AllocaOp retAlloca =
1283 mlir::cast<cir::AllocaOp>(
fnRetAlloca->getDefiningOp());
1284 auto value = cir::LoadOp::create(builder, loc, retAlloca.getAllocaType(),
1287 cir::ReturnOp::create(builder, loc, {value});
static void terminateBody(CIRGenBuilderTy &builder, mlir::Region &r, mlir::Location loc)
static mlir::LogicalResult emitStmtWithResult(CIRGenFunction &cgf, const Stmt *exprResult, AggValueSlot slot, Address *lastValue)
Defines the clang::Expr interface and subclasses for C++ expressions.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
This file defines OpenACC AST classes for statement-level contructs.
This file defines OpenMP AST classes for executable directives and clauses.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
Attr - This represents one attribute.
Represents an attribute applied to a statement.
BreakStmt - This represents a break.
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void forceCleanup(ArrayRef< mlir::Value * > valuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
mlir::LogicalResult emitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &s)
mlir::LogicalResult emitOMPParallelMasterTaskLoopSimdDirective(const OMPParallelMasterTaskLoopSimdDirective &s)
mlir::LogicalResult emitOMPSimdDirective(const OMPSimdDirective &s)
mlir::Value emitCheckedArgForAssume(const Expr *e)
Emits an argument for a call to a __builtin_assume.
mlir::LogicalResult emitDoStmt(const clang::DoStmt &s)
mlir::LogicalResult emitOMPCriticalDirective(const OMPCriticalDirective &s)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
mlir::LogicalResult emitCoreturnStmt(const CoreturnStmt &s)
mlir::LogicalResult emitOpenACCDataConstruct(const OpenACCDataConstruct &s)
mlir::LogicalResult emitOpenACCCombinedConstruct(const OpenACCCombinedConstruct &s)
mlir::LogicalResult emitOMPParallelMasterDirective(const OMPParallelMasterDirective &s)
mlir::LogicalResult emitOpenACCWaitConstruct(const OpenACCWaitConstruct &s)
mlir::LogicalResult emitOMPCancellationPointDirective(const OMPCancellationPointDirective &s)
mlir::LogicalResult emitOMPParallelMaskedTaskLoopDirective(const OMPParallelMaskedTaskLoopDirective &s)
mlir::LogicalResult emitOMPReverseDirective(const OMPReverseDirective &s)
const clang::LangOptions & getLangOpts() const
mlir::LogicalResult emitOpenACCUpdateConstruct(const OpenACCUpdateConstruct &s)
mlir::LogicalResult emitOMPTileDirective(const OMPTileDirective &s)
mlir::LogicalResult emitIfOnBoolExpr(const clang::Expr *cond, const clang::Stmt *thenS, const clang::Stmt *elseS)
Emit an if on a boolean condition to the specified blocks.
mlir::LogicalResult emitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &s)
mlir::LogicalResult emitOMPTeamsDistributeParallelForDirective(const OMPTeamsDistributeParallelForDirective &s)
mlir::LogicalResult emitOMPBarrierDirective(const OMPBarrierDirective &s)
mlir::LogicalResult emitOMPTargetParallelDirective(const OMPTargetParallelDirective &s)
mlir::LogicalResult emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s)
mlir::LogicalResult emitOMPTargetDirective(const OMPTargetDirective &s)
mlir::LogicalResult emitCXXForRangeStmt(const CXXForRangeStmt &s, llvm::ArrayRef< const Attr * > attrs)
void emitAggregateCopy(LValue dest, LValue src, QualType eltTy, AggValueSlot::Overlap_t mayOverlap, bool isVolatile=false)
Emit an aggregate copy.
mlir::LogicalResult emitOMPScopeDirective(const OMPScopeDirective &s)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
mlir::LogicalResult emitOMPDepobjDirective(const OMPDepobjDirective &s)
bool constantFoldsToBool(const clang::Expr *cond, bool &resultBool, bool allowLabels=false)
If the specified expression does not fold to a constant, or if it does but contains a label,...
mlir::LogicalResult emitReturnStmt(const clang::ReturnStmt &s)
mlir::LogicalResult emitOpenACCInitConstruct(const OpenACCInitConstruct &s)
void emitAnyExprToMem(const Expr *e, Address location, Qualifiers quals, bool isInitializer)
Emits the code necessary to evaluate an arbitrary expression into the given memory location.
mlir::LogicalResult emitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective &s)
mlir::LogicalResult emitOMPUnrollDirective(const OMPUnrollDirective &s)
mlir::LogicalResult emitOMPTaskDirective(const OMPTaskDirective &s)
mlir::LogicalResult emitOpenACCSetConstruct(const OpenACCSetConstruct &s)
RValue emitReferenceBindingToExpr(const Expr *e)
Emits a reference binding to the passed in expression.
mlir::LogicalResult emitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &s)
mlir::LogicalResult emitOMPCanonicalLoop(const OMPCanonicalLoop &s)
mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s)
mlir::LogicalResult emitOMPTeamsDirective(const OMPTeamsDirective &s)
mlir::LogicalResult emitCaseStmt(const clang::CaseStmt &s, mlir::Type condType, bool buildingTopLevelCase)
llvm::ScopedHashTableScope< const clang::Decl *, mlir::Value > SymTableScopeTy
mlir::LogicalResult emitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective &s)
mlir::LogicalResult emitOMPFuseDirective(const OMPFuseDirective &s)
mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s, bool useCurrentScope)
mlir::LogicalResult emitOMPSectionDirective(const OMPSectionDirective &s)
mlir::Block * indirectGotoBlock
IndirectBranch - The first time an indirect goto is seen we create a block reserved for the indirect ...
mlir::Operation * curFn
The current function or global initializer that is generated code for.
mlir::LogicalResult emitAsmStmt(const clang::AsmStmt &s)
mlir::LogicalResult emitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &s)
mlir::LogicalResult emitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective &s)
mlir::LogicalResult emitOpenACCComputeConstruct(const OpenACCComputeConstruct &s)
mlir::LogicalResult emitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &s)
mlir::LogicalResult emitSwitchBody(const clang::Stmt *s)
mlir::LogicalResult emitForStmt(const clang::ForStmt &s)
mlir::LogicalResult emitOMPTaskwaitDirective(const OMPTaskwaitDirective &s)
mlir::LogicalResult emitOMPFlushDirective(const OMPFlushDirective &s)
mlir::LogicalResult emitOMPGenericLoopDirective(const OMPGenericLoopDirective &s)
mlir::LogicalResult emitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &s)
std::optional< mlir::Value > fnRetAlloca
The compiler-generated variable that holds the return value.
mlir::LogicalResult emitOMPOrderedDirective(const OMPOrderedDirective &s)
mlir::LogicalResult emitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective &s)
mlir::LogicalResult emitOMPInterchangeDirective(const OMPInterchangeDirective &s)
mlir::LogicalResult emitOMPDispatchDirective(const OMPDispatchDirective &s)
mlir::LogicalResult emitOMPParallelDirective(const OMPParallelDirective &s)
mlir::LogicalResult emitAttributedStmt(const AttributedStmt &s)
mlir::LogicalResult emitOMPForSimdDirective(const OMPForSimdDirective &s)
mlir::LogicalResult emitOMPTaskLoopDirective(const OMPTaskLoopDirective &s)
Address returnValue
The temporary alloca to hold the return value.
mlir::LogicalResult emitOMPTargetDataDirective(const OMPTargetDataDirective &s)
mlir::LogicalResult emitLabel(const clang::LabelDecl &d)
mlir::LogicalResult emitOMPTargetParallelGenericLoopDirective(const OMPTargetParallelGenericLoopDirective &s)
static bool hasAggregateEvaluationKind(clang::QualType type)
mlir::LogicalResult emitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &s)
mlir::LogicalResult emitOMPMaskedTaskLoopSimdDirective(const OMPMaskedTaskLoopSimdDirective &s)
mlir::LogicalResult emitOMPAtomicDirective(const OMPAtomicDirective &s)
mlir::LogicalResult emitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &s)
mlir::LogicalResult emitBreakStmt(const clang::BreakStmt &s)
mlir::LogicalResult emitIndirectGotoStmt(const IndirectGotoStmt &s)
mlir::LogicalResult emitOMPTeamsDistributeParallelForSimdDirective(const OMPTeamsDistributeParallelForSimdDirective &s)
mlir::LogicalResult emitOMPTaskgroupDirective(const OMPTaskgroupDirective &s)
mlir::LogicalResult emitOMPParallelMaskedTaskLoopSimdDirective(const OMPParallelMaskedTaskLoopSimdDirective &s)
mlir::LogicalResult emitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &s)
void emitReturnOfRValue(mlir::Location loc, RValue rv, QualType ty)
mlir::LogicalResult emitOMPInteropDirective(const OMPInteropDirective &s)
mlir::LogicalResult emitOMPErrorDirective(const OMPErrorDirective &s)
mlir::LogicalResult emitOMPSingleDirective(const OMPSingleDirective &s)
mlir::LogicalResult emitContinueStmt(const clang::ContinueStmt &s)
mlir::LogicalResult emitOMPTaskyieldDirective(const OMPTaskyieldDirective &s)
mlir::LogicalResult emitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective &s)
mlir::LogicalResult emitOMPScanDirective(const OMPScanDirective &s)
llvm::SmallVector< mlir::Type, 2 > condTypeStack
The type of the condition for the emitting switch statement.
mlir::LogicalResult emitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &s)
void emitStopPoint(const Stmt *s)
Build a debug stoppoint if we are emitting debug info.
mlir::LogicalResult emitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &s)
mlir::LogicalResult emitOpenACCHostDataConstruct(const OpenACCHostDataConstruct &s)
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
mlir::LogicalResult emitIfStmt(const clang::IfStmt &s)
mlir::LogicalResult emitOMPForDirective(const OMPForDirective &s)
mlir::LogicalResult emitOMPMasterDirective(const OMPMasterDirective &s)
AggValueSlot::Overlap_t getOverlapForReturnValue()
Determine whether a return value slot may overlap some other object.
mlir::LogicalResult emitSwitchCase(const clang::SwitchCase &s, bool buildingTopLevelCase)
mlir::LogicalResult emitOMPMetaDirective(const OMPMetaDirective &s)
mlir::LogicalResult emitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &s)
void emitDecl(const clang::Decl &d, bool evaluateConditionDecl=false)
mlir::LogicalResult emitOMPParallelGenericLoopDirective(const OMPParallelGenericLoopDirective &s)
mlir::LogicalResult emitOMPMaskedDirective(const OMPMaskedDirective &s)
llvm::DenseMap< const VarDecl *, mlir::Value > nrvoFlags
A mapping from NRVO variables to the flags used to indicate when the NRVO has been applied to this va...
CIRGenModule & getCIRGenModule()
mlir::LogicalResult emitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct &s)
mlir::LogicalResult emitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &s)
mlir::LogicalResult emitCXXTryStmt(const clang::CXXTryStmt &s)
mlir::LogicalResult emitOMPTargetTeamsDistributeParallelForDirective(const OMPTargetTeamsDistributeParallelForDirective &s)
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
mlir::LogicalResult emitOMPParallelForDirective(const OMPParallelForDirective &s)
mlir::LogicalResult emitCaseDefaultCascade(const T *stmt, mlir::Type condType, mlir::ArrayAttr value, cir::CaseOpKind kind, bool buildingTopLevelCase)
mlir::LogicalResult emitOMPSectionsDirective(const OMPSectionsDirective &s)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
mlir::LogicalResult emitOMPDistributeDirective(const OMPDistributeDirective &s)
RValue emitAnyExpr(const clang::Expr *e, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
Emit code to compute the specified expression which can have any type.
mlir::LogicalResult emitOMPTargetTeamsDistributeParallelForSimdDirective(const OMPTargetTeamsDistributeParallelForSimdDirective &s)
mlir::LogicalResult emitOMPTargetTeamsGenericLoopDirective(const OMPTargetTeamsGenericLoopDirective &s)
mlir::LogicalResult emitDeclStmt(const clang::DeclStmt &s)
mlir::LogicalResult emitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &s)
mlir::LogicalResult emitDefaultStmt(const clang::DefaultStmt &s, mlir::Type condType, bool buildingTopLevelCase)
mlir::LogicalResult emitWhileStmt(const clang::WhileStmt &s)
mlir::LogicalResult emitLabelStmt(const clang::LabelStmt &s)
mlir::LogicalResult emitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &s)
clang::ASTContext & getContext() const
mlir::LogicalResult emitCoroutineBody(const CoroutineBodyStmt &s)
mlir::LogicalResult emitCompoundStmt(const clang::CompoundStmt &s, Address *lastValue=nullptr, AggValueSlot slot=AggValueSlot::ignored())
mlir::LogicalResult emitGotoStmt(const clang::GotoStmt &s)
mlir::LogicalResult emitOMPParallelMasterTaskLoopDirective(const OMPParallelMasterTaskLoopDirective &s)
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
mlir::LogicalResult emitOMPCancelDirective(const OMPCancelDirective &s)
mlir::LogicalResult emitOMPStripeDirective(const OMPStripeDirective &s)
mlir::LogicalResult emitOMPTargetTeamsDistributeDirective(const OMPTargetTeamsDistributeDirective &s)
mlir::LogicalResult emitCompoundStmtWithoutScope(const clang::CompoundStmt &s, Address *lastValue=nullptr, AggValueSlot slot=AggValueSlot::ignored())
mlir::LogicalResult emitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &s)
mlir::LogicalResult emitOpenACCExitDataConstruct(const OpenACCExitDataConstruct &s)
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
mlir::LogicalResult emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &s)
mlir::LogicalResult emitOMPTargetSimdDirective(const OMPTargetSimdDirective &s)
mlir::LogicalResult emitOMPAssumeDirective(const OMPAssumeDirective &s)
mlir::LogicalResult emitOpenACCLoopConstruct(const OpenACCLoopConstruct &s)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
This trivial value class is used to represent the result of an expression that is evaluated.
Address getAggregateAddress() const
Return the value of the address of the aggregate.
mlir::Value getValue() const
Return the value of this scalar value.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
CaseStmt - Represent a case statement.
CompoundStmt - This represents a group of statements like { stmt stmt }.
ContinueStmt - This represents a continue.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
DoStmt - This represents a 'do/while' stmt.
This represents one expression.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
ForStmt - This represents a 'for (init;cond;inc)' stmt.
GotoStmt - This represents a direct goto.
IfStmt - This represents an if/then/else.
IndirectGotoStmt - This represents an indirect goto.
Represents the declaration of a label.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
LabelStmt - Represents a label, which has a substatement.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A (possibly-)qualified type.
The collection of all-type qualifiers we support.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SwitchStmt - This represents a 'switch' stmt.
WhileStmt - This represents a 'while' stmt.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicDynCastAllOfMatcher< Stmt, CompoundStmt > compoundStmt
Matches compound statements.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, SwitchCase > switchCase
Matches case and default statements inside switch statements.
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
U cast(CodeGen::Address addr)
@ Other
Other implicit parameter.
static bool aggValueSlotGC()
static bool loopInfoStack()
static bool emitCondLikelihoodViaExpectIntrinsic()
static bool constantFoldSwitchStatement()
static bool insertBuiltinUnpredictable()
static bool requiresCleanups()
static bool generateDebugInfo()
static bool incrementProfileCounter()
Represents a scope, including function bodies, compound statements, and the substatements of if/while...