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()),
110 assumptionValue, cir::AssumeBundleKind::None,
117 return emitStmt(
s.getSubStmt(),
true,
s.getAttrs());
125 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
126 mlir::OpBuilder::InsertPoint scopeInsPt;
127 cir::ScopeOp::create(
129 [&](mlir::OpBuilder &
b, mlir::Type &
type, mlir::Location loc) {
130 scopeInsPt =
b.saveInsertionPoint();
132 mlir::OpBuilder::InsertionGuard guard(builder);
133 builder.restoreInsertionPoint(scopeInsPt);
134 LexicalScope lexScope(*
this, scopeLoc, builder.getInsertionBlock());
145 bool useCurrentScope,
148 return mlir::success();
150 switch (
s->getStmtClass()) {
152 case Stmt::CXXCatchStmtClass:
153 case Stmt::SEHExceptStmtClass:
154 case Stmt::SEHFinallyStmtClass:
155 case Stmt::MSDependentExistsStmtClass:
156 case Stmt::UnresolvedSYCLKernelCallStmtClass:
157 llvm_unreachable(
"invalid statement class to emit generically");
158 case Stmt::BreakStmtClass:
159 case Stmt::NullStmtClass:
160 case Stmt::CompoundStmtClass:
161 case Stmt::ContinueStmtClass:
162 case Stmt::DeclStmtClass:
163 case Stmt::ReturnStmtClass:
164 llvm_unreachable(
"should have emitted these statements as simple");
166#define STMT(Type, Base)
167#define ABSTRACT_STMT(Op)
168#define EXPR(Type, Base) case Stmt::Type##Class:
169#include "clang/AST/StmtNodes.inc"
171 assert(builder.getInsertionBlock() &&
172 "expression emission must have an insertion point");
180 return mlir::success();
182 case Stmt::IfStmtClass:
184 case Stmt::SwitchStmtClass:
186 case Stmt::ForStmtClass:
188 case Stmt::WhileStmtClass:
190 case Stmt::DoStmtClass:
192 case Stmt::CXXTryStmtClass:
194 case Stmt::CXXForRangeStmtClass:
196 case Stmt::CoroutineBodyStmtClass:
198 case Stmt::IndirectGotoStmtClass:
200 case Stmt::CoreturnStmtClass:
202 case Stmt::OpenACCComputeConstructClass:
204 case Stmt::OpenACCLoopConstructClass:
206 case Stmt::OpenACCCombinedConstructClass:
208 case Stmt::OpenACCDataConstructClass:
210 case Stmt::OpenACCEnterDataConstructClass:
212 case Stmt::OpenACCExitDataConstructClass:
214 case Stmt::OpenACCHostDataConstructClass:
216 case Stmt::OpenACCWaitConstructClass:
218 case Stmt::OpenACCInitConstructClass:
220 case Stmt::OpenACCShutdownConstructClass:
222 case Stmt::OpenACCSetConstructClass:
224 case Stmt::OpenACCUpdateConstructClass:
226 case Stmt::OpenACCCacheConstructClass:
228 case Stmt::OpenACCAtomicConstructClass:
230 case Stmt::GCCAsmStmtClass:
231 case Stmt::MSAsmStmtClass:
233 case Stmt::OMPScopeDirectiveClass:
235 case Stmt::OMPErrorDirectiveClass:
237 case Stmt::OMPParallelDirectiveClass:
239 case Stmt::OMPTaskwaitDirectiveClass:
241 case Stmt::OMPTaskyieldDirectiveClass:
243 case Stmt::OMPBarrierDirectiveClass:
245 case Stmt::OMPMetaDirectiveClass:
247 case Stmt::OMPCanonicalLoopClass:
249 case Stmt::OMPSimdDirectiveClass:
251 case Stmt::OMPTileDirectiveClass:
253 case Stmt::OMPUnrollDirectiveClass:
255 case Stmt::OMPFuseDirectiveClass:
257 case Stmt::OMPForDirectiveClass:
259 case Stmt::OMPForSimdDirectiveClass:
261 case Stmt::OMPSectionsDirectiveClass:
263 case Stmt::OMPSectionDirectiveClass:
265 case Stmt::OMPSingleDirectiveClass:
267 case Stmt::OMPMasterDirectiveClass:
269 case Stmt::OMPCriticalDirectiveClass:
271 case Stmt::OMPParallelForDirectiveClass:
273 case Stmt::OMPParallelForSimdDirectiveClass:
276 case Stmt::OMPParallelMasterDirectiveClass:
278 case Stmt::OMPParallelSectionsDirectiveClass:
281 case Stmt::OMPTaskDirectiveClass:
283 case Stmt::OMPTaskgroupDirectiveClass:
285 case Stmt::OMPFlushDirectiveClass:
287 case Stmt::OMPDepobjDirectiveClass:
289 case Stmt::OMPScanDirectiveClass:
291 case Stmt::OMPOrderedDirectiveClass:
293 case Stmt::OMPAtomicDirectiveClass:
295 case Stmt::OMPTargetDirectiveClass:
297 case Stmt::OMPTeamsDirectiveClass:
299 case Stmt::OMPCancellationPointDirectiveClass:
302 case Stmt::OMPCancelDirectiveClass:
304 case Stmt::OMPTargetDataDirectiveClass:
306 case Stmt::OMPTargetEnterDataDirectiveClass:
309 case Stmt::OMPTargetExitDataDirectiveClass:
311 case Stmt::OMPTargetParallelDirectiveClass:
313 case Stmt::OMPTargetParallelForDirectiveClass:
316 case Stmt::OMPTaskLoopDirectiveClass:
318 case Stmt::OMPTaskLoopSimdDirectiveClass:
320 case Stmt::OMPMaskedTaskLoopDirectiveClass:
322 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
325 case Stmt::OMPMasterTaskLoopDirectiveClass:
327 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
330 case Stmt::OMPParallelGenericLoopDirectiveClass:
333 case Stmt::OMPParallelMaskedDirectiveClass:
335 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
338 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
341 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
344 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
347 case Stmt::OMPDistributeDirectiveClass:
349 case Stmt::OMPDistributeParallelForDirectiveClass:
352 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
355 case Stmt::OMPDistributeSimdDirectiveClass:
357 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
360 case Stmt::OMPTargetParallelForSimdDirectiveClass:
363 case Stmt::OMPTargetSimdDirectiveClass:
365 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
368 case Stmt::OMPTargetUpdateDirectiveClass:
370 case Stmt::OMPTeamsDistributeDirectiveClass:
373 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
376 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
379 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
382 case Stmt::OMPTeamsGenericLoopDirectiveClass:
385 case Stmt::OMPTargetTeamsDirectiveClass:
387 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
390 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
393 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
396 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
399 case Stmt::OMPInteropDirectiveClass:
401 case Stmt::OMPDispatchDirectiveClass:
403 case Stmt::OMPGenericLoopDirectiveClass:
405 case Stmt::OMPReverseDirectiveClass:
407 case Stmt::OMPSplitDirectiveClass:
409 case Stmt::OMPInterchangeDirectiveClass:
411 case Stmt::OMPAssumeDirectiveClass:
413 case Stmt::OMPMaskedDirectiveClass:
415 case Stmt::OMPStripeDirectiveClass:
417 case Stmt::LabelStmtClass:
418 case Stmt::AttributedStmtClass:
419 case Stmt::GotoStmtClass:
420 case Stmt::DefaultStmtClass:
421 case Stmt::CaseStmtClass:
422 case Stmt::SEHLeaveStmtClass:
423 case Stmt::SYCLKernelCallStmtClass:
424 case Stmt::CapturedStmtClass:
425 case Stmt::ObjCAtTryStmtClass:
426 case Stmt::ObjCAtThrowStmtClass:
427 case Stmt::ObjCAtSynchronizedStmtClass:
428 case Stmt::ObjCForCollectionStmtClass:
429 case Stmt::ObjCAutoreleasePoolStmtClass:
430 case Stmt::SEHTryStmtClass:
431 case Stmt::ObjCAtCatchStmtClass:
432 case Stmt::ObjCAtFinallyStmtClass:
433 case Stmt::DeferStmtClass:
434 cgm.errorNYI(
s->getSourceRange(),
435 std::string(
"emitStmt: ") +
s->getStmtClassName());
436 return mlir::failure();
439 llvm_unreachable(
"Unexpected statement class");
443 bool useCurrentScope) {
444 switch (
s->getStmtClass()) {
446 return mlir::failure();
447 case Stmt::DeclStmtClass:
449 case Stmt::CompoundStmtClass:
453 case Stmt::GotoStmtClass:
455 case Stmt::ContinueStmtClass:
459 case Stmt::NullStmtClass:
462 case Stmt::LabelStmtClass:
464 case Stmt::CaseStmtClass:
465 case Stmt::DefaultStmtClass:
471 case Stmt::BreakStmtClass:
473 case Stmt::ReturnStmtClass:
475 case Stmt::AttributedStmtClass:
479 return mlir::success();
485 return mlir::failure();
495 mlir::Location loc) {
500 unsigned numBlocks = r.getBlocks().size();
501 for (
auto &block : r.getBlocks()) {
504 if (numBlocks != 1 && block.empty() && block.hasNoPredecessors() &&
505 block.hasNoSuccessors())
506 eraseBlocks.push_back(&block);
509 !block.back().hasTrait<mlir::OpTrait::IsTerminator>()) {
510 mlir::OpBuilder::InsertionGuard guardCase(builder);
511 builder.setInsertionPointToEnd(&block);
512 builder.createYield(loc);
516 for (
auto *
b : eraseBlocks)
521 mlir::LogicalResult res = mlir::success();
524 const Stmt *constevalExecuted;
525 if (
s.isConsteval()) {
526 constevalExecuted =
s.isNegatedConsteval() ?
s.getThen() :
s.getElse();
527 if (!constevalExecuted) {
535 auto ifStmtBuilder = [&]() -> mlir::LogicalResult {
537 return emitStmt(constevalExecuted,
true);
540 if (
emitStmt(
s.getInit(),
true).failed())
541 return mlir::failure();
543 if (
s.getConditionVariable())
550 if (
s.isConstexpr()) {
555 if (
const Stmt *executed = condConstant ?
s.getThen() :
s.getElse())
559 return mlir::success();
571 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
572 cir::ScopeOp::create(builder, scopeLoc,
573 [&](mlir::OpBuilder &
b, mlir::Location loc) {
575 builder.getInsertionBlock()};
576 res = ifStmtBuilder();
583 assert(builder.getInsertionBlock() &&
"expected valid insertion point");
585 for (
const Decl *i :
s.decls())
588 return mlir::success();
592 mlir::Location loc =
getLoc(
s.getSourceRange());
593 const Expr *rv =
s.getRetValue();
596 bool createNewScope =
false;
597 if (
const auto *ewc = dyn_cast_or_null<ExprWithCleanups>(rv)) {
598 rv = ewc->getSubExpr();
599 createNewScope =
true;
602 auto handleReturnVal = [&]() {
604 s.getNRVOCandidate()->isNRVOVariable()) {
612 if (
auto nrvoFlag =
nrvoFlags[
s.getNRVOCandidate()])
613 builder.createFlagStore(loc,
true, nrvoFlag);
624 ->isReferenceType()) {
628 builder.CIRBaseBuilderTy::createStore(loc, result.
getValue(),
631 mlir::Value value =
nullptr;
636 builder.CIRBaseBuilderTy::createStore(loc, value, *
fnRetAlloca);
655 if (!createNewScope) {
671 cir::AllocaOp retAlloca =
672 mlir::cast<cir::AllocaOp>(
fnRetAlloca->getDefiningOp());
673 auto value = cir::LoadOp::create(builder, loc, retAlloca.getAllocaType(),
676 cir::ReturnOp::create(builder, loc, {value});
678 cir::ReturnOp::create(builder, loc);
684 builder.createBlock(builder.getBlock()->getParent());
685 return mlir::success();
695 cir::GotoOp::create(builder,
getLoc(
s.getSourceRange()),
696 s.getLabel()->getName());
701 builder.createBlock(builder.getBlock()->getParent());
703 return mlir::success();
710 "If you jumping to a indirect branch should be alareadye emitted");
713 builder.createBlock(builder.getBlock()->getParent());
714 return mlir::success();
719 builder.createContinue(
getLoc(
s.getKwLoc()));
722 builder.createBlock(builder.getBlock()->getParent());
724 return mlir::success();
731 mlir::Block *currBlock = builder.getBlock();
732 mlir::Block *labelBlock = currBlock;
734 if (!currBlock->empty() || currBlock->isEntryBlock()) {
736 mlir::OpBuilder::InsertionGuard guard(builder);
737 labelBlock = builder.createBlock(builder.getBlock()->getParent());
742 builder.setInsertionPointToEnd(labelBlock);
745 builder.setInsertionPointToEnd(labelBlock);
747 cgm.mapBlockAddress(cir::BlockAddrInfoAttr::get(builder.getContext(),
748 func.getSymNameAttr(),
749 label.getLabelAttr()),
754 return mlir::success();
758 builder.createBreak(
getLoc(
s.getKwLoc()));
761 builder.createBlock(builder.getBlock()->getParent());
763 return mlir::success();
769 mlir::ArrayAttr value, CaseOpKind
kind,
770 bool buildingTopLevelCase) {
773 "only case or default stmt go here");
775 mlir::LogicalResult result = mlir::success();
777 mlir::Location loc =
getLoc(
stmt->getBeginLoc());
780 SubStmtKind subStmtKind = SubStmtKind::Other;
781 const Stmt *sub =
stmt->getSubStmt();
783 mlir::OpBuilder::InsertPoint insertPoint;
784 CaseOp::create(builder, loc, value,
kind, insertPoint);
787 mlir::OpBuilder::InsertionGuard guardSwitch(builder);
788 builder.restoreInsertionPoint(insertPoint);
791 subStmtKind = SubStmtKind::Default;
792 builder.createYield(loc);
794 subStmtKind = SubStmtKind::Case;
795 builder.createYield(loc);
800 insertPoint = builder.saveInsertionPoint();
835 if (subStmtKind == SubStmtKind::Case) {
837 }
else if (subStmtKind == SubStmtKind::Default) {
839 buildingTopLevelCase);
840 }
else if (buildingTopLevelCase) {
844 builder.restoreInsertionPoint(insertPoint);
852 bool buildingTopLevelCase) {
853 cir::CaseOpKind
kind;
854 mlir::ArrayAttr value;
855 llvm::APSInt intVal =
s.getLHS()->EvaluateKnownConstInt(
getContext());
860 if (
const Expr *rhs =
s.getRHS()) {
861 llvm::APSInt endVal = rhs->EvaluateKnownConstInt(
getContext());
862 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal),
863 cir::IntAttr::get(condType, endVal)});
864 kind = cir::CaseOpKind::Range;
866 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal)});
867 kind = cir::CaseOpKind::Equal;
871 buildingTopLevelCase);
876 bool buildingTopLevelCase) {
878 cir::CaseOpKind::Default, buildingTopLevelCase);
882 bool buildingTopLevelCase) {
884 "build switch case without specifying the type of the condition");
886 if (
s.getStmtClass() == Stmt::CaseStmtClass)
888 buildingTopLevelCase);
890 if (
s.getStmtClass() == Stmt::DefaultStmtClass)
892 buildingTopLevelCase);
894 llvm_unreachable(
"expect case or default stmt");
903 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
904 mlir::LogicalResult loopRes = mlir::success();
907 if (
emitStmt(
s.getInit(),
true).failed())
908 return mlir::failure();
909 if (
emitStmt(
s.getRangeStmt(),
true).failed())
910 return mlir::failure();
911 if (
emitStmt(
s.getBeginStmt(),
true).failed())
912 return mlir::failure();
913 if (
emitStmt(
s.getEndStmt(),
true).failed())
914 return mlir::failure();
923 forOp = builder.createFor(
926 [&](mlir::OpBuilder &
b, mlir::Location loc) {
927 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
928 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
929 mlir::Value condVal = evaluateExprAsBool(s.getCond());
930 builder.createCondition(condVal);
933 [&](mlir::OpBuilder &
b, mlir::Location loc) {
937 bool useCurrentScope = true;
938 if (emitStmt(s.getLoopVarStmt(), useCurrentScope).failed())
939 loopRes = mlir::failure();
940 if (emitStmt(s.getBody(), useCurrentScope).failed())
941 loopRes = mlir::failure();
945 [&](mlir::OpBuilder &
b, mlir::Location loc) {
947 if (emitStmt(s.getInc(), true).failed())
948 loopRes = mlir::failure();
949 builder.createYield(loc);
954 mlir::LogicalResult res = mlir::success();
955 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
956 cir::ScopeOp::create(builder, scopeLoc,
957 [&](mlir::OpBuilder &
b, mlir::Location loc) {
963 builder.getInsertionBlock()};
964 res = forStmtBuilder();
971 return mlir::success();
978 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
979 mlir::LogicalResult loopRes = mlir::success();
982 if (
emitStmt(
s.getInit(),
true).failed())
983 return mlir::failure();
991 forOp = builder.createFor(
994 [&](mlir::OpBuilder &
b, mlir::Location loc) {
995 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
996 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1001 if (s.getConditionVariable())
1002 emitDecl(*s.getConditionVariable());
1006 condVal = evaluateExprAsBool(s.getCond());
1008 condVal = cir::ConstantOp::create(b, loc, builder.getTrueAttr());
1010 builder.createCondition(condVal);
1013 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1016 if (
emitStmt(
s.getBody(),
false).failed())
1017 loopRes = mlir::failure();
1021 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1023 if (
emitStmt(
s.getInc(),
true).failed())
1024 loopRes = mlir::failure();
1025 builder.createYield(loc);
1030 auto res = mlir::success();
1031 auto scopeLoc = getLoc(
s.getSourceRange());
1032 cir::ScopeOp::create(builder, scopeLoc,
1033 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1034 LexicalScope lexScope{*
this, loc,
1035 builder.getInsertionBlock()};
1036 res = forStmtBuilder();
1042 terminateStructuredRegionBody(forOp.getBody(), getLoc(
s.getEndLoc()));
1043 return mlir::success();
1047 cir::DoWhileOp doWhileOp;
1050 auto doStmtBuilder = [&]() -> mlir::LogicalResult {
1051 mlir::LogicalResult loopRes = mlir::success();
1059 doWhileOp = builder.createDoWhile(
1062 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1063 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1064 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1068 mlir::Value condVal = evaluateExprAsBool(s.getCond());
1069 builder.createCondition(condVal);
1072 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1074 if (emitStmt(s.getBody(), false).failed())
1075 loopRes = mlir::failure();
1081 mlir::LogicalResult res = mlir::success();
1082 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1083 cir::ScopeOp::create(builder, scopeLoc,
1084 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1086 builder.getInsertionBlock()};
1087 res = doStmtBuilder();
1094 return mlir::success();
1098 cir::WhileOp whileOp;
1101 auto whileStmtBuilder = [&]() -> mlir::LogicalResult {
1102 mlir::LogicalResult loopRes = mlir::success();
1110 whileOp = builder.createWhile(
1113 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1114 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1115 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1116 mlir::Value condVal;
1119 if (s.getConditionVariable())
1120 emitDecl(*s.getConditionVariable());
1124 condVal = evaluateExprAsBool(s.getCond());
1125 builder.createCondition(condVal);
1128 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1130 if (emitStmt(s.getBody(), false).failed())
1131 loopRes = mlir::failure();
1137 mlir::LogicalResult res = mlir::success();
1138 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1139 cir::ScopeOp::create(builder, scopeLoc,
1140 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1142 builder.getInsertionBlock()};
1143 res = whileStmtBuilder();
1150 return mlir::success();
1170 mlir::Block *switchBlock = builder.getBlock();
1176 builder.setInsertionPointToEnd(switchBlock);
1179 auto *
c = body.front();
1181 return mlir::failure();
1183 body = body.drop_front();
1188 mlir::Block *lastBlock = builder.getBlock();
1189 switchBlock = builder.createBlock(switchBlock->getParent());
1190 builder.setInsertionPointToEnd(lastBlock);
1191 cir::BrOp::create(builder,
getLoc(
s->getSourceRange()), switchBlock);
1194 for (
auto *
c : body) {
1196 builder.setInsertionPointToEnd(switchBlock);
1202 return mlir::failure();
1209 return mlir::failure();
1212 return mlir::success();
1223 auto switchStmtBuilder = [&]() -> mlir::LogicalResult {
1225 if (
emitStmt(
s.getInit(),
true).failed())
1226 return mlir::failure();
1228 if (
s.getConditionVariable())
1229 emitDecl(*
s.getConditionVariable(),
true);
1239 mlir::LogicalResult res = mlir::success();
1240 swop = SwitchOp::create(
1241 builder,
getLoc(
s.getBeginLoc()), condV,
1243 [&](mlir::OpBuilder &
b, mlir::Location loc, mlir::OperationState &os) {
1244 curLexScope->setAsSwitch();
1246 condTypeStack.push_back(condV.getType());
1248 res = emitSwitchBody(s.getBody());
1250 condTypeStack.pop_back();
1257 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1258 mlir::LogicalResult res = mlir::success();
1259 cir::ScopeOp::create(builder, scopeLoc,
1260 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1262 builder.getInsertionBlock()};
1263 res = switchStmtBuilder();
1267 swop.collectCases(cases);
1268 for (
auto caseOp : cases)
1272 swop.setAllEnumCasesCovered(
s.isAllEnumCasesCovered());
1293 cgm.errorNYI(loc,
"emitReturnOfRValue: complex return type");
1302 cir::AllocaOp retAlloca =
1303 mlir::cast<cir::AllocaOp>(
fnRetAlloca->getDefiningOp());
1304 auto value = cir::LoadOp::create(builder, loc, retAlloca.getAllocaType(),
1307 cir::ReturnOp::create(builder, loc, {value});
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
Attr - This represents one attribute.
Represents an attribute applied to a statement.
BreakStmt - This represents a break.
mlir::Value getPointer() const
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 emitCXXTryStmt(const clang::CXXTryStmt &s, cxxTryBodyEmitter &bodyCallback)
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)
mlir::LogicalResult emitOMPSplitDirective(const OMPSplitDirective &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 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)
void terminateStructuredRegionBody(mlir::Region &r, mlir::Location loc)
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.
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 generateDebugInfo()
static bool loopSpecificCleanupHandling()
static bool incrementProfileCounter()
Represents a scope, including function bodies, compound statements, and the substatements of if/while...