10b57cec5SDimitry Andric //===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This contains code to emit Stmt nodes as LLVM code. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "CGDebugInfo.h" 145ffd83dbSDimitry Andric #include "CGOpenMPRuntime.h" 15480093f4SDimitry Andric #include "CodeGenFunction.h" 160b57cec5SDimitry Andric #include "CodeGenModule.h" 170b57cec5SDimitry Andric #include "TargetInfo.h" 18480093f4SDimitry Andric #include "clang/AST/Attr.h" 19fe6060f1SDimitry Andric #include "clang/AST/Expr.h" 20fe6060f1SDimitry Andric #include "clang/AST/Stmt.h" 210b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h" 220b57cec5SDimitry Andric #include "clang/Basic/Builtins.h" 23e8d8bef9SDimitry Andric #include "clang/Basic/DiagnosticSema.h" 240b57cec5SDimitry Andric #include "clang/Basic/PrettyStackTrace.h" 255ffd83dbSDimitry Andric #include "clang/Basic/SourceManager.h" 260b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 2706c3fb27SDimitry Andric #include "llvm/ADT/ArrayRef.h" 2806c3fb27SDimitry Andric #include "llvm/ADT/DenseMap.h" 29e8d8bef9SDimitry Andric #include "llvm/ADT/SmallSet.h" 300b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 31349cc55cSDimitry Andric #include "llvm/IR/Assumptions.h" 320b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 330b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h" 340b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 350b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 365ffd83dbSDimitry Andric #include "llvm/Support/SaveAndRestore.h" 37bdd1243dSDimitry Andric #include <optional> 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric using namespace clang; 400b57cec5SDimitry Andric using namespace CodeGen; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 430b57cec5SDimitry Andric // Statement Emission 440b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 450b57cec5SDimitry Andric 460fca6ea1SDimitry Andric namespace llvm { 470fca6ea1SDimitry Andric extern cl::opt<bool> EnableSingleByteCoverage; 480fca6ea1SDimitry Andric } // namespace llvm 490fca6ea1SDimitry Andric 500b57cec5SDimitry Andric void CodeGenFunction::EmitStopPoint(const Stmt *S) { 510b57cec5SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) { 520b57cec5SDimitry Andric SourceLocation Loc; 530b57cec5SDimitry Andric Loc = S->getBeginLoc(); 540b57cec5SDimitry Andric DI->EmitLocation(Builder, Loc); 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric LastStopPoint = Loc; 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) { 610b57cec5SDimitry Andric assert(S && "Null statement?"); 620b57cec5SDimitry Andric PGO.setCurrentStmt(S); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric // These statements have their own debug info handling. 65e8d8bef9SDimitry Andric if (EmitSimpleStmt(S, Attrs)) 660b57cec5SDimitry Andric return; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric // Check if we are generating unreachable code. 690b57cec5SDimitry Andric if (!HaveInsertPoint()) { 700b57cec5SDimitry Andric // If so, and the statement doesn't contain a label, then we do not need to 710b57cec5SDimitry Andric // generate actual code. This is safe because (1) the current point is 720b57cec5SDimitry Andric // unreachable, so we don't need to execute the code, and (2) we've already 730b57cec5SDimitry Andric // handled the statements which update internal data structures (like the 740b57cec5SDimitry Andric // local variable map) which could be used by subsequent statements. 750b57cec5SDimitry Andric if (!ContainsLabel(S)) { 760b57cec5SDimitry Andric // Verify that any decl statements were handled as simple, they may be in 770b57cec5SDimitry Andric // scope of subsequent reachable statements. 780b57cec5SDimitry Andric assert(!isa<DeclStmt>(*S) && "Unexpected DeclStmt!"); 790b57cec5SDimitry Andric return; 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric // Otherwise, make a new block to hold the code. 830b57cec5SDimitry Andric EnsureInsertPoint(); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric // Generate a stoppoint if we are emitting debug info. 870b57cec5SDimitry Andric EmitStopPoint(S); 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric // Ignore all OpenMP directives except for simd if OpenMP with Simd is 900b57cec5SDimitry Andric // enabled. 910b57cec5SDimitry Andric if (getLangOpts().OpenMP && getLangOpts().OpenMPSimd) { 920b57cec5SDimitry Andric if (const auto *D = dyn_cast<OMPExecutableDirective>(S)) { 930b57cec5SDimitry Andric EmitSimpleOMPExecutableDirective(*D); 940b57cec5SDimitry Andric return; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric switch (S->getStmtClass()) { 990b57cec5SDimitry Andric case Stmt::NoStmtClass: 1000b57cec5SDimitry Andric case Stmt::CXXCatchStmtClass: 1010b57cec5SDimitry Andric case Stmt::SEHExceptStmtClass: 1020b57cec5SDimitry Andric case Stmt::SEHFinallyStmtClass: 1030b57cec5SDimitry Andric case Stmt::MSDependentExistsStmtClass: 1040b57cec5SDimitry Andric llvm_unreachable("invalid statement class to emit generically"); 1050b57cec5SDimitry Andric case Stmt::NullStmtClass: 1060b57cec5SDimitry Andric case Stmt::CompoundStmtClass: 1070b57cec5SDimitry Andric case Stmt::DeclStmtClass: 1080b57cec5SDimitry Andric case Stmt::LabelStmtClass: 1090b57cec5SDimitry Andric case Stmt::AttributedStmtClass: 1100b57cec5SDimitry Andric case Stmt::GotoStmtClass: 1110b57cec5SDimitry Andric case Stmt::BreakStmtClass: 1120b57cec5SDimitry Andric case Stmt::ContinueStmtClass: 1130b57cec5SDimitry Andric case Stmt::DefaultStmtClass: 1140b57cec5SDimitry Andric case Stmt::CaseStmtClass: 1150b57cec5SDimitry Andric case Stmt::SEHLeaveStmtClass: 1160b57cec5SDimitry Andric llvm_unreachable("should have emitted these statements as simple"); 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric #define STMT(Type, Base) 1190b57cec5SDimitry Andric #define ABSTRACT_STMT(Op) 1200b57cec5SDimitry Andric #define EXPR(Type, Base) \ 1210b57cec5SDimitry Andric case Stmt::Type##Class: 1220b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc" 1230b57cec5SDimitry Andric { 1240b57cec5SDimitry Andric // Remember the block we came in on. 1250b57cec5SDimitry Andric llvm::BasicBlock *incoming = Builder.GetInsertBlock(); 1260b57cec5SDimitry Andric assert(incoming && "expression emission must have an insertion point"); 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric EmitIgnoredExpr(cast<Expr>(S)); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric llvm::BasicBlock *outgoing = Builder.GetInsertBlock(); 1310b57cec5SDimitry Andric assert(outgoing && "expression emission cleared block!"); 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric // The expression emitters assume (reasonably!) that the insertion 1340b57cec5SDimitry Andric // point is always set. To maintain that, the call-emission code 1350b57cec5SDimitry Andric // for noreturn functions has to enter a new block with no 1360b57cec5SDimitry Andric // predecessors. We want to kill that block and mark the current 1370b57cec5SDimitry Andric // insertion point unreachable in the common case of a call like 1380b57cec5SDimitry Andric // "exit();". Since expression emission doesn't otherwise create 1390b57cec5SDimitry Andric // blocks with no predecessors, we can just test for that. 1400b57cec5SDimitry Andric // However, we must be careful not to do this to our incoming 1410b57cec5SDimitry Andric // block, because *statement* emission does sometimes create 1420b57cec5SDimitry Andric // reachable blocks which will have no predecessors until later in 1430b57cec5SDimitry Andric // the function. This occurs with, e.g., labels that are not 1440b57cec5SDimitry Andric // reachable by fallthrough. 1450b57cec5SDimitry Andric if (incoming != outgoing && outgoing->use_empty()) { 1460b57cec5SDimitry Andric outgoing->eraseFromParent(); 1470b57cec5SDimitry Andric Builder.ClearInsertionPoint(); 1480b57cec5SDimitry Andric } 1490b57cec5SDimitry Andric break; 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric case Stmt::IndirectGotoStmtClass: 1530b57cec5SDimitry Andric EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break; 1560b57cec5SDimitry Andric case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S), Attrs); break; 1570b57cec5SDimitry Andric case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S), Attrs); break; 1580b57cec5SDimitry Andric case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S), Attrs); break; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break; 1630b57cec5SDimitry Andric case Stmt::GCCAsmStmtClass: // Intentional fall-through. 1640b57cec5SDimitry Andric case Stmt::MSAsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break; 1650b57cec5SDimitry Andric case Stmt::CoroutineBodyStmtClass: 1660b57cec5SDimitry Andric EmitCoroutineBody(cast<CoroutineBodyStmt>(*S)); 1670b57cec5SDimitry Andric break; 1680b57cec5SDimitry Andric case Stmt::CoreturnStmtClass: 1690b57cec5SDimitry Andric EmitCoreturnStmt(cast<CoreturnStmt>(*S)); 1700b57cec5SDimitry Andric break; 1710b57cec5SDimitry Andric case Stmt::CapturedStmtClass: { 1720b57cec5SDimitry Andric const CapturedStmt *CS = cast<CapturedStmt>(S); 1730b57cec5SDimitry Andric EmitCapturedStmt(*CS, CS->getCapturedRegionKind()); 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric break; 1760b57cec5SDimitry Andric case Stmt::ObjCAtTryStmtClass: 1770b57cec5SDimitry Andric EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S)); 1780b57cec5SDimitry Andric break; 1790b57cec5SDimitry Andric case Stmt::ObjCAtCatchStmtClass: 1800b57cec5SDimitry Andric llvm_unreachable( 1810b57cec5SDimitry Andric "@catch statements should be handled by EmitObjCAtTryStmt"); 1820b57cec5SDimitry Andric case Stmt::ObjCAtFinallyStmtClass: 1830b57cec5SDimitry Andric llvm_unreachable( 1840b57cec5SDimitry Andric "@finally statements should be handled by EmitObjCAtTryStmt"); 1850b57cec5SDimitry Andric case Stmt::ObjCAtThrowStmtClass: 1860b57cec5SDimitry Andric EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S)); 1870b57cec5SDimitry Andric break; 1880b57cec5SDimitry Andric case Stmt::ObjCAtSynchronizedStmtClass: 1890b57cec5SDimitry Andric EmitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(*S)); 1900b57cec5SDimitry Andric break; 1910b57cec5SDimitry Andric case Stmt::ObjCForCollectionStmtClass: 1920b57cec5SDimitry Andric EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S)); 1930b57cec5SDimitry Andric break; 1940b57cec5SDimitry Andric case Stmt::ObjCAutoreleasePoolStmtClass: 1950b57cec5SDimitry Andric EmitObjCAutoreleasePoolStmt(cast<ObjCAutoreleasePoolStmt>(*S)); 1960b57cec5SDimitry Andric break; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric case Stmt::CXXTryStmtClass: 1990b57cec5SDimitry Andric EmitCXXTryStmt(cast<CXXTryStmt>(*S)); 2000b57cec5SDimitry Andric break; 2010b57cec5SDimitry Andric case Stmt::CXXForRangeStmtClass: 2020b57cec5SDimitry Andric EmitCXXForRangeStmt(cast<CXXForRangeStmt>(*S), Attrs); 2030b57cec5SDimitry Andric break; 2040b57cec5SDimitry Andric case Stmt::SEHTryStmtClass: 2050b57cec5SDimitry Andric EmitSEHTryStmt(cast<SEHTryStmt>(*S)); 2060b57cec5SDimitry Andric break; 207349cc55cSDimitry Andric case Stmt::OMPMetaDirectiveClass: 208349cc55cSDimitry Andric EmitOMPMetaDirective(cast<OMPMetaDirective>(*S)); 209349cc55cSDimitry Andric break; 210fe6060f1SDimitry Andric case Stmt::OMPCanonicalLoopClass: 211fe6060f1SDimitry Andric EmitOMPCanonicalLoop(cast<OMPCanonicalLoop>(S)); 212fe6060f1SDimitry Andric break; 2130b57cec5SDimitry Andric case Stmt::OMPParallelDirectiveClass: 2140b57cec5SDimitry Andric EmitOMPParallelDirective(cast<OMPParallelDirective>(*S)); 2150b57cec5SDimitry Andric break; 2160b57cec5SDimitry Andric case Stmt::OMPSimdDirectiveClass: 2170b57cec5SDimitry Andric EmitOMPSimdDirective(cast<OMPSimdDirective>(*S)); 2180b57cec5SDimitry Andric break; 219fe6060f1SDimitry Andric case Stmt::OMPTileDirectiveClass: 220fe6060f1SDimitry Andric EmitOMPTileDirective(cast<OMPTileDirective>(*S)); 221fe6060f1SDimitry Andric break; 222fe6060f1SDimitry Andric case Stmt::OMPUnrollDirectiveClass: 223fe6060f1SDimitry Andric EmitOMPUnrollDirective(cast<OMPUnrollDirective>(*S)); 224fe6060f1SDimitry Andric break; 2250fca6ea1SDimitry Andric case Stmt::OMPReverseDirectiveClass: 2260fca6ea1SDimitry Andric EmitOMPReverseDirective(cast<OMPReverseDirective>(*S)); 2270fca6ea1SDimitry Andric break; 2280fca6ea1SDimitry Andric case Stmt::OMPInterchangeDirectiveClass: 2290fca6ea1SDimitry Andric EmitOMPInterchangeDirective(cast<OMPInterchangeDirective>(*S)); 2300fca6ea1SDimitry Andric break; 2310b57cec5SDimitry Andric case Stmt::OMPForDirectiveClass: 2320b57cec5SDimitry Andric EmitOMPForDirective(cast<OMPForDirective>(*S)); 2330b57cec5SDimitry Andric break; 2340b57cec5SDimitry Andric case Stmt::OMPForSimdDirectiveClass: 2350b57cec5SDimitry Andric EmitOMPForSimdDirective(cast<OMPForSimdDirective>(*S)); 2360b57cec5SDimitry Andric break; 2370b57cec5SDimitry Andric case Stmt::OMPSectionsDirectiveClass: 2380b57cec5SDimitry Andric EmitOMPSectionsDirective(cast<OMPSectionsDirective>(*S)); 2390b57cec5SDimitry Andric break; 2400b57cec5SDimitry Andric case Stmt::OMPSectionDirectiveClass: 2410b57cec5SDimitry Andric EmitOMPSectionDirective(cast<OMPSectionDirective>(*S)); 2420b57cec5SDimitry Andric break; 2430b57cec5SDimitry Andric case Stmt::OMPSingleDirectiveClass: 2440b57cec5SDimitry Andric EmitOMPSingleDirective(cast<OMPSingleDirective>(*S)); 2450b57cec5SDimitry Andric break; 2460b57cec5SDimitry Andric case Stmt::OMPMasterDirectiveClass: 2470b57cec5SDimitry Andric EmitOMPMasterDirective(cast<OMPMasterDirective>(*S)); 2480b57cec5SDimitry Andric break; 2490b57cec5SDimitry Andric case Stmt::OMPCriticalDirectiveClass: 2500b57cec5SDimitry Andric EmitOMPCriticalDirective(cast<OMPCriticalDirective>(*S)); 2510b57cec5SDimitry Andric break; 2520b57cec5SDimitry Andric case Stmt::OMPParallelForDirectiveClass: 2530b57cec5SDimitry Andric EmitOMPParallelForDirective(cast<OMPParallelForDirective>(*S)); 2540b57cec5SDimitry Andric break; 2550b57cec5SDimitry Andric case Stmt::OMPParallelForSimdDirectiveClass: 2560b57cec5SDimitry Andric EmitOMPParallelForSimdDirective(cast<OMPParallelForSimdDirective>(*S)); 2570b57cec5SDimitry Andric break; 258480093f4SDimitry Andric case Stmt::OMPParallelMasterDirectiveClass: 259480093f4SDimitry Andric EmitOMPParallelMasterDirective(cast<OMPParallelMasterDirective>(*S)); 260480093f4SDimitry Andric break; 2610b57cec5SDimitry Andric case Stmt::OMPParallelSectionsDirectiveClass: 2620b57cec5SDimitry Andric EmitOMPParallelSectionsDirective(cast<OMPParallelSectionsDirective>(*S)); 2630b57cec5SDimitry Andric break; 2640b57cec5SDimitry Andric case Stmt::OMPTaskDirectiveClass: 2650b57cec5SDimitry Andric EmitOMPTaskDirective(cast<OMPTaskDirective>(*S)); 2660b57cec5SDimitry Andric break; 2670b57cec5SDimitry Andric case Stmt::OMPTaskyieldDirectiveClass: 2680b57cec5SDimitry Andric EmitOMPTaskyieldDirective(cast<OMPTaskyieldDirective>(*S)); 2690b57cec5SDimitry Andric break; 270bdd1243dSDimitry Andric case Stmt::OMPErrorDirectiveClass: 271bdd1243dSDimitry Andric EmitOMPErrorDirective(cast<OMPErrorDirective>(*S)); 272bdd1243dSDimitry Andric break; 2730b57cec5SDimitry Andric case Stmt::OMPBarrierDirectiveClass: 2740b57cec5SDimitry Andric EmitOMPBarrierDirective(cast<OMPBarrierDirective>(*S)); 2750b57cec5SDimitry Andric break; 2760b57cec5SDimitry Andric case Stmt::OMPTaskwaitDirectiveClass: 2770b57cec5SDimitry Andric EmitOMPTaskwaitDirective(cast<OMPTaskwaitDirective>(*S)); 2780b57cec5SDimitry Andric break; 2790b57cec5SDimitry Andric case Stmt::OMPTaskgroupDirectiveClass: 2800b57cec5SDimitry Andric EmitOMPTaskgroupDirective(cast<OMPTaskgroupDirective>(*S)); 2810b57cec5SDimitry Andric break; 2820b57cec5SDimitry Andric case Stmt::OMPFlushDirectiveClass: 2830b57cec5SDimitry Andric EmitOMPFlushDirective(cast<OMPFlushDirective>(*S)); 2840b57cec5SDimitry Andric break; 2855ffd83dbSDimitry Andric case Stmt::OMPDepobjDirectiveClass: 2865ffd83dbSDimitry Andric EmitOMPDepobjDirective(cast<OMPDepobjDirective>(*S)); 2875ffd83dbSDimitry Andric break; 2885ffd83dbSDimitry Andric case Stmt::OMPScanDirectiveClass: 2895ffd83dbSDimitry Andric EmitOMPScanDirective(cast<OMPScanDirective>(*S)); 2905ffd83dbSDimitry Andric break; 2910b57cec5SDimitry Andric case Stmt::OMPOrderedDirectiveClass: 2920b57cec5SDimitry Andric EmitOMPOrderedDirective(cast<OMPOrderedDirective>(*S)); 2930b57cec5SDimitry Andric break; 2940b57cec5SDimitry Andric case Stmt::OMPAtomicDirectiveClass: 2950b57cec5SDimitry Andric EmitOMPAtomicDirective(cast<OMPAtomicDirective>(*S)); 2960b57cec5SDimitry Andric break; 2970b57cec5SDimitry Andric case Stmt::OMPTargetDirectiveClass: 2980b57cec5SDimitry Andric EmitOMPTargetDirective(cast<OMPTargetDirective>(*S)); 2990b57cec5SDimitry Andric break; 3000b57cec5SDimitry Andric case Stmt::OMPTeamsDirectiveClass: 3010b57cec5SDimitry Andric EmitOMPTeamsDirective(cast<OMPTeamsDirective>(*S)); 3020b57cec5SDimitry Andric break; 3030b57cec5SDimitry Andric case Stmt::OMPCancellationPointDirectiveClass: 3040b57cec5SDimitry Andric EmitOMPCancellationPointDirective(cast<OMPCancellationPointDirective>(*S)); 3050b57cec5SDimitry Andric break; 3060b57cec5SDimitry Andric case Stmt::OMPCancelDirectiveClass: 3070b57cec5SDimitry Andric EmitOMPCancelDirective(cast<OMPCancelDirective>(*S)); 3080b57cec5SDimitry Andric break; 3090b57cec5SDimitry Andric case Stmt::OMPTargetDataDirectiveClass: 3100b57cec5SDimitry Andric EmitOMPTargetDataDirective(cast<OMPTargetDataDirective>(*S)); 3110b57cec5SDimitry Andric break; 3120b57cec5SDimitry Andric case Stmt::OMPTargetEnterDataDirectiveClass: 3130b57cec5SDimitry Andric EmitOMPTargetEnterDataDirective(cast<OMPTargetEnterDataDirective>(*S)); 3140b57cec5SDimitry Andric break; 3150b57cec5SDimitry Andric case Stmt::OMPTargetExitDataDirectiveClass: 3160b57cec5SDimitry Andric EmitOMPTargetExitDataDirective(cast<OMPTargetExitDataDirective>(*S)); 3170b57cec5SDimitry Andric break; 3180b57cec5SDimitry Andric case Stmt::OMPTargetParallelDirectiveClass: 3190b57cec5SDimitry Andric EmitOMPTargetParallelDirective(cast<OMPTargetParallelDirective>(*S)); 3200b57cec5SDimitry Andric break; 3210b57cec5SDimitry Andric case Stmt::OMPTargetParallelForDirectiveClass: 3220b57cec5SDimitry Andric EmitOMPTargetParallelForDirective(cast<OMPTargetParallelForDirective>(*S)); 3230b57cec5SDimitry Andric break; 3240b57cec5SDimitry Andric case Stmt::OMPTaskLoopDirectiveClass: 3250b57cec5SDimitry Andric EmitOMPTaskLoopDirective(cast<OMPTaskLoopDirective>(*S)); 3260b57cec5SDimitry Andric break; 3270b57cec5SDimitry Andric case Stmt::OMPTaskLoopSimdDirectiveClass: 3280b57cec5SDimitry Andric EmitOMPTaskLoopSimdDirective(cast<OMPTaskLoopSimdDirective>(*S)); 3290b57cec5SDimitry Andric break; 330a7dea167SDimitry Andric case Stmt::OMPMasterTaskLoopDirectiveClass: 331a7dea167SDimitry Andric EmitOMPMasterTaskLoopDirective(cast<OMPMasterTaskLoopDirective>(*S)); 332a7dea167SDimitry Andric break; 33381ad6265SDimitry Andric case Stmt::OMPMaskedTaskLoopDirectiveClass: 33481ad6265SDimitry Andric llvm_unreachable("masked taskloop directive not supported yet."); 33581ad6265SDimitry Andric break; 336a7dea167SDimitry Andric case Stmt::OMPMasterTaskLoopSimdDirectiveClass: 337a7dea167SDimitry Andric EmitOMPMasterTaskLoopSimdDirective( 338a7dea167SDimitry Andric cast<OMPMasterTaskLoopSimdDirective>(*S)); 339a7dea167SDimitry Andric break; 34081ad6265SDimitry Andric case Stmt::OMPMaskedTaskLoopSimdDirectiveClass: 34181ad6265SDimitry Andric llvm_unreachable("masked taskloop simd directive not supported yet."); 34281ad6265SDimitry Andric break; 343a7dea167SDimitry Andric case Stmt::OMPParallelMasterTaskLoopDirectiveClass: 344a7dea167SDimitry Andric EmitOMPParallelMasterTaskLoopDirective( 345a7dea167SDimitry Andric cast<OMPParallelMasterTaskLoopDirective>(*S)); 346a7dea167SDimitry Andric break; 34781ad6265SDimitry Andric case Stmt::OMPParallelMaskedTaskLoopDirectiveClass: 34881ad6265SDimitry Andric llvm_unreachable("parallel masked taskloop directive not supported yet."); 34981ad6265SDimitry Andric break; 350480093f4SDimitry Andric case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass: 351480093f4SDimitry Andric EmitOMPParallelMasterTaskLoopSimdDirective( 352480093f4SDimitry Andric cast<OMPParallelMasterTaskLoopSimdDirective>(*S)); 353480093f4SDimitry Andric break; 35481ad6265SDimitry Andric case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass: 35581ad6265SDimitry Andric llvm_unreachable( 35681ad6265SDimitry Andric "parallel masked taskloop simd directive not supported yet."); 35781ad6265SDimitry Andric break; 3580b57cec5SDimitry Andric case Stmt::OMPDistributeDirectiveClass: 3590b57cec5SDimitry Andric EmitOMPDistributeDirective(cast<OMPDistributeDirective>(*S)); 3600b57cec5SDimitry Andric break; 3610b57cec5SDimitry Andric case Stmt::OMPTargetUpdateDirectiveClass: 3620b57cec5SDimitry Andric EmitOMPTargetUpdateDirective(cast<OMPTargetUpdateDirective>(*S)); 3630b57cec5SDimitry Andric break; 3640b57cec5SDimitry Andric case Stmt::OMPDistributeParallelForDirectiveClass: 3650b57cec5SDimitry Andric EmitOMPDistributeParallelForDirective( 3660b57cec5SDimitry Andric cast<OMPDistributeParallelForDirective>(*S)); 3670b57cec5SDimitry Andric break; 3680b57cec5SDimitry Andric case Stmt::OMPDistributeParallelForSimdDirectiveClass: 3690b57cec5SDimitry Andric EmitOMPDistributeParallelForSimdDirective( 3700b57cec5SDimitry Andric cast<OMPDistributeParallelForSimdDirective>(*S)); 3710b57cec5SDimitry Andric break; 3720b57cec5SDimitry Andric case Stmt::OMPDistributeSimdDirectiveClass: 3730b57cec5SDimitry Andric EmitOMPDistributeSimdDirective(cast<OMPDistributeSimdDirective>(*S)); 3740b57cec5SDimitry Andric break; 3750b57cec5SDimitry Andric case Stmt::OMPTargetParallelForSimdDirectiveClass: 3760b57cec5SDimitry Andric EmitOMPTargetParallelForSimdDirective( 3770b57cec5SDimitry Andric cast<OMPTargetParallelForSimdDirective>(*S)); 3780b57cec5SDimitry Andric break; 3790b57cec5SDimitry Andric case Stmt::OMPTargetSimdDirectiveClass: 3800b57cec5SDimitry Andric EmitOMPTargetSimdDirective(cast<OMPTargetSimdDirective>(*S)); 3810b57cec5SDimitry Andric break; 3820b57cec5SDimitry Andric case Stmt::OMPTeamsDistributeDirectiveClass: 3830b57cec5SDimitry Andric EmitOMPTeamsDistributeDirective(cast<OMPTeamsDistributeDirective>(*S)); 3840b57cec5SDimitry Andric break; 3850b57cec5SDimitry Andric case Stmt::OMPTeamsDistributeSimdDirectiveClass: 3860b57cec5SDimitry Andric EmitOMPTeamsDistributeSimdDirective( 3870b57cec5SDimitry Andric cast<OMPTeamsDistributeSimdDirective>(*S)); 3880b57cec5SDimitry Andric break; 3890b57cec5SDimitry Andric case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: 3900b57cec5SDimitry Andric EmitOMPTeamsDistributeParallelForSimdDirective( 3910b57cec5SDimitry Andric cast<OMPTeamsDistributeParallelForSimdDirective>(*S)); 3920b57cec5SDimitry Andric break; 3930b57cec5SDimitry Andric case Stmt::OMPTeamsDistributeParallelForDirectiveClass: 3940b57cec5SDimitry Andric EmitOMPTeamsDistributeParallelForDirective( 3950b57cec5SDimitry Andric cast<OMPTeamsDistributeParallelForDirective>(*S)); 3960b57cec5SDimitry Andric break; 3970b57cec5SDimitry Andric case Stmt::OMPTargetTeamsDirectiveClass: 3980b57cec5SDimitry Andric EmitOMPTargetTeamsDirective(cast<OMPTargetTeamsDirective>(*S)); 3990b57cec5SDimitry Andric break; 4000b57cec5SDimitry Andric case Stmt::OMPTargetTeamsDistributeDirectiveClass: 4010b57cec5SDimitry Andric EmitOMPTargetTeamsDistributeDirective( 4020b57cec5SDimitry Andric cast<OMPTargetTeamsDistributeDirective>(*S)); 4030b57cec5SDimitry Andric break; 4040b57cec5SDimitry Andric case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: 4050b57cec5SDimitry Andric EmitOMPTargetTeamsDistributeParallelForDirective( 4060b57cec5SDimitry Andric cast<OMPTargetTeamsDistributeParallelForDirective>(*S)); 4070b57cec5SDimitry Andric break; 4080b57cec5SDimitry Andric case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: 4090b57cec5SDimitry Andric EmitOMPTargetTeamsDistributeParallelForSimdDirective( 4100b57cec5SDimitry Andric cast<OMPTargetTeamsDistributeParallelForSimdDirective>(*S)); 4110b57cec5SDimitry Andric break; 4120b57cec5SDimitry Andric case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: 4130b57cec5SDimitry Andric EmitOMPTargetTeamsDistributeSimdDirective( 4140b57cec5SDimitry Andric cast<OMPTargetTeamsDistributeSimdDirective>(*S)); 4150b57cec5SDimitry Andric break; 416fe6060f1SDimitry Andric case Stmt::OMPInteropDirectiveClass: 4171fd87a68SDimitry Andric EmitOMPInteropDirective(cast<OMPInteropDirective>(*S)); 418fe6060f1SDimitry Andric break; 419fe6060f1SDimitry Andric case Stmt::OMPDispatchDirectiveClass: 4205f757f3fSDimitry Andric CGM.ErrorUnsupported(S, "OpenMP dispatch directive"); 421fe6060f1SDimitry Andric break; 4225f757f3fSDimitry Andric case Stmt::OMPScopeDirectiveClass: 4230fca6ea1SDimitry Andric CGM.ErrorUnsupported(S, "scope with FE outlining"); 4240fca6ea1SDimitry Andric break; 425fe6060f1SDimitry Andric case Stmt::OMPMaskedDirectiveClass: 426fe6060f1SDimitry Andric EmitOMPMaskedDirective(cast<OMPMaskedDirective>(*S)); 427fe6060f1SDimitry Andric break; 428349cc55cSDimitry Andric case Stmt::OMPGenericLoopDirectiveClass: 429349cc55cSDimitry Andric EmitOMPGenericLoopDirective(cast<OMPGenericLoopDirective>(*S)); 430349cc55cSDimitry Andric break; 43181ad6265SDimitry Andric case Stmt::OMPTeamsGenericLoopDirectiveClass: 43206c3fb27SDimitry Andric EmitOMPTeamsGenericLoopDirective(cast<OMPTeamsGenericLoopDirective>(*S)); 43381ad6265SDimitry Andric break; 43481ad6265SDimitry Andric case Stmt::OMPTargetTeamsGenericLoopDirectiveClass: 43506c3fb27SDimitry Andric EmitOMPTargetTeamsGenericLoopDirective( 43606c3fb27SDimitry Andric cast<OMPTargetTeamsGenericLoopDirective>(*S)); 43781ad6265SDimitry Andric break; 43881ad6265SDimitry Andric case Stmt::OMPParallelGenericLoopDirectiveClass: 43906c3fb27SDimitry Andric EmitOMPParallelGenericLoopDirective( 44006c3fb27SDimitry Andric cast<OMPParallelGenericLoopDirective>(*S)); 44181ad6265SDimitry Andric break; 44281ad6265SDimitry Andric case Stmt::OMPTargetParallelGenericLoopDirectiveClass: 44306c3fb27SDimitry Andric EmitOMPTargetParallelGenericLoopDirective( 44406c3fb27SDimitry Andric cast<OMPTargetParallelGenericLoopDirective>(*S)); 44581ad6265SDimitry Andric break; 44681ad6265SDimitry Andric case Stmt::OMPParallelMaskedDirectiveClass: 44706c3fb27SDimitry Andric EmitOMPParallelMaskedDirective(cast<OMPParallelMaskedDirective>(*S)); 44881ad6265SDimitry Andric break; 4490fca6ea1SDimitry Andric case Stmt::OpenACCComputeConstructClass: 4500fca6ea1SDimitry Andric EmitOpenACCComputeConstruct(cast<OpenACCComputeConstruct>(*S)); 4510fca6ea1SDimitry Andric break; 4520fca6ea1SDimitry Andric case Stmt::OpenACCLoopConstructClass: 4530fca6ea1SDimitry Andric EmitOpenACCLoopConstruct(cast<OpenACCLoopConstruct>(*S)); 4540fca6ea1SDimitry Andric break; 4550b57cec5SDimitry Andric } 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric 458e8d8bef9SDimitry Andric bool CodeGenFunction::EmitSimpleStmt(const Stmt *S, 459e8d8bef9SDimitry Andric ArrayRef<const Attr *> Attrs) { 4600b57cec5SDimitry Andric switch (S->getStmtClass()) { 461e8d8bef9SDimitry Andric default: 462e8d8bef9SDimitry Andric return false; 463e8d8bef9SDimitry Andric case Stmt::NullStmtClass: 464e8d8bef9SDimitry Andric break; 465e8d8bef9SDimitry Andric case Stmt::CompoundStmtClass: 466e8d8bef9SDimitry Andric EmitCompoundStmt(cast<CompoundStmt>(*S)); 467e8d8bef9SDimitry Andric break; 468e8d8bef9SDimitry Andric case Stmt::DeclStmtClass: 469e8d8bef9SDimitry Andric EmitDeclStmt(cast<DeclStmt>(*S)); 470e8d8bef9SDimitry Andric break; 471e8d8bef9SDimitry Andric case Stmt::LabelStmtClass: 472e8d8bef9SDimitry Andric EmitLabelStmt(cast<LabelStmt>(*S)); 473e8d8bef9SDimitry Andric break; 4740b57cec5SDimitry Andric case Stmt::AttributedStmtClass: 475e8d8bef9SDimitry Andric EmitAttributedStmt(cast<AttributedStmt>(*S)); 476e8d8bef9SDimitry Andric break; 477e8d8bef9SDimitry Andric case Stmt::GotoStmtClass: 478e8d8bef9SDimitry Andric EmitGotoStmt(cast<GotoStmt>(*S)); 479e8d8bef9SDimitry Andric break; 480e8d8bef9SDimitry Andric case Stmt::BreakStmtClass: 481e8d8bef9SDimitry Andric EmitBreakStmt(cast<BreakStmt>(*S)); 482e8d8bef9SDimitry Andric break; 483e8d8bef9SDimitry Andric case Stmt::ContinueStmtClass: 484e8d8bef9SDimitry Andric EmitContinueStmt(cast<ContinueStmt>(*S)); 485e8d8bef9SDimitry Andric break; 486e8d8bef9SDimitry Andric case Stmt::DefaultStmtClass: 487e8d8bef9SDimitry Andric EmitDefaultStmt(cast<DefaultStmt>(*S), Attrs); 488e8d8bef9SDimitry Andric break; 489e8d8bef9SDimitry Andric case Stmt::CaseStmtClass: 490e8d8bef9SDimitry Andric EmitCaseStmt(cast<CaseStmt>(*S), Attrs); 491e8d8bef9SDimitry Andric break; 492e8d8bef9SDimitry Andric case Stmt::SEHLeaveStmtClass: 493e8d8bef9SDimitry Andric EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S)); 494e8d8bef9SDimitry Andric break; 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric return true; 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric /// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, 5000b57cec5SDimitry Andric /// this captures the expression result of the last sub-statement and returns it 5010b57cec5SDimitry Andric /// (for use by the statement expression extension). 5020b57cec5SDimitry Andric Address CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, 5030b57cec5SDimitry Andric AggValueSlot AggSlot) { 5040b57cec5SDimitry Andric PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(), 5050b57cec5SDimitry Andric "LLVM IR generation of compound statement ('{}')"); 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric // Keep track of the current cleanup stack depth, including debug scopes. 5080b57cec5SDimitry Andric LexicalScope Scope(*this, S.getSourceRange()); 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric return EmitCompoundStmtWithoutScope(S, GetLast, AggSlot); 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric Address 5140b57cec5SDimitry Andric CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S, 5150b57cec5SDimitry Andric bool GetLast, 5160b57cec5SDimitry Andric AggValueSlot AggSlot) { 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric const Stmt *ExprResult = S.getStmtExprResult(); 5190b57cec5SDimitry Andric assert((!GetLast || (GetLast && ExprResult)) && 5200b57cec5SDimitry Andric "If GetLast is true then the CompoundStmt must have a StmtExprResult"); 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric Address RetAlloca = Address::invalid(); 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric for (auto *CurStmt : S.body()) { 5250b57cec5SDimitry Andric if (GetLast && ExprResult == CurStmt) { 5260b57cec5SDimitry Andric // We have to special case labels here. They are statements, but when put 5270b57cec5SDimitry Andric // at the end of a statement expression, they yield the value of their 5280b57cec5SDimitry Andric // subexpression. Handle this by walking through all labels we encounter, 5290b57cec5SDimitry Andric // emitting them before we evaluate the subexpr. 5300b57cec5SDimitry Andric // Similar issues arise for attributed statements. 5310b57cec5SDimitry Andric while (!isa<Expr>(ExprResult)) { 5320b57cec5SDimitry Andric if (const auto *LS = dyn_cast<LabelStmt>(ExprResult)) { 5330b57cec5SDimitry Andric EmitLabel(LS->getDecl()); 5340b57cec5SDimitry Andric ExprResult = LS->getSubStmt(); 5350b57cec5SDimitry Andric } else if (const auto *AS = dyn_cast<AttributedStmt>(ExprResult)) { 5360b57cec5SDimitry Andric // FIXME: Update this if we ever have attributes that affect the 5370b57cec5SDimitry Andric // semantics of an expression. 5380b57cec5SDimitry Andric ExprResult = AS->getSubStmt(); 5390b57cec5SDimitry Andric } else { 5400b57cec5SDimitry Andric llvm_unreachable("unknown value statement"); 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric EnsureInsertPoint(); 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric const Expr *E = cast<Expr>(ExprResult); 5470b57cec5SDimitry Andric QualType ExprTy = E->getType(); 5480b57cec5SDimitry Andric if (hasAggregateEvaluationKind(ExprTy)) { 5490b57cec5SDimitry Andric EmitAggExpr(E, AggSlot); 5500b57cec5SDimitry Andric } else { 5510b57cec5SDimitry Andric // We can't return an RValue here because there might be cleanups at 5520b57cec5SDimitry Andric // the end of the StmtExpr. Because of that, we have to emit the result 5530b57cec5SDimitry Andric // here into a temporary alloca. 5540b57cec5SDimitry Andric RetAlloca = CreateMemTemp(ExprTy); 5550b57cec5SDimitry Andric EmitAnyExprToMem(E, RetAlloca, Qualifiers(), 5560b57cec5SDimitry Andric /*IsInit*/ false); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric } else { 5590b57cec5SDimitry Andric EmitStmt(CurStmt); 5600b57cec5SDimitry Andric } 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric return RetAlloca; 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric void CodeGenFunction::SimplifyForwardingBlocks(llvm::BasicBlock *BB) { 5670b57cec5SDimitry Andric llvm::BranchInst *BI = dyn_cast<llvm::BranchInst>(BB->getTerminator()); 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric // If there is a cleanup stack, then we it isn't worth trying to 5700b57cec5SDimitry Andric // simplify this block (we would need to remove it from the scope map 5710b57cec5SDimitry Andric // and cleanup entry). 5720b57cec5SDimitry Andric if (!EHStack.empty()) 5730b57cec5SDimitry Andric return; 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric // Can only simplify direct branches. 5760b57cec5SDimitry Andric if (!BI || !BI->isUnconditional()) 5770b57cec5SDimitry Andric return; 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric // Can only simplify empty blocks. 5800b57cec5SDimitry Andric if (BI->getIterator() != BB->begin()) 5810b57cec5SDimitry Andric return; 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric BB->replaceAllUsesWith(BI->getSuccessor(0)); 5840b57cec5SDimitry Andric BI->eraseFromParent(); 5850b57cec5SDimitry Andric BB->eraseFromParent(); 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) { 5890b57cec5SDimitry Andric llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric // Fall out of the current block (if necessary). 5920b57cec5SDimitry Andric EmitBranch(BB); 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric if (IsFinished && BB->use_empty()) { 5950b57cec5SDimitry Andric delete BB; 5960b57cec5SDimitry Andric return; 5970b57cec5SDimitry Andric } 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric // Place the block after the current block, if possible, or else at 6000b57cec5SDimitry Andric // the end of the function. 6010b57cec5SDimitry Andric if (CurBB && CurBB->getParent()) 602bdd1243dSDimitry Andric CurFn->insert(std::next(CurBB->getIterator()), BB); 6030b57cec5SDimitry Andric else 604bdd1243dSDimitry Andric CurFn->insert(CurFn->end(), BB); 6050b57cec5SDimitry Andric Builder.SetInsertPoint(BB); 6060b57cec5SDimitry Andric } 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) { 6090b57cec5SDimitry Andric // Emit a branch from the current block to the target one if this 6100b57cec5SDimitry Andric // was a real block. If this was just a fall-through block after a 6110b57cec5SDimitry Andric // terminator, don't emit it. 6120b57cec5SDimitry Andric llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 6130b57cec5SDimitry Andric 6140b57cec5SDimitry Andric if (!CurBB || CurBB->getTerminator()) { 6150b57cec5SDimitry Andric // If there is no insert point or the previous block is already 6160b57cec5SDimitry Andric // terminated, don't touch it. 6170b57cec5SDimitry Andric } else { 6180b57cec5SDimitry Andric // Otherwise, create a fall-through branch. 6190b57cec5SDimitry Andric Builder.CreateBr(Target); 6200b57cec5SDimitry Andric } 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric Builder.ClearInsertionPoint(); 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric void CodeGenFunction::EmitBlockAfterUses(llvm::BasicBlock *block) { 6260b57cec5SDimitry Andric bool inserted = false; 6270b57cec5SDimitry Andric for (llvm::User *u : block->users()) { 6280b57cec5SDimitry Andric if (llvm::Instruction *insn = dyn_cast<llvm::Instruction>(u)) { 629bdd1243dSDimitry Andric CurFn->insert(std::next(insn->getParent()->getIterator()), block); 6300b57cec5SDimitry Andric inserted = true; 6310b57cec5SDimitry Andric break; 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric } 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric if (!inserted) 636bdd1243dSDimitry Andric CurFn->insert(CurFn->end(), block); 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric Builder.SetInsertPoint(block); 6390b57cec5SDimitry Andric } 6400b57cec5SDimitry Andric 6410b57cec5SDimitry Andric CodeGenFunction::JumpDest 6420b57cec5SDimitry Andric CodeGenFunction::getJumpDestForLabel(const LabelDecl *D) { 6430b57cec5SDimitry Andric JumpDest &Dest = LabelMap[D]; 6440b57cec5SDimitry Andric if (Dest.isValid()) return Dest; 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric // Create, but don't insert, the new block. 6470b57cec5SDimitry Andric Dest = JumpDest(createBasicBlock(D->getName()), 6480b57cec5SDimitry Andric EHScopeStack::stable_iterator::invalid(), 6490b57cec5SDimitry Andric NextCleanupDestIndex++); 6500b57cec5SDimitry Andric return Dest; 6510b57cec5SDimitry Andric } 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric void CodeGenFunction::EmitLabel(const LabelDecl *D) { 6540b57cec5SDimitry Andric // Add this label to the current lexical scope if we're within any 6550b57cec5SDimitry Andric // normal cleanups. Jumps "in" to this label --- when permitted by 6560b57cec5SDimitry Andric // the language --- may need to be routed around such cleanups. 6570b57cec5SDimitry Andric if (EHStack.hasNormalCleanups() && CurLexicalScope) 6580b57cec5SDimitry Andric CurLexicalScope->addLabel(D); 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric JumpDest &Dest = LabelMap[D]; 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric // If we didn't need a forward reference to this label, just go 6630b57cec5SDimitry Andric // ahead and create a destination at the current scope. 6640b57cec5SDimitry Andric if (!Dest.isValid()) { 6650b57cec5SDimitry Andric Dest = getJumpDestInCurrentScope(D->getName()); 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric // Otherwise, we need to give this label a target depth and remove 6680b57cec5SDimitry Andric // it from the branch-fixups list. 6690b57cec5SDimitry Andric } else { 6700b57cec5SDimitry Andric assert(!Dest.getScopeDepth().isValid() && "already emitted label!"); 6710b57cec5SDimitry Andric Dest.setScopeDepth(EHStack.stable_begin()); 6720b57cec5SDimitry Andric ResolveBranchFixups(Dest.getBlock()); 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric 6750b57cec5SDimitry Andric EmitBlock(Dest.getBlock()); 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric // Emit debug info for labels. 6780b57cec5SDimitry Andric if (CGDebugInfo *DI = getDebugInfo()) { 679480093f4SDimitry Andric if (CGM.getCodeGenOpts().hasReducedDebugInfo()) { 6800b57cec5SDimitry Andric DI->setLocation(D->getLocation()); 6810b57cec5SDimitry Andric DI->EmitLabel(D, Builder); 6820b57cec5SDimitry Andric } 6830b57cec5SDimitry Andric } 6840b57cec5SDimitry Andric 6850b57cec5SDimitry Andric incrementProfileCounter(D->getStmt()); 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andric /// Change the cleanup scope of the labels in this lexical scope to 6890b57cec5SDimitry Andric /// match the scope of the enclosing context. 6900b57cec5SDimitry Andric void CodeGenFunction::LexicalScope::rescopeLabels() { 6910b57cec5SDimitry Andric assert(!Labels.empty()); 6920b57cec5SDimitry Andric EHScopeStack::stable_iterator innermostScope 6930b57cec5SDimitry Andric = CGF.EHStack.getInnermostNormalCleanup(); 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric // Change the scope depth of all the labels. 6960b57cec5SDimitry Andric for (SmallVectorImpl<const LabelDecl*>::const_iterator 6970b57cec5SDimitry Andric i = Labels.begin(), e = Labels.end(); i != e; ++i) { 6980b57cec5SDimitry Andric assert(CGF.LabelMap.count(*i)); 6990b57cec5SDimitry Andric JumpDest &dest = CGF.LabelMap.find(*i)->second; 7000b57cec5SDimitry Andric assert(dest.getScopeDepth().isValid()); 7010b57cec5SDimitry Andric assert(innermostScope.encloses(dest.getScopeDepth())); 7020b57cec5SDimitry Andric dest.setScopeDepth(innermostScope); 7030b57cec5SDimitry Andric } 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andric // Reparent the labels if the new scope also has cleanups. 7060b57cec5SDimitry Andric if (innermostScope != EHScopeStack::stable_end() && ParentScope) { 7070b57cec5SDimitry Andric ParentScope->Labels.append(Labels.begin(), Labels.end()); 7080b57cec5SDimitry Andric } 7090b57cec5SDimitry Andric } 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric 7120b57cec5SDimitry Andric void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { 7130b57cec5SDimitry Andric EmitLabel(S.getDecl()); 714fe6060f1SDimitry Andric 715fe6060f1SDimitry Andric // IsEHa - emit eha.scope.begin if it's a side entry of a scope 716fe6060f1SDimitry Andric if (getLangOpts().EHAsynch && S.isSideEntry()) 717fe6060f1SDimitry Andric EmitSehCppScopeBegin(); 718fe6060f1SDimitry Andric 7190b57cec5SDimitry Andric EmitStmt(S.getSubStmt()); 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric 7220b57cec5SDimitry Andric void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) { 7235ffd83dbSDimitry Andric bool nomerge = false; 72481ad6265SDimitry Andric bool noinline = false; 72581ad6265SDimitry Andric bool alwaysinline = false; 726fe6060f1SDimitry Andric const CallExpr *musttail = nullptr; 727fe6060f1SDimitry Andric 728fe6060f1SDimitry Andric for (const auto *A : S.getAttrs()) { 72981ad6265SDimitry Andric switch (A->getKind()) { 73081ad6265SDimitry Andric default: 73181ad6265SDimitry Andric break; 73281ad6265SDimitry Andric case attr::NoMerge: 7335ffd83dbSDimitry Andric nomerge = true; 73481ad6265SDimitry Andric break; 73581ad6265SDimitry Andric case attr::NoInline: 73681ad6265SDimitry Andric noinline = true; 73781ad6265SDimitry Andric break; 73881ad6265SDimitry Andric case attr::AlwaysInline: 73981ad6265SDimitry Andric alwaysinline = true; 74081ad6265SDimitry Andric break; 7410fca6ea1SDimitry Andric case attr::MustTail: { 742fe6060f1SDimitry Andric const Stmt *Sub = S.getSubStmt(); 743fe6060f1SDimitry Andric const ReturnStmt *R = cast<ReturnStmt>(Sub); 744fe6060f1SDimitry Andric musttail = cast<CallExpr>(R->getRetValue()->IgnoreParens()); 7450fca6ea1SDimitry Andric } break; 7460fca6ea1SDimitry Andric case attr::CXXAssume: { 7470fca6ea1SDimitry Andric const Expr *Assumption = cast<CXXAssumeAttr>(A)->getAssumption(); 748*c80e69b0SDimitry Andric if (getLangOpts().CXXAssumptions && Builder.GetInsertBlock() && 7490fca6ea1SDimitry Andric !Assumption->HasSideEffects(getContext())) { 7500fca6ea1SDimitry Andric llvm::Value *AssumptionVal = EvaluateExprAsBool(Assumption); 7510fca6ea1SDimitry Andric Builder.CreateAssumption(AssumptionVal); 7520fca6ea1SDimitry Andric } 7530fca6ea1SDimitry Andric } break; 754fe6060f1SDimitry Andric } 7555ffd83dbSDimitry Andric } 756bdd1243dSDimitry Andric SaveAndRestore save_nomerge(InNoMergeAttributedStmt, nomerge); 757bdd1243dSDimitry Andric SaveAndRestore save_noinline(InNoInlineAttributedStmt, noinline); 758bdd1243dSDimitry Andric SaveAndRestore save_alwaysinline(InAlwaysInlineAttributedStmt, alwaysinline); 759bdd1243dSDimitry Andric SaveAndRestore save_musttail(MustTailCall, musttail); 7600b57cec5SDimitry Andric EmitStmt(S.getSubStmt(), S.getAttrs()); 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { 7640b57cec5SDimitry Andric // If this code is reachable then emit a stop point (if generating 7650b57cec5SDimitry Andric // debug info). We have to do this ourselves because we are on the 7660b57cec5SDimitry Andric // "simple" statement path. 7670b57cec5SDimitry Andric if (HaveInsertPoint()) 7680b57cec5SDimitry Andric EmitStopPoint(&S); 7690b57cec5SDimitry Andric 7700b57cec5SDimitry Andric EmitBranchThroughCleanup(getJumpDestForLabel(S.getLabel())); 7710b57cec5SDimitry Andric } 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andric void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { 7750b57cec5SDimitry Andric if (const LabelDecl *Target = S.getConstantTarget()) { 7760b57cec5SDimitry Andric EmitBranchThroughCleanup(getJumpDestForLabel(Target)); 7770b57cec5SDimitry Andric return; 7780b57cec5SDimitry Andric } 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric // Ensure that we have an i8* for our PHI node. 7810b57cec5SDimitry Andric llvm::Value *V = Builder.CreateBitCast(EmitScalarExpr(S.getTarget()), 7820b57cec5SDimitry Andric Int8PtrTy, "addr"); 7830b57cec5SDimitry Andric llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric // Get the basic block for the indirect goto. 7860b57cec5SDimitry Andric llvm::BasicBlock *IndGotoBB = GetIndirectGotoBlock(); 7870b57cec5SDimitry Andric 7880b57cec5SDimitry Andric // The first instruction in the block has to be the PHI for the switch dest, 7890b57cec5SDimitry Andric // add an entry for this branch. 7900b57cec5SDimitry Andric cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(V, CurBB); 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andric EmitBranch(IndGotoBB); 7930b57cec5SDimitry Andric } 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric void CodeGenFunction::EmitIfStmt(const IfStmt &S) { 796349cc55cSDimitry Andric // The else branch of a consteval if statement is always the only branch that 797349cc55cSDimitry Andric // can be runtime evaluated. 798349cc55cSDimitry Andric if (S.isConsteval()) { 799349cc55cSDimitry Andric const Stmt *Executed = S.isNegatedConsteval() ? S.getThen() : S.getElse(); 800349cc55cSDimitry Andric if (Executed) { 801349cc55cSDimitry Andric RunCleanupsScope ExecutedScope(*this); 802349cc55cSDimitry Andric EmitStmt(Executed); 803349cc55cSDimitry Andric } 804349cc55cSDimitry Andric return; 805349cc55cSDimitry Andric } 806349cc55cSDimitry Andric 8070b57cec5SDimitry Andric // C99 6.8.4.1: The first substatement is executed if the expression compares 8080b57cec5SDimitry Andric // unequal to 0. The condition must be a scalar type. 8090b57cec5SDimitry Andric LexicalScope ConditionScope(*this, S.getCond()->getSourceRange()); 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric if (S.getInit()) 8120b57cec5SDimitry Andric EmitStmt(S.getInit()); 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric if (S.getConditionVariable()) 8150b57cec5SDimitry Andric EmitDecl(*S.getConditionVariable()); 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric // If the condition constant folds and can be elided, try to avoid emitting 8180b57cec5SDimitry Andric // the condition and the dead arm of the if/else. 8190b57cec5SDimitry Andric bool CondConstant; 8200b57cec5SDimitry Andric if (ConstantFoldsToSimpleInteger(S.getCond(), CondConstant, 8210b57cec5SDimitry Andric S.isConstexpr())) { 8220b57cec5SDimitry Andric // Figure out which block (then or else) is executed. 8230b57cec5SDimitry Andric const Stmt *Executed = S.getThen(); 8240b57cec5SDimitry Andric const Stmt *Skipped = S.getElse(); 8250b57cec5SDimitry Andric if (!CondConstant) // Condition false? 8260b57cec5SDimitry Andric std::swap(Executed, Skipped); 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andric // If the skipped block has no labels in it, just emit the executed block. 8290b57cec5SDimitry Andric // This avoids emitting dead code and simplifies the CFG substantially. 8300b57cec5SDimitry Andric if (S.isConstexpr() || !ContainsLabel(Skipped)) { 8310b57cec5SDimitry Andric if (CondConstant) 8320b57cec5SDimitry Andric incrementProfileCounter(&S); 8330b57cec5SDimitry Andric if (Executed) { 8340b57cec5SDimitry Andric RunCleanupsScope ExecutedScope(*this); 8350b57cec5SDimitry Andric EmitStmt(Executed); 8360b57cec5SDimitry Andric } 8370b57cec5SDimitry Andric return; 8380b57cec5SDimitry Andric } 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric // Otherwise, the condition did not fold, or we couldn't elide it. Just emit 8420b57cec5SDimitry Andric // the conditional branch. 8430b57cec5SDimitry Andric llvm::BasicBlock *ThenBlock = createBasicBlock("if.then"); 8440b57cec5SDimitry Andric llvm::BasicBlock *ContBlock = createBasicBlock("if.end"); 8450b57cec5SDimitry Andric llvm::BasicBlock *ElseBlock = ContBlock; 8460b57cec5SDimitry Andric if (S.getElse()) 8470b57cec5SDimitry Andric ElseBlock = createBasicBlock("if.else"); 8480b57cec5SDimitry Andric 849e8d8bef9SDimitry Andric // Prefer the PGO based weights over the likelihood attribute. 850e8d8bef9SDimitry Andric // When the build isn't optimized the metadata isn't used, so don't generate 851e8d8bef9SDimitry Andric // it. 852bdd1243dSDimitry Andric // Also, differentiate between disabled PGO and a never executed branch with 853bdd1243dSDimitry Andric // PGO. Assuming PGO is in use: 854bdd1243dSDimitry Andric // - we want to ignore the [[likely]] attribute if the branch is never 855bdd1243dSDimitry Andric // executed, 856bdd1243dSDimitry Andric // - assuming the profile is poor, preserving the attribute may still be 857bdd1243dSDimitry Andric // beneficial. 858bdd1243dSDimitry Andric // As an approximation, preserve the attribute only if both the branch and the 859bdd1243dSDimitry Andric // parent context were not executed. 860e8d8bef9SDimitry Andric Stmt::Likelihood LH = Stmt::LH_None; 861bdd1243dSDimitry Andric uint64_t ThenCount = getProfileCount(S.getThen()); 862bdd1243dSDimitry Andric if (!ThenCount && !getCurrentProfileCount() && 863bdd1243dSDimitry Andric CGM.getCodeGenOpts().OptimizationLevel) 864e8d8bef9SDimitry Andric LH = Stmt::getLikelihood(S.getThen(), S.getElse()); 8651db9f3b2SDimitry Andric 8661db9f3b2SDimitry Andric // When measuring MC/DC, always fully evaluate the condition up front using 8671db9f3b2SDimitry Andric // EvaluateExprAsBool() so that the test vector bitmap can be updated prior to 8681db9f3b2SDimitry Andric // executing the body of the if.then or if.else. This is useful for when 8691db9f3b2SDimitry Andric // there is a 'return' within the body, but this is particularly beneficial 8701db9f3b2SDimitry Andric // when one if-stmt is nested within another if-stmt so that all of the MC/DC 8711db9f3b2SDimitry Andric // updates are kept linear and consistent. 8721db9f3b2SDimitry Andric if (!CGM.getCodeGenOpts().MCDCCoverage) 873bdd1243dSDimitry Andric EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock, ThenCount, LH); 8741db9f3b2SDimitry Andric else { 8751db9f3b2SDimitry Andric llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 8761db9f3b2SDimitry Andric Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock); 8771db9f3b2SDimitry Andric } 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric // Emit the 'then' code. 8800b57cec5SDimitry Andric EmitBlock(ThenBlock); 8810fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 8820fca6ea1SDimitry Andric incrementProfileCounter(S.getThen()); 8830fca6ea1SDimitry Andric else 8840b57cec5SDimitry Andric incrementProfileCounter(&S); 8850b57cec5SDimitry Andric { 8860b57cec5SDimitry Andric RunCleanupsScope ThenScope(*this); 8870b57cec5SDimitry Andric EmitStmt(S.getThen()); 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric EmitBranch(ContBlock); 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric // Emit the 'else' code if present. 8920b57cec5SDimitry Andric if (const Stmt *Else = S.getElse()) { 8930b57cec5SDimitry Andric { 8940b57cec5SDimitry Andric // There is no need to emit line number for an unconditional branch. 8950b57cec5SDimitry Andric auto NL = ApplyDebugLocation::CreateEmpty(*this); 8960b57cec5SDimitry Andric EmitBlock(ElseBlock); 8970b57cec5SDimitry Andric } 8980fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to else block. 8990fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 9000fca6ea1SDimitry Andric incrementProfileCounter(Else); 9010b57cec5SDimitry Andric { 9020b57cec5SDimitry Andric RunCleanupsScope ElseScope(*this); 9030b57cec5SDimitry Andric EmitStmt(Else); 9040b57cec5SDimitry Andric } 9050b57cec5SDimitry Andric { 9060b57cec5SDimitry Andric // There is no need to emit line number for an unconditional branch. 9070b57cec5SDimitry Andric auto NL = ApplyDebugLocation::CreateEmpty(*this); 9080b57cec5SDimitry Andric EmitBranch(ContBlock); 9090b57cec5SDimitry Andric } 9100b57cec5SDimitry Andric } 9110b57cec5SDimitry Andric 9120b57cec5SDimitry Andric // Emit the continuation block for code after the if. 9130b57cec5SDimitry Andric EmitBlock(ContBlock, true); 9140fca6ea1SDimitry Andric 9150fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to continuation 9160fca6ea1SDimitry Andric // block. 9170fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 9180fca6ea1SDimitry Andric incrementProfileCounter(&S); 9190fca6ea1SDimitry Andric } 9200fca6ea1SDimitry Andric 9210fca6ea1SDimitry Andric bool CodeGenFunction::checkIfLoopMustProgress(const Expr *ControllingExpression, 9220fca6ea1SDimitry Andric bool HasEmptyBody) { 9230fca6ea1SDimitry Andric if (CGM.getCodeGenOpts().getFiniteLoops() == 9240fca6ea1SDimitry Andric CodeGenOptions::FiniteLoopsKind::Never) 9250fca6ea1SDimitry Andric return false; 9260fca6ea1SDimitry Andric 9270fca6ea1SDimitry Andric // Now apply rules for plain C (see 6.8.5.6 in C11). 9280fca6ea1SDimitry Andric // Loops with constant conditions do not have to make progress in any C 9290fca6ea1SDimitry Andric // version. 9300fca6ea1SDimitry Andric // As an extension, we consisider loops whose constant expression 9310fca6ea1SDimitry Andric // can be constant-folded. 9320fca6ea1SDimitry Andric Expr::EvalResult Result; 9330fca6ea1SDimitry Andric bool CondIsConstInt = 9340fca6ea1SDimitry Andric !ControllingExpression || 9350fca6ea1SDimitry Andric (ControllingExpression->EvaluateAsInt(Result, getContext()) && 9360fca6ea1SDimitry Andric Result.Val.isInt()); 9370fca6ea1SDimitry Andric 9380fca6ea1SDimitry Andric bool CondIsTrue = CondIsConstInt && (!ControllingExpression || 9390fca6ea1SDimitry Andric Result.Val.getInt().getBoolValue()); 9400fca6ea1SDimitry Andric 9410fca6ea1SDimitry Andric // Loops with non-constant conditions must make progress in C11 and later. 9420fca6ea1SDimitry Andric if (getLangOpts().C11 && !CondIsConstInt) 9430fca6ea1SDimitry Andric return true; 9440fca6ea1SDimitry Andric 9450fca6ea1SDimitry Andric // [C++26][intro.progress] (DR) 9460fca6ea1SDimitry Andric // The implementation may assume that any thread will eventually do one of the 9470fca6ea1SDimitry Andric // following: 9480fca6ea1SDimitry Andric // [...] 9490fca6ea1SDimitry Andric // - continue execution of a trivial infinite loop ([stmt.iter.general]). 9500fca6ea1SDimitry Andric if (CGM.getCodeGenOpts().getFiniteLoops() == 9510fca6ea1SDimitry Andric CodeGenOptions::FiniteLoopsKind::Always || 9520fca6ea1SDimitry Andric getLangOpts().CPlusPlus11) { 9530fca6ea1SDimitry Andric if (HasEmptyBody && CondIsTrue) { 9540fca6ea1SDimitry Andric CurFn->removeFnAttr(llvm::Attribute::MustProgress); 9550fca6ea1SDimitry Andric return false; 9560fca6ea1SDimitry Andric } 9570fca6ea1SDimitry Andric return true; 9580fca6ea1SDimitry Andric } 9590fca6ea1SDimitry Andric return false; 9600fca6ea1SDimitry Andric } 9610fca6ea1SDimitry Andric 9620fca6ea1SDimitry Andric // [C++26][stmt.iter.general] (DR) 9630fca6ea1SDimitry Andric // A trivially empty iteration statement is an iteration statement matching one 9640fca6ea1SDimitry Andric // of the following forms: 9650fca6ea1SDimitry Andric // - while ( expression ) ; 9660fca6ea1SDimitry Andric // - while ( expression ) { } 9670fca6ea1SDimitry Andric // - do ; while ( expression ) ; 9680fca6ea1SDimitry Andric // - do { } while ( expression ) ; 9690fca6ea1SDimitry Andric // - for ( init-statement expression(opt); ) ; 9700fca6ea1SDimitry Andric // - for ( init-statement expression(opt); ) { } 9710fca6ea1SDimitry Andric template <typename LoopStmt> static bool hasEmptyLoopBody(const LoopStmt &S) { 9720fca6ea1SDimitry Andric if constexpr (std::is_same_v<LoopStmt, ForStmt>) { 9730fca6ea1SDimitry Andric if (S.getInc()) 9740fca6ea1SDimitry Andric return false; 9750fca6ea1SDimitry Andric } 9760fca6ea1SDimitry Andric const Stmt *Body = S.getBody(); 9770fca6ea1SDimitry Andric if (!Body || isa<NullStmt>(Body)) 9780fca6ea1SDimitry Andric return true; 9790fca6ea1SDimitry Andric if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) 9800fca6ea1SDimitry Andric return Compound->body_empty(); 9810fca6ea1SDimitry Andric return false; 9820b57cec5SDimitry Andric } 9830b57cec5SDimitry Andric 9840b57cec5SDimitry Andric void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, 9850b57cec5SDimitry Andric ArrayRef<const Attr *> WhileAttrs) { 9860b57cec5SDimitry Andric // Emit the header for the loop, which will also become 9870b57cec5SDimitry Andric // the continue target. 9880b57cec5SDimitry Andric JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond"); 9890b57cec5SDimitry Andric EmitBlock(LoopHeader.getBlock()); 9900b57cec5SDimitry Andric 9910fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens()) 9920fca6ea1SDimitry Andric ConvergenceTokenStack.push_back(emitConvergenceLoopToken( 9930fca6ea1SDimitry Andric LoopHeader.getBlock(), ConvergenceTokenStack.back())); 9940fca6ea1SDimitry Andric 9950b57cec5SDimitry Andric // Create an exit block for when the condition fails, which will 9960b57cec5SDimitry Andric // also become the break target. 9970b57cec5SDimitry Andric JumpDest LoopExit = getJumpDestInCurrentScope("while.end"); 9980b57cec5SDimitry Andric 9990b57cec5SDimitry Andric // Store the blocks to use for break and continue. 10000b57cec5SDimitry Andric BreakContinueStack.push_back(BreakContinue(LoopExit, LoopHeader)); 10010b57cec5SDimitry Andric 10020b57cec5SDimitry Andric // C++ [stmt.while]p2: 10030b57cec5SDimitry Andric // When the condition of a while statement is a declaration, the 10040b57cec5SDimitry Andric // scope of the variable that is declared extends from its point 10050b57cec5SDimitry Andric // of declaration (3.3.2) to the end of the while statement. 10060b57cec5SDimitry Andric // [...] 10070b57cec5SDimitry Andric // The object created in a condition is destroyed and created 10080b57cec5SDimitry Andric // with each iteration of the loop. 10090b57cec5SDimitry Andric RunCleanupsScope ConditionScope(*this); 10100b57cec5SDimitry Andric 10110b57cec5SDimitry Andric if (S.getConditionVariable()) 10120b57cec5SDimitry Andric EmitDecl(*S.getConditionVariable()); 10130b57cec5SDimitry Andric 10140b57cec5SDimitry Andric // Evaluate the conditional in the while header. C99 6.8.5.1: The 10150b57cec5SDimitry Andric // evaluation of the controlling expression takes place before each 10160b57cec5SDimitry Andric // execution of the loop body. 10170b57cec5SDimitry Andric llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric // while(1) is common, avoid extra exit blocks. Be sure 10200b57cec5SDimitry Andric // to correctly handle break/continue though. 1021fe6060f1SDimitry Andric llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal); 10220fca6ea1SDimitry Andric bool EmitBoolCondBranch = !C || !C->isOne(); 1023e8d8bef9SDimitry Andric const SourceRange &R = S.getSourceRange(); 1024e8d8bef9SDimitry Andric LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), CGM.getCodeGenOpts(), 1025e8d8bef9SDimitry Andric WhileAttrs, SourceLocToDebugLoc(R.getBegin()), 1026fe6060f1SDimitry Andric SourceLocToDebugLoc(R.getEnd()), 10270fca6ea1SDimitry Andric checkIfLoopMustProgress(S.getCond(), hasEmptyLoopBody(S))); 10280fca6ea1SDimitry Andric 10290fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to loop condition. 10300fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 10310fca6ea1SDimitry Andric incrementProfileCounter(S.getCond()); 10320b57cec5SDimitry Andric 10330b57cec5SDimitry Andric // As long as the condition is true, go to the loop body. 10340b57cec5SDimitry Andric llvm::BasicBlock *LoopBody = createBasicBlock("while.body"); 10350b57cec5SDimitry Andric if (EmitBoolCondBranch) { 10360b57cec5SDimitry Andric llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); 10370b57cec5SDimitry Andric if (ConditionScope.requiresCleanups()) 10380b57cec5SDimitry Andric ExitBlock = createBasicBlock("while.exit"); 1039fe6060f1SDimitry Andric llvm::MDNode *Weights = 1040fe6060f1SDimitry Andric createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody())); 1041fe6060f1SDimitry Andric if (!Weights && CGM.getCodeGenOpts().OptimizationLevel) 1042fe6060f1SDimitry Andric BoolCondVal = emitCondLikelihoodViaExpectIntrinsic( 1043fe6060f1SDimitry Andric BoolCondVal, Stmt::getLikelihood(S.getBody())); 1044e8d8bef9SDimitry Andric Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, Weights); 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric if (ExitBlock != LoopExit.getBlock()) { 10470b57cec5SDimitry Andric EmitBlock(ExitBlock); 10480b57cec5SDimitry Andric EmitBranchThroughCleanup(LoopExit); 10490b57cec5SDimitry Andric } 1050e8d8bef9SDimitry Andric } else if (const Attr *A = Stmt::getLikelihoodAttr(S.getBody())) { 1051e8d8bef9SDimitry Andric CGM.getDiags().Report(A->getLocation(), 1052e8d8bef9SDimitry Andric diag::warn_attribute_has_no_effect_on_infinite_loop) 1053e8d8bef9SDimitry Andric << A << A->getRange(); 1054e8d8bef9SDimitry Andric CGM.getDiags().Report( 1055e8d8bef9SDimitry Andric S.getWhileLoc(), 1056e8d8bef9SDimitry Andric diag::note_attribute_has_no_effect_on_infinite_loop_here) 1057e8d8bef9SDimitry Andric << SourceRange(S.getWhileLoc(), S.getRParenLoc()); 10580b57cec5SDimitry Andric } 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric // Emit the loop body. We have to emit this in a cleanup scope 10610b57cec5SDimitry Andric // because it might be a singleton DeclStmt. 10620b57cec5SDimitry Andric { 10630b57cec5SDimitry Andric RunCleanupsScope BodyScope(*this); 10640b57cec5SDimitry Andric EmitBlock(LoopBody); 10650fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to the body. 10660fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 10670fca6ea1SDimitry Andric incrementProfileCounter(S.getBody()); 10680fca6ea1SDimitry Andric else 10690b57cec5SDimitry Andric incrementProfileCounter(&S); 10700b57cec5SDimitry Andric EmitStmt(S.getBody()); 10710b57cec5SDimitry Andric } 10720b57cec5SDimitry Andric 10730b57cec5SDimitry Andric BreakContinueStack.pop_back(); 10740b57cec5SDimitry Andric 10750b57cec5SDimitry Andric // Immediately force cleanup. 10760b57cec5SDimitry Andric ConditionScope.ForceCleanup(); 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric EmitStopPoint(&S); 10790b57cec5SDimitry Andric // Branch to the loop header again. 10800b57cec5SDimitry Andric EmitBranch(LoopHeader.getBlock()); 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric LoopStack.pop(); 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric // Emit the exit block. 10850b57cec5SDimitry Andric EmitBlock(LoopExit.getBlock(), true); 10860b57cec5SDimitry Andric 10870b57cec5SDimitry Andric // The LoopHeader typically is just a branch if we skipped emitting 10880b57cec5SDimitry Andric // a branch, try to erase it. 10890b57cec5SDimitry Andric if (!EmitBoolCondBranch) 10900b57cec5SDimitry Andric SimplifyForwardingBlocks(LoopHeader.getBlock()); 10910fca6ea1SDimitry Andric 10920fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to continuation 10930fca6ea1SDimitry Andric // block. 10940fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 10950fca6ea1SDimitry Andric incrementProfileCounter(&S); 10960fca6ea1SDimitry Andric 10970fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens()) 10980fca6ea1SDimitry Andric ConvergenceTokenStack.pop_back(); 10990b57cec5SDimitry Andric } 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric void CodeGenFunction::EmitDoStmt(const DoStmt &S, 11020b57cec5SDimitry Andric ArrayRef<const Attr *> DoAttrs) { 11030b57cec5SDimitry Andric JumpDest LoopExit = getJumpDestInCurrentScope("do.end"); 11040b57cec5SDimitry Andric JumpDest LoopCond = getJumpDestInCurrentScope("do.cond"); 11050b57cec5SDimitry Andric 11060b57cec5SDimitry Andric uint64_t ParentCount = getCurrentProfileCount(); 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric // Store the blocks to use for break and continue. 11090b57cec5SDimitry Andric BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond)); 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric // Emit the body of the loop. 11120b57cec5SDimitry Andric llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); 11130b57cec5SDimitry Andric 11140fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 11150fca6ea1SDimitry Andric EmitBlockWithFallThrough(LoopBody, S.getBody()); 11160fca6ea1SDimitry Andric else 11170b57cec5SDimitry Andric EmitBlockWithFallThrough(LoopBody, &S); 11180fca6ea1SDimitry Andric 11190fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens()) 11200fca6ea1SDimitry Andric ConvergenceTokenStack.push_back( 11210fca6ea1SDimitry Andric emitConvergenceLoopToken(LoopBody, ConvergenceTokenStack.back())); 11220fca6ea1SDimitry Andric 11230b57cec5SDimitry Andric { 11240b57cec5SDimitry Andric RunCleanupsScope BodyScope(*this); 11250b57cec5SDimitry Andric EmitStmt(S.getBody()); 11260b57cec5SDimitry Andric } 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric EmitBlock(LoopCond.getBlock()); 11290fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to loop condition. 11300fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 11310fca6ea1SDimitry Andric incrementProfileCounter(S.getCond()); 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric // C99 6.8.5.2: "The evaluation of the controlling expression takes place 11340b57cec5SDimitry Andric // after each execution of the loop body." 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric // Evaluate the conditional in the while header. 11370b57cec5SDimitry Andric // C99 6.8.5p2/p4: The first substatement is executed if the expression 11380b57cec5SDimitry Andric // compares unequal to 0. The condition must be a scalar type. 11390b57cec5SDimitry Andric llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 11400b57cec5SDimitry Andric 11410b57cec5SDimitry Andric BreakContinueStack.pop_back(); 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric // "do {} while (0)" is common in macros, avoid extra blocks. Be sure 11440b57cec5SDimitry Andric // to correctly handle break/continue though. 1145fe6060f1SDimitry Andric llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal); 1146fe6060f1SDimitry Andric bool EmitBoolCondBranch = !C || !C->isZero(); 1147e8d8bef9SDimitry Andric 1148e8d8bef9SDimitry Andric const SourceRange &R = S.getSourceRange(); 1149e8d8bef9SDimitry Andric LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs, 1150e8d8bef9SDimitry Andric SourceLocToDebugLoc(R.getBegin()), 1151fe6060f1SDimitry Andric SourceLocToDebugLoc(R.getEnd()), 11520fca6ea1SDimitry Andric checkIfLoopMustProgress(S.getCond(), hasEmptyLoopBody(S))); 11530b57cec5SDimitry Andric 11540b57cec5SDimitry Andric // As long as the condition is true, iterate the loop. 11550b57cec5SDimitry Andric if (EmitBoolCondBranch) { 11560b57cec5SDimitry Andric uint64_t BackedgeCount = getProfileCount(S.getBody()) - ParentCount; 11570b57cec5SDimitry Andric Builder.CreateCondBr( 11580b57cec5SDimitry Andric BoolCondVal, LoopBody, LoopExit.getBlock(), 11590b57cec5SDimitry Andric createProfileWeightsForLoop(S.getCond(), BackedgeCount)); 11600b57cec5SDimitry Andric } 11610b57cec5SDimitry Andric 11620b57cec5SDimitry Andric LoopStack.pop(); 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric // Emit the exit block. 11650b57cec5SDimitry Andric EmitBlock(LoopExit.getBlock()); 11660b57cec5SDimitry Andric 11670b57cec5SDimitry Andric // The DoCond block typically is just a branch if we skipped 11680b57cec5SDimitry Andric // emitting a branch, try to erase it. 11690b57cec5SDimitry Andric if (!EmitBoolCondBranch) 11700b57cec5SDimitry Andric SimplifyForwardingBlocks(LoopCond.getBlock()); 11710fca6ea1SDimitry Andric 11720fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to continuation 11730fca6ea1SDimitry Andric // block. 11740fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 11750fca6ea1SDimitry Andric incrementProfileCounter(&S); 11760fca6ea1SDimitry Andric 11770fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens()) 11780fca6ea1SDimitry Andric ConvergenceTokenStack.pop_back(); 11790b57cec5SDimitry Andric } 11800b57cec5SDimitry Andric 11810b57cec5SDimitry Andric void CodeGenFunction::EmitForStmt(const ForStmt &S, 11820b57cec5SDimitry Andric ArrayRef<const Attr *> ForAttrs) { 11830b57cec5SDimitry Andric JumpDest LoopExit = getJumpDestInCurrentScope("for.end"); 11840b57cec5SDimitry Andric 11850b57cec5SDimitry Andric LexicalScope ForScope(*this, S.getSourceRange()); 11860b57cec5SDimitry Andric 11870b57cec5SDimitry Andric // Evaluate the first part before the loop. 11880b57cec5SDimitry Andric if (S.getInit()) 11890b57cec5SDimitry Andric EmitStmt(S.getInit()); 11900b57cec5SDimitry Andric 11910b57cec5SDimitry Andric // Start the loop with a block that tests the condition. 11920b57cec5SDimitry Andric // If there's an increment, the continue scope will be overwritten 11930b57cec5SDimitry Andric // later. 1194fe6060f1SDimitry Andric JumpDest CondDest = getJumpDestInCurrentScope("for.cond"); 1195fe6060f1SDimitry Andric llvm::BasicBlock *CondBlock = CondDest.getBlock(); 11960b57cec5SDimitry Andric EmitBlock(CondBlock); 11970b57cec5SDimitry Andric 11980fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens()) 11990fca6ea1SDimitry Andric ConvergenceTokenStack.push_back( 12000fca6ea1SDimitry Andric emitConvergenceLoopToken(CondBlock, ConvergenceTokenStack.back())); 1201e8d8bef9SDimitry Andric 12020b57cec5SDimitry Andric const SourceRange &R = S.getSourceRange(); 12035ffd83dbSDimitry Andric LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs, 12040b57cec5SDimitry Andric SourceLocToDebugLoc(R.getBegin()), 1205fe6060f1SDimitry Andric SourceLocToDebugLoc(R.getEnd()), 12060fca6ea1SDimitry Andric checkIfLoopMustProgress(S.getCond(), hasEmptyLoopBody(S))); 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric // Create a cleanup scope for the condition variable cleanups. 12090b57cec5SDimitry Andric LexicalScope ConditionScope(*this, S.getSourceRange()); 12100b57cec5SDimitry Andric 1211fe6060f1SDimitry Andric // If the for loop doesn't have an increment we can just use the condition as 1212fe6060f1SDimitry Andric // the continue block. Otherwise, if there is no condition variable, we can 1213fe6060f1SDimitry Andric // form the continue block now. If there is a condition variable, we can't 1214fe6060f1SDimitry Andric // form the continue block until after we've emitted the condition, because 1215fe6060f1SDimitry Andric // the condition is in scope in the increment, but Sema's jump diagnostics 1216fe6060f1SDimitry Andric // ensure that there are no continues from the condition variable that jump 1217fe6060f1SDimitry Andric // to the loop increment. 1218fe6060f1SDimitry Andric JumpDest Continue; 1219fe6060f1SDimitry Andric if (!S.getInc()) 1220fe6060f1SDimitry Andric Continue = CondDest; 1221fe6060f1SDimitry Andric else if (!S.getConditionVariable()) 1222fe6060f1SDimitry Andric Continue = getJumpDestInCurrentScope("for.inc"); 1223fe6060f1SDimitry Andric BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 1224fe6060f1SDimitry Andric 12250b57cec5SDimitry Andric if (S.getCond()) { 12260b57cec5SDimitry Andric // If the for statement has a condition scope, emit the local variable 12270b57cec5SDimitry Andric // declaration. 12280b57cec5SDimitry Andric if (S.getConditionVariable()) { 12290b57cec5SDimitry Andric EmitDecl(*S.getConditionVariable()); 1230fe6060f1SDimitry Andric 1231fe6060f1SDimitry Andric // We have entered the condition variable's scope, so we're now able to 1232fe6060f1SDimitry Andric // jump to the continue block. 1233fe6060f1SDimitry Andric Continue = S.getInc() ? getJumpDestInCurrentScope("for.inc") : CondDest; 1234fe6060f1SDimitry Andric BreakContinueStack.back().ContinueBlock = Continue; 12350b57cec5SDimitry Andric } 12360b57cec5SDimitry Andric 12370fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to loop 12380fca6ea1SDimitry Andric // condition. 12390fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 12400fca6ea1SDimitry Andric incrementProfileCounter(S.getCond()); 12410fca6ea1SDimitry Andric 12420b57cec5SDimitry Andric llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); 12430b57cec5SDimitry Andric // If there are any cleanups between here and the loop-exit scope, 12440b57cec5SDimitry Andric // create a block to stage a loop exit along. 12450b57cec5SDimitry Andric if (ForScope.requiresCleanups()) 12460b57cec5SDimitry Andric ExitBlock = createBasicBlock("for.cond.cleanup"); 12470b57cec5SDimitry Andric 12480b57cec5SDimitry Andric // As long as the condition is true, iterate the loop. 12490b57cec5SDimitry Andric llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric // C99 6.8.5p2/p4: The first substatement is executed if the expression 12520b57cec5SDimitry Andric // compares unequal to 0. The condition must be a scalar type. 12530b57cec5SDimitry Andric llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 1254fe6060f1SDimitry Andric llvm::MDNode *Weights = 1255fe6060f1SDimitry Andric createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody())); 1256fe6060f1SDimitry Andric if (!Weights && CGM.getCodeGenOpts().OptimizationLevel) 1257fe6060f1SDimitry Andric BoolCondVal = emitCondLikelihoodViaExpectIntrinsic( 1258fe6060f1SDimitry Andric BoolCondVal, Stmt::getLikelihood(S.getBody())); 1259e8d8bef9SDimitry Andric 1260e8d8bef9SDimitry Andric Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights); 12610b57cec5SDimitry Andric 12620b57cec5SDimitry Andric if (ExitBlock != LoopExit.getBlock()) { 12630b57cec5SDimitry Andric EmitBlock(ExitBlock); 12640b57cec5SDimitry Andric EmitBranchThroughCleanup(LoopExit); 12650b57cec5SDimitry Andric } 12660b57cec5SDimitry Andric 12670b57cec5SDimitry Andric EmitBlock(ForBody); 12680b57cec5SDimitry Andric } else { 12690b57cec5SDimitry Andric // Treat it as a non-zero constant. Don't even create a new block for the 12700b57cec5SDimitry Andric // body, just fall into it. 12710b57cec5SDimitry Andric } 12720b57cec5SDimitry Andric 12730fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to the body. 12740fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 12750fca6ea1SDimitry Andric incrementProfileCounter(S.getBody()); 12760fca6ea1SDimitry Andric else 12770fca6ea1SDimitry Andric incrementProfileCounter(&S); 12780b57cec5SDimitry Andric { 12790b57cec5SDimitry Andric // Create a separate cleanup scope for the body, in case it is not 12800b57cec5SDimitry Andric // a compound statement. 12810b57cec5SDimitry Andric RunCleanupsScope BodyScope(*this); 12820b57cec5SDimitry Andric EmitStmt(S.getBody()); 12830b57cec5SDimitry Andric } 12840b57cec5SDimitry Andric 12850b57cec5SDimitry Andric // If there is an increment, emit it next. 12860b57cec5SDimitry Andric if (S.getInc()) { 12870b57cec5SDimitry Andric EmitBlock(Continue.getBlock()); 12880b57cec5SDimitry Andric EmitStmt(S.getInc()); 12890fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 12900fca6ea1SDimitry Andric incrementProfileCounter(S.getInc()); 12910b57cec5SDimitry Andric } 12920b57cec5SDimitry Andric 12930b57cec5SDimitry Andric BreakContinueStack.pop_back(); 12940b57cec5SDimitry Andric 12950b57cec5SDimitry Andric ConditionScope.ForceCleanup(); 12960b57cec5SDimitry Andric 12970b57cec5SDimitry Andric EmitStopPoint(&S); 12980b57cec5SDimitry Andric EmitBranch(CondBlock); 12990b57cec5SDimitry Andric 13000b57cec5SDimitry Andric ForScope.ForceCleanup(); 13010b57cec5SDimitry Andric 13020b57cec5SDimitry Andric LoopStack.pop(); 13030b57cec5SDimitry Andric 13040b57cec5SDimitry Andric // Emit the fall-through block. 13050b57cec5SDimitry Andric EmitBlock(LoopExit.getBlock(), true); 13060fca6ea1SDimitry Andric 13070fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to continuation 13080fca6ea1SDimitry Andric // block. 13090fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 13100fca6ea1SDimitry Andric incrementProfileCounter(&S); 13110fca6ea1SDimitry Andric 13120fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens()) 13130fca6ea1SDimitry Andric ConvergenceTokenStack.pop_back(); 13140b57cec5SDimitry Andric } 13150b57cec5SDimitry Andric 13160b57cec5SDimitry Andric void 13170b57cec5SDimitry Andric CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, 13180b57cec5SDimitry Andric ArrayRef<const Attr *> ForAttrs) { 13190b57cec5SDimitry Andric JumpDest LoopExit = getJumpDestInCurrentScope("for.end"); 13200b57cec5SDimitry Andric 13210b57cec5SDimitry Andric LexicalScope ForScope(*this, S.getSourceRange()); 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric // Evaluate the first pieces before the loop. 13240b57cec5SDimitry Andric if (S.getInit()) 13250b57cec5SDimitry Andric EmitStmt(S.getInit()); 13260b57cec5SDimitry Andric EmitStmt(S.getRangeStmt()); 13270b57cec5SDimitry Andric EmitStmt(S.getBeginStmt()); 13280b57cec5SDimitry Andric EmitStmt(S.getEndStmt()); 13290b57cec5SDimitry Andric 13300b57cec5SDimitry Andric // Start the loop with a block that tests the condition. 13310b57cec5SDimitry Andric // If there's an increment, the continue scope will be overwritten 13320b57cec5SDimitry Andric // later. 13330b57cec5SDimitry Andric llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 13340b57cec5SDimitry Andric EmitBlock(CondBlock); 13350b57cec5SDimitry Andric 13360fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens()) 13370fca6ea1SDimitry Andric ConvergenceTokenStack.push_back( 13380fca6ea1SDimitry Andric emitConvergenceLoopToken(CondBlock, ConvergenceTokenStack.back())); 13390fca6ea1SDimitry Andric 13400b57cec5SDimitry Andric const SourceRange &R = S.getSourceRange(); 13415ffd83dbSDimitry Andric LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs, 13420b57cec5SDimitry Andric SourceLocToDebugLoc(R.getBegin()), 13430b57cec5SDimitry Andric SourceLocToDebugLoc(R.getEnd())); 13440b57cec5SDimitry Andric 13450b57cec5SDimitry Andric // If there are any cleanups between here and the loop-exit scope, 13460b57cec5SDimitry Andric // create a block to stage a loop exit along. 13470b57cec5SDimitry Andric llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); 13480b57cec5SDimitry Andric if (ForScope.requiresCleanups()) 13490b57cec5SDimitry Andric ExitBlock = createBasicBlock("for.cond.cleanup"); 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andric // The loop body, consisting of the specified body and the loop variable. 13520b57cec5SDimitry Andric llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 13530b57cec5SDimitry Andric 13540b57cec5SDimitry Andric // The body is executed if the expression, contextually converted 13550b57cec5SDimitry Andric // to bool, is true. 13560b57cec5SDimitry Andric llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 1357fe6060f1SDimitry Andric llvm::MDNode *Weights = 1358fe6060f1SDimitry Andric createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody())); 1359fe6060f1SDimitry Andric if (!Weights && CGM.getCodeGenOpts().OptimizationLevel) 1360fe6060f1SDimitry Andric BoolCondVal = emitCondLikelihoodViaExpectIntrinsic( 1361fe6060f1SDimitry Andric BoolCondVal, Stmt::getLikelihood(S.getBody())); 1362e8d8bef9SDimitry Andric Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights); 13630b57cec5SDimitry Andric 13640b57cec5SDimitry Andric if (ExitBlock != LoopExit.getBlock()) { 13650b57cec5SDimitry Andric EmitBlock(ExitBlock); 13660b57cec5SDimitry Andric EmitBranchThroughCleanup(LoopExit); 13670b57cec5SDimitry Andric } 13680b57cec5SDimitry Andric 13690b57cec5SDimitry Andric EmitBlock(ForBody); 13700fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 13710fca6ea1SDimitry Andric incrementProfileCounter(S.getBody()); 13720fca6ea1SDimitry Andric else 13730b57cec5SDimitry Andric incrementProfileCounter(&S); 13740b57cec5SDimitry Andric 13750b57cec5SDimitry Andric // Create a block for the increment. In case of a 'continue', we jump there. 13760b57cec5SDimitry Andric JumpDest Continue = getJumpDestInCurrentScope("for.inc"); 13770b57cec5SDimitry Andric 13780b57cec5SDimitry Andric // Store the blocks to use for break and continue. 13790b57cec5SDimitry Andric BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 13800b57cec5SDimitry Andric 13810b57cec5SDimitry Andric { 13820b57cec5SDimitry Andric // Create a separate cleanup scope for the loop variable and body. 13830b57cec5SDimitry Andric LexicalScope BodyScope(*this, S.getSourceRange()); 13840b57cec5SDimitry Andric EmitStmt(S.getLoopVarStmt()); 13850b57cec5SDimitry Andric EmitStmt(S.getBody()); 13860b57cec5SDimitry Andric } 13870b57cec5SDimitry Andric 13880b57cec5SDimitry Andric EmitStopPoint(&S); 13890b57cec5SDimitry Andric // If there is an increment, emit it next. 13900b57cec5SDimitry Andric EmitBlock(Continue.getBlock()); 13910b57cec5SDimitry Andric EmitStmt(S.getInc()); 13920b57cec5SDimitry Andric 13930b57cec5SDimitry Andric BreakContinueStack.pop_back(); 13940b57cec5SDimitry Andric 13950b57cec5SDimitry Andric EmitBranch(CondBlock); 13960b57cec5SDimitry Andric 13970b57cec5SDimitry Andric ForScope.ForceCleanup(); 13980b57cec5SDimitry Andric 13990b57cec5SDimitry Andric LoopStack.pop(); 14000b57cec5SDimitry Andric 14010b57cec5SDimitry Andric // Emit the fall-through block. 14020b57cec5SDimitry Andric EmitBlock(LoopExit.getBlock(), true); 14030fca6ea1SDimitry Andric 14040fca6ea1SDimitry Andric // When single byte coverage mode is enabled, add a counter to continuation 14050fca6ea1SDimitry Andric // block. 14060fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 14070fca6ea1SDimitry Andric incrementProfileCounter(&S); 14080fca6ea1SDimitry Andric 14090fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens()) 14100fca6ea1SDimitry Andric ConvergenceTokenStack.pop_back(); 14110b57cec5SDimitry Andric } 14120b57cec5SDimitry Andric 14130b57cec5SDimitry Andric void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { 14140b57cec5SDimitry Andric if (RV.isScalar()) { 14150b57cec5SDimitry Andric Builder.CreateStore(RV.getScalarVal(), ReturnValue); 14160b57cec5SDimitry Andric } else if (RV.isAggregate()) { 14170b57cec5SDimitry Andric LValue Dest = MakeAddrLValue(ReturnValue, Ty); 14180b57cec5SDimitry Andric LValue Src = MakeAddrLValue(RV.getAggregateAddress(), Ty); 14190b57cec5SDimitry Andric EmitAggregateCopy(Dest, Src, Ty, getOverlapForReturnValue()); 14200b57cec5SDimitry Andric } else { 14210b57cec5SDimitry Andric EmitStoreOfComplex(RV.getComplexVal(), MakeAddrLValue(ReturnValue, Ty), 14220b57cec5SDimitry Andric /*init*/ true); 14230b57cec5SDimitry Andric } 14240b57cec5SDimitry Andric EmitBranchThroughCleanup(ReturnBlock); 14250b57cec5SDimitry Andric } 14260b57cec5SDimitry Andric 14275ffd83dbSDimitry Andric namespace { 14285ffd83dbSDimitry Andric // RAII struct used to save and restore a return statment's result expression. 14295ffd83dbSDimitry Andric struct SaveRetExprRAII { 14305ffd83dbSDimitry Andric SaveRetExprRAII(const Expr *RetExpr, CodeGenFunction &CGF) 14315ffd83dbSDimitry Andric : OldRetExpr(CGF.RetExpr), CGF(CGF) { 14325ffd83dbSDimitry Andric CGF.RetExpr = RetExpr; 14335ffd83dbSDimitry Andric } 14345ffd83dbSDimitry Andric ~SaveRetExprRAII() { CGF.RetExpr = OldRetExpr; } 14355ffd83dbSDimitry Andric const Expr *OldRetExpr; 14365ffd83dbSDimitry Andric CodeGenFunction &CGF; 14375ffd83dbSDimitry Andric }; 14385ffd83dbSDimitry Andric } // namespace 14395ffd83dbSDimitry Andric 14400fca6ea1SDimitry Andric /// Determine if the given call uses the swiftasync calling convention. 14410fca6ea1SDimitry Andric static bool isSwiftAsyncCallee(const CallExpr *CE) { 1442fe6060f1SDimitry Andric auto calleeQualType = CE->getCallee()->getType(); 1443fe6060f1SDimitry Andric const FunctionType *calleeType = nullptr; 1444fe6060f1SDimitry Andric if (calleeQualType->isFunctionPointerType() || 1445fe6060f1SDimitry Andric calleeQualType->isFunctionReferenceType() || 1446fe6060f1SDimitry Andric calleeQualType->isBlockPointerType() || 1447fe6060f1SDimitry Andric calleeQualType->isMemberFunctionPointerType()) { 1448fe6060f1SDimitry Andric calleeType = calleeQualType->getPointeeType()->castAs<FunctionType>(); 1449fe6060f1SDimitry Andric } else if (auto *ty = dyn_cast<FunctionType>(calleeQualType)) { 1450fe6060f1SDimitry Andric calleeType = ty; 1451fe6060f1SDimitry Andric } else if (auto CMCE = dyn_cast<CXXMemberCallExpr>(CE)) { 1452fe6060f1SDimitry Andric if (auto methodDecl = CMCE->getMethodDecl()) { 1453fe6060f1SDimitry Andric // getMethodDecl() doesn't handle member pointers at the moment. 1454fe6060f1SDimitry Andric calleeType = methodDecl->getType()->castAs<FunctionType>(); 1455fe6060f1SDimitry Andric } else { 14560fca6ea1SDimitry Andric return false; 1457fe6060f1SDimitry Andric } 1458fe6060f1SDimitry Andric } else { 14590fca6ea1SDimitry Andric return false; 1460fe6060f1SDimitry Andric } 14610fca6ea1SDimitry Andric return calleeType->getCallConv() == CallingConv::CC_SwiftAsync; 1462fe6060f1SDimitry Andric } 1463fe6060f1SDimitry Andric 14640b57cec5SDimitry Andric /// EmitReturnStmt - Note that due to GCC extensions, this can have an operand 14650b57cec5SDimitry Andric /// if the function returns void, or may be missing one if the function returns 14660b57cec5SDimitry Andric /// non-void. Fun stuff :). 14670b57cec5SDimitry Andric void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { 14680b57cec5SDimitry Andric if (requiresReturnValueCheck()) { 14690b57cec5SDimitry Andric llvm::Constant *SLoc = EmitCheckSourceLocation(S.getBeginLoc()); 14700b57cec5SDimitry Andric auto *SLocPtr = 14710b57cec5SDimitry Andric new llvm::GlobalVariable(CGM.getModule(), SLoc->getType(), false, 14720b57cec5SDimitry Andric llvm::GlobalVariable::PrivateLinkage, SLoc); 14730b57cec5SDimitry Andric SLocPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); 14740b57cec5SDimitry Andric CGM.getSanitizerMetadata()->disableSanitizerForGlobal(SLocPtr); 14750b57cec5SDimitry Andric assert(ReturnLocation.isValid() && "No valid return location"); 14765f757f3fSDimitry Andric Builder.CreateStore(SLocPtr, ReturnLocation); 14770b57cec5SDimitry Andric } 14780b57cec5SDimitry Andric 14790b57cec5SDimitry Andric // Returning from an outlined SEH helper is UB, and we already warn on it. 14800b57cec5SDimitry Andric if (IsOutlinedSEHHelper) { 14810b57cec5SDimitry Andric Builder.CreateUnreachable(); 14820b57cec5SDimitry Andric Builder.ClearInsertionPoint(); 14830b57cec5SDimitry Andric } 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric // Emit the result value, even if unused, to evaluate the side effects. 14860b57cec5SDimitry Andric const Expr *RV = S.getRetValue(); 14870b57cec5SDimitry Andric 14885ffd83dbSDimitry Andric // Record the result expression of the return statement. The recorded 14895ffd83dbSDimitry Andric // expression is used to determine whether a block capture's lifetime should 14905ffd83dbSDimitry Andric // end at the end of the full expression as opposed to the end of the scope 14915ffd83dbSDimitry Andric // enclosing the block expression. 14925ffd83dbSDimitry Andric // 14935ffd83dbSDimitry Andric // This permits a small, easily-implemented exception to our over-conservative 14945ffd83dbSDimitry Andric // rules about not jumping to statements following block literals with 14955ffd83dbSDimitry Andric // non-trivial cleanups. 14965ffd83dbSDimitry Andric SaveRetExprRAII SaveRetExpr(RV, *this); 14970b57cec5SDimitry Andric 14985ffd83dbSDimitry Andric RunCleanupsScope cleanupScope(*this); 14995ffd83dbSDimitry Andric if (const auto *EWC = dyn_cast_or_null<ExprWithCleanups>(RV)) 15005ffd83dbSDimitry Andric RV = EWC->getSubExpr(); 15010fca6ea1SDimitry Andric 15020fca6ea1SDimitry Andric // If we're in a swiftasynccall function, and the return expression is a 15030fca6ea1SDimitry Andric // call to a swiftasynccall function, mark the call as the musttail call. 15040fca6ea1SDimitry Andric std::optional<llvm::SaveAndRestore<const CallExpr *>> SaveMustTail; 15050fca6ea1SDimitry Andric if (RV && CurFnInfo && 15060fca6ea1SDimitry Andric CurFnInfo->getASTCallingConvention() == CallingConv::CC_SwiftAsync) { 15070fca6ea1SDimitry Andric if (auto CE = dyn_cast<CallExpr>(RV)) { 15080fca6ea1SDimitry Andric if (isSwiftAsyncCallee(CE)) { 15090fca6ea1SDimitry Andric SaveMustTail.emplace(MustTailCall, CE); 15100fca6ea1SDimitry Andric } 15110fca6ea1SDimitry Andric } 15120fca6ea1SDimitry Andric } 15130fca6ea1SDimitry Andric 15140b57cec5SDimitry Andric // FIXME: Clean this up by using an LValue for ReturnTemp, 15150b57cec5SDimitry Andric // EmitStoreThroughLValue, and EmitAnyExpr. 15165ffd83dbSDimitry Andric // Check if the NRVO candidate was not globalized in OpenMP mode. 15175ffd83dbSDimitry Andric if (getLangOpts().ElideConstructors && S.getNRVOCandidate() && 15185ffd83dbSDimitry Andric S.getNRVOCandidate()->isNRVOVariable() && 15195ffd83dbSDimitry Andric (!getLangOpts().OpenMP || 15205ffd83dbSDimitry Andric !CGM.getOpenMPRuntime() 15215ffd83dbSDimitry Andric .getAddressOfLocalVariable(*this, S.getNRVOCandidate()) 15225ffd83dbSDimitry Andric .isValid())) { 15230b57cec5SDimitry Andric // Apply the named return value optimization for this return statement, 15240b57cec5SDimitry Andric // which means doing nothing: the appropriate result has already been 15250b57cec5SDimitry Andric // constructed into the NRVO variable. 15260b57cec5SDimitry Andric 15270b57cec5SDimitry Andric // If there is an NRVO flag for this variable, set it to 1 into indicate 15280b57cec5SDimitry Andric // that the cleanup code should not destroy the variable. 15290b57cec5SDimitry Andric if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()]) 15300b57cec5SDimitry Andric Builder.CreateFlagStore(Builder.getTrue(), NRVOFlag); 15310b57cec5SDimitry Andric } else if (!ReturnValue.isValid() || (RV && RV->getType()->isVoidType())) { 15320b57cec5SDimitry Andric // Make sure not to return anything, but evaluate the expression 15330b57cec5SDimitry Andric // for side effects. 1534fe6060f1SDimitry Andric if (RV) { 15350b57cec5SDimitry Andric EmitAnyExpr(RV); 1536fe6060f1SDimitry Andric } 15370b57cec5SDimitry Andric } else if (!RV) { 15380b57cec5SDimitry Andric // Do nothing (return value is left uninitialized) 15390b57cec5SDimitry Andric } else if (FnRetTy->isReferenceType()) { 15400b57cec5SDimitry Andric // If this function returns a reference, take the address of the expression 15410b57cec5SDimitry Andric // rather than the value. 15420b57cec5SDimitry Andric RValue Result = EmitReferenceBindingToExpr(RV); 15430b57cec5SDimitry Andric Builder.CreateStore(Result.getScalarVal(), ReturnValue); 15440b57cec5SDimitry Andric } else { 15450b57cec5SDimitry Andric switch (getEvaluationKind(RV->getType())) { 15460fca6ea1SDimitry Andric case TEK_Scalar: { 15470fca6ea1SDimitry Andric llvm::Value *Ret = EmitScalarExpr(RV); 15480fca6ea1SDimitry Andric if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect) 15490fca6ea1SDimitry Andric EmitStoreOfScalar(Ret, MakeAddrLValue(ReturnValue, RV->getType()), 15500fca6ea1SDimitry Andric /*isInit*/ true); 15510fca6ea1SDimitry Andric else 15520fca6ea1SDimitry Andric Builder.CreateStore(Ret, ReturnValue); 15530b57cec5SDimitry Andric break; 15540fca6ea1SDimitry Andric } 15550b57cec5SDimitry Andric case TEK_Complex: 15560b57cec5SDimitry Andric EmitComplexExprIntoLValue(RV, MakeAddrLValue(ReturnValue, RV->getType()), 15570b57cec5SDimitry Andric /*isInit*/ true); 15580b57cec5SDimitry Andric break; 15590b57cec5SDimitry Andric case TEK_Aggregate: 15600b57cec5SDimitry Andric EmitAggExpr(RV, AggValueSlot::forAddr( 15610b57cec5SDimitry Andric ReturnValue, Qualifiers(), 15620b57cec5SDimitry Andric AggValueSlot::IsDestructed, 15630b57cec5SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, 15640b57cec5SDimitry Andric AggValueSlot::IsNotAliased, 15650b57cec5SDimitry Andric getOverlapForReturnValue())); 15660b57cec5SDimitry Andric break; 15670b57cec5SDimitry Andric } 15680b57cec5SDimitry Andric } 15690b57cec5SDimitry Andric 15700b57cec5SDimitry Andric ++NumReturnExprs; 15710b57cec5SDimitry Andric if (!RV || RV->isEvaluatable(getContext())) 15720b57cec5SDimitry Andric ++NumSimpleReturnExprs; 15730b57cec5SDimitry Andric 15740b57cec5SDimitry Andric cleanupScope.ForceCleanup(); 15750b57cec5SDimitry Andric EmitBranchThroughCleanup(ReturnBlock); 15760b57cec5SDimitry Andric } 15770b57cec5SDimitry Andric 15780b57cec5SDimitry Andric void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) { 15790b57cec5SDimitry Andric // As long as debug info is modeled with instructions, we have to ensure we 15800b57cec5SDimitry Andric // have a place to insert here and write the stop point here. 15810b57cec5SDimitry Andric if (HaveInsertPoint()) 15820b57cec5SDimitry Andric EmitStopPoint(&S); 15830b57cec5SDimitry Andric 15840b57cec5SDimitry Andric for (const auto *I : S.decls()) 15850b57cec5SDimitry Andric EmitDecl(*I); 15860b57cec5SDimitry Andric } 15870b57cec5SDimitry Andric 15880b57cec5SDimitry Andric void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) { 15890b57cec5SDimitry Andric assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!"); 15900b57cec5SDimitry Andric 15910b57cec5SDimitry Andric // If this code is reachable then emit a stop point (if generating 15920b57cec5SDimitry Andric // debug info). We have to do this ourselves because we are on the 15930b57cec5SDimitry Andric // "simple" statement path. 15940b57cec5SDimitry Andric if (HaveInsertPoint()) 15950b57cec5SDimitry Andric EmitStopPoint(&S); 15960b57cec5SDimitry Andric 15970b57cec5SDimitry Andric EmitBranchThroughCleanup(BreakContinueStack.back().BreakBlock); 15980b57cec5SDimitry Andric } 15990b57cec5SDimitry Andric 16000b57cec5SDimitry Andric void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) { 16010b57cec5SDimitry Andric assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 16020b57cec5SDimitry Andric 16030b57cec5SDimitry Andric // If this code is reachable then emit a stop point (if generating 16040b57cec5SDimitry Andric // debug info). We have to do this ourselves because we are on the 16050b57cec5SDimitry Andric // "simple" statement path. 16060b57cec5SDimitry Andric if (HaveInsertPoint()) 16070b57cec5SDimitry Andric EmitStopPoint(&S); 16080b57cec5SDimitry Andric 16090b57cec5SDimitry Andric EmitBranchThroughCleanup(BreakContinueStack.back().ContinueBlock); 16100b57cec5SDimitry Andric } 16110b57cec5SDimitry Andric 16120b57cec5SDimitry Andric /// EmitCaseStmtRange - If case statement range is not too big then 16130b57cec5SDimitry Andric /// add multiple cases to switch instruction, one for each value within 16140b57cec5SDimitry Andric /// the range. If range is too big then emit "if" condition check. 1615e8d8bef9SDimitry Andric void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S, 1616e8d8bef9SDimitry Andric ArrayRef<const Attr *> Attrs) { 16170b57cec5SDimitry Andric assert(S.getRHS() && "Expected RHS value in CaseStmt"); 16180b57cec5SDimitry Andric 16190b57cec5SDimitry Andric llvm::APSInt LHS = S.getLHS()->EvaluateKnownConstInt(getContext()); 16200b57cec5SDimitry Andric llvm::APSInt RHS = S.getRHS()->EvaluateKnownConstInt(getContext()); 16210b57cec5SDimitry Andric 16220b57cec5SDimitry Andric // Emit the code for this case. We do this first to make sure it is 16230b57cec5SDimitry Andric // properly chained from our predecessor before generating the 16240b57cec5SDimitry Andric // switch machinery to enter this block. 16250b57cec5SDimitry Andric llvm::BasicBlock *CaseDest = createBasicBlock("sw.bb"); 16260b57cec5SDimitry Andric EmitBlockWithFallThrough(CaseDest, &S); 16270b57cec5SDimitry Andric EmitStmt(S.getSubStmt()); 16280b57cec5SDimitry Andric 16290b57cec5SDimitry Andric // If range is empty, do nothing. 16300b57cec5SDimitry Andric if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS)) 16310b57cec5SDimitry Andric return; 16320b57cec5SDimitry Andric 1633e8d8bef9SDimitry Andric Stmt::Likelihood LH = Stmt::getLikelihood(Attrs); 16340b57cec5SDimitry Andric llvm::APInt Range = RHS - LHS; 16350b57cec5SDimitry Andric // FIXME: parameters such as this should not be hardcoded. 16360b57cec5SDimitry Andric if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) { 16370b57cec5SDimitry Andric // Range is small enough to add multiple switch instruction cases. 16380b57cec5SDimitry Andric uint64_t Total = getProfileCount(&S); 16390b57cec5SDimitry Andric unsigned NCases = Range.getZExtValue() + 1; 16400b57cec5SDimitry Andric // We only have one region counter for the entire set of cases here, so we 16410b57cec5SDimitry Andric // need to divide the weights evenly between the generated cases, ensuring 16420b57cec5SDimitry Andric // that the total weight is preserved. E.g., a weight of 5 over three cases 16430b57cec5SDimitry Andric // will be distributed as weights of 2, 2, and 1. 16440b57cec5SDimitry Andric uint64_t Weight = Total / NCases, Rem = Total % NCases; 16450b57cec5SDimitry Andric for (unsigned I = 0; I != NCases; ++I) { 16460b57cec5SDimitry Andric if (SwitchWeights) 16470b57cec5SDimitry Andric SwitchWeights->push_back(Weight + (Rem ? 1 : 0)); 1648e8d8bef9SDimitry Andric else if (SwitchLikelihood) 1649e8d8bef9SDimitry Andric SwitchLikelihood->push_back(LH); 1650e8d8bef9SDimitry Andric 16510b57cec5SDimitry Andric if (Rem) 16520b57cec5SDimitry Andric Rem--; 16530b57cec5SDimitry Andric SwitchInsn->addCase(Builder.getInt(LHS), CaseDest); 16540b57cec5SDimitry Andric ++LHS; 16550b57cec5SDimitry Andric } 16560b57cec5SDimitry Andric return; 16570b57cec5SDimitry Andric } 16580b57cec5SDimitry Andric 16590b57cec5SDimitry Andric // The range is too big. Emit "if" condition into a new block, 16600b57cec5SDimitry Andric // making sure to save and restore the current insertion point. 16610b57cec5SDimitry Andric llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock(); 16620b57cec5SDimitry Andric 16630b57cec5SDimitry Andric // Push this test onto the chain of range checks (which terminates 16640b57cec5SDimitry Andric // in the default basic block). The switch's default will be changed 16650b57cec5SDimitry Andric // to the top of this chain after switch emission is complete. 16660b57cec5SDimitry Andric llvm::BasicBlock *FalseDest = CaseRangeBlock; 16670b57cec5SDimitry Andric CaseRangeBlock = createBasicBlock("sw.caserange"); 16680b57cec5SDimitry Andric 1669bdd1243dSDimitry Andric CurFn->insert(CurFn->end(), CaseRangeBlock); 16700b57cec5SDimitry Andric Builder.SetInsertPoint(CaseRangeBlock); 16710b57cec5SDimitry Andric 16720b57cec5SDimitry Andric // Emit range check. 16730b57cec5SDimitry Andric llvm::Value *Diff = 16740b57cec5SDimitry Andric Builder.CreateSub(SwitchInsn->getCondition(), Builder.getInt(LHS)); 16750b57cec5SDimitry Andric llvm::Value *Cond = 16760b57cec5SDimitry Andric Builder.CreateICmpULE(Diff, Builder.getInt(Range), "inbounds"); 16770b57cec5SDimitry Andric 16780b57cec5SDimitry Andric llvm::MDNode *Weights = nullptr; 16790b57cec5SDimitry Andric if (SwitchWeights) { 16800b57cec5SDimitry Andric uint64_t ThisCount = getProfileCount(&S); 16810b57cec5SDimitry Andric uint64_t DefaultCount = (*SwitchWeights)[0]; 16820b57cec5SDimitry Andric Weights = createProfileWeights(ThisCount, DefaultCount); 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric // Since we're chaining the switch default through each large case range, we 16850b57cec5SDimitry Andric // need to update the weight for the default, ie, the first case, to include 16860b57cec5SDimitry Andric // this case. 16870b57cec5SDimitry Andric (*SwitchWeights)[0] += ThisCount; 1688e8d8bef9SDimitry Andric } else if (SwitchLikelihood) 1689fe6060f1SDimitry Andric Cond = emitCondLikelihoodViaExpectIntrinsic(Cond, LH); 1690e8d8bef9SDimitry Andric 16910b57cec5SDimitry Andric Builder.CreateCondBr(Cond, CaseDest, FalseDest, Weights); 16920b57cec5SDimitry Andric 16930b57cec5SDimitry Andric // Restore the appropriate insertion point. 16940b57cec5SDimitry Andric if (RestoreBB) 16950b57cec5SDimitry Andric Builder.SetInsertPoint(RestoreBB); 16960b57cec5SDimitry Andric else 16970b57cec5SDimitry Andric Builder.ClearInsertionPoint(); 16980b57cec5SDimitry Andric } 16990b57cec5SDimitry Andric 1700e8d8bef9SDimitry Andric void CodeGenFunction::EmitCaseStmt(const CaseStmt &S, 1701e8d8bef9SDimitry Andric ArrayRef<const Attr *> Attrs) { 17020b57cec5SDimitry Andric // If there is no enclosing switch instance that we're aware of, then this 17030b57cec5SDimitry Andric // case statement and its block can be elided. This situation only happens 17040b57cec5SDimitry Andric // when we've constant-folded the switch, are emitting the constant case, 17050b57cec5SDimitry Andric // and part of the constant case includes another case statement. For 17060b57cec5SDimitry Andric // instance: switch (4) { case 4: do { case 5: } while (1); } 17070b57cec5SDimitry Andric if (!SwitchInsn) { 17080b57cec5SDimitry Andric EmitStmt(S.getSubStmt()); 17090b57cec5SDimitry Andric return; 17100b57cec5SDimitry Andric } 17110b57cec5SDimitry Andric 17120b57cec5SDimitry Andric // Handle case ranges. 17130b57cec5SDimitry Andric if (S.getRHS()) { 1714e8d8bef9SDimitry Andric EmitCaseStmtRange(S, Attrs); 17150b57cec5SDimitry Andric return; 17160b57cec5SDimitry Andric } 17170b57cec5SDimitry Andric 17180b57cec5SDimitry Andric llvm::ConstantInt *CaseVal = 17190b57cec5SDimitry Andric Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext())); 17206246ae0bSDimitry Andric 17216246ae0bSDimitry Andric // Emit debuginfo for the case value if it is an enum value. 17226246ae0bSDimitry Andric const ConstantExpr *CE; 17236246ae0bSDimitry Andric if (auto ICE = dyn_cast<ImplicitCastExpr>(S.getLHS())) 17246246ae0bSDimitry Andric CE = dyn_cast<ConstantExpr>(ICE->getSubExpr()); 17256246ae0bSDimitry Andric else 17266246ae0bSDimitry Andric CE = dyn_cast<ConstantExpr>(S.getLHS()); 17276246ae0bSDimitry Andric if (CE) { 17286246ae0bSDimitry Andric if (auto DE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) 17296246ae0bSDimitry Andric if (CGDebugInfo *Dbg = getDebugInfo()) 17306246ae0bSDimitry Andric if (CGM.getCodeGenOpts().hasReducedDebugInfo()) 17316246ae0bSDimitry Andric Dbg->EmitGlobalVariable(DE->getDecl(), 17326246ae0bSDimitry Andric APValue(llvm::APSInt(CaseVal->getValue()))); 17336246ae0bSDimitry Andric } 17346246ae0bSDimitry Andric 1735e8d8bef9SDimitry Andric if (SwitchLikelihood) 1736e8d8bef9SDimitry Andric SwitchLikelihood->push_back(Stmt::getLikelihood(Attrs)); 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric // If the body of the case is just a 'break', try to not emit an empty block. 17390b57cec5SDimitry Andric // If we're profiling or we're not optimizing, leave the block in for better 17400b57cec5SDimitry Andric // debug and coverage analysis. 17410b57cec5SDimitry Andric if (!CGM.getCodeGenOpts().hasProfileClangInstr() && 17420b57cec5SDimitry Andric CGM.getCodeGenOpts().OptimizationLevel > 0 && 17430b57cec5SDimitry Andric isa<BreakStmt>(S.getSubStmt())) { 17440b57cec5SDimitry Andric JumpDest Block = BreakContinueStack.back().BreakBlock; 17450b57cec5SDimitry Andric 17460b57cec5SDimitry Andric // Only do this optimization if there are no cleanups that need emitting. 17470b57cec5SDimitry Andric if (isObviouslyBranchWithoutCleanups(Block)) { 17480b57cec5SDimitry Andric if (SwitchWeights) 17490b57cec5SDimitry Andric SwitchWeights->push_back(getProfileCount(&S)); 17500b57cec5SDimitry Andric SwitchInsn->addCase(CaseVal, Block.getBlock()); 17510b57cec5SDimitry Andric 17520b57cec5SDimitry Andric // If there was a fallthrough into this case, make sure to redirect it to 17530b57cec5SDimitry Andric // the end of the switch as well. 17540b57cec5SDimitry Andric if (Builder.GetInsertBlock()) { 17550b57cec5SDimitry Andric Builder.CreateBr(Block.getBlock()); 17560b57cec5SDimitry Andric Builder.ClearInsertionPoint(); 17570b57cec5SDimitry Andric } 17580b57cec5SDimitry Andric return; 17590b57cec5SDimitry Andric } 17600b57cec5SDimitry Andric } 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andric llvm::BasicBlock *CaseDest = createBasicBlock("sw.bb"); 17630b57cec5SDimitry Andric EmitBlockWithFallThrough(CaseDest, &S); 17640b57cec5SDimitry Andric if (SwitchWeights) 17650b57cec5SDimitry Andric SwitchWeights->push_back(getProfileCount(&S)); 17660b57cec5SDimitry Andric SwitchInsn->addCase(CaseVal, CaseDest); 17670b57cec5SDimitry Andric 17680b57cec5SDimitry Andric // Recursively emitting the statement is acceptable, but is not wonderful for 17690b57cec5SDimitry Andric // code where we have many case statements nested together, i.e.: 17700b57cec5SDimitry Andric // case 1: 17710b57cec5SDimitry Andric // case 2: 17720b57cec5SDimitry Andric // case 3: etc. 17730b57cec5SDimitry Andric // Handling this recursively will create a new block for each case statement 17740b57cec5SDimitry Andric // that falls through to the next case which is IR intensive. It also causes 17750b57cec5SDimitry Andric // deep recursion which can run into stack depth limitations. Handle 17760b57cec5SDimitry Andric // sequential non-range case statements specially. 1777e8d8bef9SDimitry Andric // 1778e8d8bef9SDimitry Andric // TODO When the next case has a likelihood attribute the code returns to the 1779e8d8bef9SDimitry Andric // recursive algorithm. Maybe improve this case if it becomes common practice 1780e8d8bef9SDimitry Andric // to use a lot of attributes. 17810b57cec5SDimitry Andric const CaseStmt *CurCase = &S; 17820b57cec5SDimitry Andric const CaseStmt *NextCase = dyn_cast<CaseStmt>(S.getSubStmt()); 17830b57cec5SDimitry Andric 17840b57cec5SDimitry Andric // Otherwise, iteratively add consecutive cases to this switch stmt. 17850b57cec5SDimitry Andric while (NextCase && NextCase->getRHS() == nullptr) { 17860b57cec5SDimitry Andric CurCase = NextCase; 17870b57cec5SDimitry Andric llvm::ConstantInt *CaseVal = 17880b57cec5SDimitry Andric Builder.getInt(CurCase->getLHS()->EvaluateKnownConstInt(getContext())); 17890b57cec5SDimitry Andric 17900b57cec5SDimitry Andric if (SwitchWeights) 17910b57cec5SDimitry Andric SwitchWeights->push_back(getProfileCount(NextCase)); 17920b57cec5SDimitry Andric if (CGM.getCodeGenOpts().hasProfileClangInstr()) { 17930b57cec5SDimitry Andric CaseDest = createBasicBlock("sw.bb"); 1794e8d8bef9SDimitry Andric EmitBlockWithFallThrough(CaseDest, CurCase); 17950b57cec5SDimitry Andric } 1796e8d8bef9SDimitry Andric // Since this loop is only executed when the CaseStmt has no attributes 1797e8d8bef9SDimitry Andric // use a hard-coded value. 1798e8d8bef9SDimitry Andric if (SwitchLikelihood) 1799e8d8bef9SDimitry Andric SwitchLikelihood->push_back(Stmt::LH_None); 18000b57cec5SDimitry Andric 18010b57cec5SDimitry Andric SwitchInsn->addCase(CaseVal, CaseDest); 18020b57cec5SDimitry Andric NextCase = dyn_cast<CaseStmt>(CurCase->getSubStmt()); 18030b57cec5SDimitry Andric } 18040b57cec5SDimitry Andric 1805349cc55cSDimitry Andric // Generate a stop point for debug info if the case statement is 1806349cc55cSDimitry Andric // followed by a default statement. A fallthrough case before a 1807349cc55cSDimitry Andric // default case gets its own branch target. 1808349cc55cSDimitry Andric if (CurCase->getSubStmt()->getStmtClass() == Stmt::DefaultStmtClass) 1809349cc55cSDimitry Andric EmitStopPoint(CurCase); 1810349cc55cSDimitry Andric 18110b57cec5SDimitry Andric // Normal default recursion for non-cases. 18120b57cec5SDimitry Andric EmitStmt(CurCase->getSubStmt()); 18130b57cec5SDimitry Andric } 18140b57cec5SDimitry Andric 1815e8d8bef9SDimitry Andric void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S, 1816e8d8bef9SDimitry Andric ArrayRef<const Attr *> Attrs) { 18170b57cec5SDimitry Andric // If there is no enclosing switch instance that we're aware of, then this 18180b57cec5SDimitry Andric // default statement can be elided. This situation only happens when we've 18190b57cec5SDimitry Andric // constant-folded the switch. 18200b57cec5SDimitry Andric if (!SwitchInsn) { 18210b57cec5SDimitry Andric EmitStmt(S.getSubStmt()); 18220b57cec5SDimitry Andric return; 18230b57cec5SDimitry Andric } 18240b57cec5SDimitry Andric 18250b57cec5SDimitry Andric llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest(); 18260b57cec5SDimitry Andric assert(DefaultBlock->empty() && 18270b57cec5SDimitry Andric "EmitDefaultStmt: Default block already defined?"); 18280b57cec5SDimitry Andric 1829e8d8bef9SDimitry Andric if (SwitchLikelihood) 1830e8d8bef9SDimitry Andric SwitchLikelihood->front() = Stmt::getLikelihood(Attrs); 1831e8d8bef9SDimitry Andric 18320b57cec5SDimitry Andric EmitBlockWithFallThrough(DefaultBlock, &S); 18330b57cec5SDimitry Andric 18340b57cec5SDimitry Andric EmitStmt(S.getSubStmt()); 18350b57cec5SDimitry Andric } 18360b57cec5SDimitry Andric 18370b57cec5SDimitry Andric /// CollectStatementsForCase - Given the body of a 'switch' statement and a 18380b57cec5SDimitry Andric /// constant value that is being switched on, see if we can dead code eliminate 18390b57cec5SDimitry Andric /// the body of the switch to a simple series of statements to emit. Basically, 18400b57cec5SDimitry Andric /// on a switch (5) we want to find these statements: 18410b57cec5SDimitry Andric /// case 5: 18420b57cec5SDimitry Andric /// printf(...); <-- 18430b57cec5SDimitry Andric /// ++i; <-- 18440b57cec5SDimitry Andric /// break; 18450b57cec5SDimitry Andric /// 18460b57cec5SDimitry Andric /// and add them to the ResultStmts vector. If it is unsafe to do this 18470b57cec5SDimitry Andric /// transformation (for example, one of the elided statements contains a label 18480b57cec5SDimitry Andric /// that might be jumped to), return CSFC_Failure. If we handled it and 'S' 18490b57cec5SDimitry Andric /// should include statements after it (e.g. the printf() line is a substmt of 18500b57cec5SDimitry Andric /// the case) then return CSFC_FallThrough. If we handled it and found a break 18510b57cec5SDimitry Andric /// statement, then return CSFC_Success. 18520b57cec5SDimitry Andric /// 18530b57cec5SDimitry Andric /// If Case is non-null, then we are looking for the specified case, checking 18540b57cec5SDimitry Andric /// that nothing we jump over contains labels. If Case is null, then we found 18550b57cec5SDimitry Andric /// the case and are looking for the break. 18560b57cec5SDimitry Andric /// 18570b57cec5SDimitry Andric /// If the recursive walk actually finds our Case, then we set FoundCase to 18580b57cec5SDimitry Andric /// true. 18590b57cec5SDimitry Andric /// 18600b57cec5SDimitry Andric enum CSFC_Result { CSFC_Failure, CSFC_FallThrough, CSFC_Success }; 18610b57cec5SDimitry Andric static CSFC_Result CollectStatementsForCase(const Stmt *S, 18620b57cec5SDimitry Andric const SwitchCase *Case, 18630b57cec5SDimitry Andric bool &FoundCase, 18640b57cec5SDimitry Andric SmallVectorImpl<const Stmt*> &ResultStmts) { 18650b57cec5SDimitry Andric // If this is a null statement, just succeed. 18660b57cec5SDimitry Andric if (!S) 18670b57cec5SDimitry Andric return Case ? CSFC_Success : CSFC_FallThrough; 18680b57cec5SDimitry Andric 18690b57cec5SDimitry Andric // If this is the switchcase (case 4: or default) that we're looking for, then 18700b57cec5SDimitry Andric // we're in business. Just add the substatement. 18710b57cec5SDimitry Andric if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) { 18720b57cec5SDimitry Andric if (S == Case) { 18730b57cec5SDimitry Andric FoundCase = true; 18740b57cec5SDimitry Andric return CollectStatementsForCase(SC->getSubStmt(), nullptr, FoundCase, 18750b57cec5SDimitry Andric ResultStmts); 18760b57cec5SDimitry Andric } 18770b57cec5SDimitry Andric 18780b57cec5SDimitry Andric // Otherwise, this is some other case or default statement, just ignore it. 18790b57cec5SDimitry Andric return CollectStatementsForCase(SC->getSubStmt(), Case, FoundCase, 18800b57cec5SDimitry Andric ResultStmts); 18810b57cec5SDimitry Andric } 18820b57cec5SDimitry Andric 18830b57cec5SDimitry Andric // If we are in the live part of the code and we found our break statement, 18840b57cec5SDimitry Andric // return a success! 18850b57cec5SDimitry Andric if (!Case && isa<BreakStmt>(S)) 18860b57cec5SDimitry Andric return CSFC_Success; 18870b57cec5SDimitry Andric 18880b57cec5SDimitry Andric // If this is a switch statement, then it might contain the SwitchCase, the 18890b57cec5SDimitry Andric // break, or neither. 18900b57cec5SDimitry Andric if (const CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) { 18910b57cec5SDimitry Andric // Handle this as two cases: we might be looking for the SwitchCase (if so 18920b57cec5SDimitry Andric // the skipped statements must be skippable) or we might already have it. 18930b57cec5SDimitry Andric CompoundStmt::const_body_iterator I = CS->body_begin(), E = CS->body_end(); 18940b57cec5SDimitry Andric bool StartedInLiveCode = FoundCase; 18950b57cec5SDimitry Andric unsigned StartSize = ResultStmts.size(); 18960b57cec5SDimitry Andric 18970b57cec5SDimitry Andric // If we've not found the case yet, scan through looking for it. 18980b57cec5SDimitry Andric if (Case) { 18990b57cec5SDimitry Andric // Keep track of whether we see a skipped declaration. The code could be 19000b57cec5SDimitry Andric // using the declaration even if it is skipped, so we can't optimize out 19010b57cec5SDimitry Andric // the decl if the kept statements might refer to it. 19020b57cec5SDimitry Andric bool HadSkippedDecl = false; 19030b57cec5SDimitry Andric 19040b57cec5SDimitry Andric // If we're looking for the case, just see if we can skip each of the 19050b57cec5SDimitry Andric // substatements. 19060b57cec5SDimitry Andric for (; Case && I != E; ++I) { 19070b57cec5SDimitry Andric HadSkippedDecl |= CodeGenFunction::mightAddDeclToScope(*I); 19080b57cec5SDimitry Andric 19090b57cec5SDimitry Andric switch (CollectStatementsForCase(*I, Case, FoundCase, ResultStmts)) { 19100b57cec5SDimitry Andric case CSFC_Failure: return CSFC_Failure; 19110b57cec5SDimitry Andric case CSFC_Success: 19120b57cec5SDimitry Andric // A successful result means that either 1) that the statement doesn't 19130b57cec5SDimitry Andric // have the case and is skippable, or 2) does contain the case value 19140b57cec5SDimitry Andric // and also contains the break to exit the switch. In the later case, 19150b57cec5SDimitry Andric // we just verify the rest of the statements are elidable. 19160b57cec5SDimitry Andric if (FoundCase) { 19170b57cec5SDimitry Andric // If we found the case and skipped declarations, we can't do the 19180b57cec5SDimitry Andric // optimization. 19190b57cec5SDimitry Andric if (HadSkippedDecl) 19200b57cec5SDimitry Andric return CSFC_Failure; 19210b57cec5SDimitry Andric 19220b57cec5SDimitry Andric for (++I; I != E; ++I) 19230b57cec5SDimitry Andric if (CodeGenFunction::ContainsLabel(*I, true)) 19240b57cec5SDimitry Andric return CSFC_Failure; 19250b57cec5SDimitry Andric return CSFC_Success; 19260b57cec5SDimitry Andric } 19270b57cec5SDimitry Andric break; 19280b57cec5SDimitry Andric case CSFC_FallThrough: 19290b57cec5SDimitry Andric // If we have a fallthrough condition, then we must have found the 19300b57cec5SDimitry Andric // case started to include statements. Consider the rest of the 19310b57cec5SDimitry Andric // statements in the compound statement as candidates for inclusion. 19320b57cec5SDimitry Andric assert(FoundCase && "Didn't find case but returned fallthrough?"); 19330b57cec5SDimitry Andric // We recursively found Case, so we're not looking for it anymore. 19340b57cec5SDimitry Andric Case = nullptr; 19350b57cec5SDimitry Andric 19360b57cec5SDimitry Andric // If we found the case and skipped declarations, we can't do the 19370b57cec5SDimitry Andric // optimization. 19380b57cec5SDimitry Andric if (HadSkippedDecl) 19390b57cec5SDimitry Andric return CSFC_Failure; 19400b57cec5SDimitry Andric break; 19410b57cec5SDimitry Andric } 19420b57cec5SDimitry Andric } 19430b57cec5SDimitry Andric 19440b57cec5SDimitry Andric if (!FoundCase) 19450b57cec5SDimitry Andric return CSFC_Success; 19460b57cec5SDimitry Andric 19470b57cec5SDimitry Andric assert(!HadSkippedDecl && "fallthrough after skipping decl"); 19480b57cec5SDimitry Andric } 19490b57cec5SDimitry Andric 19500b57cec5SDimitry Andric // If we have statements in our range, then we know that the statements are 19510b57cec5SDimitry Andric // live and need to be added to the set of statements we're tracking. 19520b57cec5SDimitry Andric bool AnyDecls = false; 19530b57cec5SDimitry Andric for (; I != E; ++I) { 19540b57cec5SDimitry Andric AnyDecls |= CodeGenFunction::mightAddDeclToScope(*I); 19550b57cec5SDimitry Andric 19560b57cec5SDimitry Andric switch (CollectStatementsForCase(*I, nullptr, FoundCase, ResultStmts)) { 19570b57cec5SDimitry Andric case CSFC_Failure: return CSFC_Failure; 19580b57cec5SDimitry Andric case CSFC_FallThrough: 19590b57cec5SDimitry Andric // A fallthrough result means that the statement was simple and just 19600b57cec5SDimitry Andric // included in ResultStmt, keep adding them afterwards. 19610b57cec5SDimitry Andric break; 19620b57cec5SDimitry Andric case CSFC_Success: 19630b57cec5SDimitry Andric // A successful result means that we found the break statement and 19640b57cec5SDimitry Andric // stopped statement inclusion. We just ensure that any leftover stmts 19650b57cec5SDimitry Andric // are skippable and return success ourselves. 19660b57cec5SDimitry Andric for (++I; I != E; ++I) 19670b57cec5SDimitry Andric if (CodeGenFunction::ContainsLabel(*I, true)) 19680b57cec5SDimitry Andric return CSFC_Failure; 19690b57cec5SDimitry Andric return CSFC_Success; 19700b57cec5SDimitry Andric } 19710b57cec5SDimitry Andric } 19720b57cec5SDimitry Andric 19730b57cec5SDimitry Andric // If we're about to fall out of a scope without hitting a 'break;', we 19740b57cec5SDimitry Andric // can't perform the optimization if there were any decls in that scope 19750b57cec5SDimitry Andric // (we'd lose their end-of-lifetime). 19760b57cec5SDimitry Andric if (AnyDecls) { 19770b57cec5SDimitry Andric // If the entire compound statement was live, there's one more thing we 19780b57cec5SDimitry Andric // can try before giving up: emit the whole thing as a single statement. 19790b57cec5SDimitry Andric // We can do that unless the statement contains a 'break;'. 19800b57cec5SDimitry Andric // FIXME: Such a break must be at the end of a construct within this one. 19810b57cec5SDimitry Andric // We could emit this by just ignoring the BreakStmts entirely. 19820b57cec5SDimitry Andric if (StartedInLiveCode && !CodeGenFunction::containsBreak(S)) { 19830b57cec5SDimitry Andric ResultStmts.resize(StartSize); 19840b57cec5SDimitry Andric ResultStmts.push_back(S); 19850b57cec5SDimitry Andric } else { 19860b57cec5SDimitry Andric return CSFC_Failure; 19870b57cec5SDimitry Andric } 19880b57cec5SDimitry Andric } 19890b57cec5SDimitry Andric 19900b57cec5SDimitry Andric return CSFC_FallThrough; 19910b57cec5SDimitry Andric } 19920b57cec5SDimitry Andric 19930b57cec5SDimitry Andric // Okay, this is some other statement that we don't handle explicitly, like a 19940b57cec5SDimitry Andric // for statement or increment etc. If we are skipping over this statement, 19950b57cec5SDimitry Andric // just verify it doesn't have labels, which would make it invalid to elide. 19960b57cec5SDimitry Andric if (Case) { 19970b57cec5SDimitry Andric if (CodeGenFunction::ContainsLabel(S, true)) 19980b57cec5SDimitry Andric return CSFC_Failure; 19990b57cec5SDimitry Andric return CSFC_Success; 20000b57cec5SDimitry Andric } 20010b57cec5SDimitry Andric 20020b57cec5SDimitry Andric // Otherwise, we want to include this statement. Everything is cool with that 20030b57cec5SDimitry Andric // so long as it doesn't contain a break out of the switch we're in. 20040b57cec5SDimitry Andric if (CodeGenFunction::containsBreak(S)) return CSFC_Failure; 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andric // Otherwise, everything is great. Include the statement and tell the caller 20070b57cec5SDimitry Andric // that we fall through and include the next statement as well. 20080b57cec5SDimitry Andric ResultStmts.push_back(S); 20090b57cec5SDimitry Andric return CSFC_FallThrough; 20100b57cec5SDimitry Andric } 20110b57cec5SDimitry Andric 20120b57cec5SDimitry Andric /// FindCaseStatementsForValue - Find the case statement being jumped to and 20130b57cec5SDimitry Andric /// then invoke CollectStatementsForCase to find the list of statements to emit 20140b57cec5SDimitry Andric /// for a switch on constant. See the comment above CollectStatementsForCase 20150b57cec5SDimitry Andric /// for more details. 20160b57cec5SDimitry Andric static bool FindCaseStatementsForValue(const SwitchStmt &S, 20170b57cec5SDimitry Andric const llvm::APSInt &ConstantCondValue, 20180b57cec5SDimitry Andric SmallVectorImpl<const Stmt*> &ResultStmts, 20190b57cec5SDimitry Andric ASTContext &C, 20200b57cec5SDimitry Andric const SwitchCase *&ResultCase) { 20210b57cec5SDimitry Andric // First step, find the switch case that is being branched to. We can do this 20220b57cec5SDimitry Andric // efficiently by scanning the SwitchCase list. 20230b57cec5SDimitry Andric const SwitchCase *Case = S.getSwitchCaseList(); 20240b57cec5SDimitry Andric const DefaultStmt *DefaultCase = nullptr; 20250b57cec5SDimitry Andric 20260b57cec5SDimitry Andric for (; Case; Case = Case->getNextSwitchCase()) { 20270b57cec5SDimitry Andric // It's either a default or case. Just remember the default statement in 20280b57cec5SDimitry Andric // case we're not jumping to any numbered cases. 20290b57cec5SDimitry Andric if (const DefaultStmt *DS = dyn_cast<DefaultStmt>(Case)) { 20300b57cec5SDimitry Andric DefaultCase = DS; 20310b57cec5SDimitry Andric continue; 20320b57cec5SDimitry Andric } 20330b57cec5SDimitry Andric 20340b57cec5SDimitry Andric // Check to see if this case is the one we're looking for. 20350b57cec5SDimitry Andric const CaseStmt *CS = cast<CaseStmt>(Case); 20360b57cec5SDimitry Andric // Don't handle case ranges yet. 20370b57cec5SDimitry Andric if (CS->getRHS()) return false; 20380b57cec5SDimitry Andric 20390b57cec5SDimitry Andric // If we found our case, remember it as 'case'. 20400b57cec5SDimitry Andric if (CS->getLHS()->EvaluateKnownConstInt(C) == ConstantCondValue) 20410b57cec5SDimitry Andric break; 20420b57cec5SDimitry Andric } 20430b57cec5SDimitry Andric 20440b57cec5SDimitry Andric // If we didn't find a matching case, we use a default if it exists, or we 20450b57cec5SDimitry Andric // elide the whole switch body! 20460b57cec5SDimitry Andric if (!Case) { 20470b57cec5SDimitry Andric // It is safe to elide the body of the switch if it doesn't contain labels 20480b57cec5SDimitry Andric // etc. If it is safe, return successfully with an empty ResultStmts list. 20490b57cec5SDimitry Andric if (!DefaultCase) 20500b57cec5SDimitry Andric return !CodeGenFunction::ContainsLabel(&S); 20510b57cec5SDimitry Andric Case = DefaultCase; 20520b57cec5SDimitry Andric } 20530b57cec5SDimitry Andric 20540b57cec5SDimitry Andric // Ok, we know which case is being jumped to, try to collect all the 20550b57cec5SDimitry Andric // statements that follow it. This can fail for a variety of reasons. Also, 20560b57cec5SDimitry Andric // check to see that the recursive walk actually found our case statement. 20570b57cec5SDimitry Andric // Insane cases like this can fail to find it in the recursive walk since we 20580b57cec5SDimitry Andric // don't handle every stmt kind: 20590b57cec5SDimitry Andric // switch (4) { 20600b57cec5SDimitry Andric // while (1) { 20610b57cec5SDimitry Andric // case 4: ... 20620b57cec5SDimitry Andric bool FoundCase = false; 20630b57cec5SDimitry Andric ResultCase = Case; 20640b57cec5SDimitry Andric return CollectStatementsForCase(S.getBody(), Case, FoundCase, 20650b57cec5SDimitry Andric ResultStmts) != CSFC_Failure && 20660b57cec5SDimitry Andric FoundCase; 20670b57cec5SDimitry Andric } 20680b57cec5SDimitry Andric 2069bdd1243dSDimitry Andric static std::optional<SmallVector<uint64_t, 16>> 2070e8d8bef9SDimitry Andric getLikelihoodWeights(ArrayRef<Stmt::Likelihood> Likelihoods) { 2071e8d8bef9SDimitry Andric // Are there enough branches to weight them? 2072e8d8bef9SDimitry Andric if (Likelihoods.size() <= 1) 2073bdd1243dSDimitry Andric return std::nullopt; 2074e8d8bef9SDimitry Andric 2075e8d8bef9SDimitry Andric uint64_t NumUnlikely = 0; 2076e8d8bef9SDimitry Andric uint64_t NumNone = 0; 2077e8d8bef9SDimitry Andric uint64_t NumLikely = 0; 2078e8d8bef9SDimitry Andric for (const auto LH : Likelihoods) { 2079e8d8bef9SDimitry Andric switch (LH) { 2080e8d8bef9SDimitry Andric case Stmt::LH_Unlikely: 2081e8d8bef9SDimitry Andric ++NumUnlikely; 2082e8d8bef9SDimitry Andric break; 2083e8d8bef9SDimitry Andric case Stmt::LH_None: 2084e8d8bef9SDimitry Andric ++NumNone; 2085e8d8bef9SDimitry Andric break; 2086e8d8bef9SDimitry Andric case Stmt::LH_Likely: 2087e8d8bef9SDimitry Andric ++NumLikely; 2088e8d8bef9SDimitry Andric break; 2089e8d8bef9SDimitry Andric } 2090e8d8bef9SDimitry Andric } 2091e8d8bef9SDimitry Andric 2092e8d8bef9SDimitry Andric // Is there a likelihood attribute used? 2093e8d8bef9SDimitry Andric if (NumUnlikely == 0 && NumLikely == 0) 2094bdd1243dSDimitry Andric return std::nullopt; 2095e8d8bef9SDimitry Andric 2096e8d8bef9SDimitry Andric // When multiple cases share the same code they can be combined during 2097e8d8bef9SDimitry Andric // optimization. In that case the weights of the branch will be the sum of 2098e8d8bef9SDimitry Andric // the individual weights. Make sure the combined sum of all neutral cases 2099e8d8bef9SDimitry Andric // doesn't exceed the value of a single likely attribute. 2100e8d8bef9SDimitry Andric // The additions both avoid divisions by 0 and make sure the weights of None 2101e8d8bef9SDimitry Andric // don't exceed the weight of Likely. 2102e8d8bef9SDimitry Andric const uint64_t Likely = INT32_MAX / (NumLikely + 2); 2103e8d8bef9SDimitry Andric const uint64_t None = Likely / (NumNone + 1); 2104e8d8bef9SDimitry Andric const uint64_t Unlikely = 0; 2105e8d8bef9SDimitry Andric 2106e8d8bef9SDimitry Andric SmallVector<uint64_t, 16> Result; 2107e8d8bef9SDimitry Andric Result.reserve(Likelihoods.size()); 2108e8d8bef9SDimitry Andric for (const auto LH : Likelihoods) { 2109e8d8bef9SDimitry Andric switch (LH) { 2110e8d8bef9SDimitry Andric case Stmt::LH_Unlikely: 2111e8d8bef9SDimitry Andric Result.push_back(Unlikely); 2112e8d8bef9SDimitry Andric break; 2113e8d8bef9SDimitry Andric case Stmt::LH_None: 2114e8d8bef9SDimitry Andric Result.push_back(None); 2115e8d8bef9SDimitry Andric break; 2116e8d8bef9SDimitry Andric case Stmt::LH_Likely: 2117e8d8bef9SDimitry Andric Result.push_back(Likely); 2118e8d8bef9SDimitry Andric break; 2119e8d8bef9SDimitry Andric } 2120e8d8bef9SDimitry Andric } 2121e8d8bef9SDimitry Andric 2122e8d8bef9SDimitry Andric return Result; 2123e8d8bef9SDimitry Andric } 2124e8d8bef9SDimitry Andric 21250b57cec5SDimitry Andric void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { 21260b57cec5SDimitry Andric // Handle nested switch statements. 21270b57cec5SDimitry Andric llvm::SwitchInst *SavedSwitchInsn = SwitchInsn; 21280b57cec5SDimitry Andric SmallVector<uint64_t, 16> *SavedSwitchWeights = SwitchWeights; 2129e8d8bef9SDimitry Andric SmallVector<Stmt::Likelihood, 16> *SavedSwitchLikelihood = SwitchLikelihood; 21300b57cec5SDimitry Andric llvm::BasicBlock *SavedCRBlock = CaseRangeBlock; 21310b57cec5SDimitry Andric 21320b57cec5SDimitry Andric // See if we can constant fold the condition of the switch and therefore only 21330b57cec5SDimitry Andric // emit the live case statement (if any) of the switch. 21340b57cec5SDimitry Andric llvm::APSInt ConstantCondValue; 21350b57cec5SDimitry Andric if (ConstantFoldsToSimpleInteger(S.getCond(), ConstantCondValue)) { 21360b57cec5SDimitry Andric SmallVector<const Stmt*, 4> CaseStmts; 21370b57cec5SDimitry Andric const SwitchCase *Case = nullptr; 21380b57cec5SDimitry Andric if (FindCaseStatementsForValue(S, ConstantCondValue, CaseStmts, 21390b57cec5SDimitry Andric getContext(), Case)) { 21400b57cec5SDimitry Andric if (Case) 21410b57cec5SDimitry Andric incrementProfileCounter(Case); 21420b57cec5SDimitry Andric RunCleanupsScope ExecutedScope(*this); 21430b57cec5SDimitry Andric 21440b57cec5SDimitry Andric if (S.getInit()) 21450b57cec5SDimitry Andric EmitStmt(S.getInit()); 21460b57cec5SDimitry Andric 21470b57cec5SDimitry Andric // Emit the condition variable if needed inside the entire cleanup scope 21480b57cec5SDimitry Andric // used by this special case for constant folded switches. 21490b57cec5SDimitry Andric if (S.getConditionVariable()) 21500b57cec5SDimitry Andric EmitDecl(*S.getConditionVariable()); 21510b57cec5SDimitry Andric 21520b57cec5SDimitry Andric // At this point, we are no longer "within" a switch instance, so 21530b57cec5SDimitry Andric // we can temporarily enforce this to ensure that any embedded case 21540b57cec5SDimitry Andric // statements are not emitted. 21550b57cec5SDimitry Andric SwitchInsn = nullptr; 21560b57cec5SDimitry Andric 21570b57cec5SDimitry Andric // Okay, we can dead code eliminate everything except this case. Emit the 21580b57cec5SDimitry Andric // specified series of statements and we're good. 21590b57cec5SDimitry Andric for (unsigned i = 0, e = CaseStmts.size(); i != e; ++i) 21600b57cec5SDimitry Andric EmitStmt(CaseStmts[i]); 21610b57cec5SDimitry Andric incrementProfileCounter(&S); 21620b57cec5SDimitry Andric 21630b57cec5SDimitry Andric // Now we want to restore the saved switch instance so that nested 21640b57cec5SDimitry Andric // switches continue to function properly 21650b57cec5SDimitry Andric SwitchInsn = SavedSwitchInsn; 21660b57cec5SDimitry Andric 21670b57cec5SDimitry Andric return; 21680b57cec5SDimitry Andric } 21690b57cec5SDimitry Andric } 21700b57cec5SDimitry Andric 21710b57cec5SDimitry Andric JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog"); 21720b57cec5SDimitry Andric 21730b57cec5SDimitry Andric RunCleanupsScope ConditionScope(*this); 21740b57cec5SDimitry Andric 21750b57cec5SDimitry Andric if (S.getInit()) 21760b57cec5SDimitry Andric EmitStmt(S.getInit()); 21770b57cec5SDimitry Andric 21780b57cec5SDimitry Andric if (S.getConditionVariable()) 21790b57cec5SDimitry Andric EmitDecl(*S.getConditionVariable()); 21800b57cec5SDimitry Andric llvm::Value *CondV = EmitScalarExpr(S.getCond()); 21810b57cec5SDimitry Andric 21820b57cec5SDimitry Andric // Create basic block to hold stuff that comes after switch 21830b57cec5SDimitry Andric // statement. We also need to create a default block now so that 21840b57cec5SDimitry Andric // explicit case ranges tests can have a place to jump to on 21850b57cec5SDimitry Andric // failure. 21860b57cec5SDimitry Andric llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default"); 21870b57cec5SDimitry Andric SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock); 21880b57cec5SDimitry Andric if (PGO.haveRegionCounts()) { 21890b57cec5SDimitry Andric // Walk the SwitchCase list to find how many there are. 21900b57cec5SDimitry Andric uint64_t DefaultCount = 0; 21910b57cec5SDimitry Andric unsigned NumCases = 0; 21920b57cec5SDimitry Andric for (const SwitchCase *Case = S.getSwitchCaseList(); 21930b57cec5SDimitry Andric Case; 21940b57cec5SDimitry Andric Case = Case->getNextSwitchCase()) { 21950b57cec5SDimitry Andric if (isa<DefaultStmt>(Case)) 21960b57cec5SDimitry Andric DefaultCount = getProfileCount(Case); 21970b57cec5SDimitry Andric NumCases += 1; 21980b57cec5SDimitry Andric } 21990b57cec5SDimitry Andric SwitchWeights = new SmallVector<uint64_t, 16>(); 22000b57cec5SDimitry Andric SwitchWeights->reserve(NumCases); 22010b57cec5SDimitry Andric // The default needs to be first. We store the edge count, so we already 22020b57cec5SDimitry Andric // know the right weight. 22030b57cec5SDimitry Andric SwitchWeights->push_back(DefaultCount); 2204e8d8bef9SDimitry Andric } else if (CGM.getCodeGenOpts().OptimizationLevel) { 2205e8d8bef9SDimitry Andric SwitchLikelihood = new SmallVector<Stmt::Likelihood, 16>(); 2206e8d8bef9SDimitry Andric // Initialize the default case. 2207e8d8bef9SDimitry Andric SwitchLikelihood->push_back(Stmt::LH_None); 22080b57cec5SDimitry Andric } 2209e8d8bef9SDimitry Andric 22100b57cec5SDimitry Andric CaseRangeBlock = DefaultBlock; 22110b57cec5SDimitry Andric 22120b57cec5SDimitry Andric // Clear the insertion point to indicate we are in unreachable code. 22130b57cec5SDimitry Andric Builder.ClearInsertionPoint(); 22140b57cec5SDimitry Andric 22150b57cec5SDimitry Andric // All break statements jump to NextBlock. If BreakContinueStack is non-empty 22160b57cec5SDimitry Andric // then reuse last ContinueBlock. 22170b57cec5SDimitry Andric JumpDest OuterContinue; 22180b57cec5SDimitry Andric if (!BreakContinueStack.empty()) 22190b57cec5SDimitry Andric OuterContinue = BreakContinueStack.back().ContinueBlock; 22200b57cec5SDimitry Andric 22210b57cec5SDimitry Andric BreakContinueStack.push_back(BreakContinue(SwitchExit, OuterContinue)); 22220b57cec5SDimitry Andric 22230b57cec5SDimitry Andric // Emit switch body. 22240b57cec5SDimitry Andric EmitStmt(S.getBody()); 22250b57cec5SDimitry Andric 22260b57cec5SDimitry Andric BreakContinueStack.pop_back(); 22270b57cec5SDimitry Andric 22280b57cec5SDimitry Andric // Update the default block in case explicit case range tests have 22290b57cec5SDimitry Andric // been chained on top. 22300b57cec5SDimitry Andric SwitchInsn->setDefaultDest(CaseRangeBlock); 22310b57cec5SDimitry Andric 22320b57cec5SDimitry Andric // If a default was never emitted: 22330b57cec5SDimitry Andric if (!DefaultBlock->getParent()) { 22340b57cec5SDimitry Andric // If we have cleanups, emit the default block so that there's a 22350b57cec5SDimitry Andric // place to jump through the cleanups from. 22360b57cec5SDimitry Andric if (ConditionScope.requiresCleanups()) { 22370b57cec5SDimitry Andric EmitBlock(DefaultBlock); 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andric // Otherwise, just forward the default block to the switch end. 22400b57cec5SDimitry Andric } else { 22410b57cec5SDimitry Andric DefaultBlock->replaceAllUsesWith(SwitchExit.getBlock()); 22420b57cec5SDimitry Andric delete DefaultBlock; 22430b57cec5SDimitry Andric } 22440b57cec5SDimitry Andric } 22450b57cec5SDimitry Andric 22460b57cec5SDimitry Andric ConditionScope.ForceCleanup(); 22470b57cec5SDimitry Andric 22480b57cec5SDimitry Andric // Emit continuation. 22490b57cec5SDimitry Andric EmitBlock(SwitchExit.getBlock(), true); 22500b57cec5SDimitry Andric incrementProfileCounter(&S); 22510b57cec5SDimitry Andric 22520b57cec5SDimitry Andric // If the switch has a condition wrapped by __builtin_unpredictable, 22530b57cec5SDimitry Andric // create metadata that specifies that the switch is unpredictable. 22540b57cec5SDimitry Andric // Don't bother if not optimizing because that metadata would not be used. 22550b57cec5SDimitry Andric auto *Call = dyn_cast<CallExpr>(S.getCond()); 22560b57cec5SDimitry Andric if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) { 22570b57cec5SDimitry Andric auto *FD = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl()); 22580b57cec5SDimitry Andric if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) { 22590b57cec5SDimitry Andric llvm::MDBuilder MDHelper(getLLVMContext()); 22600b57cec5SDimitry Andric SwitchInsn->setMetadata(llvm::LLVMContext::MD_unpredictable, 22610b57cec5SDimitry Andric MDHelper.createUnpredictable()); 22620b57cec5SDimitry Andric } 22630b57cec5SDimitry Andric } 22640b57cec5SDimitry Andric 22650b57cec5SDimitry Andric if (SwitchWeights) { 22660b57cec5SDimitry Andric assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() && 22670b57cec5SDimitry Andric "switch weights do not match switch cases"); 22680b57cec5SDimitry Andric // If there's only one jump destination there's no sense weighting it. 22690b57cec5SDimitry Andric if (SwitchWeights->size() > 1) 22700b57cec5SDimitry Andric SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof, 22710b57cec5SDimitry Andric createProfileWeights(*SwitchWeights)); 22720b57cec5SDimitry Andric delete SwitchWeights; 2273e8d8bef9SDimitry Andric } else if (SwitchLikelihood) { 2274e8d8bef9SDimitry Andric assert(SwitchLikelihood->size() == 1 + SwitchInsn->getNumCases() && 2275e8d8bef9SDimitry Andric "switch likelihoods do not match switch cases"); 2276bdd1243dSDimitry Andric std::optional<SmallVector<uint64_t, 16>> LHW = 2277e8d8bef9SDimitry Andric getLikelihoodWeights(*SwitchLikelihood); 2278e8d8bef9SDimitry Andric if (LHW) { 2279e8d8bef9SDimitry Andric llvm::MDBuilder MDHelper(CGM.getLLVMContext()); 2280e8d8bef9SDimitry Andric SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof, 2281e8d8bef9SDimitry Andric createProfileWeights(*LHW)); 2282e8d8bef9SDimitry Andric } 2283e8d8bef9SDimitry Andric delete SwitchLikelihood; 22840b57cec5SDimitry Andric } 22850b57cec5SDimitry Andric SwitchInsn = SavedSwitchInsn; 22860b57cec5SDimitry Andric SwitchWeights = SavedSwitchWeights; 2287e8d8bef9SDimitry Andric SwitchLikelihood = SavedSwitchLikelihood; 22880b57cec5SDimitry Andric CaseRangeBlock = SavedCRBlock; 22890b57cec5SDimitry Andric } 22900b57cec5SDimitry Andric 22910b57cec5SDimitry Andric static std::string 22920b57cec5SDimitry Andric SimplifyConstraint(const char *Constraint, const TargetInfo &Target, 22930b57cec5SDimitry Andric SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=nullptr) { 22940b57cec5SDimitry Andric std::string Result; 22950b57cec5SDimitry Andric 22960b57cec5SDimitry Andric while (*Constraint) { 22970b57cec5SDimitry Andric switch (*Constraint) { 22980b57cec5SDimitry Andric default: 22990b57cec5SDimitry Andric Result += Target.convertConstraint(Constraint); 23000b57cec5SDimitry Andric break; 23010b57cec5SDimitry Andric // Ignore these 23020b57cec5SDimitry Andric case '*': 23030b57cec5SDimitry Andric case '?': 23040b57cec5SDimitry Andric case '!': 23050b57cec5SDimitry Andric case '=': // Will see this and the following in mult-alt constraints. 23060b57cec5SDimitry Andric case '+': 23070b57cec5SDimitry Andric break; 23080b57cec5SDimitry Andric case '#': // Ignore the rest of the constraint alternative. 23090b57cec5SDimitry Andric while (Constraint[1] && Constraint[1] != ',') 23100b57cec5SDimitry Andric Constraint++; 23110b57cec5SDimitry Andric break; 23120b57cec5SDimitry Andric case '&': 23130b57cec5SDimitry Andric case '%': 23140b57cec5SDimitry Andric Result += *Constraint; 23150b57cec5SDimitry Andric while (Constraint[1] && Constraint[1] == *Constraint) 23160b57cec5SDimitry Andric Constraint++; 23170b57cec5SDimitry Andric break; 23180b57cec5SDimitry Andric case ',': 23190b57cec5SDimitry Andric Result += "|"; 23200b57cec5SDimitry Andric break; 23210b57cec5SDimitry Andric case 'g': 23220b57cec5SDimitry Andric Result += "imr"; 23230b57cec5SDimitry Andric break; 23240b57cec5SDimitry Andric case '[': { 23250b57cec5SDimitry Andric assert(OutCons && 23260b57cec5SDimitry Andric "Must pass output names to constraints with a symbolic name"); 23270b57cec5SDimitry Andric unsigned Index; 23280b57cec5SDimitry Andric bool result = Target.resolveSymbolicName(Constraint, *OutCons, Index); 23290b57cec5SDimitry Andric assert(result && "Could not resolve symbolic name"); (void)result; 23300b57cec5SDimitry Andric Result += llvm::utostr(Index); 23310b57cec5SDimitry Andric break; 23320b57cec5SDimitry Andric } 23330b57cec5SDimitry Andric } 23340b57cec5SDimitry Andric 23350b57cec5SDimitry Andric Constraint++; 23360b57cec5SDimitry Andric } 23370b57cec5SDimitry Andric 23380b57cec5SDimitry Andric return Result; 23390b57cec5SDimitry Andric } 23400b57cec5SDimitry Andric 23410b57cec5SDimitry Andric /// AddVariableConstraints - Look at AsmExpr and if it is a variable declared 23420b57cec5SDimitry Andric /// as using a particular register add that as a constraint that will be used 23430b57cec5SDimitry Andric /// in this asm stmt. 23440b57cec5SDimitry Andric static std::string 23450b57cec5SDimitry Andric AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, 23460b57cec5SDimitry Andric const TargetInfo &Target, CodeGenModule &CGM, 2347e8d8bef9SDimitry Andric const AsmStmt &Stmt, const bool EarlyClobber, 2348e8d8bef9SDimitry Andric std::string *GCCReg = nullptr) { 23490b57cec5SDimitry Andric const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(&AsmExpr); 23500b57cec5SDimitry Andric if (!AsmDeclRef) 23510b57cec5SDimitry Andric return Constraint; 23520b57cec5SDimitry Andric const ValueDecl &Value = *AsmDeclRef->getDecl(); 23530b57cec5SDimitry Andric const VarDecl *Variable = dyn_cast<VarDecl>(&Value); 23540b57cec5SDimitry Andric if (!Variable) 23550b57cec5SDimitry Andric return Constraint; 23560b57cec5SDimitry Andric if (Variable->getStorageClass() != SC_Register) 23570b57cec5SDimitry Andric return Constraint; 23580b57cec5SDimitry Andric AsmLabelAttr *Attr = Variable->getAttr<AsmLabelAttr>(); 23590b57cec5SDimitry Andric if (!Attr) 23600b57cec5SDimitry Andric return Constraint; 23610b57cec5SDimitry Andric StringRef Register = Attr->getLabel(); 23620b57cec5SDimitry Andric assert(Target.isValidGCCRegisterName(Register)); 23630b57cec5SDimitry Andric // We're using validateOutputConstraint here because we only care if 23640b57cec5SDimitry Andric // this is a register constraint. 23650b57cec5SDimitry Andric TargetInfo::ConstraintInfo Info(Constraint, ""); 23660b57cec5SDimitry Andric if (Target.validateOutputConstraint(Info) && 23670b57cec5SDimitry Andric !Info.allowsRegister()) { 23680b57cec5SDimitry Andric CGM.ErrorUnsupported(&Stmt, "__asm__"); 23690b57cec5SDimitry Andric return Constraint; 23700b57cec5SDimitry Andric } 23710b57cec5SDimitry Andric // Canonicalize the register here before returning it. 23720b57cec5SDimitry Andric Register = Target.getNormalizedGCCRegisterName(Register); 2373e8d8bef9SDimitry Andric if (GCCReg != nullptr) 2374e8d8bef9SDimitry Andric *GCCReg = Register.str(); 23750b57cec5SDimitry Andric return (EarlyClobber ? "&{" : "{") + Register.str() + "}"; 23760b57cec5SDimitry Andric } 23770b57cec5SDimitry Andric 237804eeddc0SDimitry Andric std::pair<llvm::Value*, llvm::Type *> CodeGenFunction::EmitAsmInputLValue( 237904eeddc0SDimitry Andric const TargetInfo::ConstraintInfo &Info, LValue InputValue, 238004eeddc0SDimitry Andric QualType InputType, std::string &ConstraintStr, SourceLocation Loc) { 23810b57cec5SDimitry Andric if (Info.allowsRegister() || !Info.allowsMemory()) { 238204eeddc0SDimitry Andric if (CodeGenFunction::hasScalarEvaluationKind(InputType)) 238304eeddc0SDimitry Andric return {EmitLoadOfLValue(InputValue, Loc).getScalarVal(), nullptr}; 238404eeddc0SDimitry Andric 23850b57cec5SDimitry Andric llvm::Type *Ty = ConvertType(InputType); 23860b57cec5SDimitry Andric uint64_t Size = CGM.getDataLayout().getTypeSizeInBits(Ty); 23876e75b2fbSDimitry Andric if ((Size <= 64 && llvm::isPowerOf2_64(Size)) || 23886e75b2fbSDimitry Andric getTargetHooks().isScalarizableAsmOperand(*this, Ty)) { 23890b57cec5SDimitry Andric Ty = llvm::IntegerType::get(getLLVMContext(), Size); 23900b57cec5SDimitry Andric 23910fca6ea1SDimitry Andric return {Builder.CreateLoad(InputValue.getAddress().withElementType(Ty)), 239204eeddc0SDimitry Andric nullptr}; 23930b57cec5SDimitry Andric } 23940b57cec5SDimitry Andric } 23950b57cec5SDimitry Andric 23960fca6ea1SDimitry Andric Address Addr = InputValue.getAddress(); 239704eeddc0SDimitry Andric ConstraintStr += '*'; 23980fca6ea1SDimitry Andric return {InputValue.getPointer(*this), Addr.getElementType()}; 23990b57cec5SDimitry Andric } 24000b57cec5SDimitry Andric 240104eeddc0SDimitry Andric std::pair<llvm::Value *, llvm::Type *> 240204eeddc0SDimitry Andric CodeGenFunction::EmitAsmInput(const TargetInfo::ConstraintInfo &Info, 24030b57cec5SDimitry Andric const Expr *InputExpr, 24040b57cec5SDimitry Andric std::string &ConstraintStr) { 24050b57cec5SDimitry Andric // If this can't be a register or memory, i.e., has to be a constant 24060b57cec5SDimitry Andric // (immediate or symbolic), try to emit it as such. 24070b57cec5SDimitry Andric if (!Info.allowsRegister() && !Info.allowsMemory()) { 24080b57cec5SDimitry Andric if (Info.requiresImmediateConstant()) { 24090b57cec5SDimitry Andric Expr::EvalResult EVResult; 24100b57cec5SDimitry Andric InputExpr->EvaluateAsRValue(EVResult, getContext(), true); 24110b57cec5SDimitry Andric 24120b57cec5SDimitry Andric llvm::APSInt IntResult; 24130b57cec5SDimitry Andric if (EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), 24140b57cec5SDimitry Andric getContext())) 241504eeddc0SDimitry Andric return {llvm::ConstantInt::get(getLLVMContext(), IntResult), nullptr}; 24160b57cec5SDimitry Andric } 24170b57cec5SDimitry Andric 24180b57cec5SDimitry Andric Expr::EvalResult Result; 24190b57cec5SDimitry Andric if (InputExpr->EvaluateAsInt(Result, getContext())) 242004eeddc0SDimitry Andric return {llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt()), 242104eeddc0SDimitry Andric nullptr}; 24220b57cec5SDimitry Andric } 24230b57cec5SDimitry Andric 24240b57cec5SDimitry Andric if (Info.allowsRegister() || !Info.allowsMemory()) 24250b57cec5SDimitry Andric if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType())) 242604eeddc0SDimitry Andric return {EmitScalarExpr(InputExpr), nullptr}; 24270b57cec5SDimitry Andric if (InputExpr->getStmtClass() == Expr::CXXThisExprClass) 242804eeddc0SDimitry Andric return {EmitScalarExpr(InputExpr), nullptr}; 24290b57cec5SDimitry Andric InputExpr = InputExpr->IgnoreParenNoopCasts(getContext()); 24300b57cec5SDimitry Andric LValue Dest = EmitLValue(InputExpr); 24310b57cec5SDimitry Andric return EmitAsmInputLValue(Info, Dest, InputExpr->getType(), ConstraintStr, 24320b57cec5SDimitry Andric InputExpr->getExprLoc()); 24330b57cec5SDimitry Andric } 24340b57cec5SDimitry Andric 24350b57cec5SDimitry Andric /// getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline 24360b57cec5SDimitry Andric /// asm call instruction. The !srcloc MDNode contains a list of constant 24370b57cec5SDimitry Andric /// integers which are the source locations of the start of each line in the 24380b57cec5SDimitry Andric /// asm. 24390b57cec5SDimitry Andric static llvm::MDNode *getAsmSrcLocInfo(const StringLiteral *Str, 24400b57cec5SDimitry Andric CodeGenFunction &CGF) { 24410b57cec5SDimitry Andric SmallVector<llvm::Metadata *, 8> Locs; 24420b57cec5SDimitry Andric // Add the location of the first line to the MDNode. 24430b57cec5SDimitry Andric Locs.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( 2444fe6060f1SDimitry Andric CGF.Int64Ty, Str->getBeginLoc().getRawEncoding()))); 24450b57cec5SDimitry Andric StringRef StrVal = Str->getString(); 24460b57cec5SDimitry Andric if (!StrVal.empty()) { 24470b57cec5SDimitry Andric const SourceManager &SM = CGF.CGM.getContext().getSourceManager(); 24480b57cec5SDimitry Andric const LangOptions &LangOpts = CGF.CGM.getLangOpts(); 24490b57cec5SDimitry Andric unsigned StartToken = 0; 24500b57cec5SDimitry Andric unsigned ByteOffset = 0; 24510b57cec5SDimitry Andric 24520b57cec5SDimitry Andric // Add the location of the start of each subsequent line of the asm to the 24530b57cec5SDimitry Andric // MDNode. 24540b57cec5SDimitry Andric for (unsigned i = 0, e = StrVal.size() - 1; i != e; ++i) { 24550b57cec5SDimitry Andric if (StrVal[i] != '\n') continue; 24560b57cec5SDimitry Andric SourceLocation LineLoc = Str->getLocationOfByte( 24570b57cec5SDimitry Andric i + 1, SM, LangOpts, CGF.getTarget(), &StartToken, &ByteOffset); 24580b57cec5SDimitry Andric Locs.push_back(llvm::ConstantAsMetadata::get( 2459fe6060f1SDimitry Andric llvm::ConstantInt::get(CGF.Int64Ty, LineLoc.getRawEncoding()))); 24600b57cec5SDimitry Andric } 24610b57cec5SDimitry Andric } 24620b57cec5SDimitry Andric 24630b57cec5SDimitry Andric return llvm::MDNode::get(CGF.getLLVMContext(), Locs); 24640b57cec5SDimitry Andric } 24650b57cec5SDimitry Andric 24660b57cec5SDimitry Andric static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect, 2467fe6060f1SDimitry Andric bool HasUnwindClobber, bool ReadOnly, 2468fe6060f1SDimitry Andric bool ReadNone, bool NoMerge, const AsmStmt &S, 24690b57cec5SDimitry Andric const std::vector<llvm::Type *> &ResultRegTypes, 247004eeddc0SDimitry Andric const std::vector<llvm::Type *> &ArgElemTypes, 24710b57cec5SDimitry Andric CodeGenFunction &CGF, 24720b57cec5SDimitry Andric std::vector<llvm::Value *> &RegResults) { 2473fe6060f1SDimitry Andric if (!HasUnwindClobber) 2474349cc55cSDimitry Andric Result.addFnAttr(llvm::Attribute::NoUnwind); 2475fe6060f1SDimitry Andric 2476e8d8bef9SDimitry Andric if (NoMerge) 2477349cc55cSDimitry Andric Result.addFnAttr(llvm::Attribute::NoMerge); 24780b57cec5SDimitry Andric // Attach readnone and readonly attributes. 24790b57cec5SDimitry Andric if (!HasSideEffect) { 24800b57cec5SDimitry Andric if (ReadNone) 2481bdd1243dSDimitry Andric Result.setDoesNotAccessMemory(); 24820b57cec5SDimitry Andric else if (ReadOnly) 2483bdd1243dSDimitry Andric Result.setOnlyReadsMemory(); 24840b57cec5SDimitry Andric } 24850b57cec5SDimitry Andric 248604eeddc0SDimitry Andric // Add elementtype attribute for indirect constraints. 248704eeddc0SDimitry Andric for (auto Pair : llvm::enumerate(ArgElemTypes)) { 248804eeddc0SDimitry Andric if (Pair.value()) { 248904eeddc0SDimitry Andric auto Attr = llvm::Attribute::get( 249004eeddc0SDimitry Andric CGF.getLLVMContext(), llvm::Attribute::ElementType, Pair.value()); 249104eeddc0SDimitry Andric Result.addParamAttr(Pair.index(), Attr); 249204eeddc0SDimitry Andric } 249304eeddc0SDimitry Andric } 249404eeddc0SDimitry Andric 24950b57cec5SDimitry Andric // Slap the source location of the inline asm into a !srcloc metadata on the 24960b57cec5SDimitry Andric // call. 24970b57cec5SDimitry Andric if (const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S)) 24980b57cec5SDimitry Andric Result.setMetadata("srcloc", 24990b57cec5SDimitry Andric getAsmSrcLocInfo(gccAsmStmt->getAsmString(), CGF)); 25000b57cec5SDimitry Andric else { 25010b57cec5SDimitry Andric // At least put the line number on MS inline asm blobs. 2502fe6060f1SDimitry Andric llvm::Constant *Loc = 2503fe6060f1SDimitry Andric llvm::ConstantInt::get(CGF.Int64Ty, S.getAsmLoc().getRawEncoding()); 25040b57cec5SDimitry Andric Result.setMetadata("srcloc", 25050b57cec5SDimitry Andric llvm::MDNode::get(CGF.getLLVMContext(), 25060b57cec5SDimitry Andric llvm::ConstantAsMetadata::get(Loc))); 25070b57cec5SDimitry Andric } 25080b57cec5SDimitry Andric 25090b57cec5SDimitry Andric if (CGF.getLangOpts().assumeFunctionsAreConvergent()) 25100b57cec5SDimitry Andric // Conservatively, mark all inline asm blocks in CUDA or OpenCL as 25110b57cec5SDimitry Andric // convergent (meaning, they may call an intrinsically convergent op, such 25120b57cec5SDimitry Andric // as bar.sync, and so can't have certain optimizations applied around 25130b57cec5SDimitry Andric // them). 2514349cc55cSDimitry Andric Result.addFnAttr(llvm::Attribute::Convergent); 25150b57cec5SDimitry Andric // Extract all of the register value results from the asm. 25160b57cec5SDimitry Andric if (ResultRegTypes.size() == 1) { 25170b57cec5SDimitry Andric RegResults.push_back(&Result); 25180b57cec5SDimitry Andric } else { 25190b57cec5SDimitry Andric for (unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) { 25200b57cec5SDimitry Andric llvm::Value *Tmp = CGF.Builder.CreateExtractValue(&Result, i, "asmresult"); 25210b57cec5SDimitry Andric RegResults.push_back(Tmp); 25220b57cec5SDimitry Andric } 25230b57cec5SDimitry Andric } 25240b57cec5SDimitry Andric } 25250b57cec5SDimitry Andric 252606c3fb27SDimitry Andric static void 252706c3fb27SDimitry Andric EmitAsmStores(CodeGenFunction &CGF, const AsmStmt &S, 252806c3fb27SDimitry Andric const llvm::ArrayRef<llvm::Value *> RegResults, 252906c3fb27SDimitry Andric const llvm::ArrayRef<llvm::Type *> ResultRegTypes, 253006c3fb27SDimitry Andric const llvm::ArrayRef<llvm::Type *> ResultTruncRegTypes, 253106c3fb27SDimitry Andric const llvm::ArrayRef<LValue> ResultRegDests, 253206c3fb27SDimitry Andric const llvm::ArrayRef<QualType> ResultRegQualTys, 253306c3fb27SDimitry Andric const llvm::BitVector &ResultTypeRequiresCast, 253406c3fb27SDimitry Andric const llvm::BitVector &ResultRegIsFlagReg) { 253506c3fb27SDimitry Andric CGBuilderTy &Builder = CGF.Builder; 253606c3fb27SDimitry Andric CodeGenModule &CGM = CGF.CGM; 253706c3fb27SDimitry Andric llvm::LLVMContext &CTX = CGF.getLLVMContext(); 253806c3fb27SDimitry Andric 253906c3fb27SDimitry Andric assert(RegResults.size() == ResultRegTypes.size()); 254006c3fb27SDimitry Andric assert(RegResults.size() == ResultTruncRegTypes.size()); 254106c3fb27SDimitry Andric assert(RegResults.size() == ResultRegDests.size()); 254206c3fb27SDimitry Andric // ResultRegDests can be also populated by addReturnRegisterOutputs() above, 254306c3fb27SDimitry Andric // in which case its size may grow. 254406c3fb27SDimitry Andric assert(ResultTypeRequiresCast.size() <= ResultRegDests.size()); 254506c3fb27SDimitry Andric assert(ResultRegIsFlagReg.size() <= ResultRegDests.size()); 254606c3fb27SDimitry Andric 254706c3fb27SDimitry Andric for (unsigned i = 0, e = RegResults.size(); i != e; ++i) { 254806c3fb27SDimitry Andric llvm::Value *Tmp = RegResults[i]; 254906c3fb27SDimitry Andric llvm::Type *TruncTy = ResultTruncRegTypes[i]; 255006c3fb27SDimitry Andric 255106c3fb27SDimitry Andric if ((i < ResultRegIsFlagReg.size()) && ResultRegIsFlagReg[i]) { 255206c3fb27SDimitry Andric // Target must guarantee the Value `Tmp` here is lowered to a boolean 255306c3fb27SDimitry Andric // value. 255406c3fb27SDimitry Andric llvm::Constant *Two = llvm::ConstantInt::get(Tmp->getType(), 2); 255506c3fb27SDimitry Andric llvm::Value *IsBooleanValue = 255606c3fb27SDimitry Andric Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, Two); 255706c3fb27SDimitry Andric llvm::Function *FnAssume = CGM.getIntrinsic(llvm::Intrinsic::assume); 255806c3fb27SDimitry Andric Builder.CreateCall(FnAssume, IsBooleanValue); 255906c3fb27SDimitry Andric } 256006c3fb27SDimitry Andric 256106c3fb27SDimitry Andric // If the result type of the LLVM IR asm doesn't match the result type of 256206c3fb27SDimitry Andric // the expression, do the conversion. 256306c3fb27SDimitry Andric if (ResultRegTypes[i] != TruncTy) { 256406c3fb27SDimitry Andric 256506c3fb27SDimitry Andric // Truncate the integer result to the right size, note that TruncTy can be 256606c3fb27SDimitry Andric // a pointer. 256706c3fb27SDimitry Andric if (TruncTy->isFloatingPointTy()) 256806c3fb27SDimitry Andric Tmp = Builder.CreateFPTrunc(Tmp, TruncTy); 256906c3fb27SDimitry Andric else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) { 257006c3fb27SDimitry Andric uint64_t ResSize = CGM.getDataLayout().getTypeSizeInBits(TruncTy); 257106c3fb27SDimitry Andric Tmp = Builder.CreateTrunc( 257206c3fb27SDimitry Andric Tmp, llvm::IntegerType::get(CTX, (unsigned)ResSize)); 257306c3fb27SDimitry Andric Tmp = Builder.CreateIntToPtr(Tmp, TruncTy); 257406c3fb27SDimitry Andric } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) { 257506c3fb27SDimitry Andric uint64_t TmpSize = 257606c3fb27SDimitry Andric CGM.getDataLayout().getTypeSizeInBits(Tmp->getType()); 257706c3fb27SDimitry Andric Tmp = Builder.CreatePtrToInt( 257806c3fb27SDimitry Andric Tmp, llvm::IntegerType::get(CTX, (unsigned)TmpSize)); 257906c3fb27SDimitry Andric Tmp = Builder.CreateTrunc(Tmp, TruncTy); 25807a6dacacSDimitry Andric } else if (Tmp->getType()->isIntegerTy() && TruncTy->isIntegerTy()) { 258106c3fb27SDimitry Andric Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy); 25827a6dacacSDimitry Andric } else if (Tmp->getType()->isVectorTy() || TruncTy->isVectorTy()) { 258306c3fb27SDimitry Andric Tmp = Builder.CreateBitCast(Tmp, TruncTy); 258406c3fb27SDimitry Andric } 258506c3fb27SDimitry Andric } 258606c3fb27SDimitry Andric 258706c3fb27SDimitry Andric LValue Dest = ResultRegDests[i]; 258806c3fb27SDimitry Andric // ResultTypeRequiresCast elements correspond to the first 258906c3fb27SDimitry Andric // ResultTypeRequiresCast.size() elements of RegResults. 259006c3fb27SDimitry Andric if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) { 259106c3fb27SDimitry Andric unsigned Size = CGF.getContext().getTypeSize(ResultRegQualTys[i]); 25920fca6ea1SDimitry Andric Address A = Dest.getAddress().withElementType(ResultRegTypes[i]); 259306c3fb27SDimitry Andric if (CGF.getTargetHooks().isScalarizableAsmOperand(CGF, TruncTy)) { 259406c3fb27SDimitry Andric Builder.CreateStore(Tmp, A); 259506c3fb27SDimitry Andric continue; 259606c3fb27SDimitry Andric } 259706c3fb27SDimitry Andric 259806c3fb27SDimitry Andric QualType Ty = 259906c3fb27SDimitry Andric CGF.getContext().getIntTypeForBitwidth(Size, /*Signed=*/false); 260006c3fb27SDimitry Andric if (Ty.isNull()) { 260106c3fb27SDimitry Andric const Expr *OutExpr = S.getOutputExpr(i); 260206c3fb27SDimitry Andric CGM.getDiags().Report(OutExpr->getExprLoc(), 260306c3fb27SDimitry Andric diag::err_store_value_to_reg); 260406c3fb27SDimitry Andric return; 260506c3fb27SDimitry Andric } 260606c3fb27SDimitry Andric Dest = CGF.MakeAddrLValue(A, Ty); 260706c3fb27SDimitry Andric } 260806c3fb27SDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(Tmp), Dest); 260906c3fb27SDimitry Andric } 261006c3fb27SDimitry Andric } 261106c3fb27SDimitry Andric 26125f757f3fSDimitry Andric static void EmitHipStdParUnsupportedAsm(CodeGenFunction *CGF, 26135f757f3fSDimitry Andric const AsmStmt &S) { 26145f757f3fSDimitry Andric constexpr auto Name = "__ASM__hipstdpar_unsupported"; 26155f757f3fSDimitry Andric 26165f757f3fSDimitry Andric StringRef Asm; 26175f757f3fSDimitry Andric if (auto GCCAsm = dyn_cast<GCCAsmStmt>(&S)) 26185f757f3fSDimitry Andric Asm = GCCAsm->getAsmString()->getString(); 26195f757f3fSDimitry Andric 26205f757f3fSDimitry Andric auto &Ctx = CGF->CGM.getLLVMContext(); 26215f757f3fSDimitry Andric 26225f757f3fSDimitry Andric auto StrTy = llvm::ConstantDataArray::getString(Ctx, Asm); 26235f757f3fSDimitry Andric auto FnTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), 26245f757f3fSDimitry Andric {StrTy->getType()}, false); 26255f757f3fSDimitry Andric auto UBF = CGF->CGM.getModule().getOrInsertFunction(Name, FnTy); 26265f757f3fSDimitry Andric 26275f757f3fSDimitry Andric CGF->Builder.CreateCall(UBF, {StrTy}); 26285f757f3fSDimitry Andric } 26295f757f3fSDimitry Andric 26300b57cec5SDimitry Andric void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { 263181ad6265SDimitry Andric // Pop all cleanup blocks at the end of the asm statement. 263281ad6265SDimitry Andric CodeGenFunction::RunCleanupsScope Cleanups(*this); 263381ad6265SDimitry Andric 26340b57cec5SDimitry Andric // Assemble the final asm string. 26350b57cec5SDimitry Andric std::string AsmString = S.generateAsmString(getContext()); 26360b57cec5SDimitry Andric 26370b57cec5SDimitry Andric // Get all the output and input constraints together. 26380b57cec5SDimitry Andric SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos; 26390b57cec5SDimitry Andric SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos; 26400b57cec5SDimitry Andric 26415f757f3fSDimitry Andric bool IsHipStdPar = getLangOpts().HIPStdPar && getLangOpts().CUDAIsDevice; 26425f757f3fSDimitry Andric bool IsValidTargetAsm = true; 26435f757f3fSDimitry Andric for (unsigned i = 0, e = S.getNumOutputs(); i != e && IsValidTargetAsm; i++) { 26440b57cec5SDimitry Andric StringRef Name; 26450b57cec5SDimitry Andric if (const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S)) 26460b57cec5SDimitry Andric Name = GAS->getOutputName(i); 26470b57cec5SDimitry Andric TargetInfo::ConstraintInfo Info(S.getOutputConstraint(i), Name); 26480b57cec5SDimitry Andric bool IsValid = getTarget().validateOutputConstraint(Info); (void)IsValid; 26495f757f3fSDimitry Andric if (IsHipStdPar && !IsValid) 26505f757f3fSDimitry Andric IsValidTargetAsm = false; 26515f757f3fSDimitry Andric else 26520b57cec5SDimitry Andric assert(IsValid && "Failed to parse output constraint"); 26530b57cec5SDimitry Andric OutputConstraintInfos.push_back(Info); 26540b57cec5SDimitry Andric } 26550b57cec5SDimitry Andric 26565f757f3fSDimitry Andric for (unsigned i = 0, e = S.getNumInputs(); i != e && IsValidTargetAsm; i++) { 26570b57cec5SDimitry Andric StringRef Name; 26580b57cec5SDimitry Andric if (const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S)) 26590b57cec5SDimitry Andric Name = GAS->getInputName(i); 26600b57cec5SDimitry Andric TargetInfo::ConstraintInfo Info(S.getInputConstraint(i), Name); 26610b57cec5SDimitry Andric bool IsValid = 26620b57cec5SDimitry Andric getTarget().validateInputConstraint(OutputConstraintInfos, Info); 26635f757f3fSDimitry Andric if (IsHipStdPar && !IsValid) 26645f757f3fSDimitry Andric IsValidTargetAsm = false; 26655f757f3fSDimitry Andric else 26665f757f3fSDimitry Andric assert(IsValid && "Failed to parse input constraint"); 26670b57cec5SDimitry Andric InputConstraintInfos.push_back(Info); 26680b57cec5SDimitry Andric } 26690b57cec5SDimitry Andric 26705f757f3fSDimitry Andric if (!IsValidTargetAsm) 26715f757f3fSDimitry Andric return EmitHipStdParUnsupportedAsm(this, S); 26725f757f3fSDimitry Andric 26730b57cec5SDimitry Andric std::string Constraints; 26740b57cec5SDimitry Andric 26750b57cec5SDimitry Andric std::vector<LValue> ResultRegDests; 26760b57cec5SDimitry Andric std::vector<QualType> ResultRegQualTys; 26770b57cec5SDimitry Andric std::vector<llvm::Type *> ResultRegTypes; 26780b57cec5SDimitry Andric std::vector<llvm::Type *> ResultTruncRegTypes; 26790b57cec5SDimitry Andric std::vector<llvm::Type *> ArgTypes; 268004eeddc0SDimitry Andric std::vector<llvm::Type *> ArgElemTypes; 26810b57cec5SDimitry Andric std::vector<llvm::Value*> Args; 2682a7dea167SDimitry Andric llvm::BitVector ResultTypeRequiresCast; 268361cfbce3SDimitry Andric llvm::BitVector ResultRegIsFlagReg; 26840b57cec5SDimitry Andric 26850b57cec5SDimitry Andric // Keep track of inout constraints. 26860b57cec5SDimitry Andric std::string InOutConstraints; 26870b57cec5SDimitry Andric std::vector<llvm::Value*> InOutArgs; 26880b57cec5SDimitry Andric std::vector<llvm::Type*> InOutArgTypes; 268904eeddc0SDimitry Andric std::vector<llvm::Type*> InOutArgElemTypes; 26900b57cec5SDimitry Andric 26910b57cec5SDimitry Andric // Keep track of out constraints for tied input operand. 26920b57cec5SDimitry Andric std::vector<std::string> OutputConstraints; 26930b57cec5SDimitry Andric 2694e8d8bef9SDimitry Andric // Keep track of defined physregs. 2695e8d8bef9SDimitry Andric llvm::SmallSet<std::string, 8> PhysRegOutputs; 2696e8d8bef9SDimitry Andric 26970b57cec5SDimitry Andric // An inline asm can be marked readonly if it meets the following conditions: 26980b57cec5SDimitry Andric // - it doesn't have any sideeffects 26990b57cec5SDimitry Andric // - it doesn't clobber memory 27000b57cec5SDimitry Andric // - it doesn't return a value by-reference 27010b57cec5SDimitry Andric // It can be marked readnone if it doesn't have any input memory constraints 27020b57cec5SDimitry Andric // in addition to meeting the conditions listed above. 27030b57cec5SDimitry Andric bool ReadOnly = true, ReadNone = true; 27040b57cec5SDimitry Andric 27050b57cec5SDimitry Andric for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { 27060b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i]; 27070b57cec5SDimitry Andric 27080b57cec5SDimitry Andric // Simplify the output constraint. 27090b57cec5SDimitry Andric std::string OutputConstraint(S.getOutputConstraint(i)); 27100b57cec5SDimitry Andric OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, 27110b57cec5SDimitry Andric getTarget(), &OutputConstraintInfos); 27120b57cec5SDimitry Andric 27130b57cec5SDimitry Andric const Expr *OutExpr = S.getOutputExpr(i); 27140b57cec5SDimitry Andric OutExpr = OutExpr->IgnoreParenNoopCasts(getContext()); 27150b57cec5SDimitry Andric 2716e8d8bef9SDimitry Andric std::string GCCReg; 27170b57cec5SDimitry Andric OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr, 27180b57cec5SDimitry Andric getTarget(), CGM, S, 2719e8d8bef9SDimitry Andric Info.earlyClobber(), 2720e8d8bef9SDimitry Andric &GCCReg); 2721e8d8bef9SDimitry Andric // Give an error on multiple outputs to same physreg. 2722e8d8bef9SDimitry Andric if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second) 2723e8d8bef9SDimitry Andric CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg); 2724e8d8bef9SDimitry Andric 27250b57cec5SDimitry Andric OutputConstraints.push_back(OutputConstraint); 27260b57cec5SDimitry Andric LValue Dest = EmitLValue(OutExpr); 27270b57cec5SDimitry Andric if (!Constraints.empty()) 27280b57cec5SDimitry Andric Constraints += ','; 27290b57cec5SDimitry Andric 27300b57cec5SDimitry Andric // If this is a register output, then make the inline asm return it 27310b57cec5SDimitry Andric // by-value. If this is a memory result, return the value by-reference. 27326e75b2fbSDimitry Andric QualType QTy = OutExpr->getType(); 27336e75b2fbSDimitry Andric const bool IsScalarOrAggregate = hasScalarEvaluationKind(QTy) || 27346e75b2fbSDimitry Andric hasAggregateEvaluationKind(QTy); 27356e75b2fbSDimitry Andric if (!Info.allowsMemory() && IsScalarOrAggregate) { 27366e75b2fbSDimitry Andric 27370b57cec5SDimitry Andric Constraints += "=" + OutputConstraint; 27386e75b2fbSDimitry Andric ResultRegQualTys.push_back(QTy); 27390b57cec5SDimitry Andric ResultRegDests.push_back(Dest); 27406e75b2fbSDimitry Andric 27415f757f3fSDimitry Andric bool IsFlagReg = llvm::StringRef(OutputConstraint).starts_with("{@cc"); 274261cfbce3SDimitry Andric ResultRegIsFlagReg.push_back(IsFlagReg); 274361cfbce3SDimitry Andric 27446e75b2fbSDimitry Andric llvm::Type *Ty = ConvertTypeForMem(QTy); 27456e75b2fbSDimitry Andric const bool RequiresCast = Info.allowsRegister() && 27466e75b2fbSDimitry Andric (getTargetHooks().isScalarizableAsmOperand(*this, Ty) || 27476e75b2fbSDimitry Andric Ty->isAggregateType()); 27486e75b2fbSDimitry Andric 27496e75b2fbSDimitry Andric ResultTruncRegTypes.push_back(Ty); 27506e75b2fbSDimitry Andric ResultTypeRequiresCast.push_back(RequiresCast); 27516e75b2fbSDimitry Andric 27526e75b2fbSDimitry Andric if (RequiresCast) { 27536e75b2fbSDimitry Andric unsigned Size = getContext().getTypeSize(QTy); 27546e75b2fbSDimitry Andric Ty = llvm::IntegerType::get(getLLVMContext(), Size); 2755a7dea167SDimitry Andric } 27566e75b2fbSDimitry Andric ResultRegTypes.push_back(Ty); 27570b57cec5SDimitry Andric // If this output is tied to an input, and if the input is larger, then 27580b57cec5SDimitry Andric // we need to set the actual result type of the inline asm node to be the 27590b57cec5SDimitry Andric // same as the input type. 27600b57cec5SDimitry Andric if (Info.hasMatchingInput()) { 27610b57cec5SDimitry Andric unsigned InputNo; 27620b57cec5SDimitry Andric for (InputNo = 0; InputNo != S.getNumInputs(); ++InputNo) { 27630b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Input = InputConstraintInfos[InputNo]; 27640b57cec5SDimitry Andric if (Input.hasTiedOperand() && Input.getTiedOperand() == i) 27650b57cec5SDimitry Andric break; 27660b57cec5SDimitry Andric } 27670b57cec5SDimitry Andric assert(InputNo != S.getNumInputs() && "Didn't find matching input!"); 27680b57cec5SDimitry Andric 27690b57cec5SDimitry Andric QualType InputTy = S.getInputExpr(InputNo)->getType(); 27700b57cec5SDimitry Andric QualType OutputType = OutExpr->getType(); 27710b57cec5SDimitry Andric 27720b57cec5SDimitry Andric uint64_t InputSize = getContext().getTypeSize(InputTy); 27730b57cec5SDimitry Andric if (getContext().getTypeSize(OutputType) < InputSize) { 27740b57cec5SDimitry Andric // Form the asm to return the value as a larger integer or fp type. 27750b57cec5SDimitry Andric ResultRegTypes.back() = ConvertType(InputTy); 27760b57cec5SDimitry Andric } 27770b57cec5SDimitry Andric } 27780b57cec5SDimitry Andric if (llvm::Type* AdjTy = 27790b57cec5SDimitry Andric getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, 27800b57cec5SDimitry Andric ResultRegTypes.back())) 27810b57cec5SDimitry Andric ResultRegTypes.back() = AdjTy; 27820b57cec5SDimitry Andric else { 27830b57cec5SDimitry Andric CGM.getDiags().Report(S.getAsmLoc(), 27840b57cec5SDimitry Andric diag::err_asm_invalid_type_in_input) 27850b57cec5SDimitry Andric << OutExpr->getType() << OutputConstraint; 27860b57cec5SDimitry Andric } 27870b57cec5SDimitry Andric 27880b57cec5SDimitry Andric // Update largest vector width for any vector types. 27890b57cec5SDimitry Andric if (auto *VT = dyn_cast<llvm::VectorType>(ResultRegTypes.back())) 27905ffd83dbSDimitry Andric LargestVectorWidth = 27915ffd83dbSDimitry Andric std::max((uint64_t)LargestVectorWidth, 2792bdd1243dSDimitry Andric VT->getPrimitiveSizeInBits().getKnownMinValue()); 27930b57cec5SDimitry Andric } else { 27940fca6ea1SDimitry Andric Address DestAddr = Dest.getAddress(); 2795e8d8bef9SDimitry Andric // Matrix types in memory are represented by arrays, but accessed through 2796e8d8bef9SDimitry Andric // vector pointers, with the alignment specified on the access operation. 2797e8d8bef9SDimitry Andric // For inline assembly, update pointer arguments to use vector pointers. 2798e8d8bef9SDimitry Andric // Otherwise there will be a mis-match if the matrix is also an 2799e8d8bef9SDimitry Andric // input-argument which is represented as vector. 280004eeddc0SDimitry Andric if (isa<MatrixType>(OutExpr->getType().getCanonicalType())) 280106c3fb27SDimitry Andric DestAddr = DestAddr.withElementType(ConvertType(OutExpr->getType())); 280204eeddc0SDimitry Andric 280304eeddc0SDimitry Andric ArgTypes.push_back(DestAddr.getType()); 280404eeddc0SDimitry Andric ArgElemTypes.push_back(DestAddr.getElementType()); 28050fca6ea1SDimitry Andric Args.push_back(DestAddr.emitRawPointer(*this)); 28060b57cec5SDimitry Andric Constraints += "=*"; 28070b57cec5SDimitry Andric Constraints += OutputConstraint; 28080b57cec5SDimitry Andric ReadOnly = ReadNone = false; 28090b57cec5SDimitry Andric } 28100b57cec5SDimitry Andric 28110b57cec5SDimitry Andric if (Info.isReadWrite()) { 28120b57cec5SDimitry Andric InOutConstraints += ','; 28130b57cec5SDimitry Andric 28140b57cec5SDimitry Andric const Expr *InputExpr = S.getOutputExpr(i); 281504eeddc0SDimitry Andric llvm::Value *Arg; 281604eeddc0SDimitry Andric llvm::Type *ArgElemType; 281704eeddc0SDimitry Andric std::tie(Arg, ArgElemType) = EmitAsmInputLValue( 281804eeddc0SDimitry Andric Info, Dest, InputExpr->getType(), InOutConstraints, 28190b57cec5SDimitry Andric InputExpr->getExprLoc()); 28200b57cec5SDimitry Andric 28210b57cec5SDimitry Andric if (llvm::Type* AdjTy = 28220b57cec5SDimitry Andric getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, 28230b57cec5SDimitry Andric Arg->getType())) 28240b57cec5SDimitry Andric Arg = Builder.CreateBitCast(Arg, AdjTy); 28250b57cec5SDimitry Andric 28260b57cec5SDimitry Andric // Update largest vector width for any vector types. 28270b57cec5SDimitry Andric if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType())) 28285ffd83dbSDimitry Andric LargestVectorWidth = 28295ffd83dbSDimitry Andric std::max((uint64_t)LargestVectorWidth, 2830bdd1243dSDimitry Andric VT->getPrimitiveSizeInBits().getKnownMinValue()); 2831e8d8bef9SDimitry Andric // Only tie earlyclobber physregs. 2832e8d8bef9SDimitry Andric if (Info.allowsRegister() && (GCCReg.empty() || Info.earlyClobber())) 28330b57cec5SDimitry Andric InOutConstraints += llvm::utostr(i); 28340b57cec5SDimitry Andric else 28350b57cec5SDimitry Andric InOutConstraints += OutputConstraint; 28360b57cec5SDimitry Andric 28370b57cec5SDimitry Andric InOutArgTypes.push_back(Arg->getType()); 283804eeddc0SDimitry Andric InOutArgElemTypes.push_back(ArgElemType); 28390b57cec5SDimitry Andric InOutArgs.push_back(Arg); 28400b57cec5SDimitry Andric } 28410b57cec5SDimitry Andric } 28420b57cec5SDimitry Andric 28430b57cec5SDimitry Andric // If this is a Microsoft-style asm blob, store the return registers (EAX:EDX) 28440b57cec5SDimitry Andric // to the return value slot. Only do this when returning in registers. 28450b57cec5SDimitry Andric if (isa<MSAsmStmt>(&S)) { 28460b57cec5SDimitry Andric const ABIArgInfo &RetAI = CurFnInfo->getReturnInfo(); 28470b57cec5SDimitry Andric if (RetAI.isDirect() || RetAI.isExtend()) { 28480b57cec5SDimitry Andric // Make a fake lvalue for the return value slot. 28490eae32dcSDimitry Andric LValue ReturnSlot = MakeAddrLValueWithoutTBAA(ReturnValue, FnRetTy); 28500b57cec5SDimitry Andric CGM.getTargetCodeGenInfo().addReturnRegisterOutputs( 28510b57cec5SDimitry Andric *this, ReturnSlot, Constraints, ResultRegTypes, ResultTruncRegTypes, 28520b57cec5SDimitry Andric ResultRegDests, AsmString, S.getNumOutputs()); 28530b57cec5SDimitry Andric SawAsmBlock = true; 28540b57cec5SDimitry Andric } 28550b57cec5SDimitry Andric } 28560b57cec5SDimitry Andric 28570b57cec5SDimitry Andric for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { 28580b57cec5SDimitry Andric const Expr *InputExpr = S.getInputExpr(i); 28590b57cec5SDimitry Andric 28600b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; 28610b57cec5SDimitry Andric 28620b57cec5SDimitry Andric if (Info.allowsMemory()) 28630b57cec5SDimitry Andric ReadNone = false; 28640b57cec5SDimitry Andric 28650b57cec5SDimitry Andric if (!Constraints.empty()) 28660b57cec5SDimitry Andric Constraints += ','; 28670b57cec5SDimitry Andric 28680b57cec5SDimitry Andric // Simplify the input constraint. 28690b57cec5SDimitry Andric std::string InputConstraint(S.getInputConstraint(i)); 28700b57cec5SDimitry Andric InputConstraint = SimplifyConstraint(InputConstraint.c_str(), getTarget(), 28710b57cec5SDimitry Andric &OutputConstraintInfos); 28720b57cec5SDimitry Andric 28730b57cec5SDimitry Andric InputConstraint = AddVariableConstraints( 28740b57cec5SDimitry Andric InputConstraint, *InputExpr->IgnoreParenNoopCasts(getContext()), 28750b57cec5SDimitry Andric getTarget(), CGM, S, false /* No EarlyClobber */); 28760b57cec5SDimitry Andric 28770b57cec5SDimitry Andric std::string ReplaceConstraint (InputConstraint); 287804eeddc0SDimitry Andric llvm::Value *Arg; 287904eeddc0SDimitry Andric llvm::Type *ArgElemType; 288004eeddc0SDimitry Andric std::tie(Arg, ArgElemType) = EmitAsmInput(Info, InputExpr, Constraints); 28810b57cec5SDimitry Andric 28820b57cec5SDimitry Andric // If this input argument is tied to a larger output result, extend the 28830b57cec5SDimitry Andric // input to be the same size as the output. The LLVM backend wants to see 28840b57cec5SDimitry Andric // the input and output of a matching constraint be the same size. Note 28850b57cec5SDimitry Andric // that GCC does not define what the top bits are here. We use zext because 28860b57cec5SDimitry Andric // that is usually cheaper, but LLVM IR should really get an anyext someday. 28870b57cec5SDimitry Andric if (Info.hasTiedOperand()) { 28880b57cec5SDimitry Andric unsigned Output = Info.getTiedOperand(); 28890b57cec5SDimitry Andric QualType OutputType = S.getOutputExpr(Output)->getType(); 28900b57cec5SDimitry Andric QualType InputTy = InputExpr->getType(); 28910b57cec5SDimitry Andric 28920b57cec5SDimitry Andric if (getContext().getTypeSize(OutputType) > 28930b57cec5SDimitry Andric getContext().getTypeSize(InputTy)) { 28940b57cec5SDimitry Andric // Use ptrtoint as appropriate so that we can do our extension. 28950b57cec5SDimitry Andric if (isa<llvm::PointerType>(Arg->getType())) 28960b57cec5SDimitry Andric Arg = Builder.CreatePtrToInt(Arg, IntPtrTy); 28970b57cec5SDimitry Andric llvm::Type *OutputTy = ConvertType(OutputType); 28980b57cec5SDimitry Andric if (isa<llvm::IntegerType>(OutputTy)) 28990b57cec5SDimitry Andric Arg = Builder.CreateZExt(Arg, OutputTy); 29000b57cec5SDimitry Andric else if (isa<llvm::PointerType>(OutputTy)) 29010b57cec5SDimitry Andric Arg = Builder.CreateZExt(Arg, IntPtrTy); 290281ad6265SDimitry Andric else if (OutputTy->isFloatingPointTy()) 29030b57cec5SDimitry Andric Arg = Builder.CreateFPExt(Arg, OutputTy); 29040b57cec5SDimitry Andric } 29050b57cec5SDimitry Andric // Deal with the tied operands' constraint code in adjustInlineAsmType. 29060b57cec5SDimitry Andric ReplaceConstraint = OutputConstraints[Output]; 29070b57cec5SDimitry Andric } 29080b57cec5SDimitry Andric if (llvm::Type* AdjTy = 29090b57cec5SDimitry Andric getTargetHooks().adjustInlineAsmType(*this, ReplaceConstraint, 29100b57cec5SDimitry Andric Arg->getType())) 29110b57cec5SDimitry Andric Arg = Builder.CreateBitCast(Arg, AdjTy); 29120b57cec5SDimitry Andric else 29130b57cec5SDimitry Andric CGM.getDiags().Report(S.getAsmLoc(), diag::err_asm_invalid_type_in_input) 29140b57cec5SDimitry Andric << InputExpr->getType() << InputConstraint; 29150b57cec5SDimitry Andric 29160b57cec5SDimitry Andric // Update largest vector width for any vector types. 29170b57cec5SDimitry Andric if (auto *VT = dyn_cast<llvm::VectorType>(Arg->getType())) 29185ffd83dbSDimitry Andric LargestVectorWidth = 29195ffd83dbSDimitry Andric std::max((uint64_t)LargestVectorWidth, 2920bdd1243dSDimitry Andric VT->getPrimitiveSizeInBits().getKnownMinValue()); 29210b57cec5SDimitry Andric 29220b57cec5SDimitry Andric ArgTypes.push_back(Arg->getType()); 292304eeddc0SDimitry Andric ArgElemTypes.push_back(ArgElemType); 29240b57cec5SDimitry Andric Args.push_back(Arg); 29250b57cec5SDimitry Andric Constraints += InputConstraint; 29260b57cec5SDimitry Andric } 29270b57cec5SDimitry Andric 292804eeddc0SDimitry Andric // Append the "input" part of inout constraints. 292904eeddc0SDimitry Andric for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { 293004eeddc0SDimitry Andric ArgTypes.push_back(InOutArgTypes[i]); 293104eeddc0SDimitry Andric ArgElemTypes.push_back(InOutArgElemTypes[i]); 293204eeddc0SDimitry Andric Args.push_back(InOutArgs[i]); 293304eeddc0SDimitry Andric } 293404eeddc0SDimitry Andric Constraints += InOutConstraints; 293504eeddc0SDimitry Andric 29360b57cec5SDimitry Andric // Labels 29370b57cec5SDimitry Andric SmallVector<llvm::BasicBlock *, 16> Transfer; 29380b57cec5SDimitry Andric llvm::BasicBlock *Fallthrough = nullptr; 29390b57cec5SDimitry Andric bool IsGCCAsmGoto = false; 29400b57cec5SDimitry Andric if (const auto *GS = dyn_cast<GCCAsmStmt>(&S)) { 29410b57cec5SDimitry Andric IsGCCAsmGoto = GS->isAsmGoto(); 29420b57cec5SDimitry Andric if (IsGCCAsmGoto) { 29435ffd83dbSDimitry Andric for (const auto *E : GS->labels()) { 29440b57cec5SDimitry Andric JumpDest Dest = getJumpDestForLabel(E->getLabel()); 29450b57cec5SDimitry Andric Transfer.push_back(Dest.getBlock()); 29460b57cec5SDimitry Andric if (!Constraints.empty()) 29470b57cec5SDimitry Andric Constraints += ','; 2948fcaf7f86SDimitry Andric Constraints += "!i"; 29490b57cec5SDimitry Andric } 29505ffd83dbSDimitry Andric Fallthrough = createBasicBlock("asm.fallthrough"); 29510b57cec5SDimitry Andric } 29520b57cec5SDimitry Andric } 29530b57cec5SDimitry Andric 2954fe6060f1SDimitry Andric bool HasUnwindClobber = false; 2955fe6060f1SDimitry Andric 29560b57cec5SDimitry Andric // Clobbers 29570b57cec5SDimitry Andric for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { 29580b57cec5SDimitry Andric StringRef Clobber = S.getClobber(i); 29590b57cec5SDimitry Andric 29600b57cec5SDimitry Andric if (Clobber == "memory") 29610b57cec5SDimitry Andric ReadOnly = ReadNone = false; 2962fe6060f1SDimitry Andric else if (Clobber == "unwind") { 2963fe6060f1SDimitry Andric HasUnwindClobber = true; 2964fe6060f1SDimitry Andric continue; 2965fe6060f1SDimitry Andric } else if (Clobber != "cc") { 29660b57cec5SDimitry Andric Clobber = getTarget().getNormalizedGCCRegisterName(Clobber); 29675ffd83dbSDimitry Andric if (CGM.getCodeGenOpts().StackClashProtector && 29685ffd83dbSDimitry Andric getTarget().isSPRegName(Clobber)) { 29695ffd83dbSDimitry Andric CGM.getDiags().Report(S.getAsmLoc(), 29705ffd83dbSDimitry Andric diag::warn_stack_clash_protection_inline_asm); 29715ffd83dbSDimitry Andric } 29725ffd83dbSDimitry Andric } 29730b57cec5SDimitry Andric 2974fe6060f1SDimitry Andric if (isa<MSAsmStmt>(&S)) { 2975fe6060f1SDimitry Andric if (Clobber == "eax" || Clobber == "edx") { 2976fe6060f1SDimitry Andric if (Constraints.find("=&A") != std::string::npos) 2977fe6060f1SDimitry Andric continue; 2978fe6060f1SDimitry Andric std::string::size_type position1 = 2979fe6060f1SDimitry Andric Constraints.find("={" + Clobber.str() + "}"); 2980fe6060f1SDimitry Andric if (position1 != std::string::npos) { 2981fe6060f1SDimitry Andric Constraints.insert(position1 + 1, "&"); 2982fe6060f1SDimitry Andric continue; 2983fe6060f1SDimitry Andric } 2984fe6060f1SDimitry Andric std::string::size_type position2 = Constraints.find("=A"); 2985fe6060f1SDimitry Andric if (position2 != std::string::npos) { 2986fe6060f1SDimitry Andric Constraints.insert(position2 + 1, "&"); 2987fe6060f1SDimitry Andric continue; 2988fe6060f1SDimitry Andric } 2989fe6060f1SDimitry Andric } 2990fe6060f1SDimitry Andric } 29910b57cec5SDimitry Andric if (!Constraints.empty()) 29920b57cec5SDimitry Andric Constraints += ','; 29930b57cec5SDimitry Andric 29940b57cec5SDimitry Andric Constraints += "~{"; 29950b57cec5SDimitry Andric Constraints += Clobber; 29960b57cec5SDimitry Andric Constraints += '}'; 29970b57cec5SDimitry Andric } 29980b57cec5SDimitry Andric 2999fe6060f1SDimitry Andric assert(!(HasUnwindClobber && IsGCCAsmGoto) && 3000fe6060f1SDimitry Andric "unwind clobber can't be used with asm goto"); 3001fe6060f1SDimitry Andric 30020b57cec5SDimitry Andric // Add machine specific clobbers 300306c3fb27SDimitry Andric std::string_view MachineClobbers = getTarget().getClobbers(); 30040b57cec5SDimitry Andric if (!MachineClobbers.empty()) { 30050b57cec5SDimitry Andric if (!Constraints.empty()) 30060b57cec5SDimitry Andric Constraints += ','; 30070b57cec5SDimitry Andric Constraints += MachineClobbers; 30080b57cec5SDimitry Andric } 30090b57cec5SDimitry Andric 30100b57cec5SDimitry Andric llvm::Type *ResultType; 30110b57cec5SDimitry Andric if (ResultRegTypes.empty()) 30120b57cec5SDimitry Andric ResultType = VoidTy; 30130b57cec5SDimitry Andric else if (ResultRegTypes.size() == 1) 30140b57cec5SDimitry Andric ResultType = ResultRegTypes[0]; 30150b57cec5SDimitry Andric else 30160b57cec5SDimitry Andric ResultType = llvm::StructType::get(getLLVMContext(), ResultRegTypes); 30170b57cec5SDimitry Andric 30180b57cec5SDimitry Andric llvm::FunctionType *FTy = 30190b57cec5SDimitry Andric llvm::FunctionType::get(ResultType, ArgTypes, false); 30200b57cec5SDimitry Andric 30210b57cec5SDimitry Andric bool HasSideEffect = S.isVolatile() || S.getNumOutputs() == 0; 3022349cc55cSDimitry Andric 3023349cc55cSDimitry Andric llvm::InlineAsm::AsmDialect GnuAsmDialect = 3024349cc55cSDimitry Andric CGM.getCodeGenOpts().getInlineAsmDialect() == CodeGenOptions::IAD_ATT 3025349cc55cSDimitry Andric ? llvm::InlineAsm::AD_ATT 3026349cc55cSDimitry Andric : llvm::InlineAsm::AD_Intel; 30270b57cec5SDimitry Andric llvm::InlineAsm::AsmDialect AsmDialect = isa<MSAsmStmt>(&S) ? 3028349cc55cSDimitry Andric llvm::InlineAsm::AD_Intel : GnuAsmDialect; 3029349cc55cSDimitry Andric 3030fe6060f1SDimitry Andric llvm::InlineAsm *IA = llvm::InlineAsm::get( 3031fe6060f1SDimitry Andric FTy, AsmString, Constraints, HasSideEffect, 3032fe6060f1SDimitry Andric /* IsAlignStack */ false, AsmDialect, HasUnwindClobber); 30330b57cec5SDimitry Andric std::vector<llvm::Value*> RegResults; 303406c3fb27SDimitry Andric llvm::CallBrInst *CBR; 303506c3fb27SDimitry Andric llvm::DenseMap<llvm::BasicBlock *, SmallVector<llvm::Value *, 4>> 303606c3fb27SDimitry Andric CBRRegResults; 30370b57cec5SDimitry Andric if (IsGCCAsmGoto) { 303806c3fb27SDimitry Andric CBR = Builder.CreateCallBr(IA, Fallthrough, Transfer, Args); 30395ffd83dbSDimitry Andric EmitBlock(Fallthrough); 304006c3fb27SDimitry Andric UpdateAsmCallInst(*CBR, HasSideEffect, false, ReadOnly, ReadNone, 304106c3fb27SDimitry Andric InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes, 304206c3fb27SDimitry Andric *this, RegResults); 304306c3fb27SDimitry Andric // Because we are emitting code top to bottom, we don't have enough 304406c3fb27SDimitry Andric // information at this point to know precisely whether we have a critical 304506c3fb27SDimitry Andric // edge. If we have outputs, split all indirect destinations. 304606c3fb27SDimitry Andric if (!RegResults.empty()) { 304706c3fb27SDimitry Andric unsigned i = 0; 304806c3fb27SDimitry Andric for (llvm::BasicBlock *Dest : CBR->getIndirectDests()) { 304906c3fb27SDimitry Andric llvm::Twine SynthName = Dest->getName() + ".split"; 305006c3fb27SDimitry Andric llvm::BasicBlock *SynthBB = createBasicBlock(SynthName); 305106c3fb27SDimitry Andric llvm::IRBuilderBase::InsertPointGuard IPG(Builder); 305206c3fb27SDimitry Andric Builder.SetInsertPoint(SynthBB); 305306c3fb27SDimitry Andric 305406c3fb27SDimitry Andric if (ResultRegTypes.size() == 1) { 305506c3fb27SDimitry Andric CBRRegResults[SynthBB].push_back(CBR); 305606c3fb27SDimitry Andric } else { 305706c3fb27SDimitry Andric for (unsigned j = 0, e = ResultRegTypes.size(); j != e; ++j) { 305806c3fb27SDimitry Andric llvm::Value *Tmp = Builder.CreateExtractValue(CBR, j, "asmresult"); 305906c3fb27SDimitry Andric CBRRegResults[SynthBB].push_back(Tmp); 306006c3fb27SDimitry Andric } 306106c3fb27SDimitry Andric } 306206c3fb27SDimitry Andric 306306c3fb27SDimitry Andric EmitBranch(Dest); 306406c3fb27SDimitry Andric EmitBlock(SynthBB); 306506c3fb27SDimitry Andric CBR->setIndirectDest(i++, SynthBB); 306606c3fb27SDimitry Andric } 306706c3fb27SDimitry Andric } 3068fe6060f1SDimitry Andric } else if (HasUnwindClobber) { 3069fe6060f1SDimitry Andric llvm::CallBase *Result = EmitCallOrInvoke(IA, Args, ""); 3070fe6060f1SDimitry Andric UpdateAsmCallInst(*Result, HasSideEffect, true, ReadOnly, ReadNone, 307104eeddc0SDimitry Andric InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes, 307204eeddc0SDimitry Andric *this, RegResults); 30730b57cec5SDimitry Andric } else { 30740b57cec5SDimitry Andric llvm::CallInst *Result = 30750b57cec5SDimitry Andric Builder.CreateCall(IA, Args, getBundlesForFunclet(IA)); 307606c3fb27SDimitry Andric UpdateAsmCallInst(*Result, HasSideEffect, false, ReadOnly, ReadNone, 307706c3fb27SDimitry Andric InNoMergeAttributedStmt, S, ResultRegTypes, ArgElemTypes, 307806c3fb27SDimitry Andric *this, RegResults); 30790b57cec5SDimitry Andric } 30800b57cec5SDimitry Andric 308106c3fb27SDimitry Andric EmitAsmStores(*this, S, RegResults, ResultRegTypes, ResultTruncRegTypes, 308206c3fb27SDimitry Andric ResultRegDests, ResultRegQualTys, ResultTypeRequiresCast, 308306c3fb27SDimitry Andric ResultRegIsFlagReg); 30840b57cec5SDimitry Andric 308506c3fb27SDimitry Andric // If this is an asm goto with outputs, repeat EmitAsmStores, but with a 308606c3fb27SDimitry Andric // different insertion point; one for each indirect destination and with 308706c3fb27SDimitry Andric // CBRRegResults rather than RegResults. 308806c3fb27SDimitry Andric if (IsGCCAsmGoto && !CBRRegResults.empty()) { 308906c3fb27SDimitry Andric for (llvm::BasicBlock *Succ : CBR->getIndirectDests()) { 309006c3fb27SDimitry Andric llvm::IRBuilderBase::InsertPointGuard IPG(Builder); 309106c3fb27SDimitry Andric Builder.SetInsertPoint(Succ, --(Succ->end())); 309206c3fb27SDimitry Andric EmitAsmStores(*this, S, CBRRegResults[Succ], ResultRegTypes, 309306c3fb27SDimitry Andric ResultTruncRegTypes, ResultRegDests, ResultRegQualTys, 309406c3fb27SDimitry Andric ResultTypeRequiresCast, ResultRegIsFlagReg); 309561cfbce3SDimitry Andric } 30960b57cec5SDimitry Andric } 30970b57cec5SDimitry Andric } 30980b57cec5SDimitry Andric 30990b57cec5SDimitry Andric LValue CodeGenFunction::InitCapturedStruct(const CapturedStmt &S) { 31000b57cec5SDimitry Andric const RecordDecl *RD = S.getCapturedRecordDecl(); 31010b57cec5SDimitry Andric QualType RecordTy = getContext().getRecordType(RD); 31020b57cec5SDimitry Andric 31030b57cec5SDimitry Andric // Initialize the captured struct. 31040b57cec5SDimitry Andric LValue SlotLV = 31050b57cec5SDimitry Andric MakeAddrLValue(CreateMemTemp(RecordTy, "agg.captured"), RecordTy); 31060b57cec5SDimitry Andric 31070b57cec5SDimitry Andric RecordDecl::field_iterator CurField = RD->field_begin(); 31080b57cec5SDimitry Andric for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(), 31090b57cec5SDimitry Andric E = S.capture_init_end(); 31100b57cec5SDimitry Andric I != E; ++I, ++CurField) { 31110b57cec5SDimitry Andric LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField); 31120b57cec5SDimitry Andric if (CurField->hasCapturedVLAType()) { 3113e8d8bef9SDimitry Andric EmitLambdaVLACapture(CurField->getCapturedVLAType(), LV); 31140b57cec5SDimitry Andric } else { 31150b57cec5SDimitry Andric EmitInitializerForField(*CurField, LV, *I); 31160b57cec5SDimitry Andric } 31170b57cec5SDimitry Andric } 31180b57cec5SDimitry Andric 31190b57cec5SDimitry Andric return SlotLV; 31200b57cec5SDimitry Andric } 31210b57cec5SDimitry Andric 31220b57cec5SDimitry Andric /// Generate an outlined function for the body of a CapturedStmt, store any 31230b57cec5SDimitry Andric /// captured variables into the captured struct, and call the outlined function. 31240b57cec5SDimitry Andric llvm::Function * 31250b57cec5SDimitry Andric CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) { 31260b57cec5SDimitry Andric LValue CapStruct = InitCapturedStruct(S); 31270b57cec5SDimitry Andric 31280b57cec5SDimitry Andric // Emit the CapturedDecl 31290b57cec5SDimitry Andric CodeGenFunction CGF(CGM, true); 31300b57cec5SDimitry Andric CGCapturedStmtRAII CapInfoRAII(CGF, new CGCapturedStmtInfo(S, K)); 31310b57cec5SDimitry Andric llvm::Function *F = CGF.GenerateCapturedStmtFunction(S); 31320b57cec5SDimitry Andric delete CGF.CapturedStmtInfo; 31330b57cec5SDimitry Andric 31340b57cec5SDimitry Andric // Emit call to the helper function. 3135480093f4SDimitry Andric EmitCallOrInvoke(F, CapStruct.getPointer(*this)); 31360b57cec5SDimitry Andric 31370b57cec5SDimitry Andric return F; 31380b57cec5SDimitry Andric } 31390b57cec5SDimitry Andric 31400b57cec5SDimitry Andric Address CodeGenFunction::GenerateCapturedStmtArgument(const CapturedStmt &S) { 31410b57cec5SDimitry Andric LValue CapStruct = InitCapturedStruct(S); 31420fca6ea1SDimitry Andric return CapStruct.getAddress(); 31430b57cec5SDimitry Andric } 31440b57cec5SDimitry Andric 31450b57cec5SDimitry Andric /// Creates the outlined function for a CapturedStmt. 31460b57cec5SDimitry Andric llvm::Function * 31470b57cec5SDimitry Andric CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) { 31480b57cec5SDimitry Andric assert(CapturedStmtInfo && 31490b57cec5SDimitry Andric "CapturedStmtInfo should be set when generating the captured function"); 31500b57cec5SDimitry Andric const CapturedDecl *CD = S.getCapturedDecl(); 31510b57cec5SDimitry Andric const RecordDecl *RD = S.getCapturedRecordDecl(); 31520b57cec5SDimitry Andric SourceLocation Loc = S.getBeginLoc(); 31530b57cec5SDimitry Andric assert(CD->hasBody() && "missing CapturedDecl body"); 31540b57cec5SDimitry Andric 31550b57cec5SDimitry Andric // Build the argument list. 31560b57cec5SDimitry Andric ASTContext &Ctx = CGM.getContext(); 31570b57cec5SDimitry Andric FunctionArgList Args; 31580b57cec5SDimitry Andric Args.append(CD->param_begin(), CD->param_end()); 31590b57cec5SDimitry Andric 31600b57cec5SDimitry Andric // Create the function declaration. 31610b57cec5SDimitry Andric const CGFunctionInfo &FuncInfo = 31620b57cec5SDimitry Andric CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args); 31630b57cec5SDimitry Andric llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo); 31640b57cec5SDimitry Andric 31650b57cec5SDimitry Andric llvm::Function *F = 31660b57cec5SDimitry Andric llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage, 31670b57cec5SDimitry Andric CapturedStmtInfo->getHelperName(), &CGM.getModule()); 31680b57cec5SDimitry Andric CGM.SetInternalFunctionAttributes(CD, F, FuncInfo); 31690b57cec5SDimitry Andric if (CD->isNothrow()) 31700b57cec5SDimitry Andric F->addFnAttr(llvm::Attribute::NoUnwind); 31710b57cec5SDimitry Andric 31720b57cec5SDimitry Andric // Generate the function. 31730b57cec5SDimitry Andric StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getLocation(), 31740b57cec5SDimitry Andric CD->getBody()->getBeginLoc()); 31750b57cec5SDimitry Andric // Set the context parameter in CapturedStmtInfo. 31760b57cec5SDimitry Andric Address DeclPtr = GetAddrOfLocalVar(CD->getContextParam()); 31770b57cec5SDimitry Andric CapturedStmtInfo->setContextValue(Builder.CreateLoad(DeclPtr)); 31780b57cec5SDimitry Andric 31790b57cec5SDimitry Andric // Initialize variable-length arrays. 31800fca6ea1SDimitry Andric LValue Base = MakeNaturalAlignRawAddrLValue( 31810fca6ea1SDimitry Andric CapturedStmtInfo->getContextValue(), Ctx.getTagDeclType(RD)); 31820b57cec5SDimitry Andric for (auto *FD : RD->fields()) { 31830b57cec5SDimitry Andric if (FD->hasCapturedVLAType()) { 31840b57cec5SDimitry Andric auto *ExprArg = 31850b57cec5SDimitry Andric EmitLoadOfLValue(EmitLValueForField(Base, FD), S.getBeginLoc()) 31860b57cec5SDimitry Andric .getScalarVal(); 31870b57cec5SDimitry Andric auto VAT = FD->getCapturedVLAType(); 31880b57cec5SDimitry Andric VLASizeMap[VAT->getSizeExpr()] = ExprArg; 31890b57cec5SDimitry Andric } 31900b57cec5SDimitry Andric } 31910b57cec5SDimitry Andric 31920b57cec5SDimitry Andric // If 'this' is captured, load it into CXXThisValue. 31930b57cec5SDimitry Andric if (CapturedStmtInfo->isCXXThisExprCaptured()) { 31940b57cec5SDimitry Andric FieldDecl *FD = CapturedStmtInfo->getThisFieldDecl(); 31950b57cec5SDimitry Andric LValue ThisLValue = EmitLValueForField(Base, FD); 31960b57cec5SDimitry Andric CXXThisValue = EmitLoadOfLValue(ThisLValue, Loc).getScalarVal(); 31970b57cec5SDimitry Andric } 31980b57cec5SDimitry Andric 31990b57cec5SDimitry Andric PGO.assignRegionCounters(GlobalDecl(CD), F); 32000b57cec5SDimitry Andric CapturedStmtInfo->EmitBody(*this, CD->getBody()); 32010b57cec5SDimitry Andric FinishFunction(CD->getBodyRBrace()); 32020b57cec5SDimitry Andric 32030b57cec5SDimitry Andric return F; 32040b57cec5SDimitry Andric } 32050fca6ea1SDimitry Andric 32060fca6ea1SDimitry Andric namespace { 32070fca6ea1SDimitry Andric // Returns the first convergence entry/loop/anchor instruction found in |BB|. 32080fca6ea1SDimitry Andric // std::nullptr otherwise. 32090fca6ea1SDimitry Andric llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { 32100fca6ea1SDimitry Andric for (auto &I : *BB) { 32110fca6ea1SDimitry Andric auto *II = dyn_cast<llvm::IntrinsicInst>(&I); 32120fca6ea1SDimitry Andric if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) 32130fca6ea1SDimitry Andric return II; 32140fca6ea1SDimitry Andric } 32150fca6ea1SDimitry Andric return nullptr; 32160fca6ea1SDimitry Andric } 32170fca6ea1SDimitry Andric 32180fca6ea1SDimitry Andric } // namespace 32190fca6ea1SDimitry Andric 32200fca6ea1SDimitry Andric llvm::CallBase * 32210fca6ea1SDimitry Andric CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input, 32220fca6ea1SDimitry Andric llvm::Value *ParentToken) { 32230fca6ea1SDimitry Andric llvm::Value *bundleArgs[] = {ParentToken}; 32240fca6ea1SDimitry Andric llvm::OperandBundleDef OB("convergencectrl", bundleArgs); 32250fca6ea1SDimitry Andric auto Output = llvm::CallBase::addOperandBundle( 32260fca6ea1SDimitry Andric Input, llvm::LLVMContext::OB_convergencectrl, OB, Input); 32270fca6ea1SDimitry Andric Input->replaceAllUsesWith(Output); 32280fca6ea1SDimitry Andric Input->eraseFromParent(); 32290fca6ea1SDimitry Andric return Output; 32300fca6ea1SDimitry Andric } 32310fca6ea1SDimitry Andric 32320fca6ea1SDimitry Andric llvm::IntrinsicInst * 32330fca6ea1SDimitry Andric CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB, 32340fca6ea1SDimitry Andric llvm::Value *ParentToken) { 32350fca6ea1SDimitry Andric CGBuilderTy::InsertPoint IP = Builder.saveIP(); 32360fca6ea1SDimitry Andric if (BB->empty()) 32370fca6ea1SDimitry Andric Builder.SetInsertPoint(BB); 32380fca6ea1SDimitry Andric else 32390fca6ea1SDimitry Andric Builder.SetInsertPoint(BB->getFirstInsertionPt()); 32400fca6ea1SDimitry Andric 32410fca6ea1SDimitry Andric llvm::CallBase *CB = Builder.CreateIntrinsic( 32420fca6ea1SDimitry Andric llvm::Intrinsic::experimental_convergence_loop, {}, {}); 32430fca6ea1SDimitry Andric Builder.restoreIP(IP); 32440fca6ea1SDimitry Andric 32450fca6ea1SDimitry Andric llvm::CallBase *I = addConvergenceControlToken(CB, ParentToken); 32460fca6ea1SDimitry Andric return cast<llvm::IntrinsicInst>(I); 32470fca6ea1SDimitry Andric } 32480fca6ea1SDimitry Andric 32490fca6ea1SDimitry Andric llvm::IntrinsicInst * 32500fca6ea1SDimitry Andric CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { 32510fca6ea1SDimitry Andric llvm::BasicBlock *BB = &F->getEntryBlock(); 32520fca6ea1SDimitry Andric llvm::IntrinsicInst *Token = getConvergenceToken(BB); 32530fca6ea1SDimitry Andric if (Token) 32540fca6ea1SDimitry Andric return Token; 32550fca6ea1SDimitry Andric 32560fca6ea1SDimitry Andric // Adding a convergence token requires the function to be marked as 32570fca6ea1SDimitry Andric // convergent. 32580fca6ea1SDimitry Andric F->setConvergent(); 32590fca6ea1SDimitry Andric 32600fca6ea1SDimitry Andric CGBuilderTy::InsertPoint IP = Builder.saveIP(); 32610fca6ea1SDimitry Andric Builder.SetInsertPoint(&BB->front()); 32620fca6ea1SDimitry Andric llvm::CallBase *I = Builder.CreateIntrinsic( 32630fca6ea1SDimitry Andric llvm::Intrinsic::experimental_convergence_entry, {}, {}); 32640fca6ea1SDimitry Andric assert(isa<llvm::IntrinsicInst>(I)); 32650fca6ea1SDimitry Andric Builder.restoreIP(IP); 32660fca6ea1SDimitry Andric 32670fca6ea1SDimitry Andric return cast<llvm::IntrinsicInst>(I); 32680fca6ea1SDimitry Andric } 3269