16#include "mlir/IR/Builders.h"
17#include "mlir/IR/Location.h"
18#include "mlir/Support/LLVM.h"
29 const Stmt *exprResult,
38 if (
const auto *ls = dyn_cast<LabelStmt>(exprResult)) {
39 if (cgf.
emitLabel(*ls->getDecl()).failed())
40 return mlir::failure();
41 exprResult = ls->getSubStmt();
42 }
else if (
const auto *as = dyn_cast<AttributedStmt>(exprResult)) {
45 exprResult = as->getSubStmt();
47 llvm_unreachable(
"Unknown value statement");
63 return mlir::success();
68 mlir::LogicalResult result = mlir::success();
69 const Stmt *exprResult =
s.body_back();
70 assert((!lastValue || (lastValue && exprResult)) &&
71 "If lastValue is not null then the CompoundStmt must have a "
74 for (
const Stmt *curStmt :
s.body()) {
75 const bool saveResult = lastValue && exprResult == curStmt;
78 result = mlir::failure();
80 if (
emitStmt(curStmt,
false).failed())
81 result = mlir::failure();
92 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
93 mlir::OpBuilder::InsertPoint scopeInsPt;
96 [&](mlir::OpBuilder &
b, mlir::Type &
type, mlir::Location loc) {
97 scopeInsPt =
b.saveInsertionPoint();
99 mlir::OpBuilder::InsertionGuard guard(builder);
100 builder.restoreInsertionPoint(scopeInsPt);
101 LexicalScope lexScope(*
this, scopeLoc, builder.getInsertionBlock());
112 bool useCurrentScope,
115 return mlir::success();
117 switch (
s->getStmtClass()) {
119 case Stmt::CXXCatchStmtClass:
120 case Stmt::SEHExceptStmtClass:
121 case Stmt::SEHFinallyStmtClass:
122 case Stmt::MSDependentExistsStmtClass:
123 llvm_unreachable(
"invalid statement class to emit generically");
124 case Stmt::BreakStmtClass:
125 case Stmt::NullStmtClass:
126 case Stmt::CompoundStmtClass:
127 case Stmt::ContinueStmtClass:
128 case Stmt::DeclStmtClass:
129 case Stmt::ReturnStmtClass:
130 llvm_unreachable(
"should have emitted these statements as simple");
132#define STMT(Type, Base)
133#define ABSTRACT_STMT(Op)
134#define EXPR(Type, Base) case Stmt::Type##Class:
135#include "clang/AST/StmtNodes.inc"
137 assert(builder.getInsertionBlock() &&
138 "expression emission must have an insertion point");
146 return mlir::success();
148 case Stmt::IfStmtClass:
150 case Stmt::SwitchStmtClass:
152 case Stmt::ForStmtClass:
154 case Stmt::WhileStmtClass:
156 case Stmt::DoStmtClass:
158 case Stmt::CXXTryStmtClass:
160 case Stmt::CXXForRangeStmtClass:
162 case Stmt::CoroutineBodyStmtClass:
164 case Stmt::IndirectGotoStmtClass:
166 case Stmt::OpenACCComputeConstructClass:
168 case Stmt::OpenACCLoopConstructClass:
170 case Stmt::OpenACCCombinedConstructClass:
172 case Stmt::OpenACCDataConstructClass:
174 case Stmt::OpenACCEnterDataConstructClass:
176 case Stmt::OpenACCExitDataConstructClass:
178 case Stmt::OpenACCHostDataConstructClass:
180 case Stmt::OpenACCWaitConstructClass:
182 case Stmt::OpenACCInitConstructClass:
184 case Stmt::OpenACCShutdownConstructClass:
186 case Stmt::OpenACCSetConstructClass:
188 case Stmt::OpenACCUpdateConstructClass:
190 case Stmt::OpenACCCacheConstructClass:
192 case Stmt::OpenACCAtomicConstructClass:
194 case Stmt::GCCAsmStmtClass:
195 case Stmt::MSAsmStmtClass:
197 case Stmt::OMPScopeDirectiveClass:
198 case Stmt::OMPErrorDirectiveClass:
199 case Stmt::LabelStmtClass:
200 case Stmt::AttributedStmtClass:
201 case Stmt::GotoStmtClass:
202 case Stmt::DefaultStmtClass:
203 case Stmt::CaseStmtClass:
204 case Stmt::SEHLeaveStmtClass:
205 case Stmt::SYCLKernelCallStmtClass:
206 case Stmt::CoreturnStmtClass:
207 case Stmt::OMPParallelDirectiveClass:
208 case Stmt::OMPTaskwaitDirectiveClass:
209 case Stmt::OMPTaskyieldDirectiveClass:
210 case Stmt::OMPBarrierDirectiveClass:
211 case Stmt::CapturedStmtClass:
212 case Stmt::ObjCAtTryStmtClass:
213 case Stmt::ObjCAtThrowStmtClass:
214 case Stmt::ObjCAtSynchronizedStmtClass:
215 case Stmt::ObjCForCollectionStmtClass:
216 case Stmt::ObjCAutoreleasePoolStmtClass:
217 case Stmt::SEHTryStmtClass:
218 case Stmt::OMPMetaDirectiveClass:
219 case Stmt::OMPCanonicalLoopClass:
220 case Stmt::OMPSimdDirectiveClass:
221 case Stmt::OMPTileDirectiveClass:
222 case Stmt::OMPUnrollDirectiveClass:
223 case Stmt::OMPFuseDirectiveClass:
224 case Stmt::OMPForDirectiveClass:
225 case Stmt::OMPForSimdDirectiveClass:
226 case Stmt::OMPSectionsDirectiveClass:
227 case Stmt::OMPSectionDirectiveClass:
228 case Stmt::OMPSingleDirectiveClass:
229 case Stmt::OMPMasterDirectiveClass:
230 case Stmt::OMPCriticalDirectiveClass:
231 case Stmt::OMPParallelForDirectiveClass:
232 case Stmt::OMPParallelForSimdDirectiveClass:
233 case Stmt::OMPParallelMasterDirectiveClass:
234 case Stmt::OMPParallelSectionsDirectiveClass:
235 case Stmt::OMPTaskDirectiveClass:
236 case Stmt::OMPTaskgroupDirectiveClass:
237 case Stmt::OMPFlushDirectiveClass:
238 case Stmt::OMPDepobjDirectiveClass:
239 case Stmt::OMPScanDirectiveClass:
240 case Stmt::OMPOrderedDirectiveClass:
241 case Stmt::OMPAtomicDirectiveClass:
242 case Stmt::OMPTargetDirectiveClass:
243 case Stmt::OMPTeamsDirectiveClass:
244 case Stmt::OMPCancellationPointDirectiveClass:
245 case Stmt::OMPCancelDirectiveClass:
246 case Stmt::OMPTargetDataDirectiveClass:
247 case Stmt::OMPTargetEnterDataDirectiveClass:
248 case Stmt::OMPTargetExitDataDirectiveClass:
249 case Stmt::OMPTargetParallelDirectiveClass:
250 case Stmt::OMPTargetParallelForDirectiveClass:
251 case Stmt::OMPTaskLoopDirectiveClass:
252 case Stmt::OMPTaskLoopSimdDirectiveClass:
253 case Stmt::OMPMaskedTaskLoopDirectiveClass:
254 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
255 case Stmt::OMPMasterTaskLoopDirectiveClass:
256 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
257 case Stmt::OMPParallelGenericLoopDirectiveClass:
258 case Stmt::OMPParallelMaskedDirectiveClass:
259 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
260 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
261 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
262 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
263 case Stmt::OMPDistributeDirectiveClass:
264 case Stmt::OMPDistributeParallelForDirectiveClass:
265 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
266 case Stmt::OMPDistributeSimdDirectiveClass:
267 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
268 case Stmt::OMPTargetParallelForSimdDirectiveClass:
269 case Stmt::OMPTargetSimdDirectiveClass:
270 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
271 case Stmt::OMPTargetUpdateDirectiveClass:
272 case Stmt::OMPTeamsDistributeDirectiveClass:
273 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
274 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
275 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
276 case Stmt::OMPTeamsGenericLoopDirectiveClass:
277 case Stmt::OMPTargetTeamsDirectiveClass:
278 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
279 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
280 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
281 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
282 case Stmt::OMPInteropDirectiveClass:
283 case Stmt::OMPDispatchDirectiveClass:
284 case Stmt::OMPGenericLoopDirectiveClass:
285 case Stmt::OMPReverseDirectiveClass:
286 case Stmt::OMPInterchangeDirectiveClass:
287 case Stmt::OMPAssumeDirectiveClass:
288 case Stmt::OMPMaskedDirectiveClass:
289 case Stmt::OMPStripeDirectiveClass:
290 case Stmt::ObjCAtCatchStmtClass:
291 case Stmt::ObjCAtFinallyStmtClass:
292 case Stmt::DeferStmtClass:
293 cgm.errorNYI(
s->getSourceRange(),
294 std::string(
"emitStmt: ") +
s->getStmtClassName());
295 return mlir::failure();
298 llvm_unreachable(
"Unexpected statement class");
302 bool useCurrentScope) {
303 switch (
s->getStmtClass()) {
305 return mlir::failure();
306 case Stmt::DeclStmtClass:
308 case Stmt::CompoundStmtClass:
312 case Stmt::GotoStmtClass:
314 case Stmt::ContinueStmtClass:
318 case Stmt::NullStmtClass:
321 case Stmt::LabelStmtClass:
323 case Stmt::CaseStmtClass:
324 case Stmt::DefaultStmtClass:
330 case Stmt::BreakStmtClass:
332 case Stmt::ReturnStmtClass:
336 return mlir::success();
342 return mlir::failure();
352 mlir::Location loc) {
357 unsigned numBlocks = r.getBlocks().size();
358 for (
auto &block : r.getBlocks()) {
361 if (numBlocks != 1 && block.empty() && block.hasNoPredecessors() &&
362 block.hasNoSuccessors())
363 eraseBlocks.push_back(&block);
366 !block.back().hasTrait<mlir::OpTrait::IsTerminator>()) {
367 mlir::OpBuilder::InsertionGuard guardCase(builder);
368 builder.setInsertionPointToEnd(&block);
373 for (
auto *
b : eraseBlocks)
378 mlir::LogicalResult res = mlir::success();
381 const Stmt *constevalExecuted;
382 if (
s.isConsteval()) {
383 constevalExecuted =
s.isNegatedConsteval() ?
s.getThen() :
s.getElse();
384 if (!constevalExecuted) {
392 auto ifStmtBuilder = [&]() -> mlir::LogicalResult {
394 return emitStmt(constevalExecuted,
true);
397 if (
emitStmt(
s.getInit(),
true).failed())
398 return mlir::failure();
400 if (
s.getConditionVariable())
407 if (
s.isConstexpr()) {
412 if (
const Stmt *executed = condConstant ?
s.getThen() :
s.getElse())
416 return mlir::success();
428 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
429 cir::ScopeOp::create(builder, scopeLoc,
430 [&](mlir::OpBuilder &
b, mlir::Location loc) {
432 builder.getInsertionBlock()};
433 res = ifStmtBuilder();
440 assert(builder.getInsertionBlock() &&
"expected valid insertion point");
442 for (
const Decl *i :
s.decls())
445 return mlir::success();
449 mlir::Location loc =
getLoc(
s.getSourceRange());
450 const Expr *rv =
s.getRetValue();
453 bool createNewScope =
false;
454 if (
const auto *ewc = dyn_cast_or_null<ExprWithCleanups>(rv)) {
455 rv = ewc->getSubExpr();
456 createNewScope =
true;
459 auto handleReturnVal = [&]() {
461 s.getNRVOCandidate()->isNRVOVariable()) {
469 if (
auto nrvoFlag =
nrvoFlags[
s.getNRVOCandidate()])
470 builder.createFlagStore(loc,
true, nrvoFlag);
481 ->isReferenceType()) {
485 builder.CIRBaseBuilderTy::createStore(loc, result.
getValue(),
488 mlir::Value value =
nullptr;
493 builder.CIRBaseBuilderTy::createStore(loc, value, *
fnRetAlloca);
512 if (!createNewScope) {
515 mlir::Location scopeLoc =
520 mlir::OpBuilder::InsertPoint scopeBody;
521 cir::ScopeOp::create(builder, scopeLoc,
522 [&](mlir::OpBuilder &
b, mlir::Location loc) {
523 scopeBody =
b.saveInsertionPoint();
526 mlir::OpBuilder::InsertionGuard guard(builder);
527 builder.restoreInsertionPoint(scopeBody);
529 builder.getInsertionBlock()};
540 auto *retBlock =
curLexScope->getOrCreateRetBlock(*
this, loc);
544 builder.createBlock(builder.getBlock()->getParent());
546 return mlir::success();
556 cir::GotoOp::create(builder,
getLoc(
s.getSourceRange()),
557 s.getLabel()->getName());
562 builder.createBlock(builder.getBlock()->getParent());
564 return mlir::success();
571 "If you jumping to a indirect branch should be alareadye emitted");
574 builder.createBlock(builder.getBlock()->getParent());
575 return mlir::success();
580 builder.createContinue(
getLoc(
s.getKwLoc()));
583 builder.createBlock(builder.getBlock()->getParent());
585 return mlir::success();
592 mlir::Block *currBlock = builder.getBlock();
593 mlir::Block *labelBlock = currBlock;
595 if (!currBlock->empty() || currBlock->isEntryBlock()) {
597 mlir::OpBuilder::InsertionGuard guard(builder);
598 labelBlock = builder.createBlock(builder.getBlock()->getParent());
603 builder.setInsertionPointToEnd(labelBlock);
606 builder.setInsertionPointToEnd(labelBlock);
608 cgm.mapBlockAddress(cir::BlockAddrInfoAttr::get(builder.getContext(),
609 func.getSymNameAttr(),
610 label.getLabelAttr()),
616 return mlir::success();
620 builder.createBreak(
getLoc(
s.getKwLoc()));
623 builder.createBlock(builder.getBlock()->getParent());
625 return mlir::success();
631 mlir::ArrayAttr value, CaseOpKind kind,
632 bool buildingTopLevelCase) {
635 "only case or default stmt go here");
637 mlir::LogicalResult result = mlir::success();
639 mlir::Location loc =
getLoc(
stmt->getBeginLoc());
642 SubStmtKind subStmtKind = SubStmtKind::Other;
643 const Stmt *sub =
stmt->getSubStmt();
645 mlir::OpBuilder::InsertPoint insertPoint;
646 CaseOp::create(builder, loc, value, kind, insertPoint);
649 mlir::OpBuilder::InsertionGuard guardSwitch(builder);
650 builder.restoreInsertionPoint(insertPoint);
653 subStmtKind = SubStmtKind::Default;
654 builder.createYield(loc);
656 subStmtKind = SubStmtKind::Case;
657 builder.createYield(loc);
662 insertPoint = builder.saveInsertionPoint();
697 if (subStmtKind == SubStmtKind::Case) {
699 }
else if (subStmtKind == SubStmtKind::Default) {
701 buildingTopLevelCase);
702 }
else if (buildingTopLevelCase) {
706 builder.restoreInsertionPoint(insertPoint);
714 bool buildingTopLevelCase) {
715 cir::CaseOpKind kind;
716 mlir::ArrayAttr value;
717 llvm::APSInt intVal =
s.getLHS()->EvaluateKnownConstInt(
getContext());
722 if (
const Expr *rhs =
s.getRHS()) {
723 llvm::APSInt endVal = rhs->EvaluateKnownConstInt(
getContext());
724 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal),
725 cir::IntAttr::get(condType, endVal)});
726 kind = cir::CaseOpKind::Range;
728 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal)});
729 kind = cir::CaseOpKind::Equal;
733 buildingTopLevelCase);
738 bool buildingTopLevelCase) {
740 cir::CaseOpKind::Default, buildingTopLevelCase);
744 bool buildingTopLevelCase) {
746 "build switch case without specifying the type of the condition");
748 if (
s.getStmtClass() == Stmt::CaseStmtClass)
750 buildingTopLevelCase);
752 if (
s.getStmtClass() == Stmt::DefaultStmtClass)
754 buildingTopLevelCase);
756 llvm_unreachable(
"expect case or default stmt");
765 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
766 mlir::LogicalResult loopRes = mlir::success();
769 if (
emitStmt(
s.getInit(),
true).failed())
770 return mlir::failure();
771 if (
emitStmt(
s.getRangeStmt(),
true).failed())
772 return mlir::failure();
773 if (
emitStmt(
s.getBeginStmt(),
true).failed())
774 return mlir::failure();
775 if (
emitStmt(
s.getEndStmt(),
true).failed())
776 return mlir::failure();
785 forOp = builder.createFor(
788 [&](mlir::OpBuilder &
b, mlir::Location loc) {
789 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
790 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
791 mlir::Value condVal = evaluateExprAsBool(s.getCond());
792 builder.createCondition(condVal);
795 [&](mlir::OpBuilder &
b, mlir::Location loc) {
799 bool useCurrentScope = true;
800 if (emitStmt(s.getLoopVarStmt(), useCurrentScope).failed())
801 loopRes = mlir::failure();
802 if (emitStmt(s.getBody(), useCurrentScope).failed())
803 loopRes = mlir::failure();
807 [&](mlir::OpBuilder &
b, mlir::Location loc) {
809 if (emitStmt(s.getInc(), true).failed())
810 loopRes = mlir::failure();
811 builder.createYield(loc);
816 mlir::LogicalResult res = mlir::success();
817 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
818 cir::ScopeOp::create(builder, scopeLoc,
819 [&](mlir::OpBuilder &
b, mlir::Location loc) {
825 builder.getInsertionBlock()};
826 res = forStmtBuilder();
833 return mlir::success();
840 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
841 mlir::LogicalResult loopRes = mlir::success();
844 if (
emitStmt(
s.getInit(),
true).failed())
845 return mlir::failure();
853 forOp = builder.createFor(
856 [&](mlir::OpBuilder &
b, mlir::Location loc) {
857 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
858 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
863 if (s.getConditionVariable())
864 emitDecl(*s.getConditionVariable());
868 condVal = evaluateExprAsBool(s.getCond());
870 condVal = cir::ConstantOp::create(b, loc, builder.getTrueAttr());
872 builder.createCondition(condVal);
875 [&](mlir::OpBuilder &
b, mlir::Location loc) {
878 if (
emitStmt(
s.getBody(),
false).failed())
879 loopRes = mlir::failure();
883 [&](mlir::OpBuilder &
b, mlir::Location loc) {
886 loopRes = mlir::failure();
887 builder.createYield(loc);
892 auto res = mlir::success();
893 auto scopeLoc = getLoc(
s.getSourceRange());
894 cir::ScopeOp::create(builder, scopeLoc,
895 [&](mlir::OpBuilder &
b, mlir::Location loc) {
896 LexicalScope lexScope{*
this, loc,
897 builder.getInsertionBlock()};
898 res = forStmtBuilder();
905 return mlir::success();
909 cir::DoWhileOp doWhileOp;
912 auto doStmtBuilder = [&]() -> mlir::LogicalResult {
913 mlir::LogicalResult loopRes = mlir::success();
921 doWhileOp = builder.createDoWhile(
924 [&](mlir::OpBuilder &
b, mlir::Location loc) {
925 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
926 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
930 mlir::Value condVal = evaluateExprAsBool(s.getCond());
931 builder.createCondition(condVal);
934 [&](mlir::OpBuilder &
b, mlir::Location loc) {
936 if (emitStmt(s.getBody(), false).failed())
937 loopRes = mlir::failure();
943 mlir::LogicalResult res = mlir::success();
944 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
945 cir::ScopeOp::create(builder, scopeLoc,
946 [&](mlir::OpBuilder &
b, mlir::Location loc) {
948 builder.getInsertionBlock()};
949 res = doStmtBuilder();
956 return mlir::success();
960 cir::WhileOp whileOp;
963 auto whileStmtBuilder = [&]() -> mlir::LogicalResult {
964 mlir::LogicalResult loopRes = mlir::success();
972 whileOp = builder.createWhile(
975 [&](mlir::OpBuilder &
b, mlir::Location loc) {
976 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
977 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
981 if (s.getConditionVariable())
982 emitDecl(*s.getConditionVariable());
986 condVal = evaluateExprAsBool(s.getCond());
987 builder.createCondition(condVal);
990 [&](mlir::OpBuilder &
b, mlir::Location loc) {
992 if (emitStmt(s.getBody(), false).failed())
993 loopRes = mlir::failure();
999 mlir::LogicalResult res = mlir::success();
1000 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1001 cir::ScopeOp::create(builder, scopeLoc,
1002 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1004 builder.getInsertionBlock()};
1005 res = whileStmtBuilder();
1012 return mlir::success();
1030 mlir::Block *swtichBlock = builder.getBlock();
1033 builder.setInsertionPointToEnd(swtichBlock);
1039 return mlir::failure();
1046 return mlir::failure();
1049 return mlir::success();
1060 auto switchStmtBuilder = [&]() -> mlir::LogicalResult {
1062 if (
emitStmt(
s.getInit(),
true).failed())
1063 return mlir::failure();
1065 if (
s.getConditionVariable())
1066 emitDecl(*
s.getConditionVariable(),
true);
1076 mlir::LogicalResult res = mlir::success();
1077 swop = SwitchOp::create(
1078 builder,
getLoc(
s.getBeginLoc()), condV,
1080 [&](mlir::OpBuilder &
b, mlir::Location loc, mlir::OperationState &os) {
1081 curLexScope->setAsSwitch();
1083 condTypeStack.push_back(condV.getType());
1085 res = emitSwitchBody(s.getBody());
1087 condTypeStack.pop_back();
1094 mlir::Location scopeLoc =
getLoc(
s.getSourceRange());
1095 mlir::LogicalResult res = mlir::success();
1096 cir::ScopeOp::create(builder, scopeLoc,
1097 [&](mlir::OpBuilder &
b, mlir::Location loc) {
1099 builder.getInsertionBlock()};
1100 res = switchStmtBuilder();
1104 swop.collectCases(cases);
1105 for (
auto caseOp : cases)
1106 terminateBody(builder, caseOp.getCaseRegion(), caseOp.getLoc());
1109 swop.setAllEnumCasesCovered(
s.isAllEnumCasesCovered());
1123 cgm.errorNYI(loc,
"emitReturnOfRValue: complex return type");
1125 mlir::Block *retBlock =
curLexScope->getOrCreateRetBlock(*
this, loc);
1127 cir::BrOp::create(builder, loc, retBlock);
1129 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.
__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 emitDoStmt(const clang::DoStmt &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 emitOpenACCWaitConstruct(const OpenACCWaitConstruct &s)
const clang::LangOptions & getLangOpts() const
mlir::LogicalResult emitOpenACCUpdateConstruct(const OpenACCUpdateConstruct &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 emitOpenACCCacheConstruct(const OpenACCCacheConstruct &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::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
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 emitOpenACCSetConstruct(const OpenACCSetConstruct &s)
RValue emitReferenceBindingToExpr(const Expr *e)
Emits a reference binding to the passed in expression.
mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s)
mlir::LogicalResult emitCaseStmt(const clang::CaseStmt &s, mlir::Type condType, bool buildingTopLevelCase)
llvm::ScopedHashTableScope< const clang::Decl *, mlir::Value > SymTableScopeTy
mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s, bool useCurrentScope)
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 emitOpenACCComputeConstruct(const OpenACCComputeConstruct &s)
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
mlir::LogicalResult emitSwitchBody(const clang::Stmt *s)
mlir::LogicalResult emitForStmt(const clang::ForStmt &s)
std::optional< mlir::Value > fnRetAlloca
The compiler-generated variable that holds the return value.
Address returnValue
The temporary alloca to hold the return value.
mlir::LogicalResult emitLabel(const clang::LabelDecl &d)
static bool hasAggregateEvaluationKind(clang::QualType type)
mlir::LogicalResult emitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &s)
mlir::LogicalResult emitBreakStmt(const clang::BreakStmt &s)
mlir::LogicalResult emitIndirectGotoStmt(const IndirectGotoStmt &s)
void emitReturnOfRValue(mlir::Location loc, RValue rv, QualType ty)
mlir::LogicalResult emitContinueStmt(const clang::ContinueStmt &s)
llvm::SmallVector< mlir::Type, 2 > condTypeStack
The type of the condition for the emitting switch statement.
void emitStopPoint(const Stmt *s)
Build a debug stoppoint if we are emitting debug info.
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)
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)
void emitDecl(const clang::Decl &d, bool evaluateConditionDecl=false)
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 emitCXXTryStmt(const clang::CXXTryStmt &s)
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
mlir::LogicalResult emitCaseDefaultCascade(const T *stmt, mlir::Type condType, mlir::ArrayAttr value, cir::CaseOpKind kind, bool buildingTopLevelCase)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
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 emitDeclStmt(const clang::DeclStmt &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
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 emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
mlir::LogicalResult emitCompoundStmtWithoutScope(const clang::CompoundStmt &s, Address *lastValue=nullptr, AggValueSlot slot=AggValueSlot::ignored())
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 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...