16#include "mlir/IR/Builders.h"
17#include "mlir/IR/Location.h"
18#include "mlir/Support/LLVM.h"
27#include "llvm/Support/SaveAndRestore.h"
37 const AtomicAttr *aa) {
40 for (
auto option : aa->atomicOptions()) {
42 case AtomicAttr::remote_memory:
45 case AtomicAttr::no_remote_memory:
48 case AtomicAttr::fine_grained_memory:
51 case AtomicAttr::no_fine_grained_memory:
54 case AtomicAttr::ignore_denormal_mode:
57 case AtomicAttr::no_ignore_denormal_mode:
66 const Stmt *exprResult,
75 if (
const auto *ls = dyn_cast<LabelStmt>(exprResult)) {
76 if (cgf.
emitLabel(*ls->getDecl()).failed())
77 return mlir::failure();
78 exprResult = ls->getSubStmt();
79 }
else if (
const auto *as = dyn_cast<AttributedStmt>(exprResult)) {
82 exprResult = as->getSubStmt();
84 llvm_unreachable(
"Unknown value statement");
100 return mlir::success();
105 mlir::LogicalResult result = mlir::success();
107 assert((!lastValue || (lastValue && exprResult)) &&
108 "If lastValue is not null then the CompoundStmt must have a "
111 for (
const Stmt *curStmt : s.
body()) {
112 const bool saveResult = lastValue && exprResult == curStmt;
115 result = mlir::failure();
117 if (
emitStmt(curStmt,
false).failed())
118 result = mlir::failure();
130 const AtomicAttr *atomicAttr =
nullptr;
133 switch (
attr->getKind()) {
140 case attr::NoConvergent:
141 case attr::AMDGPUAvailableVisible:
142 case attr::HLSLControlFlowHint:
144 "Unimplemented statement attribute: ",
attr->getKind());
148 alwaysinline =
false;
150 case attr::AlwaysInline:
154 case attr::MustTail: {
160 case attr::CXXAssume: {
162 if (
getLangOpts().CXXAssumptions && builder.getInsertionBlock() &&
166 assumptionValue, cir::AssumeBundleKind::None,
173 assert(!(alwaysinline && noinline) &&
174 "alwaysinline and noinline are mutually exclusive");
186 mlir::LogicalResult result =
189 cgm.setAtomicOpts(savedAtomicOpts);
199 mlir::OpBuilder::InsertPoint scopeInsPt;
200 cir::ScopeOp::create(
202 [&](mlir::OpBuilder &b, mlir::Type &
type, mlir::Location loc) {
203 scopeInsPt = b.saveInsertionPoint();
205 mlir::OpBuilder::InsertionGuard guard(builder);
206 builder.restoreInsertionPoint(scopeInsPt);
207 LexicalScope lexScope(*
this, scopeLoc, builder.getInsertionBlock());
218 bool useCurrentScope,
221 return mlir::success();
225 case Stmt::CXXCatchStmtClass:
226 case Stmt::SEHExceptStmtClass:
227 case Stmt::SEHFinallyStmtClass:
228 case Stmt::MSDependentExistsStmtClass:
229 case Stmt::UnresolvedSYCLKernelCallStmtClass:
230 llvm_unreachable(
"invalid statement class to emit generically");
231 case Stmt::BreakStmtClass:
232 case Stmt::NullStmtClass:
233 case Stmt::CompoundStmtClass:
234 case Stmt::ContinueStmtClass:
235 case Stmt::DeclStmtClass:
236 case Stmt::ReturnStmtClass:
237 llvm_unreachable(
"should have emitted these statements as simple");
239#define STMT(Type, Base)
240#define ABSTRACT_STMT(Op)
241#define EXPR(Type, Base) case Stmt::Type##Class:
242#include "clang/AST/StmtNodes.inc"
244 assert(builder.getInsertionBlock() &&
245 "expression emission must have an insertion point");
253 return mlir::success();
255 case Stmt::IfStmtClass:
257 case Stmt::SwitchStmtClass:
259 case Stmt::ForStmtClass:
261 case Stmt::WhileStmtClass:
263 case Stmt::DoStmtClass:
265 case Stmt::CXXTryStmtClass:
267 case Stmt::CXXForRangeStmtClass:
269 case Stmt::CoroutineBodyStmtClass:
271 case Stmt::IndirectGotoStmtClass:
273 case Stmt::CoreturnStmtClass:
275 case Stmt::SYCLKernelCallStmtClass:
277 case Stmt::OpenACCComputeConstructClass:
279 case Stmt::OpenACCLoopConstructClass:
281 case Stmt::OpenACCCombinedConstructClass:
283 case Stmt::OpenACCDataConstructClass:
285 case Stmt::OpenACCEnterDataConstructClass:
287 case Stmt::OpenACCExitDataConstructClass:
289 case Stmt::OpenACCHostDataConstructClass:
291 case Stmt::OpenACCWaitConstructClass:
293 case Stmt::OpenACCInitConstructClass:
295 case Stmt::OpenACCShutdownConstructClass:
297 case Stmt::OpenACCSetConstructClass:
299 case Stmt::OpenACCUpdateConstructClass:
301 case Stmt::OpenACCCacheConstructClass:
303 case Stmt::OpenACCAtomicConstructClass:
305 case Stmt::GCCAsmStmtClass:
306 case Stmt::MSAsmStmtClass:
308 case Stmt::OMPScopeDirectiveClass:
310 case Stmt::OMPErrorDirectiveClass:
312 case Stmt::OMPParallelDirectiveClass:
314 case Stmt::OMPTaskwaitDirectiveClass:
316 case Stmt::OMPTaskyieldDirectiveClass:
318 case Stmt::OMPBarrierDirectiveClass:
320 case Stmt::OMPMetaDirectiveClass:
322 case Stmt::OMPCanonicalLoopClass:
324 case Stmt::OMPSimdDirectiveClass:
326 case Stmt::OMPTileDirectiveClass:
328 case Stmt::OMPUnrollDirectiveClass:
330 case Stmt::OMPFuseDirectiveClass:
332 case Stmt::OMPForDirectiveClass:
334 case Stmt::OMPForSimdDirectiveClass:
336 case Stmt::OMPSectionsDirectiveClass:
338 case Stmt::OMPSectionDirectiveClass:
340 case Stmt::OMPSingleDirectiveClass:
342 case Stmt::OMPMasterDirectiveClass:
344 case Stmt::OMPCriticalDirectiveClass:
346 case Stmt::OMPParallelForDirectiveClass:
348 case Stmt::OMPParallelForSimdDirectiveClass:
351 case Stmt::OMPParallelMasterDirectiveClass:
353 case Stmt::OMPParallelSectionsDirectiveClass:
356 case Stmt::OMPTaskDirectiveClass:
358 case Stmt::OMPTaskgroupDirectiveClass:
360 case Stmt::OMPFlushDirectiveClass:
362 case Stmt::OMPDepobjDirectiveClass:
364 case Stmt::OMPScanDirectiveClass:
366 case Stmt::OMPOrderedStandaloneDirectiveClass:
369 case Stmt::OMPOrderedBlockAssocDirectiveClass:
372 case Stmt::OMPAtomicDirectiveClass:
374 case Stmt::OMPTargetDirectiveClass:
376 case Stmt::OMPTeamsDirectiveClass:
378 case Stmt::OMPCancellationPointDirectiveClass:
381 case Stmt::OMPCancelDirectiveClass:
383 case Stmt::OMPTargetDataDirectiveClass:
385 case Stmt::OMPTargetEnterDataDirectiveClass:
388 case Stmt::OMPTargetExitDataDirectiveClass:
390 case Stmt::OMPTargetParallelDirectiveClass:
392 case Stmt::OMPTargetParallelForDirectiveClass:
395 case Stmt::OMPTaskLoopDirectiveClass:
397 case Stmt::OMPTaskLoopSimdDirectiveClass:
399 case Stmt::OMPMaskedTaskLoopDirectiveClass:
401 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
404 case Stmt::OMPMasterTaskLoopDirectiveClass:
406 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
409 case Stmt::OMPParallelGenericLoopDirectiveClass:
412 case Stmt::OMPParallelMaskedDirectiveClass:
414 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
417 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
420 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
423 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
426 case Stmt::OMPDistributeDirectiveClass:
428 case Stmt::OMPDistributeParallelForDirectiveClass:
431 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
434 case Stmt::OMPDistributeSimdDirectiveClass:
436 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
439 case Stmt::OMPTargetParallelForSimdDirectiveClass:
442 case Stmt::OMPTargetSimdDirectiveClass:
444 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
447 case Stmt::OMPTargetUpdateDirectiveClass:
449 case Stmt::OMPTeamsDistributeDirectiveClass:
452 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
455 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
458 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
461 case Stmt::OMPTeamsGenericLoopDirectiveClass:
464 case Stmt::OMPTargetTeamsDirectiveClass:
466 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
469 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
472 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
475 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
478 case Stmt::OMPInteropDirectiveClass:
480 case Stmt::OMPDispatchDirectiveClass:
482 case Stmt::OMPGenericLoopDirectiveClass:
484 case Stmt::OMPReverseDirectiveClass:
486 case Stmt::OMPSplitDirectiveClass:
488 case Stmt::OMPInterchangeDirectiveClass:
490 case Stmt::OMPFlattenDirectiveClass:
492 case Stmt::OMPAssumeDirectiveClass:
494 case Stmt::OMPMaskedDirectiveClass:
496 case Stmt::OMPStripeDirectiveClass:
498 case Stmt::LabelStmtClass:
499 case Stmt::AttributedStmtClass:
500 case Stmt::GotoStmtClass:
501 case Stmt::DefaultStmtClass:
502 case Stmt::CaseStmtClass:
503 case Stmt::SEHLeaveStmtClass:
504 case Stmt::ObjCAtTryStmtClass:
505 case Stmt::ObjCAtThrowStmtClass:
506 case Stmt::ObjCAtSynchronizedStmtClass:
507 case Stmt::ObjCForCollectionStmtClass:
508 case Stmt::ObjCAutoreleasePoolStmtClass:
509 case Stmt::SEHTryStmtClass:
510 case Stmt::ObjCAtCatchStmtClass:
511 case Stmt::ObjCAtFinallyStmtClass:
512 case Stmt::DeferStmtClass:
513 case Stmt::CXXExpansionStmtPatternClass:
514 case Stmt::CXXExpansionStmtInstantiationClass:
517 return mlir::failure();
518 case Stmt::CapturedStmtClass:
519 llvm_unreachable(
"CapturedStmt must be handled by the parent directive");
522 llvm_unreachable(
"Unexpected statement class");
526 bool useCurrentScope) {
529 return mlir::failure();
530 case Stmt::DeclStmtClass:
532 case Stmt::CompoundStmtClass:
536 case Stmt::GotoStmtClass:
538 case Stmt::ContinueStmtClass:
542 case Stmt::NullStmtClass:
545 case Stmt::LabelStmtClass:
547 case Stmt::CaseStmtClass:
548 case Stmt::DefaultStmtClass:
554 case Stmt::BreakStmtClass:
556 case Stmt::ReturnStmtClass:
558 case Stmt::AttributedStmtClass:
562 return mlir::success();
568 return mlir::failure();
578 mlir::Location loc) {
583 unsigned numBlocks = r.getBlocks().size();
584 for (
auto &block : r.getBlocks()) {
587 if (numBlocks != 1 && block.empty() && block.hasNoPredecessors() &&
588 block.hasNoSuccessors())
589 eraseBlocks.push_back(&block);
592 !block.back().hasTrait<mlir::OpTrait::IsTerminator>()) {
593 mlir::OpBuilder::InsertionGuard guardCase(builder);
594 builder.setInsertionPointToEnd(&block);
595 builder.createYield(loc);
599 for (
auto *b : eraseBlocks)
604 mlir::LogicalResult res = mlir::success();
607 const Stmt *constevalExecuted;
610 if (!constevalExecuted) {
618 auto ifStmtBuilder = [&]() -> mlir::LogicalResult {
620 return emitStmt(constevalExecuted,
true);
624 return mlir::failure();
637 std::swap(executed, skipped);
646 return mlir::success();
659 cir::ScopeOp::create(builder, scopeLoc,
660 [&](mlir::OpBuilder &b, mlir::Location loc) {
662 builder.getInsertionBlock()};
663 res = ifStmtBuilder();
670 assert(builder.getInsertionBlock() &&
"expected valid insertion point");
675 return mlir::success();
683 bool createNewScope =
false;
684 if (
const auto *ewc = dyn_cast_or_null<ExprWithCleanups>(rv)) {
685 rv = ewc->getSubExpr();
686 createNewScope =
true;
689 auto handleReturnVal = [&]() {
700 builder.createFlagStore(loc,
true, nrvoFlag);
711 ->isReferenceType()) {
715 builder.CIRBaseBuilderTy::createStore(loc, result.
getValue(),
718 mlir::Value value =
nullptr;
723 builder.CIRBaseBuilderTy::createStore(loc, value, *
fnRetAlloca);
742 if (!createNewScope) {
758 cir::AllocaOp retAlloca =
759 mlir::cast<cir::AllocaOp>(
fnRetAlloca->getDefiningOp());
760 auto value = cir::LoadOp::create(builder, loc, retAlloca.getAllocaType(),
763 cir::ReturnOp::create(builder, loc, {value});
765 cir::ReturnOp::create(builder, loc);
771 builder.createBlock(builder.getBlock()->getParent());
772 return mlir::success();
788 builder.createBlock(builder.getBlock()->getParent());
790 return mlir::success();
799 return mlir::success();
809 builder.createBlock(builder.getBlock()->getParent());
810 return mlir::success();
818 builder.createBlock(builder.getBlock()->getParent());
820 return mlir::success();
827 mlir::Block *currBlock = builder.getBlock();
828 mlir::Block *labelBlock = currBlock;
830 if (!currBlock->empty() || currBlock->isEntryBlock()) {
832 mlir::OpBuilder::InsertionGuard guard(builder);
833 labelBlock = builder.createBlock(builder.getBlock()->getParent());
838 builder.setInsertionPointToEnd(labelBlock);
847 return mlir::success();
854 builder.createBlock(builder.getBlock()->getParent());
856 return mlir::success();
862 mlir::ArrayAttr value, CaseOpKind
kind,
863 bool buildingTopLevelCase) {
866 "only case or default stmt go here");
868 mlir::LogicalResult result = mlir::success();
870 mlir::Location loc =
getLoc(
stmt->getBeginLoc());
873 SubStmtKind subStmtKind = SubStmtKind::Other;
874 const Stmt *sub =
stmt->getSubStmt();
876 mlir::OpBuilder::InsertPoint insertPoint;
877 CaseOp::create(builder, loc, value,
kind, insertPoint);
880 mlir::OpBuilder::InsertionGuard guardSwitch(builder);
881 builder.restoreInsertionPoint(insertPoint);
884 subStmtKind = SubStmtKind::Default;
885 builder.createYield(loc);
887 subStmtKind = SubStmtKind::Case;
888 builder.createYield(loc);
893 insertPoint = builder.saveInsertionPoint();
928 if (subStmtKind == SubStmtKind::Case) {
930 }
else if (subStmtKind == SubStmtKind::Default) {
932 buildingTopLevelCase);
933 }
else if (buildingTopLevelCase) {
937 builder.restoreInsertionPoint(insertPoint);
945 bool buildingTopLevelCase) {
946 cir::CaseOpKind
kind;
947 mlir::ArrayAttr value;
953 condType = builder.getUIntNTy(1);
959 llvm::APSInt endVal = rhs->EvaluateKnownConstInt(
getContext());
960 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal),
961 cir::IntAttr::get(condType, endVal)});
962 kind = cir::CaseOpKind::Range;
964 value = builder.getArrayAttr({cir::IntAttr::get(condType, intVal)});
965 kind = cir::CaseOpKind::Equal;
969 buildingTopLevelCase);
974 bool buildingTopLevelCase) {
976 cir::CaseOpKind::Default, buildingTopLevelCase);
980 bool buildingTopLevelCase) {
982 "build switch case without specifying the type of the condition");
986 buildingTopLevelCase);
990 buildingTopLevelCase);
992 llvm_unreachable(
"expect case or default stmt");
1000 cgm.getCodeGenOpts(), attrs, mustProgress);
1007 auto convertFlag = [&](
bool set) {
1008 return set ? mlir::UnitAttr::get(ctx) : mlir::UnitAttr();
1010 auto convertStateToBool =
1014 return mlir::BoolAttr();
1016 return mlir::BoolAttr::get(ctx,
true);
1018 return mlir::BoolAttr::get(ctx,
false);
1020 llvm_unreachable(
"'full' only applies to unrolling");
1022 llvm_unreachable(
"unknown bool state");
1026 -> std::optional<cir::LoopUnrollMode> {
1029 return std::nullopt;
1031 return cir::LoopUnrollMode::Enable;
1033 return cir::LoopUnrollMode::Disable;
1035 return cir::LoopUnrollMode::Full;
1038 llvm_unreachable(
"unknown unroll state");
1050 auto hints = cir::LoopHintAttr::get(
1063 if (hints.isEmpty())
1069 cir::LoopHintAttr loopHints) {
1072 loopOp.setLoopHintsAttr(loopHints);
1073 loopOp.setLoopIdAttr(
1074 mlir::DistinctAttr::create(mlir::UnitAttr::get(loopOp->getContext())));
1082 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
1083 mlir::LogicalResult loopRes = mlir::success();
1087 return mlir::failure();
1089 return mlir::failure();
1091 return mlir::failure();
1093 return mlir::failure();
1097 cir::LoopHintAttr loopHints =
1100 forOp = builder.createFor(
1103 [&](mlir::OpBuilder &b, mlir::Location loc) {
1104 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1105 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1106 mlir::Value condVal = evaluateExprAsBool(s.getCond());
1107 builder.createCondition(condVal);
1110 [&](mlir::OpBuilder &b, mlir::Location loc) {
1114 RunCleanupsScope bodyScope(*this);
1115 bool useCurrentScope = true;
1116 if (emitStmt(s.getLoopVarStmt(), useCurrentScope).failed())
1117 loopRes = mlir::failure();
1118 if (emitStmt(s.getBody(), useCurrentScope).failed())
1119 loopRes = mlir::failure();
1123 [&](mlir::OpBuilder &b, mlir::Location loc) {
1125 if (emitStmt(s.getInc(), true).failed())
1126 loopRes = mlir::failure();
1127 builder.createYield(loc);
1133 mlir::LogicalResult res = mlir::success();
1135 cir::ScopeOp::create(builder, scopeLoc,
1136 [&](mlir::OpBuilder &b, mlir::Location loc) {
1142 builder.getInsertionBlock()};
1143 res = forStmtBuilder();
1150 return mlir::success();
1157 auto forStmtBuilder = [&]() -> mlir::LogicalResult {
1158 mlir::LogicalResult loopRes = mlir::success();
1162 return mlir::failure();
1165 cir::LoopHintAttr loopHints =
getLoopHints(attrs, mustProgress);
1175 condVarExtendedTemporaries =
1177 bool needsCondCleanup =
1180 shouldEmitLifetimeMarkersForAutoVar() ||
1181 !condVarExtendedTemporaries.empty());
1184 auto condBuilder = [&](mlir::OpBuilder &b, mlir::Location loc) {
1187 mlir::Value condVal;
1192 condVarExtendedTemporaries);
1198 condVal = cir::ConstantOp::create(b, loc, builder.getTrueAttr());
1200 builder.createCondition(condVal);
1202 auto bodyBuilder = [&](mlir::OpBuilder &b, mlir::Location loc) {
1207 loopRes = mlir::failure();
1210 auto stepBuilder = [&](mlir::OpBuilder &b, mlir::Location loc) {
1213 loopRes = mlir::failure();
1214 builder.createYield(loc);
1217 if (needsCondCleanup) {
1218 cir::CleanupKind cleanupKind =
getLangOpts().Exceptions
1219 ? cir::CleanupKind::All
1220 : cir::CleanupKind::Normal;
1221 forOp = builder.createFor(
1224 [&](mlir::OpBuilder &b, mlir::Location loc) {
1225 loopCondScope.emitIntoCleanupRegion(loc);
1226 builder.createYield(loc);
1231 bodyBuilder, stepBuilder);
1238 auto res = mlir::success();
1240 cir::ScopeOp::create(builder, scopeLoc,
1241 [&](mlir::OpBuilder &b, mlir::Location loc) {
1243 builder.getInsertionBlock()};
1244 res = forStmtBuilder();
1251 return mlir::success();
1256 cir::DoWhileOp doWhileOp;
1258 auto doStmtBuilder = [&]() -> mlir::LogicalResult {
1259 mlir::LogicalResult loopRes = mlir::success();
1262 cir::LoopHintAttr loopHints =
getLoopHints(attrs, mustProgress);
1264 doWhileOp = builder.createDoWhile(
1267 [&](mlir::OpBuilder &b, mlir::Location loc) {
1268 assert(!cir::MissingFeatures::createProfileWeightsForLoop());
1269 assert(!cir::MissingFeatures::emitCondLikelihoodViaExpectIntrinsic());
1273 mlir::Value condVal = evaluateExprAsBool(s.getCond());
1274 builder.createCondition(condVal);
1277 [&](mlir::OpBuilder &b, mlir::Location loc) {
1279 RunCleanupsScope bodyScope(*this);
1280 if (emitStmt(s.getBody(), false).failed())
1281 loopRes = mlir::failure();
1288 mlir::LogicalResult res = mlir::success();
1290 cir::ScopeOp::create(builder, scopeLoc,
1291 [&](mlir::OpBuilder &b, mlir::Location loc) {
1293 builder.getInsertionBlock()};
1294 res = doStmtBuilder();
1301 return mlir::success();
1307 cir::WhileOp whileOp;
1309 auto whileStmtBuilder = [&]() -> mlir::LogicalResult {
1310 mlir::LogicalResult loopRes = mlir::success();
1313 cir::LoopHintAttr loopHints =
getLoopHints(attrs, mustProgress);
1322 condVarExtendedTemporaries =
1324 bool needsCondCleanup =
1327 shouldEmitLifetimeMarkersForAutoVar() ||
1328 !condVarExtendedTemporaries.empty());
1331 auto condBuilder = [&](mlir::OpBuilder &b, mlir::Location loc) {
1337 condVarExtendedTemporaries);
1342 builder.createCondition(condVal);
1344 auto bodyBuilder = [&](mlir::OpBuilder &b, mlir::Location loc) {
1348 loopRes = mlir::failure();
1352 if (needsCondCleanup) {
1353 cir::CleanupKind cleanupKind =
getLangOpts().Exceptions
1354 ? cir::CleanupKind::All
1355 : cir::CleanupKind::Normal;
1356 whileOp = builder.createWhile(
1359 [&](mlir::OpBuilder &b, mlir::Location loc) {
1360 loopCondScope.emitIntoCleanupRegion(loc);
1361 builder.createYield(loc);
1372 mlir::LogicalResult res = mlir::success();
1374 cir::ScopeOp::create(builder, scopeLoc,
1375 [&](mlir::OpBuilder &b, mlir::Location loc) {
1377 builder.getInsertionBlock()};
1378 res = whileStmtBuilder();
1385 return mlir::success();
1405 mlir::Block *switchBlock = builder.getBlock();
1411 builder.setInsertionPointToEnd(switchBlock);
1418 auto *c = body.front();
1421 return mlir::failure();
1423 body = body.drop_front();
1429 mlir::Block *lastBlock = builder.getBlock();
1430 switchBlock = builder.createBlock(switchBlock->getParent());
1431 builder.setInsertionPointToEnd(lastBlock);
1435 for (
auto *c : body) {
1436 if (
auto *
switchCase = dyn_cast<SwitchCase>(c)) {
1437 builder.setInsertionPointToEnd(switchBlock);
1443 return mlir::failure();
1450 return mlir::failure();
1453 return mlir::success();
1464 auto switchStmtBuilder = [&]() -> mlir::LogicalResult {
1467 return mlir::failure();
1479 condV = builder.createBoolToInt(condV, builder.getUIntNTy(1));
1487 mlir::LogicalResult res = mlir::success();
1488 swop = SwitchOp::create(
1491 [&](mlir::OpBuilder &b, mlir::Location loc, mlir::OperationState &os) {
1492 curLexScope->setAsSwitch();
1494 condTypeStack.push_back(condV.getType());
1496 res = emitSwitchBody(s.getBody());
1498 condTypeStack.pop_back();
1506 mlir::LogicalResult res = mlir::success();
1507 cir::ScopeOp::create(builder, scopeLoc,
1508 [&](mlir::OpBuilder &b, mlir::Location loc) {
1510 builder.getInsertionBlock()};
1511 res = switchStmtBuilder();
1515 swop.collectCases(cases);
1516 for (
auto caseOp : cases)
1541 assert(rv.
isComplex() &&
"Unknown rvalue kind?");
1551 cir::AllocaOp retAlloca =
1552 mlir::cast<cir::AllocaOp>(
fnRetAlloca->getDefiningOp());
1553 auto value = cir::LoadOp::create(builder, loc, retAlloca.getAllocaType(),
1556 cir::ReturnOp::create(builder, loc, {value});
static mlir::LogicalResult emitStmtWithResult(CIRGenFunction &cgf, const Stmt *exprResult, AggValueSlot slot, Address *lastValue)
static void setLoopHints(cir::LoopOpInterface loopOp, cir::LoopHintAttr loopHints)
static clang::AtomicOptions getAdjustedAtomicOptions(clang::AtomicOptions ao, const AtomicAttr *aa)
Compute the atomic options that apply for the extent of a clang::atomic attributed statement,...
Defines the clang::Expr interface and subclasses for C++ expressions.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
This file defines OpenACC AST classes for statement-level contructs.
This file defines OpenMP AST classes for executable directives and clauses.
This file defines SYCL AST classes used to represent calls to SYCL kernels.
Attr - This represents one attribute.
Represents an attribute applied to a statement.
ArrayRef< const Attr * > getAttrs() const
BreakStmt - This represents a break.
mlir::Value getPointer() const
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Captures cleanups for variables whose lifetime ends in a region owned by an enclosing op rather than ...
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void forceCleanup(ArrayRef< mlir::Value * > valuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
mlir::LogicalResult emitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &s)
mlir::LogicalResult emitOMPParallelMasterTaskLoopSimdDirective(const OMPParallelMasterTaskLoopSimdDirective &s)
mlir::LogicalResult emitOMPSimdDirective(const OMPSimdDirective &s)
mlir::Value emitCheckedArgForAssume(const Expr *e)
Emits an argument for a call to a __builtin_assume.
mlir::LogicalResult 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)
EHScopeStack::stable_iterator prologueCleanupDepth
The cleanup depth enclosing all the cleanups associated with the parameters.
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)
mlir::Value evaluateExprAsBool(const clang::Expr *e)
Perform the usual unary conversions on the specified expression and compare the result against zero,...
void emitAggregateCopy(LValue dest, LValue src, QualType eltTy, AggValueSlot::Overlap_t mayOverlap, bool isVolatile=false)
Emit an aggregate copy.
mlir::LogicalResult emitForStmt(const clang::ForStmt &s, llvm::ArrayRef< const Attr * > attrs={})
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 emitDoStmt(const clang::DoStmt &s, llvm::ArrayRef< const Attr * > attrs={})
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)
void emitLoopConditionVariable(const clang::VarDecl &d, CapturedCleanups &condCleanup, llvm::ArrayRef< QualType > extendedTemporaries)
Emit a loop's condition-variable declaration.
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 emitWhileStmt(const clang::WhileStmt &s, llvm::ArrayRef< const Attr * > attrs={})
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::LogicalResult emitAsmStmt(const clang::AsmStmt &s)
mlir::LogicalResult emitOMPFlattenDirective(const OMPFlattenDirective &s)
mlir::LogicalResult emitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &s)
mlir::LogicalResult emitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective &s)
mlir::LogicalResult emitOMPOrderedStandaloneDirective(const OMPOrderedStandaloneDirective &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 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 emitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective &s)
mlir::LogicalResult emitOMPInterchangeDirective(const OMPInterchangeDirective &s)
mlir::LogicalResult emitOMPDispatchDirective(const OMPDispatchDirective &s)
mlir::LogicalResult emitOMPParallelDirective(const OMPParallelDirective &s)
mlir::LogicalResult emitCXXTryStmt(const clang::CXXTryStmt &s, cxxTryBodyEmitter &bodyCallback, bool isFnTryBlock=false)
mlir::LogicalResult emitAttributedStmt(const AttributedStmt &s)
mlir::LogicalResult emitOMPForSimdDirective(const OMPForSimdDirective &s)
mlir::LogicalResult emitOMPTaskLoopDirective(const OMPTaskLoopDirective &s)
Address returnValue
The temporary alloca to hold the return value.
mlir::LogicalResult emitOMPTargetDataDirective(const OMPTargetDataDirective &s)
mlir::LogicalResult emitLabel(const clang::LabelDecl &d)
mlir::LogicalResult emitOMPTargetParallelGenericLoopDirective(const OMPTargetParallelGenericLoopDirective &s)
static bool hasAggregateEvaluationKind(clang::QualType type)
mlir::LogicalResult emitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &s)
mlir::LogicalResult emitOMPMaskedTaskLoopSimdDirective(const OMPMaskedTaskLoopSimdDirective &s)
mlir::LogicalResult emitOMPAtomicDirective(const OMPAtomicDirective &s)
mlir::LogicalResult emitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &s)
mlir::LogicalResult emitBreakStmt(const clang::BreakStmt &s)
mlir::LogicalResult emitIndirectGotoStmt(const IndirectGotoStmt &s)
const CallExpr * mustTailCall
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)
bool checkIfLoopMustProgress(const clang::Expr *controllingExpression, bool hasEmptyBody)
cir::LoopHintAttr getLoopHints(llvm::ArrayRef< const Attr * > attrs, bool mustProgress)
Build the hints that get attached to a loop, or a null attribute if there is nothing to say about it.
mlir::LogicalResult emitContinueStmt(const clang::ContinueStmt &s)
mlir::LogicalResult emitOMPTaskyieldDirective(const OMPTaskyieldDirective &s)
mlir::LogicalResult emitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective &s)
mlir::LogicalResult emitOMPScanDirective(const OMPScanDirective &s)
llvm::SmallVector< mlir::Type, 2 > condTypeStack
The type of the condition for the emitting switch statement.
mlir::LogicalResult emitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &s)
void emitStopPoint(const Stmt *s)
Build a debug stoppoint if we are emitting debug info.
mlir::LogicalResult emitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &s)
mlir::LogicalResult emitOpenACCHostDataConstruct(const OpenACCHostDataConstruct &s)
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
mlir::LogicalResult emitIfStmt(const clang::IfStmt &s)
mlir::LogicalResult emitOMPForDirective(const OMPForDirective &s)
mlir::LogicalResult emitOMPMasterDirective(const OMPMasterDirective &s)
AggValueSlot::Overlap_t getOverlapForReturnValue()
Determine whether a return value slot may overlap some other object.
mlir::LogicalResult emitSwitchCase(const clang::SwitchCase &s, bool buildingTopLevelCase)
mlir::LogicalResult emitOMPMetaDirective(const OMPMetaDirective &s)
mlir::LogicalResult emitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &s)
void emitDecl(const clang::Decl &d, bool evaluateConditionDecl=false)
mlir::LogicalResult emitOMPParallelGenericLoopDirective(const OMPParallelGenericLoopDirective &s)
mlir::LogicalResult emitOMPMaskedDirective(const OMPMaskedDirective &s)
mlir::LogicalResult emitOMPSplitDirective(const OMPSplitDirective &s)
llvm::DenseMap< const VarDecl *, mlir::Value > nrvoFlags
A mapping from NRVO variables to the flags used to indicate when the NRVO has been applied to this va...
CIRGenModule & getCIRGenModule()
mlir::MLIRContext & getMLIRContext()
mlir::LogicalResult emitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct &s)
mlir::LogicalResult emitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &s)
bool containsLabel(const clang::Stmt *s, bool ignoreCaseStmts=false)
Return true if the statement contains a label in it.
mlir::LogicalResult emitOMPOrderedBlockAssocDirective(const OMPOrderedBlockAssocDirective &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 emitLabelStmt(const clang::LabelStmt &s)
mlir::LogicalResult emitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &s)
LexicalScope * curLexScope
void terminateStructuredRegionBody(mlir::Region &r, mlir::Location loc)
clang::ASTContext & getContext() const
mlir::LogicalResult emitCoroutineBody(const CoroutineBodyStmt &s)
mlir::LogicalResult emitCompoundStmt(const clang::CompoundStmt &s, Address *lastValue=nullptr, AggValueSlot slot=AggValueSlot::ignored())
mlir::LogicalResult emitGotoStmt(const clang::GotoStmt &s)
bool inAlwaysInlineAttributedStmt
True if the current statement has always_inline attribute.
bool inNoInlineAttributedStmt
True if the current statement has noinline attribute.
mlir::LogicalResult emitOMPParallelMasterTaskLoopDirective(const OMPParallelMasterTaskLoopDirective &s)
static llvm::SmallVector< QualType, 2 > getLifetimeExtendedTemporariesWithDestructor(const clang::VarDecl &d)
The types of the temporaries with a destructor that the initializer of the variable d,...
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)
mlir::LogicalResult emitSYCLKernelCallStmt(const SYCLKernelCallStmt &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.
mlir::Value getComplexValue() const
Return the value of this complex value.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getRangeStmt()
SourceLocation getEndLoc() const LLVM_READONLY
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
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.
SourceLocation getEndLoc() const
This represents one expression.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
SourceLocation getEndLoc() const
GotoStmt - This represents a direct goto.
LabelDecl * getLabel() const
IfStmt - This represents an if/then/else.
bool isNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
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.
LabelDecl * getDecl() const
SourceLocation getKwLoc() const
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;.
const VarDecl * getNRVOCandidate() const
Retrieve the variable that might be used for the named return value optimization.
Encodes a location in the source.
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const char * getStmtClassName() const
SwitchStmt - This represents a 'switch' stmt.
bool isAllEnumCasesCovered() const
Returns true if the SwitchStmt is a switch of an enum value and all cases have been explicitly covere...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SourceLocation getBeginLoc() const
Represents a variable declaration or definition.
bool isNRVOVariable() const
Determine whether this local variable can be used with the named return value optimization (NRVO).
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
SourceLocation getEndLoc() const LLVM_READONLY
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
void updateLoopAttributes(LoopAttributes &Attrs, ASTContext &Ctx, const CodeGenOptions &CGOpts, llvm::ArrayRef< const Attr * > StmtAttrs, bool MustProgress)
Update Attrs with the loop hints in StmtAttrs (#pragma clang loop, #pragma unroll,...
bool hasEmptyLoopBody(const LoopStmt &S)
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.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
@ Default
Set to the current date and time.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
@ Other
Other implicit parameter.
static bool aggValueSlotGC()
static bool createProfileWeightsForLoop()
static bool loopInfoStack()
static bool emitCondLikelihoodViaExpectIntrinsic()
static bool constantFoldSwitchStatement()
static bool insertBuiltinUnpredictable()
static bool generateDebugInfo()
static bool incrementProfileCounter()
unsigned fine_grained_memory
unsigned ignore_denormal_mode
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
Attributes that may be specified on loops.
bool LICMDisabled
Value for llvm.licm.disable metadata.
LVEnableState VectorizeEnable
Value for llvm.loop.vectorize.enable metadata.
LVEnableState VectorizeScalable
unsigned UnrollCount
llvm.unroll.
LVEnableState UnrollEnable
Value for llvm.loop.unroll.* metadata (enable, disable, or full).
unsigned PipelineInitiationInterval
Value for llvm.loop.pipeline.iicount metadata.
unsigned UnrollAndJamCount
llvm.unroll.
unsigned CodeAlign
Value for 'llvm.loop.align' metadata.
unsigned VectorizeWidth
Value for llvm.loop.vectorize.width metadata.
LVEnableState UnrollAndJamEnable
Value for llvm.loop.unroll_and_jam.* metadata (enable, disable, or full).
LVEnableState VectorizePredicateEnable
Value for llvm.loop.vectorize.predicate metadata.
bool PipelineDisabled
Value for llvm.loop.pipeline.disable metadata.
bool IsParallel
Generate llvm.loop.parallel metadata for loads and stores.
LVEnableState
State of loop vectorization or unrolling.
bool MustProgress
Value for whether the loop is required to make progress.
LVEnableState DistributeEnable
Value for llvm.loop.distribute.enable metadata.
unsigned InterleaveCount
Value for llvm.loop.interleave.count metadata.