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::OpenACCComputeConstructClass:
169 case Stmt::OpenACCLoopConstructClass:
171 case Stmt::OpenACCCombinedConstructClass:
173 case Stmt::OpenACCDataConstructClass:
175 case Stmt::OpenACCEnterDataConstructClass:
177 case Stmt::OpenACCExitDataConstructClass:
179 case Stmt::OpenACCHostDataConstructClass:
181 case Stmt::OpenACCWaitConstructClass:
183 case Stmt::OpenACCInitConstructClass:
185 case Stmt::OpenACCShutdownConstructClass:
187 case Stmt::OpenACCSetConstructClass:
189 case Stmt::OpenACCUpdateConstructClass:
191 case Stmt::OpenACCCacheConstructClass:
193 case Stmt::OpenACCAtomicConstructClass:
195 case Stmt::GCCAsmStmtClass:
196 case Stmt::MSAsmStmtClass:
198 case Stmt::OMPScopeDirectiveClass:
200 case Stmt::OMPErrorDirectiveClass:
202 case Stmt::OMPParallelDirectiveClass:
204 case Stmt::OMPTaskwaitDirectiveClass:
206 case Stmt::OMPTaskyieldDirectiveClass:
208 case Stmt::OMPBarrierDirectiveClass:
210 case Stmt::OMPMetaDirectiveClass:
212 case Stmt::OMPCanonicalLoopClass:
214 case Stmt::OMPSimdDirectiveClass:
216 case Stmt::OMPTileDirectiveClass:
218 case Stmt::OMPUnrollDirectiveClass:
220 case Stmt::OMPFuseDirectiveClass:
222 case Stmt::OMPForDirectiveClass:
224 case Stmt::OMPForSimdDirectiveClass:
226 case Stmt::OMPSectionsDirectiveClass:
228 case Stmt::OMPSectionDirectiveClass:
230 case Stmt::OMPSingleDirectiveClass:
232 case Stmt::OMPMasterDirectiveClass:
234 case Stmt::OMPCriticalDirectiveClass:
236 case Stmt::OMPParallelForDirectiveClass:
238 case Stmt::OMPParallelForSimdDirectiveClass:
241 case Stmt::OMPParallelMasterDirectiveClass:
243 case Stmt::OMPParallelSectionsDirectiveClass:
246 case Stmt::OMPTaskDirectiveClass:
248 case Stmt::OMPTaskgroupDirectiveClass:
250 case Stmt::OMPFlushDirectiveClass:
252 case Stmt::OMPDepobjDirectiveClass:
254 case Stmt::OMPScanDirectiveClass:
256 case Stmt::OMPOrderedDirectiveClass:
258 case Stmt::OMPAtomicDirectiveClass:
260 case Stmt::OMPTargetDirectiveClass:
262 case Stmt::OMPTeamsDirectiveClass:
264 case Stmt::OMPCancellationPointDirectiveClass:
267 case Stmt::OMPCancelDirectiveClass:
269 case Stmt::OMPTargetDataDirectiveClass:
271 case Stmt::OMPTargetEnterDataDirectiveClass:
274 case Stmt::OMPTargetExitDataDirectiveClass:
276 case Stmt::OMPTargetParallelDirectiveClass:
278 case Stmt::OMPTargetParallelForDirectiveClass:
281 case Stmt::OMPTaskLoopDirectiveClass:
283 case Stmt::OMPTaskLoopSimdDirectiveClass:
285 case Stmt::OMPMaskedTaskLoopDirectiveClass:
287 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
290 case Stmt::OMPMasterTaskLoopDirectiveClass:
292 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
295 case Stmt::OMPParallelGenericLoopDirectiveClass:
298 case Stmt::OMPParallelMaskedDirectiveClass:
300 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
303 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
306 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
309 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
312 case Stmt::OMPDistributeDirectiveClass:
314 case Stmt::OMPDistributeParallelForDirectiveClass:
317 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
320 case Stmt::OMPDistributeSimdDirectiveClass:
322 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
325 case Stmt::OMPTargetParallelForSimdDirectiveClass:
328 case Stmt::OMPTargetSimdDirectiveClass:
330 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
333 case Stmt::OMPTargetUpdateDirectiveClass:
335 case Stmt::OMPTeamsDistributeDirectiveClass:
338 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
341 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
344 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
347 case Stmt::OMPTeamsGenericLoopDirectiveClass:
350 case Stmt::OMPTargetTeamsDirectiveClass:
352 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
355 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
358 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
361 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
364 case Stmt::OMPInteropDirectiveClass:
366 case Stmt::OMPDispatchDirectiveClass:
368 case Stmt::OMPGenericLoopDirectiveClass:
370 case Stmt::OMPReverseDirectiveClass:
372 case Stmt::OMPInterchangeDirectiveClass:
374 case Stmt::OMPAssumeDirectiveClass:
376 case Stmt::OMPMaskedDirectiveClass:
378 case Stmt::OMPStripeDirectiveClass:
380 case Stmt::LabelStmtClass:
381 case Stmt::AttributedStmtClass:
382 case Stmt::GotoStmtClass:
383 case Stmt::DefaultStmtClass:
384 case Stmt::CaseStmtClass:
385 case Stmt::SEHLeaveStmtClass:
386 case Stmt::SYCLKernelCallStmtClass:
387 case Stmt::CoreturnStmtClass:
388 case Stmt::CapturedStmtClass:
389 case Stmt::ObjCAtTryStmtClass:
390 case Stmt::ObjCAtThrowStmtClass:
391 case Stmt::ObjCAtSynchronizedStmtClass:
392 case Stmt::ObjCForCollectionStmtClass:
393 case Stmt::ObjCAutoreleasePoolStmtClass:
394 case Stmt::SEHTryStmtClass:
395 case Stmt::ObjCAtCatchStmtClass:
396 case Stmt::ObjCAtFinallyStmtClass:
397 case Stmt::DeferStmtClass:
398 cgm.errorNYI(
s->getSourceRange(),
399 std::string(
"emitStmt: ") +
s->getStmtClassName());
400 return mlir::failure();
403 llvm_unreachable(
"Unexpected statement class");
407 bool useCurrentScope) {
408 switch (
s->getStmtClass()) {
410 return mlir::failure();
411 case Stmt::DeclStmtClass:
413 case Stmt::CompoundStmtClass:
417 case Stmt::GotoStmtClass:
419 case Stmt::ContinueStmtClass:
423 case Stmt::NullStmtClass:
426 case Stmt::LabelStmtClass:
428 case Stmt::CaseStmtClass:
429 case Stmt::DefaultStmtClass:
435 case Stmt::BreakStmtClass:
437 case Stmt::ReturnStmtClass:
441 return mlir::success();
447 return mlir::failure();
457 mlir::Location loc) {
462 unsigned numBlocks = r.getBlocks().size();
463 for (
auto &block : r.getBlocks()) {
466 if (numBlocks != 1 && block.empty() && block.hasNoPredecessors() &&
467 block.hasNoSuccessors())
468 eraseBlocks.push_back(&block);
471 !block.back().hasTrait<mlir::OpTrait::IsTerminator>()) {
472 mlir::OpBuilder::InsertionGuard guardCase(builder);
473 builder.setInsertionPointToEnd(&block);
478 for (
auto *
b : eraseBlocks)
483 mlir::LogicalResult res = mlir::success();
486 const Stmt *constevalExecuted;
487 if (
s.isConsteval()) {
488 constevalExecuted =
s.isNegatedConsteval() ?
s.getThen() :
s.getElse();
489 if (!constevalExecuted) {
497 auto ifStmtBuilder = [&]() -> mlir::LogicalResult {
499 return emitStmt(constevalExecuted,
true);
502 if (
emitStmt(
s.getInit(),
true).failed())
503 return mlir::failure();
505 if (
s.getConditionVariable())
512 if (
s.isConstexpr()) {
517 if (
const Stmt *executed = condConstant ?
s.getThen() :
s.getElse())
521 return mlir::success();
533 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
534 cir::ScopeOp::create(builder, scopeLoc,
535 [&](mlir::OpBuilder &
b, mlir::Location loc) {
537 builder.getInsertionBlock()};
538 res = ifStmtBuilder();
545 assert(builder.getInsertionBlock() &&
"expected valid insertion point");
547 for (
const Decl *i :
s.decls())
550 return mlir::success();
554 mlir::Location loc =
getLoc(
s.getSourceRange());
555 const Expr *rv =
s.getRetValue();
558 bool createNewScope =
false;
559 if (
const auto *ewc = dyn_cast_or_null<ExprWithCleanups>(rv)) {
560 rv = ewc->getSubExpr();
561 createNewScope =
true;
564 auto handleReturnVal = [&]() {
566 s.getNRVOCandidate()->isNRVOVariable()) {
574 if (
auto nrvoFlag =
nrvoFlags[
s.getNRVOCandidate()])
575 builder.createFlagStore(loc,
true, nrvoFlag);
586 ->isReferenceType()) {
590 builder.CIRBaseBuilderTy::createStore(loc, result.
getValue(),
593 mlir::Value value =
nullptr;
598 builder.CIRBaseBuilderTy::createStore(loc, value, *
fnRetAlloca);
617 if (!createNewScope) {
620 mlir::Location scopeLoc =
625 mlir::OpBuilder::InsertPoint scopeBody;
626 cir::ScopeOp::create(builder, scopeLoc,
627 [&](mlir::OpBuilder &
b, mlir::Location loc) {
628 scopeBody =
b.saveInsertionPoint();
631 mlir::OpBuilder::InsertionGuard guard(builder);
632 builder.restoreInsertionPoint(scopeBody);
634 builder.getInsertionBlock()};
645 auto *retBlock =
curLexScope->getOrCreateRetBlock(*
this, loc);
649 builder.createBlock(builder.getBlock()->getParent());
651 return mlir::success();
661 cir::GotoOp::create(builder,
getLoc(
s.getSourceRange()),
662 s.getLabel()->getName());
667 builder.createBlock(builder.getBlock()->getParent());
669 return mlir::success();
676 "If you jumping to a indirect branch should be alareadye emitted");
679 builder.createBlock(builder.getBlock()->getParent());
680 return mlir::success();
685 builder.createContinue(
getLoc(
s.getKwLoc()));
688 builder.createBlock(builder.getBlock()->getParent());
690 return mlir::success();
697 mlir::Block *currBlock = builder.getBlock();
698 mlir::Block *labelBlock = currBlock;
700 if (!currBlock->empty() || currBlock->isEntryBlock()) {
702 mlir::OpBuilder::InsertionGuard guard(builder);
703 labelBlock = builder.createBlock(builder.getBlock()->getParent());
708 builder.setInsertionPointToEnd(labelBlock);
711 builder.setInsertionPointToEnd(labelBlock);
713 cgm.mapBlockAddress(cir::BlockAddrInfoAttr::get(builder.getContext(),
714 func.getSymNameAttr(),
715 label.getLabelAttr()),
721 return mlir::success();
725 builder.createBreak(
getLoc(
s.getKwLoc()));
728 builder.createBlock(builder.getBlock()->getParent());
730 return mlir::success();
736 mlir::ArrayAttr value, CaseOpKind kind,
737 bool buildingTopLevelCase) {
740 "only case or default stmt go here");
742 mlir::LogicalResult result = mlir::success();
744 mlir::Location loc =
getLoc(
stmt->getBeginLoc());
747 SubStmtKind subStmtKind = SubStmtKind::Other;
748 const Stmt *sub =
stmt->getSubStmt();
750 mlir::OpBuilder::InsertPoint insertPoint;
751 CaseOp::create(builder, loc, value, kind, insertPoint);
754 mlir::OpBuilder::InsertionGuard guardSwitch(builder);
755 builder.restoreInsertionPoint(insertPoint);
758 subStmtKind = SubStmtKind::Default;
759 builder.createYield(loc);
761 subStmtKind = SubStmtKind::Case;
762 builder.createYield(loc);
767 insertPoint = builder.saveInsertionPoint();
802 if (subStmtKind == SubStmtKind::Case) {
804 }
else if (subStmtKind == SubStmtKind::Default) {
806 buildingTopLevelCase);
807 }
else if (buildingTopLevelCase) {
811 builder.restoreInsertionPoint(insertPoint);
819 bool buildingTopLevelCase) {
820 cir::CaseOpKind kind;
821 mlir::ArrayAttr value;
822 llvm::APSInt intVal =
s.getLHS()->EvaluateKnownConstInt(
getContext());
827 if (
const Expr *rhs =
s.getRHS()) {
828 llvm::APSInt endVal = rhs->EvaluateKnownConstInt(
getContext());
829 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal),
830 cir::IntAttr::get(condType, endVal)});
831 kind = cir::CaseOpKind::Range;
833 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal)});
834 kind = cir::CaseOpKind::Equal;
838 buildingTopLevelCase);
843 bool buildingTopLevelCase) {
845 cir::CaseOpKind::Default, buildingTopLevelCase);
849 bool buildingTopLevelCase) {
851 "build switch case without specifying the type of the condition");
853 if (
s.getStmtClass() == Stmt::CaseStmtClass)
855 buildingTopLevelCase);
857 if (
s.getStmtClass() == Stmt::DefaultStmtClass)
859 buildingTopLevelCase);
861 llvm_unreachable(
"expect case or default stmt");
870 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
871 mlir::LogicalResult loopRes = mlir::success();
874 if (
emitStmt(
s.getInit(),
true).failed())
875 return mlir::failure();
876 if (
emitStmt(
s.getRangeStmt(),
true).failed())
877 return mlir::failure();
878 if (
emitStmt(
s.getBeginStmt(),
true).failed())
879 return mlir::failure();
880 if (
emitStmt(
s.getEndStmt(),
true).failed())
881 return mlir::failure();
890 forOp = builder.createFor(
893 [&](mlir::OpBuilder &
b, mlir::Location loc) {
894 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
895 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
896 mlir::Value condVal = evaluateExprAsBool(s.getCond());
897 builder.createCondition(condVal);
900 [&](mlir::OpBuilder &
b, mlir::Location loc) {
904 bool useCurrentScope = true;
905 if (emitStmt(s.getLoopVarStmt(), useCurrentScope).failed())
906 loopRes = mlir::failure();
907 if (emitStmt(s.getBody(), useCurrentScope).failed())
908 loopRes = mlir::failure();
912 [&](mlir::OpBuilder &
b, mlir::Location loc) {
914 if (emitStmt(s.getInc(), true).failed())
915 loopRes = mlir::failure();
916 builder.createYield(loc);
921 mlir::LogicalResult res = mlir::success();
922 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
923 cir::ScopeOp::create(builder, scopeLoc,
924 [&](mlir::OpBuilder &
b, mlir::Location loc) {
930 builder.getInsertionBlock()};
931 res = forStmtBuilder();
938 return mlir::success();
945 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
946 mlir::LogicalResult loopRes = mlir::success();
949 if (
emitStmt(
s.getInit(),
true).failed())
950 return mlir::failure();
958 forOp = builder.createFor(
961 [&](mlir::OpBuilder &
b, mlir::Location loc) {
962 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
963 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
968 if (s.getConditionVariable())
969 emitDecl(*s.getConditionVariable());
973 condVal = evaluateExprAsBool(s.getCond());
975 condVal = cir::ConstantOp::create(b, loc, builder.getTrueAttr());
977 builder.createCondition(condVal);
980 [&](mlir::OpBuilder &
b, mlir::Location loc) {
983 if (
emitStmt(
s.getBody(),
false).failed())
984 loopRes = mlir::failure();
988 [&](mlir::OpBuilder &
b, mlir::Location loc) {
991 loopRes = mlir::failure();
992 builder.createYield(loc);
997 auto res = mlir::success();
998 auto scopeLoc = getLoc(
s.getSourceRange());
999 cir::ScopeOp::create(builder, scopeLoc,
1000 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1001 LexicalScope lexScope{*
this, loc,
1002 builder.getInsertionBlock()};
1003 res = forStmtBuilder();
1010 return mlir::success();
1014 cir::DoWhileOp doWhileOp;
1017 auto doStmtBuilder = [&]() -> mlir::LogicalResult {
1018 mlir::LogicalResult loopRes = mlir::success();
1026 doWhileOp = builder.createDoWhile(
1029 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1030 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1031 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1035 mlir::Value condVal = evaluateExprAsBool(s.getCond());
1036 builder.createCondition(condVal);
1039 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1041 if (emitStmt(s.getBody(), false).failed())
1042 loopRes = mlir::failure();
1048 mlir::LogicalResult res = mlir::success();
1049 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1050 cir::ScopeOp::create(builder, scopeLoc,
1051 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1053 builder.getInsertionBlock()};
1054 res = doStmtBuilder();
1061 return mlir::success();
1065 cir::WhileOp whileOp;
1068 auto whileStmtBuilder = [&]() -> mlir::LogicalResult {
1069 mlir::LogicalResult loopRes = mlir::success();
1077 whileOp = builder.createWhile(
1080 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1081 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1082 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1083 mlir::Value condVal;
1086 if (s.getConditionVariable())
1087 emitDecl(*s.getConditionVariable());
1091 condVal = evaluateExprAsBool(s.getCond());
1092 builder.createCondition(condVal);
1095 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1097 if (emitStmt(s.getBody(), false).failed())
1098 loopRes = mlir::failure();
1104 mlir::LogicalResult res = mlir::success();
1105 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1106 cir::ScopeOp::create(builder, scopeLoc,
1107 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1109 builder.getInsertionBlock()};
1110 res = whileStmtBuilder();
1117 return mlir::success();
1135 mlir::Block *swtichBlock = builder.getBlock();
1138 builder.setInsertionPointToEnd(swtichBlock);
1144 return mlir::failure();
1151 return mlir::failure();
1154 return mlir::success();
1165 auto switchStmtBuilder = [&]() -> mlir::LogicalResult {
1167 if (
emitStmt(
s.getInit(),
true).failed())
1168 return mlir::failure();
1170 if (
s.getConditionVariable())
1171 emitDecl(*
s.getConditionVariable(),
true);
1181 mlir::LogicalResult res = mlir::success();
1182 swop = SwitchOp::create(
1183 builder,
getLoc(
s.getBeginLoc()), condV,
1185 [&](mlir::OpBuilder &
b, mlir::Location loc, mlir::OperationState &os) {
1186 curLexScope->setAsSwitch();
1188 condTypeStack.push_back(condV.getType());
1190 res = emitSwitchBody(s.getBody());
1192 condTypeStack.pop_back();
1199 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1200 mlir::LogicalResult res = mlir::success();
1201 cir::ScopeOp::create(builder, scopeLoc,
1202 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1204 builder.getInsertionBlock()};
1205 res = switchStmtBuilder();
1209 swop.collectCases(cases);
1210 for (
auto caseOp : cases)
1211 terminateBody(builder, caseOp.getCaseRegion(), caseOp.getLoc());
1214 swop.setAllEnumCasesCovered(
s.isAllEnumCasesCovered());
1228 cgm.errorNYI(loc,
"emitReturnOfRValue: complex return type");
1230 mlir::Block *retBlock =
curLexScope->getOrCreateRetBlock(*
this, loc);
1232 cir::BrOp::create(builder, loc, retBlock);
1234 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 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...