28#include "llvm/ADT/ArrayRef.h" 
   29#include "llvm/ADT/DenseMap.h" 
   30#include "llvm/ADT/SmallSet.h" 
   31#include "llvm/ADT/StringExtras.h" 
   32#include "llvm/IR/Assumptions.h" 
   33#include "llvm/IR/DataLayout.h" 
   34#include "llvm/IR/InlineAsm.h" 
   35#include "llvm/IR/Intrinsics.h" 
   36#include "llvm/IR/MDBuilder.h" 
   37#include "llvm/Support/SaveAndRestore.h" 
   62  assert(S && 
"Null statement?");
 
   63  PGO->setCurrentStmt(S);
 
   80      PGO->markStmtMaybeUsed(S);
 
   94    if (
const auto *D = dyn_cast<OMPExecutableDirective>(S)) {
 
  102  case Stmt::CXXCatchStmtClass:
 
  103  case Stmt::SEHExceptStmtClass:
 
  104  case Stmt::SEHFinallyStmtClass:
 
  105  case Stmt::MSDependentExistsStmtClass:
 
  106    llvm_unreachable(
"invalid statement class to emit generically");
 
  107  case Stmt::NullStmtClass:
 
  108  case Stmt::CompoundStmtClass:
 
  109  case Stmt::DeclStmtClass:
 
  110  case Stmt::LabelStmtClass:
 
  111  case Stmt::AttributedStmtClass:
 
  112  case Stmt::GotoStmtClass:
 
  113  case Stmt::BreakStmtClass:
 
  114  case Stmt::ContinueStmtClass:
 
  115  case Stmt::DefaultStmtClass:
 
  116  case Stmt::CaseStmtClass:
 
  117  case Stmt::SEHLeaveStmtClass:
 
  118  case Stmt::SYCLKernelCallStmtClass:
 
  119    llvm_unreachable(
"should have emitted these statements as simple");
 
  121#define STMT(Type, Base) 
  122#define ABSTRACT_STMT(Op) 
  123#define EXPR(Type, Base) \ 
  124  case Stmt::Type##Class: 
  125#include "clang/AST/StmtNodes.inc" 
  128    llvm::BasicBlock *incoming = 
Builder.GetInsertBlock();
 
  129    assert(incoming && 
"expression emission must have an insertion point");
 
  133    llvm::BasicBlock *outgoing = 
Builder.GetInsertBlock();
 
  134    assert(outgoing && 
"expression emission cleared block!");
 
  148    if (incoming != outgoing && outgoing->use_empty()) {
 
  149      outgoing->eraseFromParent();
 
  155  case Stmt::IndirectGotoStmtClass:
 
  166  case Stmt::GCCAsmStmtClass:  
 
  168  case Stmt::CoroutineBodyStmtClass:
 
  171  case Stmt::CoreturnStmtClass:
 
  174  case Stmt::CapturedStmtClass: {
 
  179  case Stmt::ObjCAtTryStmtClass:
 
  182  case Stmt::ObjCAtCatchStmtClass:
 
  184                    "@catch statements should be handled by EmitObjCAtTryStmt");
 
  185  case Stmt::ObjCAtFinallyStmtClass:
 
  187                  "@finally statements should be handled by EmitObjCAtTryStmt");
 
  188  case Stmt::ObjCAtThrowStmtClass:
 
  191  case Stmt::ObjCAtSynchronizedStmtClass:
 
  194  case Stmt::ObjCForCollectionStmtClass:
 
  197  case Stmt::ObjCAutoreleasePoolStmtClass:
 
  201  case Stmt::CXXTryStmtClass:
 
  204  case Stmt::CXXForRangeStmtClass:
 
  207  case Stmt::SEHTryStmtClass:
 
  210  case Stmt::OMPMetaDirectiveClass:
 
  213  case Stmt::OMPCanonicalLoopClass:
 
  216  case Stmt::OMPParallelDirectiveClass:
 
  219  case Stmt::OMPSimdDirectiveClass:
 
  222  case Stmt::OMPTileDirectiveClass:
 
  225  case Stmt::OMPStripeDirectiveClass:
 
  228  case Stmt::OMPUnrollDirectiveClass:
 
  231  case Stmt::OMPReverseDirectiveClass:
 
  234  case Stmt::OMPInterchangeDirectiveClass:
 
  237  case Stmt::OMPFuseDirectiveClass:
 
  240  case Stmt::OMPForDirectiveClass:
 
  243  case Stmt::OMPForSimdDirectiveClass:
 
  246  case Stmt::OMPSectionsDirectiveClass:
 
  249  case Stmt::OMPSectionDirectiveClass:
 
  252  case Stmt::OMPSingleDirectiveClass:
 
  255  case Stmt::OMPMasterDirectiveClass:
 
  258  case Stmt::OMPCriticalDirectiveClass:
 
  261  case Stmt::OMPParallelForDirectiveClass:
 
  264  case Stmt::OMPParallelForSimdDirectiveClass:
 
  267  case Stmt::OMPParallelMasterDirectiveClass:
 
  270  case Stmt::OMPParallelSectionsDirectiveClass:
 
  273  case Stmt::OMPTaskDirectiveClass:
 
  276  case Stmt::OMPTaskyieldDirectiveClass:
 
  279  case Stmt::OMPErrorDirectiveClass:
 
  282  case Stmt::OMPBarrierDirectiveClass:
 
  285  case Stmt::OMPTaskwaitDirectiveClass:
 
  288  case Stmt::OMPTaskgroupDirectiveClass:
 
  291  case Stmt::OMPFlushDirectiveClass:
 
  294  case Stmt::OMPDepobjDirectiveClass:
 
  297  case Stmt::OMPScanDirectiveClass:
 
  300  case Stmt::OMPOrderedDirectiveClass:
 
  303  case Stmt::OMPAtomicDirectiveClass:
 
  306  case Stmt::OMPTargetDirectiveClass:
 
  309  case Stmt::OMPTeamsDirectiveClass:
 
  312  case Stmt::OMPCancellationPointDirectiveClass:
 
  315  case Stmt::OMPCancelDirectiveClass:
 
  318  case Stmt::OMPTargetDataDirectiveClass:
 
  321  case Stmt::OMPTargetEnterDataDirectiveClass:
 
  324  case Stmt::OMPTargetExitDataDirectiveClass:
 
  327  case Stmt::OMPTargetParallelDirectiveClass:
 
  330  case Stmt::OMPTargetParallelForDirectiveClass:
 
  333  case Stmt::OMPTaskLoopDirectiveClass:
 
  336  case Stmt::OMPTaskLoopSimdDirectiveClass:
 
  339  case Stmt::OMPMasterTaskLoopDirectiveClass:
 
  342  case Stmt::OMPMaskedTaskLoopDirectiveClass:
 
  345  case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
 
  349  case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
 
  353  case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
 
  357  case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
 
  361  case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
 
  365  case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
 
  369  case Stmt::OMPDistributeDirectiveClass:
 
  372  case Stmt::OMPTargetUpdateDirectiveClass:
 
  375  case Stmt::OMPDistributeParallelForDirectiveClass:
 
  379  case Stmt::OMPDistributeParallelForSimdDirectiveClass:
 
  383  case Stmt::OMPDistributeSimdDirectiveClass:
 
  386  case Stmt::OMPTargetParallelForSimdDirectiveClass:
 
  390  case Stmt::OMPTargetSimdDirectiveClass:
 
  393  case Stmt::OMPTeamsDistributeDirectiveClass:
 
  396  case Stmt::OMPTeamsDistributeSimdDirectiveClass:
 
  400  case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
 
  404  case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
 
  408  case Stmt::OMPTargetTeamsDirectiveClass:
 
  411  case Stmt::OMPTargetTeamsDistributeDirectiveClass:
 
  415  case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
 
  419  case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
 
  423  case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
 
  427  case Stmt::OMPInteropDirectiveClass:
 
  430  case Stmt::OMPDispatchDirectiveClass:
 
  431    CGM.ErrorUnsupported(S, 
"OpenMP dispatch directive");
 
  433  case Stmt::OMPScopeDirectiveClass:
 
  436  case Stmt::OMPMaskedDirectiveClass:
 
  439  case Stmt::OMPGenericLoopDirectiveClass:
 
  442  case Stmt::OMPTeamsGenericLoopDirectiveClass:
 
  445  case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
 
  449  case Stmt::OMPParallelGenericLoopDirectiveClass:
 
  453  case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
 
  457  case Stmt::OMPParallelMaskedDirectiveClass:
 
  460  case Stmt::OMPAssumeDirectiveClass:
 
  463  case Stmt::OpenACCComputeConstructClass:
 
  466  case Stmt::OpenACCLoopConstructClass:
 
  469  case Stmt::OpenACCCombinedConstructClass:
 
  472  case Stmt::OpenACCDataConstructClass:
 
  475  case Stmt::OpenACCEnterDataConstructClass:
 
  478  case Stmt::OpenACCExitDataConstructClass:
 
  481  case Stmt::OpenACCHostDataConstructClass:
 
  484  case Stmt::OpenACCWaitConstructClass:
 
  487  case Stmt::OpenACCInitConstructClass:
 
  490  case Stmt::OpenACCShutdownConstructClass:
 
  493  case Stmt::OpenACCSetConstructClass:
 
  496  case Stmt::OpenACCUpdateConstructClass:
 
  499  case Stmt::OpenACCAtomicConstructClass:
 
  502  case Stmt::OpenACCCacheConstructClass:
 
 
  513  case Stmt::NullStmtClass:
 
  515  case Stmt::CompoundStmtClass:
 
  518  case Stmt::DeclStmtClass:
 
  521  case Stmt::LabelStmtClass:
 
  524  case Stmt::AttributedStmtClass:
 
  527  case Stmt::GotoStmtClass:
 
  530  case Stmt::BreakStmtClass:
 
  533  case Stmt::ContinueStmtClass:
 
  536  case Stmt::DefaultStmtClass:
 
  539  case Stmt::CaseStmtClass:
 
  542  case Stmt::SEHLeaveStmtClass:
 
  545  case Stmt::SYCLKernelCallStmtClass:
 
 
  572                             "LLVM IR generation of compound statement ('{}')");
 
 
  586  assert((!GetLast || (GetLast && 
ExprResult)) &&
 
  587         "If GetLast is true then the CompoundStmt must have a StmtExprResult");
 
  591  for (
auto *CurStmt : S.
body()) {
 
  599        if (
const auto *LS = dyn_cast<LabelStmt>(
ExprResult)) {
 
  602        } 
else if (
const auto *AS = dyn_cast<AttributedStmt>(
ExprResult)) {
 
  607          llvm_unreachable(
"unknown value statement");
 
 
  634  llvm::BranchInst *BI = dyn_cast<llvm::BranchInst>(BB->getTerminator());
 
  643  if (!BI || !BI->isUnconditional())
 
  647  if (BI->getIterator() != BB->begin())
 
  650  BB->replaceAllUsesWith(BI->getSuccessor(0));
 
  651  BI->eraseFromParent();
 
  652  BB->eraseFromParent();
 
 
  656  llvm::BasicBlock *CurBB = 
Builder.GetInsertBlock();
 
  661  if (IsFinished && BB->use_empty()) {
 
  668  if (CurBB && CurBB->getParent())
 
  669    CurFn->insert(std::next(CurBB->getIterator()), BB);
 
 
  679  llvm::BasicBlock *CurBB = 
Builder.GetInsertBlock();
 
  681  if (!CurBB || CurBB->getTerminator()) {
 
 
  693  bool inserted = 
false;
 
  694  for (llvm::User *u : block->users()) {
 
  695    if (llvm::Instruction *insn = dyn_cast<llvm::Instruction>(u)) {
 
  696      CurFn->insert(std::next(insn->getParent()->getIterator()), block);
 
 
  711  if (Dest.
isValid()) 
return Dest;
 
 
  724  if (
EHStack.hasNormalCleanups() && CurLexicalScope)
 
  725    CurLexicalScope->addLabel(D);
 
  746    if (
CGM.getCodeGenOpts().hasReducedDebugInfo()) {
 
 
  758  assert(!Labels.empty());
 
  760    = 
CGF.EHStack.getInnermostNormalCleanup();
 
  764    assert(
CGF.LabelMap.count(Label));
 
  773    ParentScope->Labels.append(Labels.begin(), Labels.end());
 
 
  789  bool nomerge = 
false;
 
  790  bool noinline = 
false;
 
  791  bool alwaysinline = 
false;
 
  792  bool noconvergent = 
false;
 
  793  HLSLControlFlowHintAttr::Spelling flattenOrBranch =
 
  794      HLSLControlFlowHintAttr::SpellingNotCalculated;
 
  796  const AtomicAttr *AA = 
nullptr;
 
  798  for (
const auto *A : S.
getAttrs()) {
 
  799    switch (A->getKind()) {
 
  808    case attr::AlwaysInline:
 
  811    case attr::NoConvergent:
 
  814    case attr::MustTail: {
 
  819    case attr::CXXAssume: {
 
  824        Builder.CreateAssumption(AssumptionVal);
 
  830    case attr::HLSLControlFlowHint: {
 
 
  867  llvm::BasicBlock *CurBB = 
Builder.GetInsertBlock();
 
  877  if (CurBB && CurBB->getTerminator())
 
 
  913    const Stmt *Skipped = Else;
 
  915      std::swap(Executed, Skipped);
 
  927      PGO->markStmtMaybeUsed(Skipped);
 
  936  llvm::BasicBlock *ElseBlock = ContBlock;
 
  954      CGM.getCodeGenOpts().OptimizationLevel)
 
  963  if (!
CGM.getCodeGenOpts().MCDCCoverage) {
 
  970    Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);
 
 
 1016                                              bool HasEmptyBody) {
 
 1017  if (
CGM.getCodeGenOpts().getFiniteLoops() ==
 
 1027  bool CondIsConstInt =
 
 1028      !ControllingExpression ||
 
 1032  bool CondIsTrue = CondIsConstInt && (!ControllingExpression ||
 
 1033                                       Result.Val.getInt().getBoolValue());
 
 1044  if (
CGM.getCodeGenOpts().getFiniteLoops() ==
 
 1047    if (HasEmptyBody && CondIsTrue) {
 
 1048      CurFn->removeFnAttr(llvm::Attribute::MustProgress);
 
 
 1066  if constexpr (std::is_same_v<LoopStmt, ForStmt>) {
 
 1070  const Stmt *Body = S.getBody();
 
 1073  if (
const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body))
 
 1074    return Compound->body_empty();
 
 
 1085  if (
CGM.shouldEmitConvergenceTokens())
 
 1087        emitConvergenceLoopToken(LoopHeader.
getBlock()));
 
 1094  BreakContinueStack.push_back(BreakContinue(S, 
LoopExit, LoopHeader));
 
 1117  llvm::ConstantInt *
C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
 
 1118  bool EmitBoolCondBranch = !
C || !
C->isOne();
 
 1131  if (EmitBoolCondBranch) {
 
 1132    llvm::BasicBlock *ExitBlock = 
LoopExit.getBlock();
 
 1135    llvm::MDNode *Weights =
 
 1137    if (!Weights && 
CGM.getCodeGenOpts().OptimizationLevel)
 
 1138      BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
 
 1140    auto *I = 
Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, Weights);
 
 1146    if (
auto *CondI = dyn_cast<llvm::Instruction>(BoolCondVal))
 
 1150    if (ExitBlock != 
LoopExit.getBlock()) {
 
 1155    CGM.getDiags().Report(A->getLocation(),
 
 1156                          diag::warn_attribute_has_no_effect_on_infinite_loop)
 
 1157        << A << A->getRange();
 
 1158    CGM.getDiags().Report(
 
 1160        diag::note_attribute_has_no_effect_on_infinite_loop_here)
 
 1177  BreakContinueStack.pop_back();
 
 1193  if (!EmitBoolCondBranch)
 
 1201  if (
CGM.shouldEmitConvergenceTokens())
 
 
 1213  BreakContinueStack.push_back(BreakContinue(S, 
LoopExit, LoopCond));
 
 1223  if (
CGM.shouldEmitConvergenceTokens())
 
 1244  BreakContinueStack.pop_back();
 
 1248  llvm::ConstantInt *
C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
 
 1249  bool EmitBoolCondBranch = !
C || !
C->isZero();
 
 1252  LoopStack.push(LoopBody, 
CGM.getContext(), 
CGM.getCodeGenOpts(), DoAttrs,
 
 1258  if (EmitBoolCondBranch) {
 
 1260    auto *I = 
Builder.CreateCondBr(
 
 1261        BoolCondVal, LoopBody, 
LoopExit.getBlock(),
 
 1262        createProfileWeightsForLoop(S.
getCond(), BackedgeCount));
 
 1269    if (
auto *CondI = dyn_cast<llvm::Instruction>(BoolCondVal))
 
 1281  if (!EmitBoolCondBranch)
 
 1289  if (
CGM.shouldEmitConvergenceTokens())
 
 
 1297  std::optional<LexicalScope> ForScope;
 
 1309  llvm::BasicBlock *CondBlock = CondDest.
getBlock();
 
 1312  if (
CGM.shouldEmitConvergenceTokens())
 
 1316  LoopStack.push(CondBlock, 
CGM.getContext(), 
CGM.getCodeGenOpts(), ForAttrs,
 
 1333    Continue = CondDest;
 
 1336  BreakContinueStack.push_back(BreakContinue(S, 
LoopExit, Continue));
 
 1347      BreakContinueStack.back().ContinueBlock = Continue;
 
 1355    llvm::BasicBlock *ExitBlock = 
LoopExit.getBlock();
 
 1358    if (ForScope && ForScope->requiresCleanups())
 
 1370    llvm::MDNode *Weights =
 
 1372    if (!Weights && 
CGM.getCodeGenOpts().OptimizationLevel)
 
 1373      BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
 
 1376    auto *I = 
Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
 
 1381    if (
auto *CondI = dyn_cast<llvm::Instruction>(BoolCondVal))
 
 1385    if (ExitBlock != 
LoopExit.getBlock()) {
 
 1410  auto *FinalBodyBB = 
Builder.GetInsertBlock();
 
 1420  BreakContinueStack.pop_back();
 
 1428    ForScope->ForceCleanup();
 
 1440  if (
CGM.shouldEmitConvergenceTokens())
 
 
 1470  if (
CGM.shouldEmitConvergenceTokens())
 
 1474  LoopStack.push(CondBlock, 
CGM.getContext(), 
CGM.getCodeGenOpts(), ForAttrs,
 
 1480  llvm::BasicBlock *ExitBlock = 
LoopExit.getBlock();
 
 1490  llvm::MDNode *Weights =
 
 1492  if (!Weights && 
CGM.getCodeGenOpts().OptimizationLevel)
 
 1493    BoolCondVal = emitCondLikelihoodViaExpectIntrinsic(
 
 1495  auto *I = 
Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
 
 1500  if (
auto *CondI = dyn_cast<llvm::Instruction>(BoolCondVal))
 
 1504  if (ExitBlock != 
LoopExit.getBlock()) {
 
 1519  BreakContinueStack.push_back(BreakContinue(S, 
LoopExit, Continue));
 
 1529  auto *FinalBodyBB = 
Builder.GetInsertBlock();
 
 1536  BreakContinueStack.pop_back();
 
 1552  if (
CGM.shouldEmitConvergenceTokens())
 
 
 1562void CodeGenFunction::EmitReturnOfRValue(
RValue RV, 
QualType Ty) {
 
 1578struct SaveRetExprRAII {
 
 1579  SaveRetExprRAII(
const Expr *RetExpr, CodeGenFunction &CGF)
 
 1580      : OldRetExpr(CGF.RetExpr), CGF(CGF) {
 
 1583  ~SaveRetExprRAII() { CGF.RetExpr = OldRetExpr; }
 
 1584  const Expr *OldRetExpr;
 
 1585  CodeGenFunction &CGF;
 
 1593  if (calleeQualType->isFunctionPointerType() ||
 
 1594      calleeQualType->isFunctionReferenceType() ||
 
 1595      calleeQualType->isBlockPointerType() ||
 
 1596      calleeQualType->isMemberFunctionPointerType()) {
 
 1598  } 
else if (
auto *ty = dyn_cast<FunctionType>(calleeQualType)) {
 
 1600  } 
else if (
auto CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
 
 1601    if (
auto methodDecl = CMCE->getMethodDecl()) {
 
 
 1618  if (requiresReturnValueCheck()) {
 
 1621        new llvm::GlobalVariable(
CGM.getModule(), SLoc->getType(), 
false,
 
 1622                                 llvm::GlobalVariable::PrivateLinkage, SLoc);
 
 1623    SLocPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
 1624    CGM.getSanitizerMetadata()->disableSanitizerForGlobal(SLocPtr);
 
 1625    assert(ReturnLocation.isValid() && 
"No valid return location");
 
 1626    Builder.CreateStore(SLocPtr, ReturnLocation);
 
 1632    Builder.ClearInsertionPoint();
 
 1646  SaveRetExprRAII SaveRetExpr(RV, *
this);
 
 1649  if (
const auto *EWC = dyn_cast_or_null<ExprWithCleanups>(RV))
 
 1650    RV = EWC->getSubExpr();
 
 1654  std::optional<llvm::SaveAndRestore<const CallExpr *>> SaveMustTail;
 
 1657    if (
auto CE = dyn_cast<CallExpr>(RV)) {
 
 1670       !
CGM.getOpenMPRuntime()
 
 1689  } 
else if (
FnRetTy->isReferenceType()) {
 
 1725    ++NumSimpleReturnExprs;
 
 
 1737  for (
const auto *I : S.
decls())
 
 
 1742    -> 
const BreakContinue * {
 
 1743  if (!S.hasLabelTarget())
 
 1744    return &BreakContinueStack.back();
 
 1746  const Stmt *LoopOrSwitch = S.getNamedLoopOrSwitch();
 
 1747  assert(LoopOrSwitch && 
"break/continue target not set?");
 
 1748  for (
const BreakContinue &BC : llvm::reverse(BreakContinueStack))
 
 1749    if (BC.LoopOrSwitch == LoopOrSwitch)
 
 1752  llvm_unreachable(
"break/continue target not found");
 
 
 1756  assert(!BreakContinueStack.empty() && 
"break stmt not in a loop or switch!");
 
 
 1769  assert(!BreakContinueStack.empty() && 
"continue stmt not in a loop!");
 
 
 1786  assert(S.
getRHS() && 
"Expected RHS value in CaseStmt");
 
 1799  if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS))
 
 1803  llvm::APInt Range = RHS - LHS;
 
 1805  if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {
 
 1808    unsigned NCases = Range.getZExtValue() + 1;
 
 1813    uint64_t Weight = Total / NCases, Rem = Total % NCases;
 
 1814    for (
unsigned I = 0; I != NCases; ++I) {
 
 1816        SwitchWeights->push_back(Weight + (Rem ? 1 : 0));
 
 1817      else if (SwitchLikelihood)
 
 1818        SwitchLikelihood->push_back(LH);
 
 1822      SwitchInsn->addCase(
Builder.getInt(LHS), CaseDest);
 
 1830  llvm::BasicBlock *RestoreBB = 
Builder.GetInsertBlock();
 
 1835  llvm::BasicBlock *FalseDest = CaseRangeBlock;
 
 1839  Builder.SetInsertPoint(CaseRangeBlock);
 
 1843    Builder.CreateSub(SwitchInsn->getCondition(), 
Builder.getInt(LHS));
 
 1847  llvm::MDNode *Weights = 
nullptr;
 
 1848  if (SwitchWeights) {
 
 1850    uint64_t DefaultCount = (*SwitchWeights)[0];
 
 1851    Weights = createProfileWeights(ThisCount, DefaultCount);
 
 1856    (*SwitchWeights)[0] += ThisCount;
 
 1857  } 
else if (SwitchLikelihood)
 
 1858    Cond = emitCondLikelihoodViaExpectIntrinsic(
Cond, LH);
 
 1860  Builder.CreateCondBr(
Cond, CaseDest, FalseDest, Weights);
 
 1864    Builder.SetInsertPoint(RestoreBB);
 
 1866    Builder.ClearInsertionPoint();
 
 
 1887  llvm::ConstantInt *CaseVal =
 
 1892  if (
auto ICE = dyn_cast<ImplicitCastExpr>(S.
getLHS()))
 
 1893    CE = dyn_cast<ConstantExpr>(ICE->getSubExpr());
 
 1895    CE = dyn_cast<ConstantExpr>(S.
getLHS());
 
 1897    if (
auto DE = dyn_cast<DeclRefExpr>(CE->
getSubExpr()))
 
 1899        if (
CGM.getCodeGenOpts().hasReducedDebugInfo())
 
 1900          Dbg->EmitGlobalVariable(DE->getDecl(),
 
 1901              APValue(llvm::APSInt(CaseVal->getValue())));
 
 1904  if (SwitchLikelihood)
 
 1910  if (!
CGM.getCodeGenOpts().hasProfileClangInstr() &&
 
 1911      CGM.getCodeGenOpts().OptimizationLevel > 0 &&
 
 1919      SwitchInsn->addCase(CaseVal, 
Block.getBlock());
 
 1923      if (
Builder.GetInsertBlock()) {
 
 1925        Builder.ClearInsertionPoint();
 
 1935  SwitchInsn->addCase(CaseVal, CaseDest);
 
 1954  while (NextCase && NextCase->
getRHS() == 
nullptr) {
 
 1956    llvm::ConstantInt *CaseVal =
 
 1961    if (
CGM.getCodeGenOpts().hasProfileClangInstr()) {
 
 1967    if (SwitchLikelihood)
 
 1970    SwitchInsn->addCase(CaseVal, CaseDest);
 
 1971    NextCase = dyn_cast<CaseStmt>(CurCase->
getSubStmt());
 
 
 1994  llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();
 
 1995  assert(DefaultBlock->empty() &&
 
 1996         "EmitDefaultStmt: Default block already defined?");
 
 1998  if (SwitchLikelihood)
 
 
 2040  if (
const SwitchCase *SC = dyn_cast<SwitchCase>(S)) {
 
 2059  if (
const CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) {
 
 2063    bool StartedInLiveCode = FoundCase;
 
 2064    unsigned StartSize = ResultStmts.size();
 
 2071      bool HadSkippedDecl = 
false;
 
 2075      for (; Case && I != E; ++I) {
 
 2091            for (++I; I != E; ++I)
 
 2101          assert(FoundCase && 
"Didn't find case but returned fallthrough?");
 
 2116      assert(!HadSkippedDecl && 
"fallthrough after skipping decl");
 
 2121    bool AnyDecls = 
false;
 
 2122    for (; I != E; ++I) {
 
 2135        for (++I; I != E; ++I)
 
 2152        ResultStmts.resize(StartSize);
 
 2153        ResultStmts.push_back(S);
 
 2177  ResultStmts.push_back(S);
 
 
 2186                                       const llvm::APSInt &ConstantCondValue,
 
 2198    if (
const DefaultStmt *DS = dyn_cast<DefaultStmt>(Case)) {
 
 2206    if (CS->
getRHS()) 
return false;
 
 2231  bool FoundCase = 
false;
 
 
 2238static std::optional<SmallVector<uint64_t, 16>>
 
 2241  if (Likelihoods.size() <= 1)
 
 2242    return std::nullopt;
 
 2244  uint64_t NumUnlikely = 0;
 
 2245  uint64_t NumNone = 0;
 
 2246  uint64_t NumLikely = 0;
 
 2247  for (
const auto LH : Likelihoods) {
 
 2262  if (NumUnlikely == 0 && NumLikely == 0)
 
 2263    return std::nullopt;
 
 2271  const uint64_t Likely = INT32_MAX / (NumLikely + 2);
 
 2272  const uint64_t 
None = Likely / (NumNone + 1);
 
 2273  const uint64_t Unlikely = 0;
 
 2276  Result.reserve(Likelihoods.size());
 
 2277  for (
const auto LH : Likelihoods) {
 
 2280      Result.push_back(Unlikely);
 
 2283      Result.push_back(
None);
 
 2286      Result.push_back(Likely);
 
 
 2296  llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
 
 2299  llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
 
 2303  llvm::APSInt ConstantCondValue;
 
 2324      SwitchInsn = 
nullptr;
 
 2331      PGO->markStmtMaybeUsed(S.
getBody());
 
 2335      SwitchInsn = SavedSwitchInsn;
 
 2358  SwitchInsn = 
Builder.CreateSwitch(CondV, DefaultBlock);
 
 2362    llvm::MDBuilder MDHelper(
CGM.getLLVMContext());
 
 2363    llvm::ConstantInt *BranchHintConstant =
 
 2365                HLSLControlFlowHintAttr::Spelling::Microsoft_branch
 
 2366            ? llvm::ConstantInt::get(
CGM.Int32Ty, 1)
 
 2367            : llvm::ConstantInt::get(
CGM.Int32Ty, 2);
 
 2368    llvm::Metadata *Vals[] = {MDHelper.createString(
"hlsl.controlflow.hint"),
 
 2369                              MDHelper.createConstant(BranchHintConstant)};
 
 2370    SwitchInsn->setMetadata(
"hlsl.controlflow.hint",
 
 2371                            llvm::MDNode::get(
CGM.getLLVMContext(), Vals));
 
 2374  if (PGO->haveRegionCounts()) {
 
 2376    uint64_t DefaultCount = 0;
 
 2377    unsigned NumCases = 0;
 
 2386    SwitchWeights->reserve(NumCases);
 
 2389    SwitchWeights->push_back(DefaultCount);
 
 2390  } 
else if (
CGM.getCodeGenOpts().OptimizationLevel) {
 
 2396  CaseRangeBlock = DefaultBlock;
 
 2399  Builder.ClearInsertionPoint();
 
 2404  if (!BreakContinueStack.empty())
 
 2405    OuterContinue = BreakContinueStack.back().ContinueBlock;
 
 2407  BreakContinueStack.push_back(BreakContinue(S, SwitchExit, OuterContinue));
 
 2412  BreakContinueStack.pop_back();
 
 2416  SwitchInsn->setDefaultDest(CaseRangeBlock);
 
 2419  if (!DefaultBlock->getParent()) {
 
 2427      DefaultBlock->replaceAllUsesWith(SwitchExit.
getBlock());
 
 2428      delete DefaultBlock;
 
 2442  if (
Call && 
CGM.getCodeGenOpts().OptimizationLevel != 0) {
 
 2443    auto *FD = dyn_cast_or_null<FunctionDecl>(
Call->getCalleeDecl());
 
 2444    if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
 
 2446      SwitchInsn->setMetadata(llvm::LLVMContext::MD_unpredictable,
 
 2447                              MDHelper.createUnpredictable());
 
 2451  if (SwitchWeights) {
 
 2452    assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() &&
 
 2453           "switch weights do not match switch cases");
 
 2455    if (SwitchWeights->size() > 1)
 
 2456      SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
 
 2457                              createProfileWeights(*SwitchWeights));
 
 2458    delete SwitchWeights;
 
 2459  } 
else if (SwitchLikelihood) {
 
 2460    assert(SwitchLikelihood->size() == 1 + SwitchInsn->getNumCases() &&
 
 2461           "switch likelihoods do not match switch cases");
 
 2462    std::optional<SmallVector<uint64_t, 16>> LHW =
 
 2465      llvm::MDBuilder MDHelper(
CGM.getLLVMContext());
 
 2466      SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
 
 2467                              createProfileWeights(*LHW));
 
 2469    delete SwitchLikelihood;
 
 2471  SwitchInsn = SavedSwitchInsn;
 
 2472  SwitchWeights = SavedSwitchWeights;
 
 2473  SwitchLikelihood = SavedSwitchLikelihood;
 
 2474  CaseRangeBlock = SavedCRBlock;
 
 
 2484                       std::string *GCCReg = 
nullptr) {
 
 2485  const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(&AsmExpr);
 
 2494  AsmLabelAttr *
Attr = Variable->getAttr<AsmLabelAttr>();
 
 2497  StringRef Register = 
Attr->getLabel();
 
 2498  assert(
Target.isValidGCCRegisterName(Register));
 
 2502  if (
Target.validateOutputConstraint(Info) &&
 
 2508  Register = 
Target.getNormalizedGCCRegisterName(Register);
 
 2509  if (GCCReg != 
nullptr)
 
 2510    *GCCReg = Register.str();
 
 2511  return (EarlyClobber ? 
"&{" : 
"{") + Register.str() + 
"}";
 
 
 2514std::pair<llvm::Value*, llvm::Type *> CodeGenFunction::EmitAsmInputLValue(
 
 2515    const TargetInfo::ConstraintInfo &Info, LValue InputValue,
 
 2516    QualType InputType, std::string &ConstraintStr, SourceLocation Loc) {
 
 2523    if ((Size <= 64 && llvm::isPowerOf2_64(Size)) ||
 
 2527      return {
Builder.CreateLoad(InputValue.getAddress().withElementType(Ty)),
 
 2532  Address 
Addr = InputValue.getAddress();
 
 2533  ConstraintStr += 
'*';
 
 2534  return {InputValue.getPointer(*
this), 
Addr.getElementType()};
 
 2537std::pair<llvm::Value *, llvm::Type *>
 
 2538CodeGenFunction::EmitAsmInput(
const TargetInfo::ConstraintInfo &Info,
 
 2539                              const Expr *InputExpr,
 
 2540                              std::string &ConstraintStr) {
 
 2545      Expr::EvalResult EVResult;
 
 2548      llvm::APSInt IntResult;
 
 2551        return {llvm::ConstantInt::get(
getLLVMContext(), IntResult), 
nullptr};
 
 2563  if (InputExpr->
getStmtClass() == Expr::CXXThisExprClass)
 
 2567  return EmitAsmInputLValue(Info, Dest, InputExpr->
getType(), ConstraintStr,
 
 2579  Locs.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
 
 2582  if (!StrVal.empty()) {
 
 2585    unsigned StartToken = 0;
 
 2586    unsigned ByteOffset = 0;
 
 2590    for (
unsigned i = 0, e = StrVal.size() - 1; i != e; ++i) {
 
 2591      if (StrVal[i] != 
'\n') 
continue;
 
 2593          i + 1, 
SM, LangOpts, CGF.
getTarget(), &StartToken, &ByteOffset);
 
 2594      Locs.push_back(llvm::ConstantAsMetadata::get(
 
 
 2603                              bool HasUnwindClobber, 
bool ReadOnly,
 
 2604                              bool ReadNone, 
bool NoMerge, 
bool NoConvergent,
 
 2606                              const std::vector<llvm::Type *> &ResultRegTypes,
 
 2607                              const std::vector<llvm::Type *> &ArgElemTypes,
 
 2609                              std::vector<llvm::Value *> &RegResults) {
 
 2610  if (!HasUnwindClobber)
 
 2611    Result.addFnAttr(llvm::Attribute::NoUnwind);
 
 2614    Result.addFnAttr(llvm::Attribute::NoMerge);
 
 2616  if (!HasSideEffect) {
 
 2618      Result.setDoesNotAccessMemory();
 
 2620      Result.setOnlyReadsMemory();
 
 2624  for (
auto Pair : llvm::enumerate(ArgElemTypes)) {
 
 2626      auto Attr = llvm::Attribute::get(
 
 2627          CGF.
getLLVMContext(), llvm::Attribute::ElementType, Pair.value());
 
 2628      Result.addParamAttr(Pair.index(), 
Attr);
 
 2635  if (
const auto *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S);
 
 2637      (SL = dyn_cast<StringLiteral>(gccAsmStmt->getAsmStringExpr()))) {
 
 2642    llvm::Constant *Loc =
 
 2644    Result.setMetadata(
"srcloc",
 
 2646                                         llvm::ConstantAsMetadata::get(Loc)));
 
 2657    Result.addFnAttr(llvm::Attribute::Convergent);
 
 2659  if (ResultRegTypes.size() == 1) {
 
 2660    RegResults.push_back(&Result);
 
 2662    for (
unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) {
 
 2663      llvm::Value *Tmp = CGF.
Builder.CreateExtractValue(&Result, i, 
"asmresult");
 
 2664      RegResults.push_back(Tmp);
 
 
 2676              const llvm::BitVector &ResultTypeRequiresCast,
 
 2677              const std::vector<std::optional<std::pair<unsigned, unsigned>>>
 
 2683  assert(RegResults.size() == ResultRegTypes.size());
 
 2684  assert(RegResults.size() == ResultTruncRegTypes.size());
 
 2685  assert(RegResults.size() == ResultRegDests.size());
 
 2688  assert(ResultTypeRequiresCast.size() <= ResultRegDests.size());
 
 2689  assert(ResultBounds.size() <= ResultRegDests.size());
 
 2691  for (
unsigned i = 0, e = RegResults.size(); i != e; ++i) {
 
 2692    llvm::Value *Tmp = RegResults[i];
 
 2693    llvm::Type *TruncTy = ResultTruncRegTypes[i];
 
 2695    if ((i < ResultBounds.size()) && ResultBounds[i].has_value()) {
 
 2696      const auto [LowerBound, UpperBound] = ResultBounds[i].value();
 
 2698      assert(LowerBound == 0 && 
"Output operand lower bound is not zero.");
 
 2699      llvm::Constant *UpperBoundConst =
 
 2700          llvm::ConstantInt::get(Tmp->getType(), UpperBound);
 
 2701      llvm::Value *IsBooleanValue =
 
 2702          Builder.CreateCmp(llvm::CmpInst::ICMP_ULT, Tmp, UpperBoundConst);
 
 2704      Builder.CreateCall(FnAssume, IsBooleanValue);
 
 2709    if (ResultRegTypes[i] != TruncTy) {
 
 2713      if (TruncTy->isFloatingPointTy())
 
 2714        Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
 
 2715      else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
 
 2717        Tmp = Builder.CreateTrunc(
 
 2718            Tmp, llvm::IntegerType::get(CTX, (
unsigned)ResSize));
 
 2719        Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
 
 2720      } 
else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
 
 2723        Tmp = Builder.CreatePtrToInt(
 
 2724            Tmp, llvm::IntegerType::get(CTX, (
unsigned)TmpSize));
 
 2725        Tmp = Builder.CreateTrunc(Tmp, TruncTy);
 
 2726      } 
else if (Tmp->getType()->isIntegerTy() && TruncTy->isIntegerTy()) {
 
 2727        Tmp = Builder.CreateZExtOrTrunc(Tmp, TruncTy);
 
 2728      } 
else if (Tmp->getType()->isVectorTy() || TruncTy->isVectorTy()) {
 
 2729        Tmp = Builder.CreateBitCast(Tmp, TruncTy);
 
 2734    LValue Dest = ResultRegDests[i];
 
 2737    if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) {
 
 2739      Address A = Dest.getAddress().withElementType(ResultRegTypes[i]);
 
 2741        llvm::StoreInst *S = Builder.CreateStore(Tmp, A);
 
 2751                              diag::err_store_value_to_reg);
 
 
 2762  constexpr auto Name = 
"__ASM__hipstdpar_unsupported";
 
 2765  if (
auto GCCAsm = dyn_cast<GCCAsmStmt>(&S))
 
 2766    Asm = GCCAsm->getAsmString();
 
 2770  auto StrTy = llvm::ConstantDataArray::getString(Ctx, 
Asm);
 
 2771  auto FnTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx),
 
 2772                                      {StrTy->getType()}, 
false);
 
 2773  auto UBF = CGF->
CGM.
getModule().getOrInsertFunction(Name, FnTy);
 
 2775  CGF->
Builder.CreateCall(UBF, {StrTy});
 
 
 2790  bool IsValidTargetAsm = 
true;
 
 2791  for (
unsigned i = 0, e = S.
getNumOutputs(); i != e && IsValidTargetAsm; i++) {
 
 2793    if (
const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
 
 2794      Name = GAS->getOutputName(i);
 
 2797    if (IsHipStdPar && !IsValid)
 
 2798      IsValidTargetAsm = 
false;
 
 2800      assert(IsValid && 
"Failed to parse output constraint");
 
 2801    OutputConstraintInfos.push_back(Info);
 
 2804  for (
unsigned i = 0, e = S.
getNumInputs(); i != e && IsValidTargetAsm; i++) {
 
 2806    if (
const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
 
 2807      Name = GAS->getInputName(i);
 
 2811    if (IsHipStdPar && !IsValid)
 
 2812      IsValidTargetAsm = 
false;
 
 2814      assert(IsValid && 
"Failed to parse input constraint");
 
 2815    InputConstraintInfos.push_back(Info);
 
 2818  if (!IsValidTargetAsm)
 
 2821  std::string Constraints;
 
 2823  std::vector<LValue> ResultRegDests;
 
 2824  std::vector<QualType> ResultRegQualTys;
 
 2825  std::vector<llvm::Type *> ResultRegTypes;
 
 2826  std::vector<llvm::Type *> ResultTruncRegTypes;
 
 2827  std::vector<llvm::Type *> ArgTypes;
 
 2828  std::vector<llvm::Type *> ArgElemTypes;
 
 2829  std::vector<llvm::Value*> Args;
 
 2830  llvm::BitVector ResultTypeRequiresCast;
 
 2831  std::vector<std::optional<std::pair<unsigned, unsigned>>> ResultBounds;
 
 2834  std::string InOutConstraints;
 
 2835  std::vector<llvm::Value*> InOutArgs;
 
 2836  std::vector<llvm::Type*> InOutArgTypes;
 
 2837  std::vector<llvm::Type*> InOutArgElemTypes;
 
 2840  std::vector<std::string> OutputConstraints;
 
 2843  llvm::SmallSet<std::string, 8> PhysRegOutputs;
 
 2851  bool ReadOnly = 
true, ReadNone = 
true;
 
 2859        StringRef(OutputConstraint).substr(1), &OutputConstraintInfos);
 
 2870    if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
 
 2871      CGM.Error(S.
getAsmLoc(), 
"multiple outputs to hard register: " + GCCReg);
 
 2873    OutputConstraints.push_back(OutputConstraint);
 
 2875    if (!Constraints.empty())
 
 2885      Constraints += 
"=" + OutputConstraint;
 
 2886      ResultRegQualTys.push_back(QTy);
 
 2887      ResultRegDests.push_back(Dest);
 
 2894           Ty->isAggregateType());
 
 2896      ResultTruncRegTypes.push_back(Ty);
 
 2897      ResultTypeRequiresCast.push_back(RequiresCast);
 
 2904          CGM.Error(OutExpr->
getExprLoc(), 
"output size should not be zero");
 
 2906      ResultRegTypes.push_back(Ty);
 
 2912        for (InputNo = 0; InputNo != S.
getNumInputs(); ++InputNo) {
 
 2917        assert(InputNo != S.
getNumInputs() && 
"Didn't find matching input!");
 
 2928      if (llvm::Type* AdjTy =
 
 2930                                                 ResultRegTypes.back()))
 
 2931        ResultRegTypes.back() = AdjTy;
 
 2934                              diag::err_asm_invalid_type_in_input)
 
 2935            << OutExpr->
getType() << OutputConstraint;
 
 2939      if (
auto *VT = dyn_cast<llvm::VectorType>(ResultRegTypes.back()))
 
 2940        LargestVectorWidth =
 
 2941            std::max((uint64_t)LargestVectorWidth,
 
 2942                     VT->getPrimitiveSizeInBits().getKnownMinValue());
 
 2953      ArgTypes.push_back(DestAddr.
getType());
 
 2956      Constraints += 
"=*";
 
 2957      Constraints += OutputConstraint;
 
 2958      ReadOnly = ReadNone = 
false;
 
 2962      InOutConstraints += 
',';
 
 2966      llvm::Type *ArgElemType;
 
 2967      std::tie(Arg, ArgElemType) = EmitAsmInputLValue(
 
 2968          Info, Dest, InputExpr->
getType(), InOutConstraints,
 
 2971      if (llvm::Type* AdjTy =
 
 2974        Arg = 
Builder.CreateBitCast(Arg, AdjTy);
 
 2977      if (
auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
 
 2978        LargestVectorWidth =
 
 2979            std::max((uint64_t)LargestVectorWidth,
 
 2980                     VT->getPrimitiveSizeInBits().getKnownMinValue());
 
 2983        InOutConstraints += llvm::utostr(i);
 
 2985        InOutConstraints += OutputConstraint;
 
 2987      InOutArgTypes.push_back(Arg->getType());
 
 2988      InOutArgElemTypes.push_back(ArgElemType);
 
 2989      InOutArgs.push_back(Arg);
 
 3000      CGM.getTargetCodeGenInfo().addReturnRegisterOutputs(
 
 3001          *
this, ReturnSlot, Constraints, ResultRegTypes, ResultTruncRegTypes,
 
 3007  for (
unsigned i = 0, e = S.
getNumInputs(); i != e; i++) {
 
 3015    if (!Constraints.empty())
 
 3027    std::string ReplaceConstraint (InputConstraint);
 
 3029    llvm::Type *ArgElemType;
 
 3030    std::tie(Arg, ArgElemType) = EmitAsmInput(Info, InputExpr, Constraints);
 
 3049          Arg = 
Builder.CreateZExt(Arg, OutputTy);
 
 3052        else if (OutputTy->isFloatingPointTy())
 
 3053          Arg = 
Builder.CreateFPExt(Arg, OutputTy);
 
 3056      ReplaceConstraint = OutputConstraints[Output];
 
 3058    if (llvm::Type* AdjTy =
 
 3061      Arg = 
Builder.CreateBitCast(Arg, AdjTy);
 
 3063      CGM.getDiags().Report(S.
getAsmLoc(), diag::err_asm_invalid_type_in_input)
 
 3064          << InputExpr->
getType() << InputConstraint;
 
 3067    if (
auto *VT = dyn_cast<llvm::VectorType>(Arg->getType()))
 
 3068      LargestVectorWidth =
 
 3069          std::max((uint64_t)LargestVectorWidth,
 
 3070                   VT->getPrimitiveSizeInBits().getKnownMinValue());
 
 3072    ArgTypes.push_back(Arg->getType());
 
 3073    ArgElemTypes.push_back(ArgElemType);
 
 3074    Args.push_back(Arg);
 
 3075    Constraints += InputConstraint;
 
 3079  for (
unsigned i = 0, e = InOutArgs.size(); i != e; i++) {
 
 3080    ArgTypes.push_back(InOutArgTypes[i]);
 
 3081    ArgElemTypes.push_back(InOutArgElemTypes[i]);
 
 3082    Args.push_back(InOutArgs[i]);
 
 3084  Constraints += InOutConstraints;
 
 3088  llvm::BasicBlock *Fallthrough = 
nullptr;
 
 3089  bool IsGCCAsmGoto = 
false;
 
 3090  if (
const auto *GS = dyn_cast<GCCAsmStmt>(&S)) {
 
 3091    IsGCCAsmGoto = GS->isAsmGoto();
 
 3093      for (
const auto *E : GS->labels()) {
 
 3095        Transfer.push_back(Dest.
getBlock());
 
 3096        if (!Constraints.empty())
 
 3098        Constraints += 
"!i";
 
 3104  bool HasUnwindClobber = 
false;
 
 3110    if (Clobber == 
"memory")
 
 3111      ReadOnly = ReadNone = 
false;
 
 3112    else if (Clobber == 
"unwind") {
 
 3113      HasUnwindClobber = 
true;
 
 3115    } 
else if (Clobber != 
"cc") {
 
 3117      if (
CGM.getCodeGenOpts().StackClashProtector &&
 
 3120                              diag::warn_stack_clash_protection_inline_asm);
 
 3125      if (Clobber == 
"eax" || Clobber == 
"edx") {
 
 3126        if (Constraints.find(
"=&A") != std::string::npos)
 
 3128        std::string::size_type position1 =
 
 3129            Constraints.find(
"={" + Clobber + 
"}");
 
 3130        if (position1 != std::string::npos) {
 
 3131          Constraints.insert(position1 + 1, 
"&");
 
 3134        std::string::size_type position2 = Constraints.find(
"=A");
 
 3135        if (position2 != std::string::npos) {
 
 3136          Constraints.insert(position2 + 1, 
"&");
 
 3141    if (!Constraints.empty())
 
 3144    Constraints += 
"~{";
 
 3145    Constraints += Clobber;
 
 3149  assert(!(HasUnwindClobber && IsGCCAsmGoto) &&
 
 3150         "unwind clobber can't be used with asm goto");
 
 3154  if (!MachineClobbers.empty()) {
 
 3155    if (!Constraints.empty())
 
 3157    Constraints += MachineClobbers;
 
 3160  llvm::Type *ResultType;
 
 3161  if (ResultRegTypes.empty())
 
 3163  else if (ResultRegTypes.size() == 1)
 
 3164    ResultType = ResultRegTypes[0];
 
 3166    ResultType = llvm::StructType::get(
getLLVMContext(), ResultRegTypes);
 
 3168  llvm::FunctionType *FTy =
 
 3169    llvm::FunctionType::get(ResultType, ArgTypes, 
false);
 
 3173  llvm::InlineAsm::AsmDialect GnuAsmDialect =
 
 3175          ? llvm::InlineAsm::AD_ATT
 
 3176          : llvm::InlineAsm::AD_Intel;
 
 3178    llvm::InlineAsm::AD_Intel : GnuAsmDialect;
 
 3180  llvm::InlineAsm *IA = llvm::InlineAsm::get(
 
 3181      FTy, AsmString, Constraints, HasSideEffect,
 
 3182       false, AsmDialect, HasUnwindClobber);
 
 3183  std::vector<llvm::Value*> RegResults;
 
 3184  llvm::CallBrInst *CBR;
 
 3185  llvm::DenseMap<llvm::BasicBlock *, SmallVector<llvm::Value *, 4>>
 
 3188    CBR = 
Builder.CreateCallBr(IA, Fallthrough, Transfer, Args);
 
 3193                      ArgElemTypes, *
this, RegResults);
 
 3197    if (!RegResults.empty()) {
 
 3199      for (llvm::BasicBlock *Dest : CBR->getIndirectDests()) {
 
 3200        llvm::Twine SynthName = Dest->getName() + 
".split";
 
 3202        llvm::IRBuilderBase::InsertPointGuard IPG(
Builder);
 
 3203        Builder.SetInsertPoint(SynthBB);
 
 3205        if (ResultRegTypes.size() == 1) {
 
 3206          CBRRegResults[SynthBB].push_back(CBR);
 
 3208          for (
unsigned j = 0, e = ResultRegTypes.size(); j != e; ++j) {
 
 3209            llvm::Value *Tmp = 
Builder.CreateExtractValue(CBR, j, 
"asmresult");
 
 3210            CBRRegResults[SynthBB].push_back(Tmp);
 
 3216        CBR->setIndirectDest(i++, SynthBB);
 
 3219  } 
else if (HasUnwindClobber) {
 
 3224                      ArgElemTypes, *
this, RegResults);
 
 3231                      ArgElemTypes, *
this, RegResults);
 
 3234  EmitAsmStores(*
this, S, RegResults, ResultRegTypes, ResultTruncRegTypes,
 
 3235                ResultRegDests, ResultRegQualTys, ResultTypeRequiresCast,
 
 3241  if (IsGCCAsmGoto && !CBRRegResults.empty()) {
 
 3242    for (llvm::BasicBlock *Succ : CBR->getIndirectDests()) {
 
 3243      llvm::IRBuilderBase::InsertPointGuard IPG(
Builder);
 
 3244      Builder.SetInsertPoint(Succ, --(Succ->end()));
 
 3245      EmitAsmStores(*
this, S, CBRRegResults[Succ], ResultRegTypes,
 
 3246                    ResultTruncRegTypes, ResultRegDests, ResultRegQualTys,
 
 3247                    ResultTypeRequiresCast, ResultBounds);
 
 
 3263       I != E; ++I, ++CurField) {
 
 3265    if (CurField->hasCapturedVLAType()) {
 
 
 3282  CodeGenFunction CGF(
CGM, 
true);
 
 
 3302    "CapturedStmtInfo should be set when generating the captured function");
 
 3306  assert(CD->
hasBody() && 
"missing CapturedDecl body");
 
 3315    CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.
VoidTy, Args);
 
 3316  llvm::FunctionType *FuncLLVMTy = 
CGM.getTypes().GetFunctionType(FuncInfo);
 
 3319    llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
 
 3321  CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
 
 3323    F->addFnAttr(llvm::Attribute::NoUnwind);
 
 3335  for (
auto *FD : RD->
fields()) {
 
 3336    if (FD->hasCapturedVLAType()) {
 
 3340      auto VAT = FD->getCapturedVLAType();
 
 3341      VLASizeMap[VAT->getSizeExpr()] = ExprArg;
 
 3352  PGO->assignRegionCounters(
GlobalDecl(CD), F);
 
 
 3362  for (
auto &I : *BB) {
 
 3363    if (
auto *CI = dyn_cast<llvm::ConvergenceControlInst>(&I))
 
 
 3370CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input) {
 
 3372  assert(ParentToken);
 
 3374  llvm::Value *bundleArgs[] = {ParentToken};
 
 3375  llvm::OperandBundleDef OB(
"convergencectrl", bundleArgs);
 
 3376  auto *Output = llvm::CallBase::addOperandBundle(
 
 3377      Input, llvm::LLVMContext::OB_convergencectrl, OB, Input->getIterator());
 
 3378  Input->replaceAllUsesWith(Output);
 
 3379  Input->eraseFromParent();
 
 3383llvm::ConvergenceControlInst *
 
 3384CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB) {
 
 3386  assert(ParentToken);
 
 3387  return llvm::ConvergenceControlInst::CreateLoop(*BB, ParentToken);
 
 3390llvm::ConvergenceControlInst *
 
 3391CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) {
 
 3392  llvm::BasicBlock *BB = &F->getEntryBlock();
 
 3400  return llvm::ConvergenceControlInst::CreateEntry(*BB);
 
Defines enum values for all the target-independent builtin functions.
static std::string AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, const TargetInfo &Target, CodeGenModule &CGM, const AsmStmt &Stmt, const bool EarlyClobber, std::string *GCCReg=nullptr)
AddVariableConstraints - Look at AsmExpr and if it is a variable declared as using a particular regis...
static bool FindCaseStatementsForValue(const SwitchStmt &S, const llvm::APSInt &ConstantCondValue, SmallVectorImpl< const Stmt * > &ResultStmts, ASTContext &C, const SwitchCase *&ResultCase)
FindCaseStatementsForValue - Find the case statement being jumped to and then invoke CollectStatement...
static llvm::ConvergenceControlInst * getConvergenceToken(llvm::BasicBlock *BB)
static void EmitHipStdParUnsupportedAsm(CodeGenFunction *CGF, const AsmStmt &S)
static std::optional< SmallVector< uint64_t, 16 > > getLikelihoodWeights(ArrayRef< Stmt::Likelihood > Likelihoods)
static llvm::MDNode * getAsmSrcLocInfo(const StringLiteral *Str, CodeGenFunction &CGF)
getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline asm call instruction.
static bool isSwiftAsyncCallee(const CallExpr *CE)
Determine if the given call uses the swiftasync calling convention.
static CSFC_Result CollectStatementsForCase(const Stmt *S, const SwitchCase *Case, bool &FoundCase, SmallVectorImpl< const Stmt * > &ResultStmts)
static void EmitAsmStores(CodeGenFunction &CGF, const AsmStmt &S, const llvm::ArrayRef< llvm::Value * > RegResults, const llvm::ArrayRef< llvm::Type * > ResultRegTypes, const llvm::ArrayRef< llvm::Type * > ResultTruncRegTypes, const llvm::ArrayRef< LValue > ResultRegDests, const llvm::ArrayRef< QualType > ResultRegQualTys, const llvm::BitVector &ResultTypeRequiresCast, const std::vector< std::optional< std::pair< unsigned, unsigned > > > &ResultBounds)
static bool hasEmptyLoopBody(const LoopStmt &S)
CSFC_Result
CollectStatementsForCase - Given the body of a 'switch' statement and a constant value that is being ...
static void UpdateAsmCallInst(llvm::CallBase &Result, bool HasSideEffect, bool HasUnwindClobber, bool ReadOnly, bool ReadNone, bool NoMerge, bool NoConvergent, const AsmStmt &S, const std::vector< llvm::Type * > &ResultRegTypes, const std::vector< llvm::Type * > &ArgElemTypes, CodeGenFunction &CGF, std::vector< llvm::Value * > &RegResults)
llvm::MachO::Target Target
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
Defines the SourceManager interface.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType getCanonicalTagType(const TagDecl *TD) const
AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
std::string getInputConstraint(unsigned i) const
getInputConstraint - Return the specified input constraint.
std::string getOutputConstraint(unsigned i) const
getOutputConstraint - Return the constraint string for the specified output operand.
SourceLocation getAsmLoc() const
const Expr * getInputExpr(unsigned i) const
unsigned getNumClobbers() const
const Expr * getOutputExpr(unsigned i) const
unsigned getNumOutputs() const
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
unsigned getNumInputs() const
std::string getClobber(unsigned i) const
Attr - This represents one attribute.
Represents an attribute applied to a statement.
ArrayRef< const Attr * > getAttrs() const
BreakStmt - This represents a break.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Represents the body of a CapturedStmt, and serves as its DeclContext.
ImplicitParamDecl * getContextParam() const
Retrieve the parameter containing captured variables.
param_iterator param_end() const
Retrieve an iterator one past the last parameter decl.
param_iterator param_begin() const
Retrieve an iterator pointing to the first parameter decl.
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
This captures a statement into a function.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
const RecordDecl * getCapturedRecordDecl() const
Retrieve the record declaration for captured variables.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument.
SourceLocation getBeginLoc() const LLVM_READONLY
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument.
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
CapturedRegionKind getCapturedRegionKind() const
Retrieve the captured region kind.
CaseStmt - Represent a case statement.
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
CGFunctionInfo - Class to encapsulate the information about a function definition.
API for captured statement code generation.
RAII for correct setting/restoring of CapturedStmtInfo.
void rescopeLabels()
Change the cleanup scope of the labels in this lexical scope to match the scope of the enclosing cont...
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
bool requiresCleanups() const
Determine whether this scope requires any cleanups.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitOMPParallelMaskedTaskLoopDirective(const OMPParallelMaskedTaskLoopDirective &S)
void EmitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &S)
void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)
void EmitCXXTryStmt(const CXXTryStmt &S)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
void EmitSehCppScopeBegin()
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
llvm::DenseMap< const VarDecl *, llvm::Value * > NRVOFlags
A mapping from NRVO variables to the flags used to indicate when the NRVO has been applied to this va...
bool IsOutlinedSEHHelper
True if the current function is an outlined SEH helper.
void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S)
Emit an OMPCanonicalLoop using the OpenMPIRBuilder.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
void EmitCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef< const Attr * > Attrs={})
void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S)
void EmitOMPScanDirective(const OMPScanDirective &S)
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
void EmitOpenACCExitDataConstruct(const OpenACCExitDataConstruct &S)
LValue InitCapturedStruct(const CapturedStmt &S)
void addInstToNewSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
Add KeyInstruction and an optional Backup instruction to a new atom group (See ApplyAtomGroup for mor...
CGCapturedStmtInfo * CapturedStmtInfo
void EmitOMPDistributeDirective(const OMPDistributeDirective &S)
void EmitOMPParallelForDirective(const OMPParallelForDirective &S)
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
Emits a call or invoke instruction to the given function, depending on the current state of the EH st...
void EmitOMPMasterDirective(const OMPMasterDirective &S)
void EmitOMPParallelMasterTaskLoopSimdDirective(const OMPParallelMasterTaskLoopSimdDirective &S)
void EmitOpenACCInitConstruct(const OpenACCInitConstruct &S)
void EmitOMPFlushDirective(const OMPFlushDirective &S)
void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S)
JumpDest getJumpDestForLabel(const LabelDecl *S)
getBasicBlockForLabel - Return the LLVM basicblock that the specified label maps to.
void EmitCoreturnStmt(const CoreturnStmt &S)
void EmitOMPTargetTeamsDistributeParallelForSimdDirective(const OMPTargetTeamsDistributeParallelForSimdDirective &S)
SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack
Stack to track the controlled convergence tokens.
void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S)
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
bool EmitSimpleStmt(const Stmt *S, ArrayRef< const Attr * > Attrs)
EmitSimpleStmt - Try to emit a "simple" statement which does not necessarily require an insertion poi...
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S)
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
const LangOptions & getLangOpts() const
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
void EmitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &S)
bool InNoConvergentAttributedStmt
True if the current statement has noconvergent attribute.
void EmitOpenACCWaitConstruct(const OpenACCWaitConstruct &S)
void EmitBlockAfterUses(llvm::BasicBlock *BB)
EmitBlockAfterUses - Emit the given block somewhere hopefully near its uses, and leave the insertion ...
void SimplifyForwardingBlocks(llvm::BasicBlock *BB)
SimplifyForwardingBlocks - If the given basic block is only a branch to another basic block,...
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
bool InNoMergeAttributedStmt
True if the current statement has nomerge attribute.
void EmitOMPScopeDirective(const OMPScopeDirective &S)
LValue MakeAddrLValueWithoutTBAA(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
JumpDest ReturnBlock
ReturnBlock - Unified return block.
void EmitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective &S)
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)
Converts Location to a DebugLoc, if debug information is enabled.
void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field, bool IsInBounds=true)
const TargetInfo & getTarget() const
Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
void EmitGotoStmt(const GotoStmt &S)
void EmitOMPDepobjDirective(const OMPDepobjDirective &S)
void EmitOMPMetaDirective(const OMPMetaDirective &S)
void EmitOMPCriticalDirective(const OMPCriticalDirective &S)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
void EmitOMPCancelDirective(const OMPCancelDirective &S)
const Expr * RetExpr
If a return statement is being visited, this holds the return statment's result expression.
void EmitOMPBarrierDirective(const OMPBarrierDirective &S)
void EmitOMPOrderedDirective(const OMPOrderedDirective &S)
void EmitForStmt(const ForStmt &S, ArrayRef< const Attr * > Attrs={})
void EmitOMPSectionsDirective(const OMPSectionsDirective &S)
void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S)
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
void EmitOMPInteropDirective(const OMPInteropDirective &S)
void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S)
void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S)
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void EmitWhileStmt(const WhileStmt &S, ArrayRef< const Attr * > Attrs={})
void EmitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective &S)
void EmitOMPTargetParallelGenericLoopDirective(const OMPTargetParallelGenericLoopDirective &S)
Emit combined directive 'target parallel loop' as if its constituent constructs are 'target',...
void EmitOpenACCCombinedConstruct(const OpenACCCombinedConstruct &S)
void ResolveBranchFixups(llvm::BasicBlock *Target)
void EmitOMPTeamsDistributeParallelForSimdDirective(const OMPTeamsDistributeParallelForSimdDirective &S)
void EmitOMPMaskedDirective(const OMPMaskedDirective &S)
bool checkIfLoopMustProgress(const Expr *, bool HasEmptyBody)
Returns true if a loop must make progress, which means the mustprogress attribute can be added.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
void EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S)
CGDebugInfo * getDebugInfo()
void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S)
void EmitOMPReverseDirective(const OMPReverseDirective &S)
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)
void EmitOpenACCDataConstruct(const OpenACCDataConstruct &S)
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...
void EmitOMPTargetTeamsDistributeParallelForDirective(const OMPTargetTeamsDistributeParallelForDirective &S)
void EmitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective &S)
void EmitObjCAtTryStmt(const ObjCAtTryStmt &S)
const TargetCodeGenInfo & getTargetHooks() const
void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S)
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S)
bool InNoInlineAttributedStmt
True if the current statement has noinline attribute.
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
void EmitOMPMaskedTaskLoopSimdDirective(const OMPMaskedTaskLoopSimdDirective &S)
void EmitCoroutineBody(const CoroutineBodyStmt &S)
void EmitOMPParallelDirective(const OMPParallelDirective &S)
void EmitOMPTaskDirective(const OMPTaskDirective &S)
void EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S)
void EmitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective &S)
void EmitOMPAssumeDirective(const OMPAssumeDirective &S)
void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S)
ASTContext & getContext() const
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S)
void EmitOMPTargetTeamsGenericLoopDirective(const OMPTargetTeamsGenericLoopDirective &S)
void EmitIfStmt(const IfStmt &S)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
void EmitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &S)
void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
void EmitOpenACCCacheConstruct(const OpenACCCacheConstruct &S)
void EmitOpenACCLoopConstruct(const OpenACCLoopConstruct &S)
void EmitOMPTeamsDistributeParallelForDirective(const OMPTeamsDistributeParallelForDirective &S)
void EmitOMPFuseDirective(const OMPFuseDirective &S)
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init)
void EmitAsmStmt(const AsmStmt &S)
void EmitDefaultStmt(const DefaultStmt &S, ArrayRef< const Attr * > Attrs)
void EmitOMPTargetTeamsDistributeDirective(const OMPTargetTeamsDistributeDirective &S)
void EmitSwitchStmt(const SwitchStmt &S)
static bool mightAddDeclToScope(const Stmt *S)
Determine if the given statement might introduce a declaration into the current scope,...
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S)
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S)
void EmitOMPTargetDirective(const OMPTargetDirective &S)
void EmitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct &S)
llvm::Function * EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K)
Generate an outlined function for the body of a CapturedStmt, store any captured variables into the c...
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void EmitOMPTeamsDirective(const OMPTeamsDirective &S)
static bool containsBreak(const Stmt *S)
containsBreak - Return true if the statement contains a break out of it.
void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D)
Emit simple code for OpenMP directives in Simd-only mode.
HLSLControlFlowHintAttr::Spelling HLSLControlFlowAttr
HLSL Branch attribute.
bool InAlwaysInlineAttributedStmt
True if the current statement has always_inline attribute.
void EmitCaseStmt(const CaseStmt &S, ArrayRef< const Attr * > Attrs)
void EmitOMPErrorDirective(const OMPErrorDirective &S)
void EmitBreakStmt(const BreakStmt &S)
void EmitOMPParallelMaskedTaskLoopSimdDirective(const OMPParallelMaskedTaskLoopSimdDirective &S)
void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S)
void EmitOpenACCComputeConstruct(const OpenACCComputeConstruct &S)
void EmitDoStmt(const DoStmt &S, ArrayRef< const Attr * > Attrs={})
void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S)
const TargetInfo & Target
Address GenerateCapturedStmtArgument(const CapturedStmt &S)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
void EmitOMPSimdDirective(const OMPSimdDirective &S)
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitOMPParallelGenericLoopDirective(const OMPLoopDirective &S)
void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S)
void EmitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &S)
unsigned NextCleanupDestIndex
AggValueSlot::Overlap_t getOverlapForReturnValue()
Determine whether a return value slot may overlap some other object.
const BreakContinue * GetDestForLoopControlStmt(const LoopControlStmt &S)
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::BasicBlock * GetIndirectGotoBlock()
void EmitOpenACCHostDataConstruct(const OpenACCHostDataConstruct &S)
void EmitOpenACCUpdateConstruct(const OpenACCUpdateConstruct &S)
void EmitOMPUnrollDirective(const OMPUnrollDirective &S)
void EmitOMPStripeDirective(const OMPStripeDirective &S)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
static bool hasAggregateEvaluationKind(QualType T)
void EmitCaseStmtRange(const CaseStmt &S, ArrayRef< const Attr * > Attrs)
EmitCaseStmtRange - If case statement range is not too big then add multiple cases to switch instruct...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitOMPSingleDirective(const OMPSingleDirective &S)
void EmitReturnStmt(const ReturnStmt &S)
EmitReturnStmt - Note that due to GCC extensions, this can have an operand if the function returns vo...
void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
llvm::Value * EmitCheckedArgForAssume(const Expr *E)
Emits an argument for a call to a __builtin_assume.
llvm::Function * GenerateCapturedStmtFunction(const CapturedStmt &S)
Creates the outlined function for a CapturedStmt.
const CallExpr * MustTailCall
const CGFunctionInfo * CurFnInfo
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitDeclStmt(const DeclStmt &S)
void EmitLabelStmt(const LabelStmt &S)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
void EmitOMPTileDirective(const OMPTileDirective &S)
void EmitDecl(const Decl &D, bool EvaluateConditionDecl=false)
EmitDecl - Emit a declaration.
void EmitOMPAtomicDirective(const OMPAtomicDirective &S)
void EmitOpenACCSetConstruct(const OpenACCSetConstruct &S)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitAttributedStmt(const AttributedStmt &S)
void EmitOMPParallelMasterTaskLoopDirective(const OMPParallelMasterTaskLoopDirective &S)
void EmitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective &S)
void EmitOMPSectionDirective(const OMPSectionDirective &S)
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
void EmitOMPForSimdDirective(const OMPForSimdDirective &S)
llvm::LLVMContext & getLLVMContext()
bool SawAsmBlock
Whether we processed a Microsoft-style asm block during CodeGen.
void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
void EmitIndirectGotoStmt(const IndirectGotoStmt &S)
void MaybeEmitDeferredVarDeclInit(const VarDecl *var)
bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const
isObviouslyBranchWithoutCleanups - Return true if a branch to the specified destination obviously has...
void EmitSEHTryStmt(const SEHTryStmt &S)
void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S)
void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S)
When instrumenting to collect profile data, the counts for some blocks such as switch cases need to n...
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitOMPForDirective(const OMPForDirective &S)
void EmitLabel(const LabelDecl *D)
EmitLabel - Emit the block for the given label.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
void EmitContinueStmt(const ContinueStmt &S)
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
DiagnosticsEngine & getDiags() const
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
const llvm::DataLayout & getDataLayout() const
ASTContext & getContext() const
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
A saved depth on the scope stack.
bool encloses(stable_iterator I) const
Returns true if this scope encloses I.
static stable_iterator invalid()
static stable_iterator stable_end()
Create a stable reference to the bottom of the EH stack.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
llvm::Value * getPointer(CodeGenFunction &CGF) const
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
virtual bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF, llvm::Type *Ty) const
Target hook to decide whether an inline asm operand can be passed by value.
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
SourceLocation getLBracLoc() const
Stmt * getStmtExprResult()
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
ContinueStmt - This represents a continue.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
SourceLocation getLocation() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
DoStmt - This represents a 'do/while' stmt.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
This represents a GCC inline-assembly statement extension.
GlobalDecl - represents a global declaration.
GotoStmt - This represents a direct goto.
LabelDecl * getLabel() const
IfStmt - This represents an if/then/else.
bool isNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
IndirectGotoStmt - This represents an indirect goto.
LabelDecl * getConstantTarget()
getConstantTarget - Returns the fixed target of this indirect goto, if one exists.
Represents the declaration of a label.
LabelStmt * getStmt() const
LabelStmt - Represents a label, which has a substatement.
LabelDecl * getDecl() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool assumeFunctionsAreConvergent() const
Base class for BreakStmt and ContinueStmt.
Represents a point when we exit a loop.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
The collection of all-type qualifiers we support.
Represents a struct/union/class.
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
SourceLocation getBeginLoc() const
const VarDecl * getNRVOCandidate() const
Retrieve the variable that might be used for the named return value optimization.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Likelihood
The likelihood of a branch being taken.
@ LH_Unlikely
Branch has the [[unlikely]] attribute.
@ LH_None
No attribute set or branches of the IfStmt have the same attribute.
@ LH_Likely
Branch has the [[likely]] attribute.
static const Attr * getLikelihoodAttr(const Stmt *S)
SourceLocation getBeginLoc() const LLVM_READONLY
static Likelihood getLikelihood(ArrayRef< const Attr * > Attrs)
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
StringRef getString() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
Exposes information about the current target.
bool validateInputConstraint(MutableArrayRef< ConstraintInfo > OutputConstraints, ConstraintInfo &info) const
std::string simplifyConstraint(StringRef Constraint, SmallVectorImpl< ConstraintInfo > *OutCons=nullptr) const
StringRef getNormalizedGCCRegisterName(StringRef Name, bool ReturnCanonical=false) const
Returns the "normalized" GCC register name.
bool validateOutputConstraint(ConstraintInfo &Info) const
virtual std::string_view getClobbers() const =0
Returns a string of target-specific clobbers, in LLVM format.
const T * castAs() const
Member-template castAs<specific type>.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isNRVOVariable() const
Determine whether this local variable can be used with the named return value optimization (NRVO).
WhileStmt - This represents a 'while' stmt.
SourceLocation getWhileLoc() const
SourceLocation getRParenLoc() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Defines the clang::TargetInfo interface.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
CapturedRegionKind
The different kinds of captured statement.
@ Asm
Assembly: we accept this only so that we can preprocess it.
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
ActionResult< Expr * > ExprResult
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
void setScopeDepth(EHScopeStack::stable_iterator depth)
llvm::BasicBlock * getBlock() const
EHScopeStack::stable_iterator getScopeDepth() const
llvm::IntegerType * Int64Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool hasMatchingInput() const
Return true if this output operand has a matching (tied) input operand.
unsigned getTiedOperand() const
bool allowsMemory() const
std::optional< std::pair< unsigned, unsigned > > getOutputOperandBounds() const
bool requiresImmediateConstant() const
bool hasTiedOperand() const
Return true if this input operand is a matching constraint that ties it to an output operand.
bool allowsRegister() const