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();
93 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
94 mlir::OpBuilder::InsertPoint scopeInsPt;
97 [&](mlir::OpBuilder &
b, mlir::Type &
type, mlir::Location loc) {
98 scopeInsPt =
b.saveInsertionPoint();
100 mlir::OpBuilder::InsertionGuard guard(builder);
101 builder.restoreInsertionPoint(scopeInsPt);
102 LexicalScope lexScope(*
this, scopeLoc, builder.getInsertionBlock());
113 bool useCurrentScope,
116 return mlir::success();
118 switch (
s->getStmtClass()) {
120 case Stmt::CXXCatchStmtClass:
121 case Stmt::SEHExceptStmtClass:
122 case Stmt::SEHFinallyStmtClass:
123 case Stmt::MSDependentExistsStmtClass:
124 llvm_unreachable(
"invalid statement class to emit generically");
125 case Stmt::BreakStmtClass:
126 case Stmt::NullStmtClass:
127 case Stmt::CompoundStmtClass:
128 case Stmt::ContinueStmtClass:
129 case Stmt::DeclStmtClass:
130 case Stmt::ReturnStmtClass:
131 llvm_unreachable(
"should have emitted these statements as simple");
133#define STMT(Type, Base)
134#define ABSTRACT_STMT(Op)
135#define EXPR(Type, Base) case Stmt::Type##Class:
136#include "clang/AST/StmtNodes.inc"
138 assert(builder.getInsertionBlock() &&
139 "expression emission must have an insertion point");
147 return mlir::success();
149 case Stmt::IfStmtClass:
151 case Stmt::SwitchStmtClass:
153 case Stmt::ForStmtClass:
155 case Stmt::WhileStmtClass:
157 case Stmt::DoStmtClass:
159 case Stmt::CXXTryStmtClass:
161 case Stmt::CXXForRangeStmtClass:
163 case Stmt::CoroutineBodyStmtClass:
165 case Stmt::IndirectGotoStmtClass:
167 case Stmt::CoreturnStmtClass:
169 case Stmt::OpenACCComputeConstructClass:
171 case Stmt::OpenACCLoopConstructClass:
173 case Stmt::OpenACCCombinedConstructClass:
175 case Stmt::OpenACCDataConstructClass:
177 case Stmt::OpenACCEnterDataConstructClass:
179 case Stmt::OpenACCExitDataConstructClass:
181 case Stmt::OpenACCHostDataConstructClass:
183 case Stmt::OpenACCWaitConstructClass:
185 case Stmt::OpenACCInitConstructClass:
187 case Stmt::OpenACCShutdownConstructClass:
189 case Stmt::OpenACCSetConstructClass:
191 case Stmt::OpenACCUpdateConstructClass:
193 case Stmt::OpenACCCacheConstructClass:
195 case Stmt::OpenACCAtomicConstructClass:
197 case Stmt::GCCAsmStmtClass:
198 case Stmt::MSAsmStmtClass:
200 case Stmt::OMPScopeDirectiveClass:
202 case Stmt::OMPErrorDirectiveClass:
204 case Stmt::OMPParallelDirectiveClass:
206 case Stmt::OMPTaskwaitDirectiveClass:
208 case Stmt::OMPTaskyieldDirectiveClass:
210 case Stmt::OMPBarrierDirectiveClass:
212 case Stmt::OMPMetaDirectiveClass:
214 case Stmt::OMPCanonicalLoopClass:
216 case Stmt::OMPSimdDirectiveClass:
218 case Stmt::OMPTileDirectiveClass:
220 case Stmt::OMPUnrollDirectiveClass:
222 case Stmt::OMPFuseDirectiveClass:
224 case Stmt::OMPForDirectiveClass:
226 case Stmt::OMPForSimdDirectiveClass:
228 case Stmt::OMPSectionsDirectiveClass:
230 case Stmt::OMPSectionDirectiveClass:
232 case Stmt::OMPSingleDirectiveClass:
234 case Stmt::OMPMasterDirectiveClass:
236 case Stmt::OMPCriticalDirectiveClass:
238 case Stmt::OMPParallelForDirectiveClass:
240 case Stmt::OMPParallelForSimdDirectiveClass:
243 case Stmt::OMPParallelMasterDirectiveClass:
245 case Stmt::OMPParallelSectionsDirectiveClass:
248 case Stmt::OMPTaskDirectiveClass:
250 case Stmt::OMPTaskgroupDirectiveClass:
252 case Stmt::OMPFlushDirectiveClass:
254 case Stmt::OMPDepobjDirectiveClass:
256 case Stmt::OMPScanDirectiveClass:
258 case Stmt::OMPOrderedDirectiveClass:
260 case Stmt::OMPAtomicDirectiveClass:
262 case Stmt::OMPTargetDirectiveClass:
264 case Stmt::OMPTeamsDirectiveClass:
266 case Stmt::OMPCancellationPointDirectiveClass:
269 case Stmt::OMPCancelDirectiveClass:
271 case Stmt::OMPTargetDataDirectiveClass:
273 case Stmt::OMPTargetEnterDataDirectiveClass:
276 case Stmt::OMPTargetExitDataDirectiveClass:
278 case Stmt::OMPTargetParallelDirectiveClass:
280 case Stmt::OMPTargetParallelForDirectiveClass:
283 case Stmt::OMPTaskLoopDirectiveClass:
285 case Stmt::OMPTaskLoopSimdDirectiveClass:
287 case Stmt::OMPMaskedTaskLoopDirectiveClass:
289 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
292 case Stmt::OMPMasterTaskLoopDirectiveClass:
294 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
297 case Stmt::OMPParallelGenericLoopDirectiveClass:
300 case Stmt::OMPParallelMaskedDirectiveClass:
302 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
305 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
308 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
311 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
314 case Stmt::OMPDistributeDirectiveClass:
316 case Stmt::OMPDistributeParallelForDirectiveClass:
319 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
322 case Stmt::OMPDistributeSimdDirectiveClass:
324 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
327 case Stmt::OMPTargetParallelForSimdDirectiveClass:
330 case Stmt::OMPTargetSimdDirectiveClass:
332 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
335 case Stmt::OMPTargetUpdateDirectiveClass:
337 case Stmt::OMPTeamsDistributeDirectiveClass:
340 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
343 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
346 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
349 case Stmt::OMPTeamsGenericLoopDirectiveClass:
352 case Stmt::OMPTargetTeamsDirectiveClass:
354 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
357 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
360 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
363 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
366 case Stmt::OMPInteropDirectiveClass:
368 case Stmt::OMPDispatchDirectiveClass:
370 case Stmt::OMPGenericLoopDirectiveClass:
372 case Stmt::OMPReverseDirectiveClass:
374 case Stmt::OMPInterchangeDirectiveClass:
376 case Stmt::OMPAssumeDirectiveClass:
378 case Stmt::OMPMaskedDirectiveClass:
380 case Stmt::OMPStripeDirectiveClass:
382 case Stmt::LabelStmtClass:
383 case Stmt::AttributedStmtClass:
384 case Stmt::GotoStmtClass:
385 case Stmt::DefaultStmtClass:
386 case Stmt::CaseStmtClass:
387 case Stmt::SEHLeaveStmtClass:
388 case Stmt::SYCLKernelCallStmtClass:
389 case Stmt::CapturedStmtClass:
390 case Stmt::ObjCAtTryStmtClass:
391 case Stmt::ObjCAtThrowStmtClass:
392 case Stmt::ObjCAtSynchronizedStmtClass:
393 case Stmt::ObjCForCollectionStmtClass:
394 case Stmt::ObjCAutoreleasePoolStmtClass:
395 case Stmt::SEHTryStmtClass:
396 case Stmt::ObjCAtCatchStmtClass:
397 case Stmt::ObjCAtFinallyStmtClass:
398 case Stmt::DeferStmtClass:
399 cgm.errorNYI(
s->getSourceRange(),
400 std::string(
"emitStmt: ") +
s->getStmtClassName());
401 return mlir::failure();
404 llvm_unreachable(
"Unexpected statement class");
408 bool useCurrentScope) {
409 switch (
s->getStmtClass()) {
411 return mlir::failure();
412 case Stmt::DeclStmtClass:
414 case Stmt::CompoundStmtClass:
418 case Stmt::GotoStmtClass:
420 case Stmt::ContinueStmtClass:
424 case Stmt::NullStmtClass:
427 case Stmt::LabelStmtClass:
429 case Stmt::CaseStmtClass:
430 case Stmt::DefaultStmtClass:
436 case Stmt::BreakStmtClass:
438 case Stmt::ReturnStmtClass:
442 return mlir::success();
448 return mlir::failure();
458 mlir::Location loc) {
463 unsigned numBlocks = r.getBlocks().size();
464 for (
auto &block : r.getBlocks()) {
467 if (numBlocks != 1 && block.empty() && block.hasNoPredecessors() &&
468 block.hasNoSuccessors())
469 eraseBlocks.push_back(&block);
472 !block.back().hasTrait<mlir::OpTrait::IsTerminator>()) {
473 mlir::OpBuilder::InsertionGuard guardCase(builder);
474 builder.setInsertionPointToEnd(&block);
479 for (
auto *
b : eraseBlocks)
484 mlir::LogicalResult res = mlir::success();
487 const Stmt *constevalExecuted;
488 if (
s.isConsteval()) {
489 constevalExecuted =
s.isNegatedConsteval() ?
s.getThen() :
s.getElse();
490 if (!constevalExecuted) {
498 auto ifStmtBuilder = [&]() -> mlir::LogicalResult {
500 return emitStmt(constevalExecuted,
true);
503 if (
emitStmt(
s.getInit(),
true).failed())
504 return mlir::failure();
506 if (
s.getConditionVariable())
513 if (
s.isConstexpr()) {
518 if (
const Stmt *executed = condConstant ?
s.getThen() :
s.getElse())
522 return mlir::success();
534 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
535 cir::ScopeOp::create(builder, scopeLoc,
536 [&](mlir::OpBuilder &
b, mlir::Location loc) {
538 builder.getInsertionBlock()};
539 res = ifStmtBuilder();
546 assert(builder.getInsertionBlock() &&
"expected valid insertion point");
548 for (
const Decl *i :
s.decls())
551 return mlir::success();
555 mlir::Location loc =
getLoc(
s.getSourceRange());
556 const Expr *rv =
s.getRetValue();
559 bool createNewScope =
false;
560 if (
const auto *ewc = dyn_cast_or_null<ExprWithCleanups>(rv)) {
561 rv = ewc->getSubExpr();
562 createNewScope =
true;
565 auto handleReturnVal = [&]() {
567 s.getNRVOCandidate()->isNRVOVariable()) {
575 if (
auto nrvoFlag =
nrvoFlags[
s.getNRVOCandidate()])
576 builder.createFlagStore(loc,
true, nrvoFlag);
587 ->isReferenceType()) {
591 builder.CIRBaseBuilderTy::createStore(loc, result.
getValue(),
594 mlir::Value value =
nullptr;
599 builder.CIRBaseBuilderTy::createStore(loc, value, *
fnRetAlloca);
618 if (!createNewScope) {
621 mlir::Location scopeLoc =
626 mlir::OpBuilder::InsertPoint scopeBody;
627 cir::ScopeOp::create(builder, scopeLoc,
628 [&](mlir::OpBuilder &
b, mlir::Location loc) {
629 scopeBody =
b.saveInsertionPoint();
632 mlir::OpBuilder::InsertionGuard guard(builder);
633 builder.restoreInsertionPoint(scopeBody);
635 builder.getInsertionBlock()};
646 auto *retBlock =
curLexScope->getOrCreateRetBlock(*
this, loc);
650 builder.createBlock(builder.getBlock()->getParent());
652 return mlir::success();
662 cir::GotoOp::create(builder,
getLoc(
s.getSourceRange()),
663 s.getLabel()->getName());
668 builder.createBlock(builder.getBlock()->getParent());
670 return mlir::success();
677 "If you jumping to a indirect branch should be alareadye emitted");
680 builder.createBlock(builder.getBlock()->getParent());
681 return mlir::success();
686 builder.createContinue(
getLoc(
s.getKwLoc()));
689 builder.createBlock(builder.getBlock()->getParent());
691 return mlir::success();
698 mlir::Block *currBlock = builder.getBlock();
699 mlir::Block *labelBlock = currBlock;
701 if (!currBlock->empty() || currBlock->isEntryBlock()) {
703 mlir::OpBuilder::InsertionGuard guard(builder);
704 labelBlock = builder.createBlock(builder.getBlock()->getParent());
709 builder.setInsertionPointToEnd(labelBlock);
712 builder.setInsertionPointToEnd(labelBlock);
714 cgm.mapBlockAddress(cir::BlockAddrInfoAttr::get(builder.getContext(),
715 func.getSymNameAttr(),
716 label.getLabelAttr()),
722 return mlir::success();
726 builder.createBreak(
getLoc(
s.getKwLoc()));
729 builder.createBlock(builder.getBlock()->getParent());
731 return mlir::success();
737 mlir::ArrayAttr value, CaseOpKind kind,
738 bool buildingTopLevelCase) {
741 "only case or default stmt go here");
743 mlir::LogicalResult result = mlir::success();
745 mlir::Location loc =
getLoc(
stmt->getBeginLoc());
748 SubStmtKind subStmtKind = SubStmtKind::Other;
749 const Stmt *sub =
stmt->getSubStmt();
751 mlir::OpBuilder::InsertPoint insertPoint;
752 CaseOp::create(builder, loc, value, kind, insertPoint);
755 mlir::OpBuilder::InsertionGuard guardSwitch(builder);
756 builder.restoreInsertionPoint(insertPoint);
759 subStmtKind = SubStmtKind::Default;
760 builder.createYield(loc);
762 subStmtKind = SubStmtKind::Case;
763 builder.createYield(loc);
768 insertPoint = builder.saveInsertionPoint();
803 if (subStmtKind == SubStmtKind::Case) {
805 }
else if (subStmtKind == SubStmtKind::Default) {
807 buildingTopLevelCase);
808 }
else if (buildingTopLevelCase) {
812 builder.restoreInsertionPoint(insertPoint);
820 bool buildingTopLevelCase) {
821 cir::CaseOpKind kind;
822 mlir::ArrayAttr value;
823 llvm::APSInt intVal =
s.getLHS()->EvaluateKnownConstInt(
getContext());
828 if (
const Expr *rhs =
s.getRHS()) {
829 llvm::APSInt endVal = rhs->EvaluateKnownConstInt(
getContext());
830 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal),
831 cir::IntAttr::get(condType, endVal)});
832 kind = cir::CaseOpKind::Range;
834 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal)});
835 kind = cir::CaseOpKind::Equal;
839 buildingTopLevelCase);
844 bool buildingTopLevelCase) {
846 cir::CaseOpKind::Default, buildingTopLevelCase);
850 bool buildingTopLevelCase) {
852 "build switch case without specifying the type of the condition");
854 if (
s.getStmtClass() == Stmt::CaseStmtClass)
856 buildingTopLevelCase);
858 if (
s.getStmtClass() == Stmt::DefaultStmtClass)
860 buildingTopLevelCase);
862 llvm_unreachable(
"expect case or default stmt");
871 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
872 mlir::LogicalResult loopRes = mlir::success();
875 if (
emitStmt(
s.getInit(),
true).failed())
876 return mlir::failure();
877 if (
emitStmt(
s.getRangeStmt(),
true).failed())
878 return mlir::failure();
879 if (
emitStmt(
s.getBeginStmt(),
true).failed())
880 return mlir::failure();
881 if (
emitStmt(
s.getEndStmt(),
true).failed())
882 return mlir::failure();
891 forOp = builder.createFor(
894 [&](mlir::OpBuilder &
b, mlir::Location loc) {
895 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
896 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
897 mlir::Value condVal = evaluateExprAsBool(s.getCond());
898 builder.createCondition(condVal);
901 [&](mlir::OpBuilder &
b, mlir::Location loc) {
905 bool useCurrentScope = true;
906 if (emitStmt(s.getLoopVarStmt(), useCurrentScope).failed())
907 loopRes = mlir::failure();
908 if (emitStmt(s.getBody(), useCurrentScope).failed())
909 loopRes = mlir::failure();
913 [&](mlir::OpBuilder &
b, mlir::Location loc) {
915 if (emitStmt(s.getInc(), true).failed())
916 loopRes = mlir::failure();
917 builder.createYield(loc);
922 mlir::LogicalResult res = mlir::success();
923 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
924 cir::ScopeOp::create(builder, scopeLoc,
925 [&](mlir::OpBuilder &
b, mlir::Location loc) {
931 builder.getInsertionBlock()};
932 res = forStmtBuilder();
939 return mlir::success();
946 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
947 mlir::LogicalResult loopRes = mlir::success();
950 if (
emitStmt(
s.getInit(),
true).failed())
951 return mlir::failure();
959 forOp = builder.createFor(
962 [&](mlir::OpBuilder &
b, mlir::Location loc) {
963 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
964 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
969 if (s.getConditionVariable())
970 emitDecl(*s.getConditionVariable());
974 condVal = evaluateExprAsBool(s.getCond());
976 condVal = cir::ConstantOp::create(b, loc, builder.getTrueAttr());
978 builder.createCondition(condVal);
981 [&](mlir::OpBuilder &
b, mlir::Location loc) {
984 if (
emitStmt(
s.getBody(),
false).failed())
985 loopRes = mlir::failure();
989 [&](mlir::OpBuilder &
b, mlir::Location loc) {
992 loopRes = mlir::failure();
993 builder.createYield(loc);
998 auto res = mlir::success();
999 auto scopeLoc = getLoc(
s.getSourceRange());
1000 cir::ScopeOp::create(builder, scopeLoc,
1001 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1002 LexicalScope lexScope{*
this, loc,
1003 builder.getInsertionBlock()};
1004 res = forStmtBuilder();
1011 return mlir::success();
1015 cir::DoWhileOp doWhileOp;
1018 auto doStmtBuilder = [&]() -> mlir::LogicalResult {
1019 mlir::LogicalResult loopRes = mlir::success();
1027 doWhileOp = builder.createDoWhile(
1030 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1031 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1032 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1036 mlir::Value condVal = evaluateExprAsBool(s.getCond());
1037 builder.createCondition(condVal);
1040 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1042 if (emitStmt(s.getBody(), false).failed())
1043 loopRes = mlir::failure();
1049 mlir::LogicalResult res = mlir::success();
1050 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1051 cir::ScopeOp::create(builder, scopeLoc,
1052 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1054 builder.getInsertionBlock()};
1055 res = doStmtBuilder();
1062 return mlir::success();
1066 cir::WhileOp whileOp;
1069 auto whileStmtBuilder = [&]() -> mlir::LogicalResult {
1070 mlir::LogicalResult loopRes = mlir::success();
1078 whileOp = builder.createWhile(
1081 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1082 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1083 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1084 mlir::Value condVal;
1087 if (s.getConditionVariable())
1088 emitDecl(*s.getConditionVariable());
1092 condVal = evaluateExprAsBool(s.getCond());
1093 builder.createCondition(condVal);
1096 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1098 if (emitStmt(s.getBody(), false).failed())
1099 loopRes = mlir::failure();
1105 mlir::LogicalResult res = mlir::success();
1106 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1107 cir::ScopeOp::create(builder, scopeLoc,
1108 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1110 builder.getInsertionBlock()};
1111 res = whileStmtBuilder();
1118 return mlir::success();
1136 mlir::Block *swtichBlock = builder.getBlock();
1139 builder.setInsertionPointToEnd(swtichBlock);
1145 return mlir::failure();
1152 return mlir::failure();
1155 return mlir::success();
1166 auto switchStmtBuilder = [&]() -> mlir::LogicalResult {
1168 if (
emitStmt(
s.getInit(),
true).failed())
1169 return mlir::failure();
1171 if (
s.getConditionVariable())
1172 emitDecl(*
s.getConditionVariable(),
true);
1182 mlir::LogicalResult res = mlir::success();
1183 swop = SwitchOp::create(
1184 builder,
getLoc(
s.getBeginLoc()), condV,
1186 [&](mlir::OpBuilder &
b, mlir::Location loc, mlir::OperationState &os) {
1187 curLexScope->setAsSwitch();
1189 condTypeStack.push_back(condV.getType());
1191 res = emitSwitchBody(s.getBody());
1193 condTypeStack.pop_back();
1200 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1201 mlir::LogicalResult res = mlir::success();
1202 cir::ScopeOp::create(builder, scopeLoc,
1203 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1205 builder.getInsertionBlock()};
1206 res = switchStmtBuilder();
1210 swop.collectCases(cases);
1211 for (
auto caseOp : cases)
1212 terminateBody(builder, caseOp.getCaseRegion(), caseOp.getLoc());
1215 swop.setAllEnumCasesCovered(
s.isAllEnumCasesCovered());
1229 cgm.errorNYI(loc,
"emitReturnOfRValue: complex return type");
1231 mlir::Block *retBlock =
curLexScope->getOrCreateRetBlock(*
this, loc);
1233 cir::BrOp::create(builder, loc, retBlock);
1235 cgm.errorNYI(loc,
"return of r-value with cleanup stack");
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.
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.
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()
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::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.
JumpDest returnBlock(mlir::Block *retBlock)
Unified return block.
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)
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
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 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.
cir::BrOp emitBranchThroughCleanup(mlir::Location loc, JumpDest dest)
Build a unconditional branch to the lexical scope cleanup block or with the labeled blocked if alread...
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)
EHScopeStack::stable_iterator currentCleanupStackDepth
mlir::LogicalResult emitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &s)
LexicalScope * curLexScope
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.
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)
const FunctionProtoType * T
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 ehstackBranches()
static bool emitBranchThroughCleanup()
static bool requiresCleanups()
static bool generateDebugInfo()
static bool incrementProfileCounter()
Represents a scope, including function bodies, compound statements, and the substatements of if/while...