A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/CGStmtOpenMP_8cpp_source.html below:

clang: lib/CodeGen/CGStmtOpenMP.cpp Source File

28#include "llvm/ADT/SmallSet.h" 29#include "llvm/BinaryFormat/Dwarf.h" 30#include "llvm/Frontend/OpenMP/OMPConstants.h" 31#include "llvm/Frontend/OpenMP/OMPIRBuilder.h" 32#include "llvm/IR/Constants.h" 33#include "llvm/IR/DebugInfoMetadata.h" 34#include "llvm/IR/Instructions.h" 35#include "llvm/IR/IntrinsicInst.h" 36#include "llvm/IR/Metadata.h" 37#include "llvm/Support/AtomicOrdering.h" 38#include "llvm/Support/Debug.h" 40using namespace clang

;

41using namespace

CodeGen;

42using namespace

llvm::omp;

44#define TTL_CODEGEN_TYPE "target-teams-loop-codegen" 53class

OMPLexicalScope :

public

CodeGenFunction::LexicalScope {

55 for

(

const auto

*

C

: S.clauses()) {

57 if

(

const auto

*PreInit =

58

cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {

59 for

(

const auto

*I : PreInit->decls()) {

60 if

(!I->hasAttr<OMPCaptureNoInitAttr>()) {

63

CodeGenFunction::AutoVarEmission Emission =

72

CodeGenFunction::OMPPrivateScope InlinedShareds;

78

cast<BlockDecl>(CGF.

CurCodeDecl

)->capturesVariable(VD));

84 const

std::optional<OpenMPDirectiveKind> CapturedRegion = std::nullopt,

85 const bool

EmitPreInitStmt =

true

)

89

emitPreInitStmt(CGF, S);

92

assert(S.hasAssociatedStmt() &&

93 "Expected associated statement for inlined directive."

);

94 const CapturedStmt

*CS = S.getCapturedStmt(*CapturedRegion);

95 for

(

const auto

&

C

: CS->

captures

()) {

96 if

(

C

.capturesVariable() ||

C

.capturesVariableByCopy()) {

97 auto

*VD =

C

.getCapturedVar();

99 "Canonical decl must be captured."

);

103

InlinedShareds.isGlobalVarCaptured(VD)),

108

(void)InlinedShareds.Privatize();

114class

OMPParallelScope final :

public

OMPLexicalScope {

124

: OMPLexicalScope(CGF, S,

std

::nullopt,

125

EmitPreInitStmt(S)) {}

130class

OMPTeamsScope final :

public

OMPLexicalScope {

139

: OMPLexicalScope(CGF, S,

std

::nullopt,

140

EmitPreInitStmt(S)) {}

145class

OMPLoopScope :

public

CodeGenFunction::RunCleanupsScope {

147 const Stmt

*PreInits;

148

CodeGenFunction::OMPMapVars PreCondVars;

149 if

(

auto

*LD = dyn_cast<OMPLoopDirective>(&S)) {

150

llvm::DenseSet<const VarDecl *> EmittedAsPrivate;

151 for

(

const auto

*

E

: LD->counters()) {

152 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

154

(void)PreCondVars.setVarAddr(

159 for

(

const Expr

*IRef :

C

->varlist()) {

161

cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());

162 if

(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {

163 QualType

OrigVDTy = OrigVD->getType().getNonReferenceType();

164

(void)PreCondVars.setVarAddr(

173

(void)PreCondVars.apply(CGF);

176

LD->getInnermostCapturedStmt()->getCapturedStmt(),

177 true

, LD->getLoopsNumber(),

178

[&CGF](

unsigned

Cnt,

const Stmt

*CurStmt) {

179 if

(

const auto

*CXXFor = dyn_cast<CXXForRangeStmt>(CurStmt)) {

180 if

(

const Stmt

*

Init

= CXXFor->getInit())

182

CGF.

EmitStmt

(CXXFor->getRangeStmt());

183

CGF.

EmitStmt

(CXXFor->getEndStmt());

187

PreInits = LD->getPreInits();

188

}

else if

(

const auto

*

Tile

= dyn_cast<OMPTileDirective>(&S)) {

189

PreInits =

Tile

->getPreInits();

190

}

else if

(

const auto

*Unroll = dyn_cast<OMPUnrollDirective>(&S)) {

191

PreInits = Unroll->getPreInits();

192

}

else if

(

const auto

*Reverse = dyn_cast<OMPReverseDirective>(&S)) {

193

PreInits = Reverse->getPreInits();

194

}

else if

(

const auto

*Interchange =

195

dyn_cast<OMPInterchangeDirective>(&S)) {

196

PreInits = Interchange->getPreInits();

198

llvm_unreachable(

"Unknown loop-based directive kind."

);

205 if

(

auto

*PreInitCompound = dyn_cast<CompoundStmt>(PreInits))

206

llvm::append_range(PreInitStmts, PreInitCompound->body());

208

PreInitStmts.push_back(PreInits);

210 for

(

const Stmt

*S : PreInitStmts) {

213 if

(

auto

*PreInitDecl = dyn_cast<DeclStmt>(S)) {

214 for

(

Decl

*I : PreInitDecl->decls())

221

PreCondVars.restore(CGF);

227

emitPreInitStmt(CGF, S);

231class

OMPSimdLexicalScope :

public

CodeGenFunction::LexicalScope {

232

CodeGenFunction::OMPPrivateScope InlinedShareds;

238

cast<BlockDecl>(CGF.

CurCodeDecl

)->capturesVariable(VD));

244

InlinedShareds(CGF) {

245 for

(

const auto

*

C

: S.clauses()) {

247 if

(

const auto

*PreInit =

248

cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {

249 for

(

const auto

*I : PreInit->decls()) {

250 if

(!I->hasAttr<OMPCaptureNoInitAttr>()) {

253

CodeGenFunction::AutoVarEmission Emission =

259

}

else if

(

const auto

*UDP = dyn_cast<OMPUseDevicePtrClause>(

C

)) {

260 for

(

const Expr

*

E

: UDP->varlist()) {

261 const Decl

*

D

= cast<DeclRefExpr>(

E

)->getDecl();

262 if

(

const auto

*OED = dyn_cast<OMPCapturedExprDecl>(

D

))

265

}

else if

(

const auto

*UDP = dyn_cast<OMPUseDeviceAddrClause>(

C

)) {

266 for

(

const Expr

*

E

: UDP->varlist()) {

268 if

(

const auto

*OED = dyn_cast<OMPCapturedExprDecl>(

D

))

275 if

(

const auto

*TG = dyn_cast<OMPTaskgroupDirective>(&S)) {

276 if

(

const Expr

*

E

= TG->getReductionRef())

277

CGF.

EmitVarDecl

(*cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl()));

281

llvm::DenseSet<CanonicalDeclPtr<const Decl>> CopyArrayTemps;

283 if

(

C

->getModifier() != OMPC_REDUCTION_inscan)

285 for

(

const Expr

*

E

:

C

->copy_array_temps())

286

CopyArrayTemps.insert(cast<DeclRefExpr>(

E

)->getDecl());

288 const auto

*CS = cast_or_null<CapturedStmt>(S.getAssociatedStmt());

291 if

(

C

.capturesVariable() ||

C

.capturesVariableByCopy()) {

292 auto

*VD =

C

.getCapturedVar();

293 if

(CopyArrayTemps.contains(VD))

296 "Canonical decl must be captured."

);

298

isCapturedVar(CGF, VD) ||

300

InlinedShareds.isGlobalVarCaptured(VD)),

308

(void)InlinedShareds.Privatize();

319 if

(Kind != OMPD_loop)

324

BindKind =

C

->getBindKind();

327 case

OMPC_BIND_parallel:

329 case

OMPC_BIND_teams:

330 return

OMPD_distribute;

331 case

OMPC_BIND_thread:

342LValue

CodeGenFunction::EmitOMPSharedLValue(

const Expr

*

E

) {

343 if

(

const auto

*OrigDRE = dyn_cast<DeclRefExpr>(

E

)) {

344 if

(

const auto

*OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) {

345

OrigVD = OrigVD->getCanonicalDecl();

360

llvm::Value *

Size

=

nullptr

;

361 auto

SizeInChars =

C

.getTypeSizeInChars(Ty);

362 if

(SizeInChars.isZero()) {

368 Size

?

Builder

.CreateNUWMul(Size, VlaSize.NumElts) : VlaSize.NumElts;

370

SizeInChars =

C

.getTypeSizeInChars(Ty);

371 if

(SizeInChars.isZero())

372 return

llvm::ConstantInt::get(

SizeTy

,

0);

380 const RecordDecl

*RD = S.getCapturedRecordDecl();

382 auto

CurCap = S.captures().begin();

384 E

= S.capture_init_end();

385

I !=

E

; ++I, ++CurField, ++CurCap) {

386 if

(CurField->hasCapturedVLAType()) {

388

llvm::Value *Val = VLASizeMap[VAT->

getSizeExpr

()];

389

CapturedVars.push_back(Val);

390

}

else if

(CurCap->capturesThis()) {

391

CapturedVars.push_back(CXXThisValue);

392

}

else if

(CurCap->capturesVariableByCopy()) {

397 if

(!CurField->getType()->isAnyPointerType()) {

401

Twine(CurCap->getCapturedVar()->getName(),

".casted"

));

407

Ctx.

getPointerType

(CurField->getType()), CurCap->getLocation());

417

CapturedVars.push_back(CV);

419

assert(CurCap->capturesVariable() &&

"Expected capture by reference."

);

441 return C

.getLValueReferenceType(

447 if

(

const auto

*VLA = dyn_cast<VariableArrayType>(A))

449 if

(!A->isVariablyModifiedType())

450 return C

.getCanonicalType(

T

);

452 return C

.getCanonicalParamType(

T

);

457struct

FunctionOptions {

462 const bool

UIntPtrCastRequired =

true

;

465 const bool

RegisterCastedArgsOnly =

false

;

467 const

StringRef FunctionName;

470 explicit

FunctionOptions(

const CapturedStmt

*S,

bool

UIntPtrCastRequired,

471 bool

RegisterCastedArgsOnly, StringRef FunctionName,

473

: S(S), UIntPtrCastRequired(UIntPtrCastRequired),

474

RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),

475

FunctionName(FunctionName),

Loc

(

Loc

) {}

481

llvm::MapVector<

const Decl

*, std::pair<const VarDecl *, Address>>

483

llvm::DenseMap<

const Decl

*, std::pair<const Expr *, llvm::Value *>>

485

llvm::Value *&CXXThisValue,

const

FunctionOptions &FO) {

487 const RecordDecl

*RD = FO.S->getCapturedRecordDecl();

488

assert(CD->

hasBody

() &&

"missing CapturedDecl body"

);

490

CXXThisValue =

nullptr

;

500 auto

I = FO.S->captures().begin();

502 if

(!FO.UIntPtrCastRequired) {

522 if

(FO.UIntPtrCastRequired &&

524

I->capturesVariableArrayType()))

527 if

(I->capturesVariable() || I->capturesVariableByCopy()) {

528

CapVar = I->getCapturedVar();

530

}

else if

(I->capturesThis()) {

533

assert(I->capturesVariableArrayType());

543

}

else if

(DebugFunctionDecl && (CapVar || I->capturesThis())) {

545

Ctx, DebugFunctionDecl,

546

CapVar ? CapVar->

getBeginLoc

() : FD->getBeginLoc(),

547

CapVar ? CapVar->

getLocation

() : FD->getLocation(), II, ArgType,

553

Args.emplace_back(Arg);

555

TargetArgs.emplace_back(

556

FO.UIntPtrCastRequired

573

llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,

577

F->setDoesNotThrow();

578

F->setDoesNotRecurse();

582

F->removeFnAttr(llvm::Attribute::NoInline);

583

F->addFnAttr(llvm::Attribute::AlwaysInline);

588

FO.UIntPtrCastRequired ? FO.Loc : FO.S->getBeginLoc(),

589

FO.UIntPtrCastRequired ? FO.Loc

592

I = FO.S->captures().begin();

596 if

(!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) {

604 if

(I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {

605 const VarDecl

*CurVD = I->getCapturedVar();

606 if

(!FO.RegisterCastedArgsOnly)

607

LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});

615 if

(FD->hasCapturedVLAType()) {

616 if

(FO.UIntPtrCastRequired) {

619

Args[Cnt]->getName(), ArgLVal),

624

VLASizes.try_emplace(Args[Cnt], VAT->

getSizeExpr

(), ExprArg);

625

}

else if

(I->capturesVariable()) {

626 const VarDecl

*Var = I->getCapturedVar();

636 if

(!FO.RegisterCastedArgsOnly) {

640

}

else if

(I->capturesVariableByCopy()) {

641

assert(!FD->getType()->isAnyPointerType() &&

642 "Not expecting a captured pointer."

);

643 const VarDecl

*Var = I->getCapturedVar();

644

LocalAddrs.insert({Args[Cnt],

645

{Var, FO.UIntPtrCastRequired

647

CGF, I->getLocation(), FD->getType(),

648

Args[Cnt]->getName(), ArgLVal)

652

assert(I->capturesThis());

654

LocalAddrs.insert({Args[Cnt], {

nullptr

, ArgLVal.

getAddress

()}});

668 "CapturedStmtInfo should be set when generating the captured function"

);

671 bool

NeedWrapperFunction =

674

llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs,

676

llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes,

679

llvm::raw_svector_ostream Out(Buffer);

683

llvm::Function *WrapperF =

nullptr

;

684 if

(NeedWrapperFunction) {

687

FunctionOptions WrapperFO(&S,

true

,

693

WrapperCGF.CXXThisValue, WrapperFO);

696

FunctionOptions FO(&S, !NeedWrapperFunction,

false

,

699

*

this

, WrapperArgs, WrapperLocalAddrs, WrapperVLASizes, CXXThisValue, FO);

700

CodeGenFunction::OMPPrivateScope LocalScope(*

this

);

701 for

(

const auto

&LocalAddrPair : WrapperLocalAddrs) {

702 if

(LocalAddrPair.second.first) {

703

LocalScope.addPrivate(LocalAddrPair.second.first,

704

LocalAddrPair.second.second);

707

(void)LocalScope.Privatize();

708 for

(

const auto

&VLASizePair : WrapperVLASizes)

709

VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;

712

(void)LocalScope.ForceCleanup();

714 if

(!NeedWrapperFunction)

718

WrapperF->removeFromParent();

719

F->getParent()->getFunctionList().insertAfter(F->getIterator(), WrapperF);

722 auto

*PI = F->arg_begin();

723 for

(

const auto

*Arg : Args) {

725 auto

I = LocalAddrs.find(Arg);

726 if

(I != LocalAddrs.end()) {

727 LValue

LV = WrapperCGF.MakeAddrLValue(

729

I->second.first ? I->second.first->getType() : Arg->getType(),

733 CallArg

= WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());

735 auto

EI = VLASizes.find(Arg);

736 if

(EI != VLASizes.end()) {

740

WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg),

742 CallArg

= WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());

745

CallArgs.emplace_back(WrapperCGF.EmitFromMemory(

CallArg

, Arg->

getType

()));

749

WrapperCGF.FinishFunction();

764

llvm::Value *NumElements =

emitArrayLength

(ArrayTy, ElementTy, DestAddr);

771

DestBegin, NumElements);

776

llvm::Value *IsEmpty =

777 Builder

.CreateICmpEQ(DestBegin, DestEnd,

"omp.arraycpy.isempty"

);

778 Builder

.CreateCondBr(IsEmpty, DoneBB, BodyBB);

781

llvm::BasicBlock *EntryBB =

Builder

.GetInsertBlock();

786

llvm::PHINode *SrcElementPHI =

787 Builder

.CreatePHI(SrcBegin->getType(), 2,

"omp.arraycpy.srcElementPast"

);

788

SrcElementPHI->addIncoming(SrcBegin, EntryBB);

793

llvm::PHINode *DestElementPHI =

Builder

.CreatePHI(

794

DestBegin->getType(), 2,

"omp.arraycpy.destElementPast"

);

795

DestElementPHI->addIncoming(DestBegin, EntryBB);

801

CopyGen(DestElementCurrent, SrcElementCurrent);

804

llvm::Value *DestElementNext =

806

1,

"omp.arraycpy.dest.element"

);

807

llvm::Value *SrcElementNext =

809

1,

"omp.arraycpy.src.element"

);

812 Builder

.CreateICmpEQ(DestElementNext, DestEnd,

"omp.arraycpy.done"

);

813 Builder

.CreateCondBr(Done, DoneBB, BodyBB);

814

DestElementPHI->addIncoming(DestElementNext,

Builder

.GetInsertBlock());

815

SrcElementPHI->addIncoming(SrcElementNext,

Builder

.GetInsertBlock());

825 const auto

*BO = dyn_cast<BinaryOperator>(

Copy

);

826 if

(BO && BO->getOpcode() == BO_Assign) {

835

DestAddr, SrcAddr, OriginalType,

840

CodeGenFunction::OMPPrivateScope Remap(*

this

);

841

Remap.addPrivate(DestVD, DestElement);

842

Remap.addPrivate(SrcVD, SrcElement);

843

(void)Remap.Privatize();

849

CodeGenFunction::OMPPrivateScope Remap(*

this

);

850

Remap.addPrivate(SrcVD, SrcAddr);

851

Remap.addPrivate(DestVD, DestAddr);

852

(void)Remap.Privatize();

859

OMPPrivateScope &PrivateScope) {

863 bool

DeviceConstTarget =

getLangOpts

().OpenMPIsTargetDevice &&

865 bool

FirstprivateIsLastprivate =

false

;

866

llvm::DenseMap<const VarDecl *, OpenMPLastprivateModifier> Lastprivates;

868 for

(

const auto

*

D

:

C

->varlist())

869

Lastprivates.try_emplace(

873

llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate;

878 bool

MustEmitFirstprivateCopy =

879

CaptureRegions.size() == 1 && CaptureRegions.back() == OMPD_unknown;

881 const auto

*IRef =

C

->varlist_begin();

882 const auto

*InitsRef =

C

->inits().begin();

883 for

(

const Expr

*IInit :

C

->private_copies()) {

884 const auto

*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());

885 bool

ThisFirstprivateIsLastprivate =

886

Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;

888 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());

889 if

(!MustEmitFirstprivateCopy && !ThisFirstprivateIsLastprivate && FD &&

891

(!VD || !VD->

hasAttr

<OMPAllocateDeclAttr>())) {

892

EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());

899 if

(DeviceConstTarget && OrigVD->getType().isConstant(

getContext

()) &&

901

(!VD || !VD->

hasAttr

<OMPAllocateDeclAttr>())) {

902

EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());

907

FirstprivateIsLastprivate =

908

FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;

909 if

(EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {

911

cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());

920 if

(CE && !CE.isReference()) {

926 if

(CE && CE.isReference()) {

927

OriginalLVal = CE.getReferenceLValue(*

this

, &DRE);

929

assert(!CE &&

"Expected non-constant firstprivate."

);

948

Emission.getAllocatedAddress(), OriginalLVal.

getAddress

(),

Type

,

952

RunCleanupsScope InitScope(*this);

954

setAddrOfLocalVar(VDInit, SrcElement);

955

EmitAnyExprToMem(Init, DestElement,

956

Init->getType().getQualifiers(),

958

LocalDeclMap.erase(VDInit);

963

PrivateScope.addPrivate(OrigVD, Emission.getAllocatedAddress());

969

setAddrOfLocalVar(VDInit, OriginalAddr);

971

LocalDeclMap.erase(VDInit);

973 if

(ThisFirstprivateIsLastprivate &&

974

Lastprivates[OrigVD->getCanonicalDecl()] ==

975

OMPC_LASTPRIVATE_conditional) {

980

(*IRef)->getExprLoc());

985

LocalDeclMap.erase(VD);

986

setAddrOfLocalVar(VD, VDAddr);

988

IsRegistered = PrivateScope.addPrivate(OrigVD, VDAddr);

990

assert(IsRegistered &&

991 "firstprivate var already registered as private"

);

999 return

FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();

1004

CodeGenFunction::OMPPrivateScope &PrivateScope) {

1007

llvm::DenseSet<const VarDecl *> EmittedAsPrivate;

1009 auto

IRef =

C

->varlist_begin();

1010 for

(

const Expr

*IInit :

C

->private_copies()) {

1011 const auto

*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());

1012 if

(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {

1013 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());

1018

assert(IsRegistered &&

"private var already registered as private"

);

1034

llvm::DenseSet<const VarDecl *> CopiedVars;

1035

llvm::BasicBlock *CopyBegin =

nullptr

, *CopyEnd =

nullptr

;

1037 auto

IRef =

C

->varlist_begin();

1038 auto

ISrcRef =

C

->source_exprs().begin();

1039 auto

IDestRef =

C

->destination_exprs().begin();

1040 for

(

const Expr

*AssignOp :

C

->assignment_ops()) {

1041 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());

1049 getContext

().getTargetInfo().isTLSSupported()) {

1051 "Copyin threadprivates should have been captured!"

);

1055

LocalDeclMap.erase(VD);

1065 if

(CopiedVars.size() == 1) {

1071 auto

*MasterAddrInt =

Builder

.CreatePtrToInt(

1073 auto

*PrivateAddrInt =

Builder

.CreatePtrToInt(

1076 Builder

.CreateICmpNE(MasterAddrInt, PrivateAddrInt), CopyBegin,

1081

cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());

1082 const auto

*DestVD =

1083

cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());

1084 EmitOMPCopy

(

Type

, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);

1103 bool

HasAtLeastOneLastprivate =

false

;

1105

llvm::DenseSet<const VarDecl *> SIMDLCVs;

1107 const auto

*LoopDirective = cast<OMPLoopDirective>(&

D

);

1108 for

(

const Expr

*

C

: LoopDirective->counters()) {

1113

llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;

1115

HasAtLeastOneLastprivate =

true

;

1118 const auto

*IRef =

C

->varlist_begin();

1119 const auto

*IDestRef =

C

->destination_exprs().begin();

1120 for

(

const Expr

*IInit :

C

->private_copies()) {

1123 const auto

*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());

1126 if

(AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {

1127 const auto

*DestVD =

1128

cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());

1133

PrivateScope.addPrivate(DestVD,

EmitLValue

(&DRE).getAddress());

1137 if

(IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {

1138 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());

1140 if

(

C

->getKind() == OMPC_LASTPRIVATE_conditional) {

1143

setAddrOfLocalVar(VD, VDAddr);

1149 bool

IsRegistered = PrivateScope.addPrivate(OrigVD, VDAddr);

1150

assert(IsRegistered &&

1151 "lastprivate var already registered as private"

);

1159 return

HasAtLeastOneLastprivate;

1164

llvm::Value *IsLastIterCond) {

1173

llvm::BasicBlock *ThenBB =

nullptr

;

1174

llvm::BasicBlock *DoneBB =

nullptr

;

1175 if

(IsLastIterCond) {

1181

return C->getKind() == OMPC_LASTPRIVATE_conditional;

1190 Builder

.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);

1193

llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;

1194

llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;

1195 if

(

const auto

*LoopDirective = dyn_cast<OMPLoopDirective>(&

D

)) {

1196 auto

IC = LoopDirective->counters().begin();

1197 for

(

const Expr

*F : LoopDirective->finals()) {

1201

AlreadyEmittedVars.insert(

D

);

1203

LoopCountersAndUpdates[

D

] = F;

1208 auto

IRef =

C

->varlist_begin();

1209 auto

ISrcRef =

C

->source_exprs().begin();

1210 auto

IDestRef =

C

->destination_exprs().begin();

1211 for

(

const Expr

*AssignOp :

C

->assignment_ops()) {

1212 const auto

*PrivateVD =

1213

cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());

1215 const auto

*CanonicalVD = PrivateVD->getCanonicalDecl();

1216 if

(AlreadyEmittedVars.insert(CanonicalVD).second) {

1220 if

(

const Expr

*FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))

1223

cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());

1224 const auto

*DestVD =

1225

cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());

1228 if

(

const auto

*RefTy = PrivateVD->getType()->getAs<

ReferenceType

>())

1234 if

(

C

->getKind() == OMPC_LASTPRIVATE_conditional)

1236

*

this

,

MakeAddrLValue

(PrivateAddr, (*IRef)->getType()), PrivateVD,

1237

(*IRef)->getExprLoc());

1240 EmitOMPCopy

(

Type

, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);

1246 if

(

const Expr

*PostUpdate =

C

->getPostUpdateExpr())

1255

CodeGenFunction::OMPPrivateScope &PrivateScope,

bool

ForInscan) {

1267 if

(ForInscan != (

C

->getModifier() == OMPC_REDUCTION_inscan))

1269

Shareds.append(

C

->varlist_begin(),

C

->varlist_end());

1270

Privates.append(

C

->privates().begin(),

C

->privates().end());

1271

ReductionOps.append(

C

->reduction_ops().begin(),

C

->reduction_ops().end());

1272

LHSs.append(

C

->lhs_exprs().begin(),

C

->lhs_exprs().end());

1273

RHSs.append(

C

->rhs_exprs().begin(),

C

->rhs_exprs().end());

1274 if

(

C

->getModifier() == OMPC_REDUCTION_task) {

1275 Data

.ReductionVars.append(

C

->privates().begin(),

C

->privates().end());

1276 Data

.ReductionOrigs.append(

C

->varlist_begin(),

C

->varlist_end());

1277 Data

.ReductionCopies.append(

C

->privates().begin(),

C

->privates().end());

1278 Data

.ReductionOps.append(

C

->reduction_ops().begin(),

1279 C

->reduction_ops().end());

1280

TaskLHSs.append(

C

->lhs_exprs().begin(),

C

->lhs_exprs().end());

1281

TaskRHSs.append(

C

->rhs_exprs().begin(),

C

->rhs_exprs().end());

1286 auto

*ILHS = LHSs.begin();

1287 auto

*IRHS = RHSs.begin();

1288 auto

*IPriv = Privates.begin();

1289 for

(

const Expr

*IRef : Shareds) {

1290 const auto

*PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());

1292

RedCG.emitSharedOrigLValue(*

this

, Count);

1293

RedCG.emitAggregateType(*

this

, Count);

1295

RedCG.emitInitialization(*

this

, Count, Emission.getAllocatedAddress(),

1296

RedCG.getSharedLValue(Count).getAddress(),

1298

CGF.EmitAutoVarInit(Emission);

1302 Address

BaseAddr = RedCG.adjustPrivateAddress(

1303

*

this

, Count, Emission.getAllocatedAddress());

1305

PrivateScope.addPrivate(RedCG.getBaseDecl(Count), BaseAddr);

1306

assert(IsRegistered &&

"private var already registered as private"

);

1310 const auto

*LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());

1311 const auto

*RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());

1313 bool

isaOMPArraySectionExpr = isa<ArraySectionExpr>(IRef);

1317

PrivateScope.addPrivate(LHSVD, RedCG.getSharedLValue(Count).getAddress());

1320

isa<ArraySubscriptExpr>(IRef)) {

1323

PrivateScope.addPrivate(LHSVD, RedCG.getSharedLValue(Count).getAddress());

1324

PrivateScope.addPrivate(RHSVD,

1330 Address

OriginalAddr = RedCG.getSharedLValue(Count).getAddress();

1337

PrivateScope.addPrivate(LHSVD, OriginalAddr);

1338

PrivateScope.addPrivate(

1348 if

(!

Data

.ReductionVars.empty()) {

1350 Data

.IsReductionWithTaskMod =

true

;

1354 const Expr

*TaskRedRef =

nullptr

;

1357

TaskRedRef = cast<OMPParallelDirective>(

D

).getTaskReductionRefExpr();

1360

TaskRedRef = cast<OMPForDirective>(

D

).getTaskReductionRefExpr();

1363

TaskRedRef = cast<OMPSectionsDirective>(

D

).getTaskReductionRefExpr();

1365 case

OMPD_parallel_for:

1366

TaskRedRef = cast<OMPParallelForDirective>(

D

).getTaskReductionRefExpr();

1368 case

OMPD_parallel_master:

1370

cast<OMPParallelMasterDirective>(

D

).getTaskReductionRefExpr();

1372 case

OMPD_parallel_sections:

1374

cast<OMPParallelSectionsDirective>(

D

).getTaskReductionRefExpr();

1376 case

OMPD_target_parallel:

1378

cast<OMPTargetParallelDirective>(

D

).getTaskReductionRefExpr();

1380 case

OMPD_target_parallel_for:

1382

cast<OMPTargetParallelForDirective>(

D

).getTaskReductionRefExpr();

1384 case

OMPD_distribute_parallel_for:

1386

cast<OMPDistributeParallelForDirective>(

D

).getTaskReductionRefExpr();

1388 case

OMPD_teams_distribute_parallel_for:

1389

TaskRedRef = cast<OMPTeamsDistributeParallelForDirective>(

D

)

1390

.getTaskReductionRefExpr();

1392 case

OMPD_target_teams_distribute_parallel_for:

1393

TaskRedRef = cast<OMPTargetTeamsDistributeParallelForDirective>(

D

)

1394

.getTaskReductionRefExpr();

1402 case

OMPD_parallel_for_simd:

1404 case

OMPD_taskyield:

1408 case

OMPD_taskgroup:

1416 case

OMPD_cancellation_point:

1418 case

OMPD_target_data:

1419 case

OMPD_target_enter_data:

1420 case

OMPD_target_exit_data:

1422 case

OMPD_taskloop_simd:

1423 case

OMPD_master_taskloop:

1424 case

OMPD_master_taskloop_simd:

1425 case

OMPD_parallel_master_taskloop:

1426 case

OMPD_parallel_master_taskloop_simd:

1427 case

OMPD_distribute:

1428 case

OMPD_target_update:

1429 case

OMPD_distribute_parallel_for_simd:

1430 case

OMPD_distribute_simd:

1431 case

OMPD_target_parallel_for_simd:

1432 case

OMPD_target_simd:

1433 case

OMPD_teams_distribute:

1434 case

OMPD_teams_distribute_simd:

1435 case

OMPD_teams_distribute_parallel_for_simd:

1436 case

OMPD_target_teams:

1437 case

OMPD_target_teams_distribute:

1438 case

OMPD_target_teams_distribute_parallel_for_simd:

1439 case

OMPD_target_teams_distribute_simd:

1440 case

OMPD_declare_target:

1441 case

OMPD_end_declare_target:

1442 case

OMPD_threadprivate:

1444 case

OMPD_declare_reduction:

1445 case

OMPD_declare_mapper:

1446 case

OMPD_declare_simd:

1448 case

OMPD_declare_variant:

1449 case

OMPD_begin_declare_variant:

1450 case

OMPD_end_declare_variant:

1453

llvm_unreachable(

"Unexpected directive with task reductions."

);

1456 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(TaskRedRef)->getDecl());

1459 false

, TaskRedRef->

getType

());

1471 bool

HasAtLeastOneReduction =

false

;

1472 bool

IsReductionWithTaskMod =

false

;

1475 if

(

C

->getModifier() == OMPC_REDUCTION_inscan)

1477

HasAtLeastOneReduction =

true

;

1478

Privates.append(

C

->privates().begin(),

C

->privates().end());

1479

LHSExprs.append(

C

->lhs_exprs().begin(),

C

->lhs_exprs().end());

1480

RHSExprs.append(

C

->rhs_exprs().begin(),

C

->rhs_exprs().end());

1481

ReductionOps.append(

C

->reduction_ops().begin(),

C

->reduction_ops().end());

1482

IsReductionWithTaskMod =

1483

IsReductionWithTaskMod ||

C

->getModifier() == OMPC_REDUCTION_task;

1485 if

(HasAtLeastOneReduction) {

1487 if

(IsReductionWithTaskMod) {

1491 bool

TeamsLoopCanBeParallel =

false

;

1492 if

(

auto

*TTLD = dyn_cast<OMPTargetTeamsGenericLoopDirective>(&

D

))

1493

TeamsLoopCanBeParallel = TTLD->canBeParallelFor();

1496

TeamsLoopCanBeParallel || ReductionKind == OMPD_simd;

1497 bool

SimpleReduction = ReductionKind == OMPD_simd;

1501

*

this

,

D

.

getEndLoc

(), Privates, LHSExprs, RHSExprs, ReductionOps,

1502

{WithNowait, SimpleReduction, ReductionKind});

1508 const

llvm::function_ref<llvm::Value *(

CodeGenFunction

&)> CondGen) {

1511

llvm::BasicBlock *DoneBB =

nullptr

;

1513 if

(

const Expr

*PostUpdate =

C

->getPostUpdateExpr()) {

1515 if

(llvm::Value *Cond = CondGen(CGF)) {

1520

CGF.

Builder

.CreateCondBr(Cond, ThenBB, DoneBB);

1538

CodeGenBoundParametersTy;

1546

llvm::DenseSet<CanonicalDeclPtr<const VarDecl>> PrivateDecls;

1548 for

(

const Expr

*Ref :

C

->varlist()) {

1549 if

(!Ref->getType()->isScalarType())

1551 const auto

*DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());

1554

PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));

1559 for

(

const Expr

*Ref :

C

->varlist()) {

1560 if

(!Ref->getType()->isScalarType())

1562 const auto

*DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());

1565

PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));

1570 for

(

const Expr

*Ref :

C

->varlist()) {

1571 if

(!Ref->getType()->isScalarType())

1573 const auto

*DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());

1576

PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));

1585 for

(

const Expr

*Ref :

C

->varlist()) {

1586 if

(!Ref->getType()->isScalarType())

1588 const auto

*DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());

1591

PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));

1595

CGF, S, PrivateDecls);

1601 const

CodeGenBoundParametersTy &CodeGenBoundParameters) {

1602 const CapturedStmt

*CS = S.getCapturedStmt(OMPD_parallel);

1603

llvm::Value *NumThreads =

nullptr

;

1604

llvm::Function *OutlinedFn =

1609

CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);

1610

NumThreads = CGF.

EmitScalarExpr

(NumThreadsClause->getNumThreads(),

1613

CGF, NumThreads, NumThreadsClause->getBeginLoc());

1616

CodeGenFunction::RunCleanupsScope ProcBindScope(CGF);

1618

CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getBeginLoc());

1620 const Expr

*IfCond =

nullptr

;

1621 for

(

const auto

*

C

: S.getClausesOfKind<

OMPIfClause

>()) {

1622 if

(

C

->getNameModifier() == OMPD_unknown ||

1623 C

->getNameModifier() == OMPD_parallel) {

1624

IfCond =

C

->getCondition();

1629

OMPParallelScope

Scope

(CGF, S);

1635

CodeGenBoundParameters(CGF, S, CapturedVars);

1638

CapturedVars, IfCond, NumThreads);

1643 if

(!CVD->

hasAttr

<OMPAllocateDeclAttr>())

1645 const auto

*AA = CVD->

getAttr

<OMPAllocateDeclAttr>();

1647 return

!((AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc ||

1648

AA->getAllocatorType() == OMPAllocateDeclAttr::OMPNullMemAlloc) &&

1649

!AA->getAllocator());

1664

CGF, S.getBeginLoc(), OMPD_unknown,

false

,

1684

Size = CGF.

Builder

.CreateNUWAdd(

1693 const auto

*AA = CVD->

getAttr

<OMPAllocateDeclAttr>();

1694

assert(AA->getAllocator() &&

1695 "Expected allocator expression for non-default allocator."

);

1696

llvm::Value *Allocator = CGF.

EmitScalarExpr

(AA->getAllocator());

1699 if

(Allocator->getType()->isIntegerTy())

1701 else if

(Allocator->getType()->isPointerTy())

1705

llvm::Value *Addr = OMPBuilder.createOMPAlloc(

1706

CGF.

Builder

, Size, Allocator,

1708

llvm::CallInst *FreeCI =

1709

OMPBuilder.createOMPFree(CGF.

Builder

, Addr, Allocator);

1730

llvm::Value *

Data

=

1733

std::string Suffix = getNameWithSeparators({

"cache"

,

""

});

1736

llvm::CallInst *ThreadPrivateCacheCall =

1737

OMPBuilder.createCachedThreadPrivate(CGF.

Builder

,

Data

, Size, CacheName);

1745

llvm::raw_svector_ostream OS(Buffer);

1746

StringRef Sep = FirstSeparator;

1747 for

(StringRef Part : Parts) {

1751 return

OS.str().str();

1758 Builder

.restoreIP(CodeGenIP);

1759

llvm::BasicBlock *FiniBB = splitBBWithSuffix(

Builder

,

false

,

1760 "."

+ RegionName +

".after"

);

1767 if

(

Builder

.saveIP().isSet())

1775 Builder

.restoreIP(CodeGenIP);

1776

llvm::BasicBlock *FiniBB = splitBBWithSuffix(

Builder

,

false

,

1777 "."

+ RegionName +

".after"

);

1784 if

(

Builder

.saveIP().isSet())

1792

llvm::Value *IfCond =

nullptr

;

1793 if

(

const auto

*

C

= S.getSingleClause<

OMPIfClause

>())

1797

llvm::Value *NumThreads =

nullptr

;

1802

ProcBindKind ProcBind = OMP_PROC_BIND_default;

1804

ProcBind = ProcBindClause->getProcBindKind();

1806 using

InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;

1810 auto

FiniCB = [

this

](InsertPointTy IP) {

1812 return

llvm::Error::success();

1819 auto

PrivCB = [](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,

1820

llvm::Value &, llvm::Value &Val, llvm::Value *&ReplVal) {

1828 const CapturedStmt

*CS = S.getCapturedStmt(OMPD_parallel);

1831 auto

BodyGenCB = [&,

this

](InsertPointTy AllocaIP,

1832

InsertPointTy CodeGenIP) {

1834

*

this

, ParallelRegionBodyStmt, AllocaIP, CodeGenIP,

"parallel"

);

1835 return

llvm::Error::success();

1838

CGCapturedStmtInfo CGSI(*CS,

CR_OpenMP

);

1839

CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*

this

, &CGSI);

1840

llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(

1842

llvm::OpenMPIRBuilder::InsertPointTy AfterIP = cantFail(

1843

OMPBuilder.createParallel(

Builder

, AllocaIP, BodyGenCB, PrivCB, FiniCB,

1844

IfCond, NumThreads, ProcBind, S.hasCancel()));

1852

OMPPrivateScope PrivateScope(CGF);

1857

(void)PrivateScope.Privatize();

1858

CGF.

EmitStmt

(S.getCapturedStmt(OMPD_parallel)->getCapturedStmt());

1879class

OMPTransformDirectiveScopeRAII {

1880

OMPLoopScope *

Scope

=

nullptr

;

1881

CodeGenFunction::CGCapturedStmtInfo *CGSI =

nullptr

;

1882

CodeGenFunction::CGCapturedStmtRAII *CapInfoRAII =

nullptr

;

1884

OMPTransformDirectiveScopeRAII(

const

OMPTransformDirectiveScopeRAII &) =

1886

OMPTransformDirectiveScopeRAII &

1887

operator=(

const

OMPTransformDirectiveScopeRAII &) =

delete

;

1891 if

(

const auto

*Dir = dyn_cast<OMPLoopBasedDirective>(S)) {

1892 Scope

=

new

OMPLoopScope(CGF, *Dir);

1893

CGSI =

new

CodeGenFunction::CGCapturedStmtInfo(

CR_OpenMP

);

1894

CapInfoRAII =

new

CodeGenFunction::CGCapturedStmtRAII(CGF, CGSI);

1897

~OMPTransformDirectiveScopeRAII() {

1908 int

MaxLevel,

int

Level = 0) {

1909

assert(Level < MaxLevel &&

"Too deep lookup during loop body codegen."

);

1910 const Stmt

*SimplifiedS = S->IgnoreContainers();

1911 if

(

const auto

*CS = dyn_cast<CompoundStmt>(SimplifiedS)) {

1914 "LLVM IR generation of compound statement ('{}')"

);

1917

CodeGenFunction::LexicalScope

Scope

(CGF, S->getSourceRange());

1918 for

(

const Stmt

*CurStmt : CS->body())

1919 emitBody

(CGF, CurStmt, NextLoop, MaxLevel, Level);

1922 if

(SimplifiedS == NextLoop) {

1923 if

(

auto

*Dir = dyn_cast<OMPLoopTransformationDirective>(SimplifiedS))

1924

SimplifiedS = Dir->getTransformedStmt();

1925 if

(

const auto

*CanonLoop = dyn_cast<OMPCanonicalLoop>(SimplifiedS))

1926

SimplifiedS = CanonLoop->getLoopStmt();

1927 if

(

const auto

*For = dyn_cast<ForStmt>(SimplifiedS)) {

1930

assert(isa<CXXForRangeStmt>(SimplifiedS) &&

1931 "Expected canonical for loop or range-based for loop."

);

1932 const auto

*CXXFor = cast<CXXForRangeStmt>(SimplifiedS);

1933

CGF.

EmitStmt

(CXXFor->getLoopVarStmt());

1934

S = CXXFor->getBody();

1936 if

(Level + 1 < MaxLevel) {

1939 emitBody

(CGF, S, NextLoop, MaxLevel, Level + 1);

1948

RunCleanupsScope BodyScope(*

this

);

1950 for

(

const Expr

*UE :

D

.updates())

1958 for

(

const Expr

*UE :

C

->updates())

1965

BreakContinueStack.push_back(BreakContinue(

LoopExit

, Continue));

1966 for

(

const Expr

*

E

:

D

.finals_conditions()) {

1977

OMPPrivateScope InscanScope(*

this

);

1979 bool

IsInscanRegion = InscanScope.Privatize();

1980 if

(IsInscanRegion) {

1990 if

(EKind != OMPD_simd && !

getLangOpts

().OpenMPSimd)

1999 D

.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();

2004 D

.getLoopsNumber());

2012

BreakContinueStack.pop_back();

2023

std::unique_ptr<CodeGenFunction::CGCapturedStmtInfo> CSI =

2024

std::make_unique<CodeGenFunction::CGCapturedStmtInfo>(*S);

2025

CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, CSI.get());

2032static

llvm::CallInst *

2037

EffectiveArgs.reserve(Args.size() + 1);

2038

llvm::append_range(EffectiveArgs, Args);

2039

EffectiveArgs.push_back(Cap.second);

2044

llvm::CanonicalLoopInfo *

2046

assert(Depth == 1 &&

"Nested loops with OpenMPIRBuilder not yet implemented"

);

2058

assert(

OMPLoopNestStack

.size() >= (

size_t

)Depth &&

"Found too few loops"

);

2072 const Stmt

*SyntacticalLoop = S->getLoopStmt();

2079

LexicalScope ForScope(*

this

, S->getSourceRange());

2083 const Stmt

*BodyStmt;

2084 if

(

const auto

*For = dyn_cast<ForStmt>(SyntacticalLoop)) {

2085 if

(

const Stmt

*InitStmt = For->getInit())

2087

BodyStmt = For->getBody();

2088

}

else if

(

const auto

*RangeFor =

2089

dyn_cast<CXXForRangeStmt>(SyntacticalLoop)) {

2090 if

(

const DeclStmt

*RangeStmt = RangeFor->getRangeStmt())

2092 if

(

const DeclStmt

*BeginStmt = RangeFor->getBeginStmt())

2094 if

(

const DeclStmt

*EndStmt = RangeFor->getEndStmt())

2096 if

(

const DeclStmt

*LoopVarStmt = RangeFor->getLoopVarStmt())

2098

BodyStmt = RangeFor->getBody();

2100

llvm_unreachable(

"Expected for-stmt or range-based for-stmt"

);

2103 const CapturedStmt

*DistanceFunc = S->getDistanceFunc();

2120 auto

BodyGen = [&,

this

](llvm::OpenMPIRBuilder::InsertPointTy CodeGenIP,

2121

llvm::Value *IndVar) {

2122 Builder

.restoreIP(CodeGenIP);

2126 const DeclRefExpr

*LoopVarRef = S->getLoopVarRef();

2132

RunCleanupsScope BodyScope(*

this

);

2134 return

llvm::Error::success();

2137

llvm::CanonicalLoopInfo *CL =

2138

cantFail(OMPBuilder.createCanonicalLoop(

Builder

, BodyGen, DistVal));

2141 Builder

.restoreIP(CL->getAfterIP());

2142

ForScope.ForceCleanup();

2150 const Expr

*IncExpr,

2161 const auto

&OMPED = cast<OMPExecutableDirective>(S);

2162 const CapturedStmt

*ICS = OMPED.getInnermostCapturedStmt();

2176

llvm::BasicBlock *ExitBlock =

LoopExit

.getBlock();

2177 if

(RequiresCleanup)

2184 if

(ExitBlock !=

LoopExit

.getBlock()) {

2194

BreakContinueStack.push_back(BreakContinue(

LoopExit

, Continue));

2201

PostIncGen(*

this

);

2202

BreakContinueStack.pop_back();

2213 bool

HasLinears =

false

;

2215 for

(

const Expr

*

Init

:

C

->inits()) {

2217 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

Init

)->getDecl());

2218 if

(

const auto

*Ref =

2221 const auto

*OrigVD = cast<VarDecl>(Ref->getDecl());

2237 if

(

const auto

*CS = cast_or_null<BinaryOperator>(

C

->getCalcStep()))

2238 if

(

const auto

*SaveRef = cast<DeclRefExpr>(CS->getLHS())) {

2249 const

llvm::function_ref<llvm::Value *(

CodeGenFunction

&)> CondGen) {

2252

llvm::BasicBlock *DoneBB =

nullptr

;

2255 auto

IC =

C

->varlist_begin();

2256 for

(

const Expr

*F :

C

->finals()) {

2258 if

(llvm::Value *Cond = CondGen(*

this

)) {

2263 Builder

.CreateCondBr(Cond, ThenBB, DoneBB);

2267 const auto

*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());

2272

CodeGenFunction::OMPPrivateScope VarScope(*

this

);

2273

VarScope.addPrivate(OrigVD, OrigAddr);

2274

(void)VarScope.Privatize();

2278 if

(

const Expr

*PostUpdate =

C

->getPostUpdateExpr())

2290

llvm::APInt ClauseAlignment(64, 0);

2291 if

(

const Expr

*AlignmentExpr = Clause->getAlignment()) {

2294

ClauseAlignment = AlignmentCI->getValue();

2296 for

(

const Expr

*

E

: Clause->varlist()) {

2297

llvm::APInt Alignment(ClauseAlignment);

2298 if

(Alignment == 0) {

2308

assert((Alignment == 0 || Alignment.isPowerOf2()) &&

2309 "alignment is not power of 2"

);

2310 if

(Alignment != 0) {

2324 auto

I = S.private_counters().begin();

2325 for

(

const Expr

*

E

: S.counters()) {

2326 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

2327 const auto

*PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());

2331

LocalDeclMap.erase(PrivateVD);

2332

(void)LoopScope.addPrivate(VD, VarEmission.getAllocatedAddress());

2340

(void)LoopScope.addPrivate(PrivateVD, VarEmission.getAllocatedAddress());

2346 if

(!

C

->getNumForLoops())

2348 for

(

unsigned

I = S.getLoopsNumber(),

E

=

C

->getLoopNumIterations().size();

2350 const auto

*DRE = cast<DeclRefExpr>(

C

->getLoopCounter(I));

2351 const auto

*VD = cast<VarDecl>(DRE->getDecl());

2354 if

(DRE->refersToEnclosingVariableOrCapture()) {

2355

(void)LoopScope.addPrivate(

2363 const Expr

*Cond, llvm::BasicBlock *TrueBlock,

2364

llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {

2368

CodeGenFunction::OMPPrivateScope PreCondScope(CGF);

2370

(void)PreCondScope.Privatize();

2372 for

(

const Expr

*I : S.inits()) {

2378

CodeGenFunction::OMPMapVars PreCondVars;

2379 for

(

const Expr

*

E

: S.dependent_counters()) {

2383 "dependent counter must not be an iterator."

);

2384 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

2387

(void)PreCondVars.setVarAddr(CGF, VD, CounterAddr);

2389

(void)PreCondVars.apply(CGF);

2390 for

(

const Expr

*

E

: S.dependent_inits()) {

2397

PreCondVars.restore(CGF);

2404

llvm::DenseSet<const VarDecl *> SIMDLCVs;

2407 const auto

*LoopDirective = cast<OMPLoopDirective>(&

D

);

2408 for

(

const Expr

*

C

: LoopDirective->counters()) {

2414 auto

CurPrivate =

C

->privates().begin();

2415 for

(

const Expr

*

E

:

C

->varlist()) {

2416 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

2417 const auto

*PrivateVD =

2418

cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());

2424

assert(IsRegistered &&

"linear var already registered as private"

);

2442 auto

*Val = cast<llvm::ConstantInt>(Len.

getScalarVal

());

2451 auto

*Val = cast<llvm::ConstantInt>(Len.

getScalarVal

());

2466 if

(

C

->getKind() == OMPC_ORDER_concurrent)

2469 if

((EKind == OMPD_simd ||

2473

return C->getModifier() == OMPC_REDUCTION_inscan;

2481 const

llvm::function_ref<llvm::Value *(

CodeGenFunction

&)> CondGen) {

2484

llvm::BasicBlock *DoneBB =

nullptr

;

2485 auto

IC =

D

.counters().begin();

2486 auto

IPC =

D

.private_counters().begin();

2487 for

(

const Expr

*F :

D

.finals()) {

2488 const auto

*OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());

2489 const auto

*PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());

2490 const auto

*CED = dyn_cast<OMPCapturedExprDecl>(OrigVD);

2492

OrigVD->hasGlobalStorage() || CED) {

2494 if

(llvm::Value *Cond = CondGen(*

this

)) {

2499 Builder

.CreateCondBr(Cond, ThenBB, DoneBB);

2512

OMPPrivateScope VarScope(*

this

);

2513

VarScope.addPrivate(OrigVD, OrigAddr);

2514

(void)VarScope.Privatize();

2526

CodeGenFunction::JumpDest

LoopExit

) {

2534 auto

VDecl = cast<VarDecl>(Helper->

getDecl

());

2542 auto

&&ThenGen = [&S, &SimdInitGen, &BodyCodeGen](

CodeGenFunction

&CGF,

2545

CodeGenFunction::OMPLocalDeclMapRAII

Scope

(CGF);

2551

CodeGenFunction::OMPLocalDeclMapRAII

Scope

(CGF);

2556 const Expr

*IfCond =

nullptr

;

2559 for

(

const auto

*

C

: S.getClausesOfKind<

OMPIfClause

>()) {

2561

(

C

->getNameModifier() == OMPD_unknown ||

2562 C

->getNameModifier() == OMPD_simd)) {

2563

IfCond =

C

->getCondition();

2578

Action.

Enter

(CGF);

2579

OMPLoopScope PreInitScope(CGF, S);

2592

(void)

EmitOMPHelperVar

(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()));

2593

(void)

EmitOMPHelperVar

(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()));

2601

llvm::BasicBlock *ContBlock =

nullptr

;

2608 emitPreCond

(CGF, S, S.getPreCond(), ThenBlock, ContBlock,

2615 const Expr

*IVExpr = S.getIterationVariable();

2616 const auto

*IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());

2623 if

(

const auto

*LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {

2624

CGF.

EmitVarDecl

(*cast<VarDecl>(LIExpr->getDecl()));

2632

CodeGenFunction::OMPPrivateScope LoopScope(CGF);

2638

CGF, S, CGF.

EmitLValue

(S.getIterationVariable()));

2640

(void)LoopScope.Privatize();

2651

S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),

2653

emitOMPLoopBodyWithStopPoint(CGF, S,

2654

CodeGenFunction::JumpDest());

2660 if

(HasLastprivateClause)

2665

LoopScope.restoreMap();

2681 if

(!(isa<OMPSimdlenClause>(

C

) || isa<OMPSafelenClause>(

C

) ||

2682

isa<OMPOrderClause>(

C

) || isa<OMPAlignedClause>(

C

)))

2689 if

(

const auto

*CanonLoop = dyn_cast<OMPCanonicalLoop>(S.getRawStmt())) {

2690 if

(

const Stmt

*SyntacticalLoop = CanonLoop->getLoopStmt()) {

2691 for

(

const Stmt

*SubStmt : SyntacticalLoop->

children

()) {

2694 if

(

const CompoundStmt

*CS = dyn_cast<CompoundStmt>(SubStmt)) {

2698 if

(isa<OMPOrderedDirective>(CSSubStmt)) {

2709static

llvm::MapVector<llvm::Value *, llvm::Value *>

2711

llvm::MapVector<llvm::Value *, llvm::Value *> AlignedVars;

2713

llvm::APInt ClauseAlignment(64, 0);

2714 if

(

const Expr

*AlignmentExpr = Clause->getAlignment()) {

2717

ClauseAlignment = AlignmentCI->getValue();

2719 for

(

const Expr

*

E

: Clause->varlist()) {

2720

llvm::APInt Alignment(ClauseAlignment);

2721 if

(Alignment == 0) {

2731

assert((Alignment == 0 || Alignment.isPowerOf2()) &&

2732 "alignment is not power of 2"

);

2734

AlignedVars[PtrValue] = CGF.

Builder

.getInt64(Alignment.getSExtValue());

2744 bool

UseOMPIRBuilder =

2746 if

(UseOMPIRBuilder) {

2750 if

(UseOMPIRBuilder) {

2751

llvm::MapVector<llvm::Value *, llvm::Value *> AlignedVars =

2754 const Stmt

*Inner = S.getRawStmt();

2755

llvm::CanonicalLoopInfo *CLI =

2756

CGF.EmitOMPCollapsedCanonicalLoopNest(Inner, 1);

2758

llvm::OpenMPIRBuilder &OMPBuilder =

2761

llvm::ConstantInt *Simdlen =

nullptr

;

2765 auto

*Val = cast<llvm::ConstantInt>(Len.

getScalarVal

());

2768

llvm::ConstantInt *Safelen =

nullptr

;

2772 auto

*Val = cast<llvm::ConstantInt>(Len.

getScalarVal

());

2775

llvm::omp::OrderKind Order = llvm::omp::OrderKind::OMP_ORDER_unknown;

2777 if

(

C

->getKind() == OpenMPOrderClauseKind::OMPC_ORDER_concurrent) {

2778

Order = llvm::omp::OrderKind::OMP_ORDER_concurrent;

2783

OMPBuilder.applySimd(CLI, AlignedVars,

2784 nullptr

, Order, Simdlen, Safelen);

2791

OMPLexicalScope

Scope

(CGF, S, OMPD_unknown);

2798

CodeGenFunction::ParentLoopDirectiveForScanRegion ScanRegion(CGF, S);

2806

OMPLexicalScope

Scope

(CGF, S, OMPD_unknown);

2819

OMPTransformDirectiveScopeRAII TileScope(*

this

, &S);

2825

OMPTransformDirectiveScopeRAII ReverseScope(*

this

, &S);

2832

OMPTransformDirectiveScopeRAII InterchangeScope(*

this

, &S);

2839 if

(UseOMPIRBuilder) {

2841 const Stmt

*Inner = S.getRawStmt();

2852

llvm::CanonicalLoopInfo *UnrolledCLI =

nullptr

;

2856

OMPBuilder.unrollLoopFull(DL, CLI);

2857

}

else if

(

auto

*PartialClause = S.getSingleClause<

OMPPartialClause

>()) {

2859 if

(

Expr

*FactorExpr = PartialClause->getFactor()) {

2860

Factor = FactorExpr->EvaluateKnownConstInt(

getContext

()).getZExtValue();

2861

assert(Factor >= 1 &&

"Only positive factors are valid"

);

2863

OMPBuilder.unrollLoopPartial(DL, CLI, Factor,

2864

NeedsUnrolledCLI ? &UnrolledCLI :

nullptr

);

2866

OMPBuilder.unrollLoopHeuristic(DL, CLI);

2869

assert((!NeedsUnrolledCLI || UnrolledCLI) &&

2870 "NeedsUnrolledCLI implies UnrolledCLI to be set"

);

2886

}

else if

(

auto

*PartialClause = S.getSingleClause<

OMPPartialClause

>()) {

2887 if

(

Expr

*FactorExpr = PartialClause->getFactor()) {

2889

FactorExpr->EvaluateKnownConstInt(

getContext

()).getZExtValue();

2890

assert(Factor >= 1 &&

"Only positive factors are valid"

);

2898void

CodeGenFunction::EmitOMPOuterLoop(

2900

CodeGenFunction::OMPPrivateScope &LoopScope,

2901 const

CodeGenFunction::OMPLoopArguments &LoopArgs,

2906 const Expr

*IVExpr = S.getIterationVariable();

2920

llvm::Value *BoolCondVal =

nullptr

;

2921 if

(!DynamicOrOrdered) {

2932

RT.

emitForNext

(*

this

, S.getBeginLoc(), IVSize, IVSigned, LoopArgs.IL,

2933

LoopArgs.LB, LoopArgs.UB, LoopArgs.ST);

2938

llvm::BasicBlock *ExitBlock =

LoopExit

.getBlock();

2939 if

(LoopScope.requiresCleanups())

2943 Builder

.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);

2944 if

(ExitBlock !=

LoopExit

.getBlock()) {

2952 if

(DynamicOrOrdered)

2957

BreakContinueStack.push_back(BreakContinue(

LoopExit

, Continue));

2968 if

(

C

->getKind() == OMPC_ORDER_concurrent)

2974

[&S, &LoopArgs,

LoopExit

, &CodeGenLoop, IVSize, IVSigned, &CodeGenOrdered,

2982

CGF.EmitOMPInnerLoop(

2983

S, LoopScope.requiresCleanups(), LoopArgs.Cond, LoopArgs.IncExpr,

2985

CodeGenLoop(CGF, S, LoopExit);

2988

CodeGenOrdered(CGF, Loc, IVSize, IVSigned);

2993

BreakContinueStack.pop_back();

2994 if

(!DynamicOrOrdered) {

3007 auto

&&CodeGen = [DynamicOrOrdered, &S, &LoopArgs](

CodeGenFunction

&CGF) {

3008 if

(!DynamicOrOrdered)

3009

CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),

3012

OMPCancelStack.emitExit(*

this

, EKind, CodeGen);

3015void

CodeGenFunction::EmitOMPForOuterLoop(

3018 const

OMPLoopArguments &LoopArgs,

3023 const bool

DynamicOrOrdered = Ordered || RT.

isDynamic

(ScheduleKind.

Schedule

);

3026

LoopArgs.Chunk !=

nullptr

)) &&

3027 "static non-chunked schedule does not need outer loop"

);

3081 const Expr

*IVExpr = S.getIterationVariable();

3085 if

(DynamicOrOrdered) {

3086 const

std::pair<llvm::Value *, llvm::Value *> DispatchBounds =

3087

CGDispatchBounds(*

this

, S, LoopArgs.LB, LoopArgs.UB);

3088

llvm::Value *LBVal = DispatchBounds.first;

3089

llvm::Value *UBVal = DispatchBounds.second;

3093

IVSigned, Ordered, DipatchRTInputValues);

3096

IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB,

3097

LoopArgs.ST, LoopArgs.Chunk);

3104 const unsigned

IVSize,

3105 const bool

IVSigned) {

3112

OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,

3113

LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB);

3114

OuterLoopArgs.IncExpr = S.getInc();

3115

OuterLoopArgs.Init = S.getInit();

3116

OuterLoopArgs.Cond = S.getCond();

3117

OuterLoopArgs.NextLB = S.getNextLowerBound();

3118

OuterLoopArgs.NextUB = S.getNextUpperBound();

3119

OuterLoopArgs.DKind = LoopArgs.DKind;

3120

EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs,

3122 if

(DynamicOrOrdered) {

3128 const unsigned

IVSize,

const bool

IVSigned) {}

3130void

CodeGenFunction::EmitOMPDistributeOuterLoop(

3132

OMPPrivateScope &LoopScope,

const

OMPLoopArguments &LoopArgs,

3142 const Expr

*IVExpr = S.getIterationVariable();

3148

IVSize, IVSigned,

false

, LoopArgs.IL, LoopArgs.LB,

3149

LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk);

3156

IncExpr = S.getDistInc();

3158

IncExpr = S.getInc();

3163

OMPLoopArguments OuterLoopArgs;

3164

OuterLoopArgs.LB = LoopArgs.LB;

3165

OuterLoopArgs.UB = LoopArgs.UB;

3166

OuterLoopArgs.ST = LoopArgs.ST;

3167

OuterLoopArgs.IL = LoopArgs.IL;

3168

OuterLoopArgs.Chunk = LoopArgs.Chunk;

3170

? S.getCombinedEnsureUpperBound()

3171

: S.getEnsureUpperBound();

3172

OuterLoopArgs.IncExpr = IncExpr;

3174

? S.getCombinedInit()

3177

? S.getCombinedCond()

3180

? S.getCombinedNextLowerBound()

3181

: S.getNextLowerBound();

3183

? S.getCombinedNextUpperBound()

3184

: S.getNextUpperBound();

3185

OuterLoopArgs.DKind = OMPD_distribute;

3187

EmitOMPOuterLoop(

false

,

false

, S,

3188

LoopScope, OuterLoopArgs, CodeGenLoopContent,

3192static

std::pair<LValue, LValue>

3235static

std::pair<llvm::Value *, llvm::Value *>

3246

llvm::Value *LBVal =

3248

llvm::Value *UBVal =

3250 return

{LBVal, UBVal};

3256 const auto

&Dir = cast<OMPLoopDirective>(S);

3258

CGF.

EmitLValue

(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable()));

3259

llvm::Value *LBCast = CGF.

Builder

.CreateIntCast(

3261

CapturedVars.push_back(LBCast);

3263

CGF.

EmitLValue

(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable()));

3265

llvm::Value *UBCast = CGF.

Builder

.CreateIntCast(

3267

CapturedVars.push_back(UBCast);

3273

CodeGenFunction::JumpDest

LoopExit

) {

3278 bool

HasCancel =

false

;

3280 if

(

const auto

*

D

= dyn_cast<OMPTeamsDistributeParallelForDirective>(&S))

3281

HasCancel =

D

->hasCancel();

3282 else if

(

const auto

*

D

= dyn_cast<OMPDistributeParallelForDirective>(&S))

3283

HasCancel =

D

->hasCancel();

3284 else if

(

const auto

*

D

=

3285

dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&S))

3286

HasCancel =

D

->hasCancel();

3288

CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel);

3296

CGInlinedWorksharingLoop,

3306

OMPLexicalScope

Scope

(*

this

, S, OMPD_parallel);

3316

OMPLexicalScope

Scope

(*

this

, S, OMPD_parallel);

3325

OMPLexicalScope

Scope

(*

this

, S, OMPD_unknown);

3335

llvm::Function *

Fn

;

3336

llvm::Constant *Addr;

3339

S, ParentName, Fn, Addr,

true

, CodeGen);

3340

assert(Fn && Addr &&

"Target device function emission failed."

);

3352struct

ScheduleKindModifiersTy {

3368 const auto

*IVExpr = cast<DeclRefExpr>(S.getIterationVariable());

3369 const auto

*IVDecl = cast<VarDecl>(IVExpr->getDecl());

3375 if

(

const auto

*LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {

3383 bool

HasLastprivateClause;

3386

OMPLoopScope PreInitScope(*

this

, S);

3391

llvm::BasicBlock *ContBlock =

nullptr

;

3398 emitPreCond

(*

this

, S, S.getPreCond(), ThenBlock, ContBlock,

3404

RunCleanupsScope DoacrossCleanupScope(*

this

);

3405 bool

Ordered =

false

;

3406 if

(

const auto

*OrderedClause = S.getSingleClause<

OMPOrderedClause

>()) {

3407 if

(OrderedClause->getNumForLoops())

3413

llvm::DenseSet<const Expr *> EmittedFinals;

3418

std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*

this

, S);

3419 LValue

LB = Bounds.first;

3420 LValue

UB = Bounds.second;

3429

OMPPrivateScope LoopScope(*

this

);

3435

*

this

, S.getBeginLoc(), OMPD_unknown,

false

,

3440

*

this

, S,

EmitLValue

(S.getIterationVariable()));

3445

(void)LoopScope.Privatize();

3450 const Expr

*ChunkExpr =

nullptr

;

3453

ScheduleKind.

Schedule

=

C

->getScheduleKind();

3454

ScheduleKind.

M1

=

C

->getFirstScheduleModifier();

3455

ScheduleKind.

M2

=

C

->getSecondScheduleModifier();

3456

ChunkExpr =

C

->getChunkSize();

3460

*

this

, S, ScheduleKind.

Schedule

, ChunkExpr);

3462 bool

HasChunkSizeOne =

false

;

3463

llvm::Value *Chunk =

nullptr

;

3467

S.getIterationVariable()->getType(),

3471

llvm::APSInt EvaluatedChunk =

Result

.Val.getInt();

3472

HasChunkSizeOne = (EvaluatedChunk.getLimitedValue() == 1);

3481 bool

StaticChunkedOne =

3483

Chunk !=

nullptr

) &&

3487

(ScheduleKind.

Schedule

== OMPC_SCHEDULE_static &&

3488

!(ScheduleKind.

M1

== OMPC_SCHEDULE_MODIFIER_nonmonotonic ||

3489

ScheduleKind.

M2

== OMPC_SCHEDULE_MODIFIER_nonmonotonic)) ||

3490

ScheduleKind.

M1

== OMPC_SCHEDULE_MODIFIER_monotonic ||

3491

ScheduleKind.

M2

== OMPC_SCHEDULE_MODIFIER_monotonic;

3493

Chunk !=

nullptr

) ||

3494

StaticChunkedOne) &&

3504

if (C->getKind() == OMPC_ORDER_concurrent)

3505

CGF.LoopStack.setParallel(

true);

3508

[IVSize, IVSigned, Ordered, IL, LB, UB, ST, StaticChunkedOne, Chunk,

3509

&S, ScheduleKind,

LoopExit

, EKind,

3517

IVSize, IVSigned, Ordered, IL.getAddress(), LB.getAddress(),

3518

UB.getAddress(), ST.getAddress(),

3519

StaticChunkedOne ? Chunk :

nullptr

);

3520

CGF.CGM.getOpenMPRuntime().emitForStaticInit(

3521

CGF, S.getBeginLoc(), EKind, ScheduleKind, StaticInit);

3523 if

(!StaticChunkedOne)

3524

CGF.EmitIgnoredExpr(S.getEnsureUpperBound());

3526

CGF.EmitIgnoredExpr(S.getInit());

3540

CGF.EmitOMPInnerLoop(

3541

S, LoopScope.requiresCleanups(),

3542

StaticChunkedOne ? S.getCombinedParForInDistCond()

3544

StaticChunkedOne ? S.getDistInc() : S.getInc(),

3546

emitOMPLoopBodyWithStopPoint(CGF, S, LoopExit);

3553

CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),

3556

OMPCancelStack.emitExit(*

this

, EKind, CodeGen);

3560

OMPLoopArguments LoopArguments(LB.getAddress(), UB.getAddress(),

3561

ST.getAddress(), IL.getAddress(), Chunk,

3563

LoopArguments.DKind = OMPD_for;

3564

EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,

3565

LoopArguments, CGDispatchBounds);

3569 return

CGF.

Builder

.CreateIsNotNull(

3575

?

OMPD_parallel_for_simd

3580 return

CGF.

Builder

.CreateIsNotNull(

3584 if

(HasLastprivateClause)

3588

LoopScope.restoreMap();

3590 return

CGF.

Builder

.CreateIsNotNull(

3594

DoacrossCleanupScope.ForceCleanup();

3601 return

HasLastprivateClause;

3607static

std::pair<LValue, LValue>

3609 const auto

&LS = cast<OMPLoopDirective>(S);

3621static

std::pair<llvm::Value *, llvm::Value *>

3624 const auto

&LS = cast<OMPLoopDirective>(S);

3625 const Expr

*IVExpr = LS.getIterationVariable();

3627

llvm::Value *LBVal = CGF.

Builder

.getIntN(IVSize, 0);

3628

llvm::Value *UBVal = CGF.

EmitScalarExpr

(LS.getLastIteration());

3629 return

{LBVal, UBVal};

3641

llvm::function_ref<llvm::Value *(

CodeGenFunction

&)> NumIteratorsGen) {

3642

llvm::Value *OMPScanNumIterations = CGF.

Builder

.CreateIntCast(

3643

NumIteratorsGen(CGF), CGF.

SizeTy

,

false

);

3649

assert(

C

->getModifier() == OMPC_REDUCTION_inscan &&

3650 "Only inscan reductions are expected."

);

3651

Shareds.append(

C

->varlist_begin(),

C

->varlist_end());

3652

Privates.append(

C

->privates().begin(),

C

->privates().end());

3653

ReductionOps.append(

C

->reduction_ops().begin(),

C

->reduction_ops().end());

3654

CopyArrayTemps.append(

C

->copy_array_temps().begin(),

3655 C

->copy_array_temps().end());

3663 auto

*ITA = CopyArrayTemps.begin();

3664 for

(

const Expr

*IRef : Privates) {

3665 const auto

*PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());

3668 if

(PrivateVD->getType()->isVariablyModifiedType()) {

3672

CodeGenFunction::OpaqueValueMapping DimMapping(

3674

cast<OpaqueValueExpr>(

3675

cast<VariableArrayType>((*ITA)->getType()->getAsArrayTypeUnsafe())

3679

CGF.

EmitVarDecl

(*cast<VarDecl>(cast<DeclRefExpr>(*ITA)->getDecl()));

3693

llvm::function_ref<llvm::Value *(

CodeGenFunction

&)> NumIteratorsGen) {

3694

llvm::Value *OMPScanNumIterations = CGF.

Builder

.CreateIntCast(

3695

NumIteratorsGen(CGF), CGF.

SizeTy

,

false

);

3703

assert(

C

->getModifier() == OMPC_REDUCTION_inscan &&

3704 "Only inscan reductions are expected."

);

3705

Shareds.append(

C

->varlist_begin(),

C

->varlist_end());

3706

LHSs.append(

C

->lhs_exprs().begin(),

C

->lhs_exprs().end());

3707

RHSs.append(

C

->rhs_exprs().begin(),

C

->rhs_exprs().end());

3708

Privates.append(

C

->privates().begin(),

C

->privates().end());

3709

CopyOps.append(

C

->copy_ops().begin(),

C

->copy_ops().end());

3710

CopyArrayElems.append(

C

->copy_array_elems().begin(),

3711 C

->copy_array_elems().end());

3715

llvm::Value *OMPLast = CGF.

Builder

.CreateNSWSub(

3716

OMPScanNumIterations,

3717

llvm::ConstantInt::get(CGF.

SizeTy

, 1,

false

));

3718 for

(

unsigned

I = 0,

E

= CopyArrayElems.size(); I <

E

; ++I) {

3719 const Expr

*PrivateExpr = Privates[I];

3720 const Expr

*OrigExpr = Shareds[I];

3721 const Expr

*CopyArrayElem = CopyArrayElems[I];

3722

CodeGenFunction::OpaqueValueMapping IdxMapping(

3724

cast<OpaqueValueExpr>(

3725

cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),

3731

cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),

3732

cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()), CopyOps[I]);

3757

llvm::function_ref<llvm::Value *(

CodeGenFunction

&)> NumIteratorsGen,

3760

llvm::Value *OMPScanNumIterations = CGF.

Builder

.CreateIntCast(

3761

NumIteratorsGen(CGF), CGF.

SizeTy

,

false

);

3768

assert(

C

->getModifier() == OMPC_REDUCTION_inscan &&

3769 "Only inscan reductions are expected."

);

3770

Privates.append(

C

->privates().begin(),

C

->privates().end());

3771

ReductionOps.append(

C

->reduction_ops().begin(),

C

->reduction_ops().end());

3772

LHSs.append(

C

->lhs_exprs().begin(),

C

->lhs_exprs().end());

3773

RHSs.append(

C

->rhs_exprs().begin(),

C

->rhs_exprs().end());

3774

CopyArrayElems.append(

C

->copy_array_elems().begin(),

3775 C

->copy_array_elems().end());

3777

CodeGenFunction::ParentLoopDirectiveForScanRegion ScanRegion(CGF, S);

3786

CodeGenFunction::OMPLocalDeclMapRAII

Scope

(CGF);

3790 auto

&&CodeGen = [&S, OMPScanNumIterations, &LHSs, &RHSs, &CopyArrayElems,

3797

llvm::BasicBlock *InputBB = CGF.Builder.GetInsertBlock();

3798

llvm::BasicBlock *LoopBB = CGF.createBasicBlock(

"omp.outer.log.scan.body"

);

3799

llvm::BasicBlock *ExitBB = CGF.createBasicBlock(

"omp.outer.log.scan.exit"

);

3801

CGF.CGM.getIntrinsic(llvm::Intrinsic::log2, CGF.DoubleTy);

3803

CGF.Builder.CreateUIToFP(OMPScanNumIterations, CGF.DoubleTy);

3804

llvm::Value *LogVal = CGF.EmitNounwindRuntimeCall(F, Arg);

3805

F = CGF.CGM.getIntrinsic(llvm::Intrinsic::ceil, CGF.DoubleTy);

3806

LogVal = CGF.EmitNounwindRuntimeCall(F, LogVal);

3807

LogVal = CGF.Builder.CreateFPToUI(LogVal, CGF.IntTy);

3808

llvm::Value *NMin1 = CGF.Builder.CreateNUWSub(

3809

OMPScanNumIterations, llvm::ConstantInt::get(CGF.SizeTy, 1));

3811

CGF.EmitBlock(LoopBB);

3812 auto

*Counter = CGF.Builder.CreatePHI(CGF.IntTy, 2);

3814 auto

*Pow2K = CGF.Builder.CreatePHI(CGF.SizeTy, 2);

3815

Counter->addIncoming(llvm::ConstantInt::get(CGF.IntTy, 0), InputBB);

3816

Pow2K->addIncoming(llvm::ConstantInt::get(CGF.SizeTy, 1), InputBB);

3819

llvm::BasicBlock *InnerLoopBB =

3820

CGF.createBasicBlock(

"omp.inner.log.scan.body"

);

3821

llvm::BasicBlock *InnerExitBB =

3822

CGF.createBasicBlock(

"omp.inner.log.scan.exit"

);

3823

llvm::Value *CmpI = CGF.Builder.CreateICmpUGE(NMin1, Pow2K);

3824

CGF.Builder.CreateCondBr(CmpI, InnerLoopBB, InnerExitBB);

3825

CGF.EmitBlock(InnerLoopBB);

3826 auto

*IVal = CGF.Builder.CreatePHI(CGF.SizeTy, 2);

3827

IVal->addIncoming(NMin1, LoopBB);

3829

CodeGenFunction::OMPPrivateScope PrivScope(CGF);

3830 auto

*ILHS = LHSs.begin();

3831 auto

*IRHS = RHSs.begin();

3832 for

(

const Expr

*CopyArrayElem : CopyArrayElems) {

3833 const auto

*LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());

3834 const auto

*RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());

3837

CodeGenFunction::OpaqueValueMapping IdxMapping(

3839

cast<OpaqueValueExpr>(

3840

cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),

3842

LHSAddr = CGF.EmitLValue(CopyArrayElem).getAddress();

3844

PrivScope.addPrivate(LHSVD, LHSAddr);

3847

llvm::Value *OffsetIVal = CGF.Builder.CreateNUWSub(IVal, Pow2K);

3848

CodeGenFunction::OpaqueValueMapping IdxMapping(

3850

cast<OpaqueValueExpr>(

3851

cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),

3853

RHSAddr = CGF.EmitLValue(CopyArrayElem).getAddress();

3855

PrivScope.addPrivate(RHSVD, RHSAddr);

3859

PrivScope.Privatize();

3860

CGF.CGM.getOpenMPRuntime().emitReduction(

3861

CGF, S.getEndLoc(), Privates, LHSs, RHSs, ReductionOps,

3862

{

true,

true, OMPD_unknown});

3864

llvm::Value *NextIVal =

3865

CGF.Builder.CreateNUWSub(IVal, llvm::ConstantInt::get(CGF.SizeTy, 1));

3866

IVal->addIncoming(NextIVal, CGF.Builder.GetInsertBlock());

3867

CmpI = CGF.Builder.CreateICmpUGE(NextIVal, Pow2K);

3868

CGF.Builder.CreateCondBr(CmpI, InnerLoopBB, InnerExitBB);

3869

CGF.EmitBlock(InnerExitBB);

3871

CGF.Builder.CreateNUWAdd(Counter, llvm::ConstantInt::get(CGF.IntTy, 1));

3872

Counter->addIncoming(Next, CGF.Builder.GetInsertBlock());

3874

llvm::Value *NextPow2K =

3875

CGF.Builder.CreateShl(Pow2K, 1,

""

,

true

);

3876

Pow2K->addIncoming(NextPow2K, CGF.Builder.GetInsertBlock());

3877

llvm::Value *Cmp = CGF.Builder.CreateICmpNE(Next, LogVal);

3878

CGF.Builder.CreateCondBr(Cmp, LoopBB, ExitBB);

3880

CGF.EmitBlock(ExitBB);

3884

CGF.CGM.getOpenMPRuntime().emitMasterRegion(CGF, CodeGen, S.getBeginLoc());

3885

CGF.CGM.getOpenMPRuntime().emitBarrierCall(

3886

CGF, S.getBeginLoc(), OMPD_unknown,

false

,

3893

CGF.OMPFirstScanLoop =

false

;

3900 bool

HasLastprivates;

3904

return C->getModifier() == OMPC_REDUCTION_inscan;

3907

CodeGenFunction::OMPLocalDeclMapRAII

Scope

(CGF);

3908

OMPLoopScope LoopScope(CGF, S);

3911 const auto

&&FirstGen = [&S, HasCancel, EKind](

CodeGenFunction

&CGF) {

3912

CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel);

3920 const auto

&&SecondGen = [&S, HasCancel, EKind,

3922

CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel);

3933

CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel);

3938 return

HasLastprivates;

3948 if

(isa<OMPNowaitClause, OMPBindClause>(

C

))

3951 if

(

auto

*SC = dyn_cast<OMPScheduleClause>(

C

)) {

3956 switch

(SC->getScheduleKind()) {

3957 case

OMPC_SCHEDULE_auto:

3958 case

OMPC_SCHEDULE_dynamic:

3959 case

OMPC_SCHEDULE_runtime:

3960 case

OMPC_SCHEDULE_guided:

3961 case

OMPC_SCHEDULE_static:

3974static

llvm::omp::ScheduleKind

3976 switch

(ScheduleClauseKind) {

3978 return

llvm::omp::OMP_SCHEDULE_Default;

3979 case

OMPC_SCHEDULE_auto:

3980 return

llvm::omp::OMP_SCHEDULE_Auto;

3981 case

OMPC_SCHEDULE_dynamic:

3982 return

llvm::omp::OMP_SCHEDULE_Dynamic;

3983 case

OMPC_SCHEDULE_guided:

3984 return

llvm::omp::OMP_SCHEDULE_Guided;

3985 case

OMPC_SCHEDULE_runtime:

3986 return

llvm::omp::OMP_SCHEDULE_Runtime;

3987 case

OMPC_SCHEDULE_static:

3988 return

llvm::omp::OMP_SCHEDULE_Static;

3990

llvm_unreachable(

"Unhandled schedule kind"

);

3997 bool

HasLastprivates =

false

;

4000 auto

&&CodeGen = [&S, &

CGM

, HasCancel, &HasLastprivates,

4003 if

(UseOMPIRBuilder) {

4006

llvm::omp::ScheduleKind SchedKind = llvm::omp::OMP_SCHEDULE_Default;

4007

llvm::Value *ChunkSize =

nullptr

;

4011 if

(

const Expr

*ChunkSizeExpr = SchedClause->getChunkSize())

4016 const Stmt

*Inner = S.getRawStmt();

4017

llvm::CanonicalLoopInfo *CLI =

4020

llvm::OpenMPIRBuilder &OMPBuilder =

4022

llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(

4024

cantFail(OMPBuilder.applyWorkshareLoop(

4025

CGF.

Builder

.getCurrentDebugLocation(), CLI, AllocaIP, NeedsBarrier,

4026

SchedKind, ChunkSize,

false

,

4037

OMPLexicalScope

Scope

(CGF, S, OMPD_unknown);

4042 if

(!UseOMPIRBuilder) {

4056 bool

HasLastprivates =

false

;

4064

OMPLexicalScope

Scope

(*

this

, S, OMPD_unknown);

4077

llvm::Value *

Init

=

nullptr

) {

4085 const Stmt

*

CapturedStmt

= S.getInnermostCapturedStmt()->getCapturedStmt();

4086 const auto

*CS = dyn_cast<CompoundStmt>(

CapturedStmt

);

4087 bool

HasLastprivates =

false

;

4093 C

.getIntTypeForBitwidth(

32,

1);

4096

CGF.Builder.getInt32(0));

4097

llvm::ConstantInt *GlobalUBVal = CS !=

nullptr 4098

? CGF.Builder.getInt32(CS->size() - 1)

4099

: CGF.Builder.getInt32(0);

4103

CGF.Builder.getInt32(1));

4105

CGF.Builder.getInt32(0));

4109

CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);

4111

CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);

4132

llvm::BasicBlock *ExitBB = CGF.createBasicBlock(

".omp.sections.exit"

);

4134

CGF.Builder.CreateSwitch(CGF.EmitLoadOfScalar(IV, S.getBeginLoc()),

4135

ExitBB, CS ==

nullptr

? 1 : CS->size());

4137 unsigned

CaseNumber = 0;

4139 auto

CaseBB = CGF.createBasicBlock(

".omp.sections.case"

);

4140

CGF.EmitBlock(CaseBB);

4141 SwitchStmt

->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);

4142

CGF.EmitStmt(SubStmt);

4143

CGF.EmitBranch(ExitBB);

4147

llvm::BasicBlock *CaseBB = CGF.createBasicBlock(

".omp.sections.case"

);

4148

CGF.EmitBlock(CaseBB);

4149 SwitchStmt

->addCase(CGF.Builder.getInt32(0), CaseBB);

4151

CGF.EmitBranch(ExitBB);

4153

CGF.EmitBlock(ExitBB,

true

);

4156

CodeGenFunction::OMPPrivateScope LoopScope(CGF);

4157 if

(CGF.EmitOMPFirstprivateClause(S, LoopScope)) {

4161

CGF.CGM.getOpenMPRuntime().emitBarrierCall(

4162

CGF, S.getBeginLoc(), OMPD_unknown,

false

,

4165

CGF.EmitOMPPrivateClause(S, LoopScope);

4167

HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);

4168

CGF.EmitOMPReductionClauseInit(S, LoopScope);

4169

(void)LoopScope.Privatize();

4171

CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);

4175

ScheduleKind.

Schedule

= OMPC_SCHEDULE_static;

4179

CGF.CGM.getOpenMPRuntime().emitForStaticInit(CGF, S.getBeginLoc(), EKind,

4180

ScheduleKind, StaticInit);

4182

llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, S.getBeginLoc());

4183

llvm::Value *MinUBGlobalUB = CGF.Builder.CreateSelect(

4184

CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);

4185

CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);

4187

CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getBeginLoc()), IV);

4189

CGF.EmitOMPInnerLoop(S,

false

, Cond, Inc, BodyGen,

4193

CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),

4196

CGF.OMPCancelStack.emitExit(CGF, EKind, CodeGen);

4197

CGF.EmitOMPReductionClauseFinal(S,

OMPD_parallel);

4200 return

CGF.

Builder

.CreateIsNotNull(

4205 if

(HasLastprivates)

4208

CGF.

Builder

.CreateIsNotNull(

4212 bool

HasCancel =

false

;

4213 if

(

auto

*OSD = dyn_cast<OMPSectionsDirective>(&S))

4214

HasCancel = OSD->hasCancel();

4215 else if

(

auto

*OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))

4216

HasCancel = OPSD->hasCancel();

4217

OMPCancelStackRAII CancelRegion(*

this

, EKind, HasCancel);

4236

OMPPrivateScope PrivateScope(CGF);

4240

(void)PrivateScope.Privatize();

4241

CGF.

EmitStmt

(S.getInnermostCapturedStmt()->getCapturedStmt());

4246

OMPLexicalScope

Scope

(*

this

, S, OMPD_unknown);

4260 using

InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;

4261 using

BodyGenCallbackTy = llvm::OpenMPIRBuilder::StorableBodyGenCallbackTy;

4263 auto

FiniCB = [

this

](InsertPointTy IP) {

4265 return

llvm::Error::success();

4268 const CapturedStmt

*ICS = S.getInnermostCapturedStmt();

4269 const Stmt

*

CapturedStmt

= S.getInnermostCapturedStmt()->getCapturedStmt();

4270 const auto

*CS = dyn_cast<CompoundStmt>(

CapturedStmt

);

4274 auto

SectionCB = [

this

, SubStmt](InsertPointTy AllocaIP,

4275

InsertPointTy CodeGenIP) {

4277

*

this

, SubStmt, AllocaIP, CodeGenIP,

"section"

);

4278 return

llvm::Error::success();

4280

SectionCBVector.push_back(SectionCB);

4283 auto

SectionCB = [

this

,

CapturedStmt

](InsertPointTy AllocaIP,

4284

InsertPointTy CodeGenIP) {

4286

*

this

,

CapturedStmt

, AllocaIP, CodeGenIP,

"section"

);

4287 return

llvm::Error::success();

4289

SectionCBVector.push_back(SectionCB);

4296 auto

PrivCB = [](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,

4297

llvm::Value &, llvm::Value &Val, llvm::Value *&ReplVal) {

4305

CGCapturedStmtInfo CGSI(*ICS,

CR_OpenMP

);

4306

CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*

this

, &CGSI);

4307

llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(

4309

llvm::OpenMPIRBuilder::InsertPointTy AfterIP =

4310

cantFail(OMPBuilder.createSections(

4311 Builder

, AllocaIP, SectionCBVector, PrivCB, FiniCB, S.hasCancel(),

4319

OMPLexicalScope

Scope

(*

this

, S, OMPD_unknown);

4334 using

InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;

4336 const Stmt

*SectionRegionBodyStmt = S.getAssociatedStmt();

4337 auto

FiniCB = [

this

](InsertPointTy IP) {

4339 return

llvm::Error::success();

4342 auto

BodyGenCB = [SectionRegionBodyStmt,

this

](InsertPointTy AllocaIP,

4343

InsertPointTy CodeGenIP) {

4345

*

this

, SectionRegionBodyStmt, AllocaIP, CodeGenIP,

"section"

);

4346 return

llvm::Error::success();

4349

LexicalScope

Scope

(*

this

, S.getSourceRange());

4351

llvm::OpenMPIRBuilder::InsertPointTy AfterIP =

4352

cantFail(OMPBuilder.createSection(

Builder

, BodyGenCB, FiniCB));

4357

LexicalScope

Scope

(*

this

, S.getSourceRange());

4372

CopyprivateVars.append(

C

->varlist_begin(),

C

->varlist_end());

4373

DestExprs.append(

C

->destination_exprs().begin(),

4374 C

->destination_exprs().end());

4375

SrcExprs.append(

C

->source_exprs().begin(),

C

->source_exprs().end());

4376

AssignmentOps.append(

C

->assignment_ops().begin(),

4377 C

->assignment_ops().end());

4386

CGF.

EmitStmt

(S.getInnermostCapturedStmt()->getCapturedStmt());

4391

OMPLexicalScope

Scope

(*

this

, S, OMPD_unknown);

4393

CopyprivateVars, DestExprs,

4394

SrcExprs, AssignmentOps);

4398 if

(!S.getSingleClause<

OMPNowaitClause

>() && CopyprivateVars.empty()) {

4400

*

this

, S.getBeginLoc(),

4418 using

InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;

4420 const Stmt

*MasterRegionBodyStmt = S.getAssociatedStmt();

4422 auto

FiniCB = [

this

](InsertPointTy IP) {

4424 return

llvm::Error::success();

4427 auto

BodyGenCB = [MasterRegionBodyStmt,

this

](InsertPointTy AllocaIP,

4428

InsertPointTy CodeGenIP) {

4430

*

this

, MasterRegionBodyStmt, AllocaIP, CodeGenIP,

"master"

);

4431 return

llvm::Error::success();

4434

LexicalScope

Scope

(*

this

, S.getSourceRange());

4436

llvm::OpenMPIRBuilder::InsertPointTy AfterIP =

4437

cantFail(OMPBuilder.createMaster(

Builder

, BodyGenCB, FiniCB));

4442

LexicalScope

Scope

(*

this

, S.getSourceRange());

4452 Expr

*Filter =

nullptr

;

4453 if

(

const auto

*FilterClause = S.getSingleClause<

OMPFilterClause

>())

4454

Filter = FilterClause->getThreadID();

4462 using

InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;

4464 const Stmt

*MaskedRegionBodyStmt = S.getAssociatedStmt();

4466 if

(

const auto

*FilterClause = S.getSingleClause<

OMPFilterClause

>())

4467 Filter

= FilterClause->getThreadID();

4468

llvm::Value *FilterVal =

Filter 4472 auto

FiniCB = [

this

](InsertPointTy IP) {

4474 return

llvm::Error::success();

4477 auto

BodyGenCB = [MaskedRegionBodyStmt,

this

](InsertPointTy AllocaIP,

4478

InsertPointTy CodeGenIP) {

4480

*

this

, MaskedRegionBodyStmt, AllocaIP, CodeGenIP,

"masked"

);

4481 return

llvm::Error::success();

4484

LexicalScope

Scope

(*

this

, S.getSourceRange());

4486

llvm::OpenMPIRBuilder::InsertPointTy AfterIP = cantFail(

4487

OMPBuilder.createMasked(

Builder

, BodyGenCB, FiniCB, FilterVal));

4492

LexicalScope

Scope

(*

this

, S.getSourceRange());

4500 using

InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;

4502 const Stmt

*CriticalRegionBodyStmt = S.getAssociatedStmt();

4503 const Expr

*Hint =

nullptr

;

4504 if

(

const auto

*HintClause = S.getSingleClause<

OMPHintClause

>())

4505

Hint = HintClause->getHint();

4510

llvm::Value *HintInst =

nullptr

;

4515 auto

FiniCB = [

this

](InsertPointTy IP) {

4517 return

llvm::Error::success();

4520 auto

BodyGenCB = [CriticalRegionBodyStmt,

this

](InsertPointTy AllocaIP,

4521

InsertPointTy CodeGenIP) {

4523

*

this

, CriticalRegionBodyStmt, AllocaIP, CodeGenIP,

"critical"

);

4524 return

llvm::Error::success();

4527

LexicalScope

Scope

(*

this

, S.getSourceRange());

4529

llvm::OpenMPIRBuilder::InsertPointTy AfterIP =

4530

cantFail(OMPBuilder.createCritical(

Builder

, BodyGenCB, FiniCB,

4531

S.getDirectiveName().getAsString(),

4540

CGF.

EmitStmt

(S.getAssociatedStmt());

4542 const Expr

*Hint =

nullptr

;

4543 if

(

const auto

*HintClause = S.getSingleClause<

OMPHintClause

>())

4544

Hint = HintClause->getHint();

4545

LexicalScope

Scope

(*

this

, S.getSourceRange());

4548

S.getDirectiveName().getAsString(),

4549

CodeGen, S.getBeginLoc(), Hint);

4563

CodeGenFunction::OMPLocalDeclMapRAII

Scope

(CGF);

4565

CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGSI);

4566

OMPLoopScope LoopScope(CGF, S);

4571

return C->getModifier() == OMPC_REDUCTION_inscan;

4597

CodeGenFunction::OMPLocalDeclMapRAII

Scope

(CGF);

4599

CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGSI);

4600

OMPLoopScope LoopScope(CGF, S);

4605

return C->getModifier() == OMPC_REDUCTION_inscan;

4626

OMPPrivateScope PrivateScope(CGF);

4631

(void)PrivateScope.Privatize();

4653

OMPPrivateScope PrivateScope(CGF);

4658

(void)PrivateScope.Privatize();

4681

CGF.EmitSections(S);

4695class

CheckVarsEscapingUntiedTaskDeclContext final

4700 explicit

CheckVarsEscapingUntiedTaskDeclContext() =

default

;

4701 virtual

~CheckVarsEscapingUntiedTaskDeclContext() =

default

;

4702 void

VisitDeclStmt(

const DeclStmt

*S) {

4706 for

(

const Decl

*

D

: S->decls()) {

4707 if

(

const auto

*VD = dyn_cast_or_null<VarDecl>(

D

))

4709

PrivateDecls.push_back(VD);

4715 void

VisitBlockExpr(

const BlockExpr

*) {}

4716 void

VisitStmt(

const Stmt

*S) {

4719 for

(

const Stmt

*Child : S->children())

4733 bool

OmpAllMemory =

false

;

4736

return C->getDependencyKind() == OMPC_DEPEND_outallmemory ||

4737

C->getDependencyKind() == OMPC_DEPEND_inoutallmemory;

4739

OmpAllMemory =

true

;

4744 Data

.Dependences.emplace_back(OMPC_DEPEND_outallmemory,

4747

DD.

DepExprs

.push_back(

nullptr

);

4753 if

(Kind == OMPC_DEPEND_outallmemory || Kind == OMPC_DEPEND_inoutallmemory)

4755 if

(OmpAllMemory && (Kind == OMPC_DEPEND_out || Kind == OMPC_DEPEND_inout))

4758 Data

.Dependences.emplace_back(

C

->getDependencyKind(),

C

->getModifier());

4759

DD.

DepExprs

.append(

C

->varlist_begin(),

C

->varlist_end());

4768 const CapturedStmt

*CS = S.getCapturedStmt(CapturedRegion);

4770 auto

PartId = std::next(I);

4771 auto

TaskT = std::next(I, 4);

4773 if

(

const auto

*Clause = S.getSingleClause<

OMPFinalClause

>()) {

4776 const Expr

*Cond = Clause->getCondition();

4779 Data

.Final.setInt(CondConstant);

4784 Data

.Final.setInt(

false

);

4788 const Expr

*Prio = Clause->getPriority();

4789 Data

.Priority.setInt(

true

);

4797

llvm::DenseSet<const VarDecl *> EmittedAsPrivate;

4800 auto

IRef =

C

->varlist_begin();

4801 for

(

const Expr

*IInit :

C

->private_copies()) {

4802 const auto

*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());

4803 if

(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {

4804 Data

.PrivateVars.push_back(*IRef);

4805 Data

.PrivateCopies.push_back(IInit);

4810

EmittedAsPrivate.clear();

4813 auto

IRef =

C

->varlist_begin();

4814 auto

IElemInitRef =

C

->inits().begin();

4815 for

(

const Expr

*IInit :

C

->private_copies()) {

4816 const auto

*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());

4817 if

(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {

4818 Data

.FirstprivateVars.push_back(*IRef);

4819 Data

.FirstprivateCopies.push_back(IInit);

4820 Data

.FirstprivateInits.push_back(*IElemInitRef);

4827

llvm::MapVector<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;

4829 auto

IRef =

C

->varlist_begin();

4830 auto ID

=

C

->destination_exprs().begin();

4831 for

(

const Expr

*IInit :

C

->private_copies()) {

4832 const auto

*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());

4833 if

(EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {

4834 Data

.LastprivateVars.push_back(*IRef);

4835 Data

.LastprivateCopies.push_back(IInit);

4837

LastprivateDstsOrigs.insert(

4838

std::make_pair(cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),

4839

cast<DeclRefExpr>(*IRef)));

4847 Data

.ReductionVars.append(

C

->varlist_begin(),

C

->varlist_end());

4848 Data

.ReductionOrigs.append(

C

->varlist_begin(),

C

->varlist_end());

4849 Data

.ReductionCopies.append(

C

->privates().begin(),

C

->privates().end());

4850 Data

.ReductionOps.append(

C

->reduction_ops().begin(),

4851 C

->reduction_ops().end());

4852

LHSs.append(

C

->lhs_exprs().begin(),

C

->lhs_exprs().end());

4853

RHSs.append(

C

->rhs_exprs().begin(),

C

->rhs_exprs().end());

4856

*

this

, S.getBeginLoc(), LHSs, RHSs,

Data

);

4861

CheckVarsEscapingUntiedTaskDeclContext Checker;

4862

Checker.Visit(S.getInnermostCapturedStmt()->getCapturedStmt());

4863 Data

.PrivateLocals.append(Checker.getPrivateDecls().begin(),

4864

Checker.getPrivateDecls().end());

4866 auto

&&CodeGen = [&

Data

, &S, CS, &BodyGen, &LastprivateDstsOrigs,

4869

llvm::MapVector<CanonicalDeclPtr<const VarDecl>,

4870

std::pair<Address, Address>>

4873

OMPPrivateScope

Scope

(CGF);

4875 if

(

auto

*DI = CGF.getDebugInfo()) {

4876

llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields =

4877

CGF.CapturedStmtInfo->getCaptureFields();

4878

llvm::Value *ContextValue = CGF.CapturedStmtInfo->getContextValue();

4879 if

(CaptureFields.size() && ContextValue) {

4880 unsigned

CharWidth = CGF.getContext().getCharWidth();

4894 for

(

auto

It = CaptureFields.begin(); It != CaptureFields.end(); ++It) {

4895 const VarDecl

*SharedVar = It->first;

4898

CGF.getContext().getASTRecordLayout(CaptureRecord);

4900

Layout.

getFieldOffset

(It->second->getFieldIndex()) / CharWidth;

4901 if

(CGF.CGM.getCodeGenOpts().hasReducedDebugInfo())

4902

(void)DI->EmitDeclareOfAutoVariable(SharedVar, ContextValue,

4903

CGF.Builder,

false

);

4906 auto

UpdateExpr = [](llvm::LLVMContext &Ctx,

auto

*

Declare

,

4911

Ops.push_back(llvm::dwarf::DW_OP_plus_uconst);

4912

Ops.push_back(Offset);

4914

Ops.push_back(llvm::dwarf::DW_OP_deref);

4915 Declare

->setExpression(llvm::DIExpression::get(Ctx, Ops));

4917

llvm::Instruction &

Last

= CGF.Builder.GetInsertBlock()->back();

4918 if

(

auto

DDI = dyn_cast<llvm::DbgVariableIntrinsic>(&

Last

))

4919

UpdateExpr(DDI->getContext(), DDI, Offset);

4922

assert(!

Last

.isTerminator() &&

"unexpected terminator"

);

4924

CGF.Builder.GetInsertBlock()->getTrailingDbgRecords()) {

4925 for

(llvm::DbgVariableRecord &DVR : llvm::reverse(

4926

llvm::filterDbgVars(Marker->getDbgRecordRange()))) {

4927

UpdateExpr(

Last

.getContext(), &DVR, Offset);

4935 if

(!

Data

.PrivateVars.empty() || !

Data

.FirstprivateVars.empty() ||

4936

!

Data

.LastprivateVars.empty() || !

Data

.PrivateLocals.empty()) {

4937 enum

{ PrivatesParam = 2, CopyFnParam = 3 };

4938

llvm::Value *CopyFn = CGF.Builder.CreateLoad(

4939

CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));

4940

llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(

4941

CS->getCapturedDecl()->getParam(PrivatesParam)));

4946

CallArgs.push_back(PrivatesPtr);

4947

ParamTypes.push_back(PrivatesPtr->getType());

4948 for

(

const Expr

*

E

:

Data

.PrivateVars) {

4949 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

4951

CGF.getContext().getPointerType(

E

->

getType

()),

".priv.ptr.addr"

);

4952

PrivatePtrs.emplace_back(VD, PrivatePtr);

4953

CallArgs.push_back(PrivatePtr.

getPointer

());

4954

ParamTypes.push_back(PrivatePtr.

getType

());

4956 for

(

const Expr

*

E

:

Data

.FirstprivateVars) {

4957 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

4959

CGF.CreateMemTemp(CGF.getContext().getPointerType(

E

->

getType

()),

4960 ".firstpriv.ptr.addr"

);

4961

PrivatePtrs.emplace_back(VD, PrivatePtr);

4962

FirstprivatePtrs.emplace_back(VD, PrivatePtr);

4963

CallArgs.push_back(PrivatePtr.

getPointer

());

4964

ParamTypes.push_back(PrivatePtr.

getType

());

4966 for

(

const Expr

*

E

:

Data

.LastprivateVars) {

4967 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

4969

CGF.CreateMemTemp(CGF.getContext().getPointerType(

E

->

getType

()),

4970 ".lastpriv.ptr.addr"

);

4971

PrivatePtrs.emplace_back(VD, PrivatePtr);

4972

CallArgs.push_back(PrivatePtr.

getPointer

());

4973

ParamTypes.push_back(PrivatePtr.

getType

());

4978

Ty = CGF.getContext().getPointerType(Ty);

4980

Ty = CGF.getContext().getPointerType(Ty);

4982

CGF.getContext().getPointerType(Ty),

".local.ptr.addr"

);

4983 auto Result

= UntiedLocalVars.insert(

4986 if

(

Result

.second ==

false

)

4987

*

Result

.first = std::make_pair(

4989

CallArgs.push_back(PrivatePtr.

getPointer

());

4990

ParamTypes.push_back(PrivatePtr.

getType

());

4992 auto

*CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(),

4993

ParamTypes,

false

);

4994

CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(

4995

CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);

4996 for

(

const auto

&Pair : LastprivateDstsOrigs) {

4997 const auto

*OrigVD = cast<VarDecl>(Pair.second->getDecl());

5000

CGF.CapturedStmtInfo->lookup(OrigVD) !=

nullptr

,

5002

Pair.second->getExprLoc());

5003 Scope

.addPrivate(Pair.first, CGF.EmitLValue(&DRE).getAddress());

5005 for

(

const auto

&Pair : PrivatePtrs) {

5007

CGF.Builder.CreateLoad(Pair.second),

5008

CGF.ConvertTypeForMem(Pair.first->getType().getNonReferenceType()),

5009

CGF.getContext().getDeclAlign(Pair.first));

5010 Scope

.addPrivate(Pair.first, Replacement);

5011 if

(

auto

*DI = CGF.getDebugInfo())

5012 if

(CGF.CGM.getCodeGenOpts().hasReducedDebugInfo())

5013

(void)DI->EmitDeclareOfAutoVariable(

5014

Pair.first, Pair.second.getBasePointer(), CGF.Builder,

5019 for

(

auto

&Pair : UntiedLocalVars) {

5020 QualType

VDType = Pair.first->getType().getNonReferenceType();

5021 if

(Pair.first->getType()->isLValueReferenceType())

5022

VDType = CGF.getContext().getPointerType(VDType);

5024

llvm::Value *Ptr = CGF.Builder.CreateLoad(Pair.second.first);

5027

CGF.ConvertTypeForMem(CGF.getContext().getPointerType(VDType)),

5028

CGF.getPointerAlign());

5029

Pair.second.first = Replacement;

5030

Ptr = CGF.Builder.CreateLoad(Replacement);

5031

Replacement =

Address

(Ptr, CGF.ConvertTypeForMem(VDType),

5032

CGF.getContext().getDeclAlign(Pair.first));

5033

Pair.second.second = Replacement;

5035

llvm::Value *Ptr = CGF.Builder.CreateLoad(Pair.second.first);

5036 Address

Replacement(Ptr, CGF.ConvertTypeForMem(VDType),

5037

CGF.getContext().getDeclAlign(Pair.first));

5038

Pair.second.first = Replacement;

5042 if

(

Data

.Reductions) {

5043

OMPPrivateScope FirstprivateScope(CGF);

5044 for

(

const auto

&Pair : FirstprivatePtrs) {

5046

CGF.Builder.CreateLoad(Pair.second),

5047

CGF.ConvertTypeForMem(Pair.first->getType().getNonReferenceType()),

5048

CGF.getContext().getDeclAlign(Pair.first));

5049

FirstprivateScope.addPrivate(Pair.first, Replacement);

5051

(void)FirstprivateScope.Privatize();

5052

OMPLexicalScope LexScope(CGF, S, CapturedRegion);

5054 Data

.ReductionCopies,

Data

.ReductionOps);

5055

llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad(

5056

CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9)));

5057 for

(

unsigned

Cnt = 0,

E

=

Data

.ReductionVars.size(); Cnt <

E

; ++Cnt) {

5058

RedCG.emitSharedOrigLValue(CGF, Cnt);

5059

RedCG.emitAggregateType(CGF, Cnt);

5063

CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),

5065 Address

Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(

5066

CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));

5068

CGF.EmitScalarConversion(Replacement.emitRawPointer(CGF),

5069

CGF.getContext().VoidPtrTy,

5070

CGF.getContext().getPointerType(

5071 Data

.ReductionCopies[Cnt]->getType()),

5072 Data

.ReductionCopies[Cnt]->getExprLoc()),

5073

CGF.ConvertTypeForMem(

Data

.ReductionCopies[Cnt]->getType()),

5074

Replacement.getAlignment());

5075

Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);

5076 Scope

.addPrivate(RedCG.getBaseDecl(Cnt), Replacement);

5080

(void)

Scope

.Privatize();

5086 auto

IPriv =

C

->privates().begin();

5087 auto

IRed =

C

->reduction_ops().begin();

5088 auto

ITD =

C

->taskgroup_descriptors().begin();

5089 for

(

const Expr

*Ref :

C

->varlist()) {

5090

InRedVars.emplace_back(Ref);

5091

InRedPrivs.emplace_back(*IPriv);

5092

InRedOps.emplace_back(*IRed);

5093

TaskgroupDescriptors.emplace_back(*ITD);

5094

std::advance(IPriv, 1);

5095

std::advance(IRed, 1);

5096

std::advance(ITD, 1);

5101

OMPPrivateScope InRedScope(CGF);

5102 if

(!InRedVars.empty()) {

5104 for

(

unsigned

Cnt = 0,

E

= InRedVars.size(); Cnt <

E

; ++Cnt) {

5105

RedCG.emitSharedOrigLValue(CGF, Cnt);

5106

RedCG.emitAggregateType(CGF, Cnt);

5112

CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),

5114

llvm::Value *ReductionsPtr;

5115 if

(

const Expr

*TRExpr = TaskgroupDescriptors[Cnt]) {

5116

ReductionsPtr = CGF.EmitLoadOfScalar(CGF.EmitLValue(TRExpr),

5117

TRExpr->getExprLoc());

5119

ReductionsPtr = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);

5121 Address

Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(

5122

CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));

5124

CGF.EmitScalarConversion(

5125

Replacement.emitRawPointer(CGF), CGF.getContext().VoidPtrTy,

5126

CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()),

5127

InRedPrivs[Cnt]->getExprLoc()),

5128

CGF.ConvertTypeForMem(InRedPrivs[Cnt]->getType()),

5129

Replacement.getAlignment());

5130

Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);

5131

InRedScope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement);

5134

(void)InRedScope.Privatize();

5143

S, *I, *PartId, *TaskT, EKind, CodeGen,

Data

.Tied,

Data

.NumberOfParts);

5144

OMPLexicalScope

Scope

(*

this

, S, std::nullopt,

5147

TaskGen(*

this

, OutlinedFn,

Data

);

5164 QualType

ElemType =

C

.getBaseElementType(Ty);

5174 Data

.FirstprivateVars.emplace_back(OrigRef);

5175 Data

.FirstprivateCopies.emplace_back(PrivateRef);

5176 Data

.FirstprivateInits.emplace_back(InitRef);

5182

OMPTargetDataInfo &InputInfo) {

5188 auto

PartId = std::next(I);

5189 auto

TaskT = std::next(I, 4);

5192 Data

.Final.setInt(

false

);

5195 auto

IRef =

C

->varlist_begin();

5196 auto

IElemInitRef =

C

->inits().begin();

5197 for

(

auto

*IInit :

C

->private_copies()) {

5198 Data

.FirstprivateVars.push_back(*IRef);

5199 Data

.FirstprivateCopies.push_back(IInit);

5200 Data

.FirstprivateInits.push_back(*IElemInitRef);

5208 Data

.ReductionVars.append(

C

->varlist_begin(),

C

->varlist_end());

5209 Data

.ReductionOrigs.append(

C

->varlist_begin(),

C

->varlist_end());

5210 Data

.ReductionCopies.append(

C

->privates().begin(),

C

->privates().end());

5211 Data

.ReductionOps.append(

C

->reduction_ops().begin(),

5212 C

->reduction_ops().end());

5213

LHSs.append(

C

->lhs_exprs().begin(),

C

->lhs_exprs().end());

5214

RHSs.append(

C

->rhs_exprs().begin(),

C

->rhs_exprs().end());

5216

OMPPrivateScope TargetScope(*

this

);

5221 if

(InputInfo.NumberOfTargetItems > 0) {

5224

llvm::APInt ArrSize(

32, InputInfo.NumberOfTargetItems);

5229 getContext

(),

Data

, BaseAndPointerAndMapperType, CD, S.getBeginLoc());

5231 getContext

(),

Data

, BaseAndPointerAndMapperType, CD, S.getBeginLoc());

5238

TargetScope.addPrivate(BPVD, InputInfo.BasePointersArray);

5239

TargetScope.addPrivate(PVD, InputInfo.PointersArray);

5240

TargetScope.addPrivate(SVD, InputInfo.SizesArray);

5243 if

(!isa_and_nonnull<llvm::ConstantPointerNull>(

5244

InputInfo.MappersArray.emitRawPointer(*

this

))) {

5246 getContext

(),

Data

, BaseAndPointerAndMapperType, CD, S.getBeginLoc());

5247

TargetScope.addPrivate(MVD, InputInfo.MappersArray);

5250

(void)TargetScope.Privatize();

5253 auto

&&CodeGen = [&

Data

, &S, CS, &BodyGen, BPVD, PVD, SVD, MVD, EKind,

5256

OMPPrivateScope

Scope

(CGF);

5257 if

(!

Data

.FirstprivateVars.empty()) {

5258 enum

{ PrivatesParam = 2, CopyFnParam = 3 };

5259

llvm::Value *CopyFn = CGF.Builder.CreateLoad(

5260

CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));

5261

llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(

5262

CS->getCapturedDecl()->getParam(PrivatesParam)));

5267

CallArgs.push_back(PrivatesPtr);

5268

ParamTypes.push_back(PrivatesPtr->getType());

5269 for

(

const Expr

*

E

:

Data

.FirstprivateVars) {

5270 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

5272

CGF.CreateMemTemp(CGF.getContext().getPointerType(

E

->

getType

()),

5273 ".firstpriv.ptr.addr"

);

5274

PrivatePtrs.emplace_back(VD, PrivatePtr);

5275

CallArgs.push_back(PrivatePtr.

getPointer

());

5276

ParamTypes.push_back(PrivatePtr.

getType

());

5278 auto

*CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(),

5279

ParamTypes,

false

);

5280

CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(

5281

CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);

5282 for

(

const auto

&Pair : PrivatePtrs) {

5284

CGF.Builder.CreateLoad(Pair.second),

5285

CGF.ConvertTypeForMem(Pair.first->getType().getNonReferenceType()),

5286

CGF.getContext().getDeclAlign(Pair.first));

5287 Scope

.addPrivate(Pair.first, Replacement);

5290

CGF.processInReduction(S,

Data

, CGF, CS,

Scope

);

5291 if

(InputInfo.NumberOfTargetItems > 0) {

5292

InputInfo.BasePointersArray = CGF.Builder.CreateConstArrayGEP(

5293

CGF.GetAddrOfLocalVar(BPVD),

0);

5294

InputInfo.PointersArray = CGF.Builder.CreateConstArrayGEP(

5295

CGF.GetAddrOfLocalVar(PVD),

0);

5296

InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP(

5297

CGF.GetAddrOfLocalVar(SVD),

0);

5300

InputInfo.MappersArray = CGF.Builder.CreateConstArrayGEP(

5301

CGF.GetAddrOfLocalVar(MVD),

0);

5305

OMPLexicalScope LexScope(CGF, S, OMPD_task,

false

);

5307 if

(CGF.CGM.getLangOpts().OpenMP >= 51 &&

5312

CGF.CGM.getOpenMPRuntime().emitThreadLimitClause(

5313

CGF, TL->getThreadLimit().front(), S.getBeginLoc());

5318

S, *I, *PartId, *TaskT, EKind, CodeGen,

true

,

5319 Data

.NumberOfParts);

5320

llvm::APInt TrueOrFalse(32, S.hasClausesOfKind<

OMPNowaitClause

>() ? 1 : 0);

5325

SharedsTy, CapturedStruct, &IfCond,

Data

);

5332

OMPPrivateScope &

Scope

) {

5334 if

(

Data

.Reductions) {

5336

OMPLexicalScope LexScope(CGF, S, CapturedRegion);

5338 Data

.ReductionCopies,

Data

.ReductionOps);

5341 for

(

unsigned

Cnt = 0,

E

=

Data

.ReductionVars.size(); Cnt <

E

; ++Cnt) {

5342

RedCG.emitSharedOrigLValue(CGF, Cnt);

5343

RedCG.emitAggregateType(CGF, Cnt);

5350

CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));

5355 Data

.ReductionCopies[Cnt]->getType()),

5356 Data

.ReductionCopies[Cnt]->getExprLoc()),

5358

Replacement.getAlignment());

5359

Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);

5360 Scope

.addPrivate(RedCG.getBaseDecl(Cnt), Replacement);

5363

(void)

Scope

.Privatize();

5369 auto

IPriv =

C

->privates().begin();

5370 auto

IRed =

C

->reduction_ops().begin();

5371 auto

ITD =

C

->taskgroup_descriptors().begin();

5372 for

(

const Expr

*Ref :

C

->varlist()) {

5373

InRedVars.emplace_back(Ref);

5374

InRedPrivs.emplace_back(*IPriv);

5375

InRedOps.emplace_back(*IRed);

5376

TaskgroupDescriptors.emplace_back(*ITD);

5377

std::advance(IPriv, 1);

5378

std::advance(IRed, 1);

5379

std::advance(ITD, 1);

5382

OMPPrivateScope InRedScope(CGF);

5383 if

(!InRedVars.empty()) {

5385 for

(

unsigned

Cnt = 0,

E

= InRedVars.size(); Cnt <

E

; ++Cnt) {

5386

RedCG.emitSharedOrigLValue(CGF, Cnt);

5387

RedCG.emitAggregateType(CGF, Cnt);

5393

llvm::Value *ReductionsPtr;

5394 if

(

const Expr

*TRExpr = TaskgroupDescriptors[Cnt]) {

5398

ReductionsPtr = llvm::ConstantPointerNull::get(CGF.

VoidPtrTy

);

5401

CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));

5406

InRedPrivs[Cnt]->getExprLoc()),

5408

Replacement.getAlignment());

5409

Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);

5410

InRedScope.addPrivate(RedCG.getBaseDecl(Cnt), Replacement);

5413

(void)InRedScope.Privatize();

5421 const Expr

*IfCond =

nullptr

;

5422 for

(

const auto

*

C

: S.getClausesOfKind<

OMPIfClause

>()) {

5423 if

(

C

->getNameModifier() == OMPD_unknown ||

5424 C

->getNameModifier() == OMPD_task) {

5425

IfCond =

C

->getCondition();

5436 auto

&&TaskGen = [&S, SharedsTy, CapturedStruct,

5439

CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getBeginLoc(), S, OutlinedFn,

5440

SharedsTy, CapturedStruct, IfCond,

5457 bool

IsFatal =

false

;

5476 return T

.clauses().empty();

5481

OMPLexicalScope

Scope

(*

this

, S, OMPD_unknown);

5484 using

InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;

5488 auto

BodyGenCB = [&,

this

](InsertPointTy AllocaIP,

5489

InsertPointTy CodeGenIP) {

5490 Builder

.restoreIP(CodeGenIP);

5491 EmitStmt

(S.getInnermostCapturedStmt()->getCapturedStmt());

5492 return

llvm::Error::success();

5494

CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;

5497

llvm::OpenMPIRBuilder::InsertPointTy AfterIP =

5498

cantFail(OMPBuilder.createTaskgroup(

Builder

, AllocaIP, BodyGenCB));

5504 if

(

const Expr

*

E

= S.getReductionRef()) {

5509 Data

.ReductionVars.append(

C

->varlist_begin(),

C

->varlist_end());

5510 Data

.ReductionOrigs.append(

C

->varlist_begin(),

C

->varlist_end());

5511 Data

.ReductionCopies.append(

C

->privates().begin(),

C

->privates().end());

5512 Data

.ReductionOps.append(

C

->reduction_ops().begin(),

5513 C

->reduction_ops().end());

5514

LHSs.append(

C

->lhs_exprs().begin(),

C

->lhs_exprs().end());

5515

RHSs.append(

C

->rhs_exprs().begin(),

C

->rhs_exprs().end());

5517

llvm::Value *ReductionDesc =

5520 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

5525

CGF.

EmitStmt

(S.getInnermostCapturedStmt()->getCapturedStmt());

5532

? llvm::AtomicOrdering::NotAtomic

5533

: llvm::AtomicOrdering::AcquireRelease;

5537 if

(

const auto

*FlushClause = S.getSingleClause<

OMPFlushClause

>())

5539

FlushClause->varlist_end());

5542

S.getBeginLoc(), AO);

5552 for

(

auto

&Dep :

Data

.Dependences) {

5554

*

this

, Dep, DC->getBeginLoc());

5565

*

this

, DOLVal, UC->getDependencyKind(), UC->getBeginLoc());

5584 if

(

C

->getModifier() != OMPC_REDUCTION_inscan)

5586

Shareds.append(

C

->varlist_begin(),

C

->varlist_end());

5587

Privates.append(

C

->privates().begin(),

C

->privates().end());

5588

LHSs.append(

C

->lhs_exprs().begin(),

C

->lhs_exprs().end());

5589

RHSs.append(

C

->rhs_exprs().begin(),

C

->rhs_exprs().end());

5590

ReductionOps.append(

C

->reduction_ops().begin(),

C

->reduction_ops().end());

5591

CopyOps.append(

C

->copy_ops().begin(),

C

->copy_ops().end());

5592

CopyArrayTemps.append(

C

->copy_array_temps().begin(),

5593 C

->copy_array_temps().end());

5594

CopyArrayElems.append(

C

->copy_array_elems().begin(),

5595 C

->copy_array_elems().end());

5636

llvm::BasicBlock *OMPScanReduce =

createBasicBlock

(

"omp.inscan.reduce"

);

5639

: BreakContinueStack.back().ContinueBlock.getBlock());

5644

LexicalScope

Scope

(*

this

, S.getSourceRange());

5650 for

(

unsigned

I = 0,

E

= CopyArrayElems.size(); I <

E

; ++I) {

5651 const Expr

*PrivateExpr = Privates[I];

5652 const Expr

*TempExpr = CopyArrayTemps[I];

5654

*cast<VarDecl>(cast<DeclRefExpr>(TempExpr)->getDecl()));

5659

cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),

5660

cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),

5665

*

this

, ParentDir.

getEndLoc

(), Privates, LHSs, RHSs, ReductionOps,

5666

{

true,

true, OMPD_simd});

5667 for

(

unsigned

I = 0,

E

= CopyArrayElems.size(); I <

E

; ++I) {

5668 const Expr

*PrivateExpr = Privates[I];

5675 const Expr

*TempExpr = CopyArrayTemps[I];

5681

cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),

5682

cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()), CopyOps[I]);

5687

? BreakContinueStack.back().ContinueBlock.getBlock()

5693 EmitBranch

(BreakContinueStack.back().ContinueBlock.getBlock());

5698 const auto

*IVExpr = cast<OMPLoopDirective>(ParentDir)

5699

.getIterationVariable()

5704 for

(

unsigned

I = 0,

E

= CopyArrayElems.size(); I <

E

; ++I) {

5705 const Expr

*PrivateExpr = Privates[I];

5706 const Expr

*OrigExpr = Shareds[I];

5707 const Expr

*CopyArrayElem = CopyArrayElems[I];

5708

OpaqueValueMapping IdxMapping(

5710

cast<OpaqueValueExpr>(

5711

cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),

5717

cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),

5718

cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()), CopyOps[I]);

5721 EmitBranch

(BreakContinueStack.back().ContinueBlock.getBlock());

5724 EmitBranch

(BreakContinueStack.back().ContinueBlock.getBlock());

5729 const auto

*IVExpr = cast<OMPLoopDirective>(ParentDir)

5730

.getIterationVariable()

5735

llvm::BasicBlock *ExclusiveExitBB =

nullptr

;

5740 Builder

.CreateCondBr(Cmp, ExclusiveExitBB, ContBB);

5743

IdxVal =

Builder

.CreateNUWSub(IdxVal, llvm::ConstantInt::get(

SizeTy

, 1));

5745 for

(

unsigned

I = 0,

E

= CopyArrayElems.size(); I <

E

; ++I) {

5746 const Expr

*PrivateExpr = Privates[I];

5747 const Expr

*OrigExpr = Shareds[I];

5748 const Expr

*CopyArrayElem = CopyArrayElems[I];

5749

OpaqueValueMapping IdxMapping(

5751

cast<OpaqueValueExpr>(

5752

cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),

5758

cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),

5759

cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()), CopyOps[I]);

5774 const auto

*IVExpr = cast<DeclRefExpr>(S.getIterationVariable());

5775 const auto

*IVDecl = cast<VarDecl>(IVExpr->getDecl());

5781 if

(

const auto

*LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {

5789 bool

HasLastprivateClause =

false

;

5792

OMPLoopScope PreInitScope(*

this

, S);

5797

llvm::BasicBlock *ContBlock =

nullptr

;

5804 emitPreCond

(*

this

, S, S.getPreCond(), ThenBlock, ContBlock,

5816

*

this

, cast<DeclRefExpr>(

5818

? S.getCombinedLowerBoundVariable()

5819

: S.getLowerBoundVariable())));

5821

*

this

, cast<DeclRefExpr>(

5823

? S.getCombinedUpperBoundVariable()

5824

: S.getUpperBoundVariable())));

5830

OMPPrivateScope LoopScope(*

this

);

5836

*

this

, S.getBeginLoc(), OMPD_unknown,

false

,

5846

(void)LoopScope.Privatize();

5851

llvm::Value *Chunk =

nullptr

;

5854

ScheduleKind =

C

->getDistScheduleKind();

5855 if

(

const Expr

*Ch =

C

->getChunkSize()) {

5858

S.getIterationVariable()->getType(),

5864

*

this

, S, ScheduleKind, Chunk);

5877 bool

StaticChunked =

5881

Chunk !=

nullptr

) ||

5886

StaticChunked ? Chunk :

nullptr

);

5893

? S.getCombinedEnsureUpperBound()

5894

: S.getEnsureUpperBound());

5897

? S.getCombinedInit()

5902

? S.getCombinedCond()

5906

Cond = S.getCombinedDistCond();

5938

[&S, &LoopScope, Cond, IncExpr,

LoopExit

, &CodeGenLoop,

5940

CGF.EmitOMPInnerLoop(

5941

S, LoopScope.requiresCleanups(), Cond, IncExpr,

5943

CodeGenLoop(CGF, S, LoopExit);

5946

if (StaticChunked) {

5947

CGF.EmitIgnoredExpr(S.getCombinedNextLowerBound());

5948

CGF.EmitIgnoredExpr(S.getCombinedNextUpperBound());

5949

CGF.EmitIgnoredExpr(S.getCombinedEnsureUpperBound());

5950

CGF.EmitIgnoredExpr(S.getCombinedInit());

5960 const

OMPLoopArguments LoopArguments = {

5963

EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments,

5968 return

CGF.

Builder

.CreateIsNotNull(

5979 return

CGF.

Builder

.CreateIsNotNull(

5984 if

(HasLastprivateClause) {

6007

OMPLexicalScope

Scope

(CGF, S, OMPD_unknown);

6020

CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;

6023

Fn->setDoesNotRecurse();

6027template

<

typename

T>

6029

llvm::OpenMPIRBuilder::InsertPointTy AllocaIP,

6030

llvm::OpenMPIRBuilder &OMPBuilder) {

6032 unsigned

NumLoops =

C

->getNumLoops();

6036 for

(

unsigned

I = 0; I < NumLoops; I++) {

6037 const Expr

*CounterVal =

C

->getLoopData(I);

6042

StoreValues.emplace_back(StoreValue);

6044

OMPDoacrossKind<T> ODK;

6045 bool

IsDependSource = ODK.isSource(

C

);

6047

OMPBuilder.createOrderedDepend(CGF.

Builder

, AllocaIP, NumLoops,

6048

StoreValues,

".cnt.addr"

, IsDependSource));

6054 using

InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;

6059

assert(!S.hasAssociatedStmt() &&

"No associated statement must be in " 6060 "ordered depend|doacross construct."

);

6072 auto

FiniCB = [

this

](InsertPointTy IP) {

6074 return

llvm::Error::success();

6077 auto

BodyGenCB = [&S,

C

,

this

](InsertPointTy AllocaIP,

6078

InsertPointTy CodeGenIP) {

6079 Builder

.restoreIP(CodeGenIP);

6083

llvm::BasicBlock *FiniBB = splitBBWithSuffix(

6084 Builder

,

false

,

".ordered.after"

);

6087

llvm::Function *OutlinedFn =

6089

assert(S.getBeginLoc().isValid() &&

6090 "Outlined function call location must be valid."

);

6093

OutlinedFn, CapturedVars);

6098 return

llvm::Error::success();

6101

OMPLexicalScope

Scope

(*

this

, S, OMPD_unknown);

6102

llvm::OpenMPIRBuilder::InsertPointTy AfterIP = cantFail(

6103

OMPBuilder.createOrderedThreadsSimd(

Builder

, BodyGenCB, FiniCB, !

C

));

6110

assert(!S.hasAssociatedStmt() &&

6111 "No associated statement must be in ordered depend construct."

);

6117

assert(!S.hasAssociatedStmt() &&

6118 "No associated statement must be in ordered doacross construct."

);

6129

CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);

6130

llvm::Function *OutlinedFn =

6133

OutlinedFn, CapturedVars);

6139

OMPLexicalScope

Scope

(*

this

, S, OMPD_unknown);

6147 "DestType must have scalar evaluation kind."

);

6148

assert(!Val.

isAggregate

() &&

"Must be a scalar or complex."

);

6159 "DestType must have complex evaluation kind."

);

6168

ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));

6170

assert(Val.

isComplex

() &&

"Must be a scalar or complex."

);

6191

llvm::AtomicOrdering AO,

LValue

LVal,

6196

LVal,

Loc

, llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO),

6205

*

this

, RVal, RValTy, LVal.

getType

(),

Loc

)),

6214

llvm_unreachable(

"Must be a scalar or complex."

);

6222

assert(

V

->isLValue() &&

"V of 'omp atomic read' is not lvalue"

);

6223

assert(

X

->isLValue() &&

"X of 'omp atomic read' is not lvalue"

);

6232 case

llvm::AtomicOrdering::Acquire:

6233 case

llvm::AtomicOrdering::AcquireRelease:

6234 case

llvm::AtomicOrdering::SequentiallyConsistent:

6236

llvm::AtomicOrdering::Acquire);

6238 case

llvm::AtomicOrdering::Monotonic:

6239 case

llvm::AtomicOrdering::Release:

6241 case

llvm::AtomicOrdering::NotAtomic:

6242 case

llvm::AtomicOrdering::Unordered:

6243

llvm_unreachable(

"Unexpected ordering."

);

6250

llvm::AtomicOrdering AO,

const Expr

*

X

,

6253

assert(

X

->isLValue() &&

"X of 'omp atomic write' is not lvalue"

);

6261 case

llvm::AtomicOrdering::Release:

6262 case

llvm::AtomicOrdering::AcquireRelease:

6263 case

llvm::AtomicOrdering::SequentiallyConsistent:

6265

llvm::AtomicOrdering::Release);

6267 case

llvm::AtomicOrdering::Acquire:

6268 case

llvm::AtomicOrdering::Monotonic:

6270 case

llvm::AtomicOrdering::NotAtomic:

6271 case

llvm::AtomicOrdering::Unordered:

6272

llvm_unreachable(

"Unexpected ordering."

);

6279

llvm::AtomicOrdering AO,

6280 bool

IsXLHSInRHSPart) {

6285 if

(BO == BO_Comma || !

Update

.isScalar() || !

X

.isSimple() ||

6286

(!isa<llvm::ConstantInt>(

Update

.getScalarVal()) &&

6287

(

Update

.getScalarVal()->getType() !=

X

.getAddress().getElementType())) ||

6290 return

std::make_pair(

false

,

RValue::get

(

nullptr

));

6293 if

(

T

->isIntegerTy())

6296 if

(

T

->isFloatingPointTy() && (BO == BO_Add || BO == BO_Sub))

6302 if

(!CheckAtomicSupport(

Update

.getScalarVal()->getType(), BO) ||

6303

!CheckAtomicSupport(

X

.getAddress().getElementType(), BO))

6304 return

std::make_pair(

false

,

RValue::get

(

nullptr

));

6306 bool

IsInteger =

X

.getAddress().getElementType()->isIntegerTy();

6307

llvm::AtomicRMWInst::BinOp RMWOp;

6310

RMWOp = IsInteger ? llvm::AtomicRMWInst::Add : llvm::AtomicRMWInst::FAdd;

6313 if

(!IsXLHSInRHSPart)

6314 return

std::make_pair(

false

,

RValue::get

(

nullptr

));

6315

RMWOp = IsInteger ? llvm::AtomicRMWInst::Sub : llvm::AtomicRMWInst::FSub;

6318

RMWOp = llvm::AtomicRMWInst::And;

6321

RMWOp = llvm::AtomicRMWInst::Or;

6324

RMWOp = llvm::AtomicRMWInst::Xor;

6328

RMWOp =

X

.getType()->hasSignedIntegerRepresentation()

6329

? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min

6330

: llvm::AtomicRMWInst::Max)

6331

: (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin

6332

: llvm::AtomicRMWInst::UMax);

6334

RMWOp = IsXLHSInRHSPart ? llvm::AtomicRMWInst::FMin

6335

: llvm::AtomicRMWInst::FMax;

6339

RMWOp =

X

.getType()->hasSignedIntegerRepresentation()

6340

? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max

6341

: llvm::AtomicRMWInst::Min)

6342

: (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax

6343

: llvm::AtomicRMWInst::UMin);

6345

RMWOp = IsXLHSInRHSPart ? llvm::AtomicRMWInst::FMax

6346

: llvm::AtomicRMWInst::FMin;

6349

RMWOp = llvm::AtomicRMWInst::Xchg;

6358 return

std::make_pair(

false

,

RValue::get

(

nullptr

));

6377

llvm_unreachable(

"Unsupported atomic update operation"

);

6379

llvm::Value *UpdateVal =

Update

.getScalarVal();

6380 if

(

auto

*IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {

6382

UpdateVal = CGF.

Builder

.CreateIntCast(

6383

IC,

X

.getAddress().getElementType(),

6384 X

.getType()->hasSignedIntegerRepresentation());

6386

UpdateVal = CGF.

Builder

.CreateCast(llvm::Instruction::CastOps::UIToFP, IC,

6387 X

.getAddress().getElementType());

6389

llvm::AtomicRMWInst *Res =

6397 const

llvm::function_ref<

RValue

(

RValue

)> CommonGen) {

6406 if

(

X

.isGlobalReg()) {

6419

llvm::AtomicOrdering AO,

const Expr

*

X

,

6423 "Update expr in 'atomic update' must be a binary operator."

);

6431

assert(

X

->isLValue() &&

"X of 'omp atomic update' is not lvalue"

);

6434 const auto

*LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());

6435 const auto

*RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());

6438 auto

&&Gen = [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](

RValue

XRValue) {

6439

CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);

6440

CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);

6444

XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO,

Loc

, Gen);

6451 case

llvm::AtomicOrdering::Release:

6452 case

llvm::AtomicOrdering::AcquireRelease:

6453 case

llvm::AtomicOrdering::SequentiallyConsistent:

6455

llvm::AtomicOrdering::Release);

6457 case

llvm::AtomicOrdering::Acquire:

6458 case

llvm::AtomicOrdering::Monotonic:

6460 case

llvm::AtomicOrdering::NotAtomic:

6461 case

llvm::AtomicOrdering::Unordered:

6462

llvm_unreachable(

"Unexpected ordering."

);

6480

llvm_unreachable(

"Must be a scalar or complex."

);

6484

llvm::AtomicOrdering AO,

6485 bool

IsPostfixUpdate,

const Expr

*

V

,

6487 const Expr

*UE,

bool

IsXLHSInRHSPart,

6489

assert(

X

->isLValue() &&

"X of 'omp atomic capture' is not lvalue"

);

6490

assert(

V

->isLValue() &&

"V of 'omp atomic capture' is not lvalue"

);

6499 "Update expr in 'atomic capture' must be a binary operator."

);

6507 const auto

*LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());

6508 const auto

*RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());

6510

NewVValType = XRValExpr->

getType

();

6512 auto

&&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,

6513

IsPostfixUpdate](

RValue

XRValue) {

6514

CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);

6515

CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);

6517

NewVVal = IsPostfixUpdate ? XRValue : Res;

6521

XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO,

Loc

, Gen);

6525 if

(IsPostfixUpdate) {

6527

NewVVal = Res.second;

6531

CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);

6532

CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second);

6538

NewVValType =

X

->getType().getNonReferenceType();

6540 X

->getType().getNonReferenceType(),

Loc

);

6541 auto

&&Gen = [&NewVVal, ExprRValue](

RValue

XRValue) {

6547

XLValue, ExprRValue,

BO_Assign,

false

, AO,

6552

NewVVal = IsPostfixUpdate ? Res.

second

: ExprRValue;

6568 case

llvm::AtomicOrdering::Release:

6570

llvm::AtomicOrdering::Release);

6572 case

llvm::AtomicOrdering::Acquire:

6574

llvm::AtomicOrdering::Acquire);

6576 case

llvm::AtomicOrdering::AcquireRelease:

6577 case

llvm::AtomicOrdering::SequentiallyConsistent:

6579

CGF, {},

Loc

, llvm::AtomicOrdering::AcquireRelease);

6581 case

llvm::AtomicOrdering::Monotonic:

6583 case

llvm::AtomicOrdering::NotAtomic:

6584 case

llvm::AtomicOrdering::Unordered:

6585

llvm_unreachable(

"Unexpected ordering."

);

6591 CodeGenFunction

&CGF, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO,

6593 const Expr

*CE,

bool

IsXBinopExpr,

bool

IsPostfixUpdate,

bool

IsFailOnly,

6595

llvm::OpenMPIRBuilder &OMPBuilder =

6598

OMPAtomicCompareOp Op;

6599

assert(isa<BinaryOperator>(CE) &&

"CE is not a BinaryOperator"

);

6600 switch

(cast<BinaryOperator>(CE)->getOpcode()) {

6602

Op = OMPAtomicCompareOp::EQ;

6605

Op = OMPAtomicCompareOp::MIN;

6608

Op = OMPAtomicCompareOp::MAX;

6611

llvm_unreachable(

"unsupported atomic compare binary operator"

);

6617 auto

EmitRValueWithCastIfNeeded = [&CGF,

Loc

](

const Expr

*

X

,

const Expr

*

E

) {

6622 if

(NewE->

getType

() ==

X

->getType())

6627

llvm::Value *EVal = EmitRValueWithCastIfNeeded(

X

,

E

);

6628

llvm::Value *DVal =

D

? EmitRValueWithCastIfNeeded(

X

,

D

) :

nullptr

;

6629 if

(

auto

*CI = dyn_cast<llvm::ConstantInt>(EVal))

6630

EVal = CGF.

Builder

.CreateIntCast(

6634 if

(

auto

*CI = dyn_cast<llvm::ConstantInt>(DVal))

6635

DVal = CGF.

Builder

.CreateIntCast(

6637 D

->getType()->hasSignedIntegerRepresentation());

6639

llvm::OpenMPIRBuilder::AtomicOpValue XOpVal{

6641 X

->getType()->hasSignedIntegerRepresentation(),

6642 X

->getType().isVolatileQualified()};

6643

llvm::OpenMPIRBuilder::AtomicOpValue VOpVal, ROpVal;

6648 V

->getType()->hasSignedIntegerRepresentation(),

6649 V

->getType().isVolatileQualified()};

6659 if

(FailAO == llvm::AtomicOrdering::NotAtomic) {

6662

CGF.

Builder

.restoreIP(OMPBuilder.createAtomicCompare(

6663

CGF.

Builder

, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,

6664

IsPostfixUpdate, IsFailOnly));

6666

CGF.

Builder

.restoreIP(OMPBuilder.createAtomicCompare(

6667

CGF.

Builder

, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,

6668

IsPostfixUpdate, IsFailOnly, FailAO));

6672

llvm::AtomicOrdering AO,

6673

llvm::AtomicOrdering FailAO,

bool

IsPostfixUpdate,

6676 const Expr

*CE,

bool

IsXLHSInRHSPart,

6691

IsXLHSInRHSPart,

Loc

);

6693 case

OMPC_compare: {

6695

IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly,

Loc

);

6699

llvm_unreachable(

"Clause is not allowed in 'omp atomic'."

);

6706

llvm::AtomicOrdering FailAO = llvm::AtomicOrdering::NotAtomic;

6707 bool

MemOrderingSpecified =

false

;

6709

AO = llvm::AtomicOrdering::SequentiallyConsistent;

6710

MemOrderingSpecified =

true

;

6712

AO = llvm::AtomicOrdering::AcquireRelease;

6713

MemOrderingSpecified =

true

;

6715

AO = llvm::AtomicOrdering::Acquire;

6716

MemOrderingSpecified =

true

;

6718

AO = llvm::AtomicOrdering::Release;

6719

MemOrderingSpecified =

true

;

6721

AO = llvm::AtomicOrdering::Monotonic;

6722

MemOrderingSpecified =

true

;

6724

llvm::SmallSet<OpenMPClauseKind, 2> KindsEncountered;

6733 if

(K == OMPC_seq_cst || K == OMPC_acq_rel || K == OMPC_acquire ||

6734

K == OMPC_release || K == OMPC_relaxed || K == OMPC_hint)

6737

KindsEncountered.insert(K);

6742 if

(KindsEncountered.contains(OMPC_compare) &&

6743

KindsEncountered.contains(OMPC_capture))

6744 Kind

= OMPC_compare;

6745 if

(!MemOrderingSpecified) {

6746

llvm::AtomicOrdering DefaultOrder =

6748 if

(DefaultOrder == llvm::AtomicOrdering::Monotonic ||

6749

DefaultOrder == llvm::AtomicOrdering::SequentiallyConsistent ||

6750

(DefaultOrder == llvm::AtomicOrdering::AcquireRelease &&

6751

Kind == OMPC_capture)) {

6753

}

else if

(DefaultOrder == llvm::AtomicOrdering::AcquireRelease) {

6754 if

(Kind == OMPC_unknown || Kind == OMPC_update || Kind == OMPC_write) {

6755

AO = llvm::AtomicOrdering::Release;

6756

}

else if

(Kind == OMPC_read) {

6757

assert(Kind == OMPC_read &&

"Unexpected atomic kind."

);

6758

AO = llvm::AtomicOrdering::Acquire;

6763 if

(KindsEncountered.contains(OMPC_compare) &&

6764

KindsEncountered.contains(OMPC_fail)) {

6765 Kind

= OMPC_compare;

6766 const auto

*FailClause = S.getSingleClause<

OMPFailClause

>();

6769 if

(FailParameter == llvm::omp::OMPC_relaxed)

6770

FailAO = llvm::AtomicOrdering::Monotonic;

6771 else if

(FailParameter == llvm::omp::OMPC_acquire)

6772

FailAO = llvm::AtomicOrdering::Acquire;

6773 else if

(FailParameter == llvm::omp::OMPC_seq_cst)

6774

FailAO = llvm::AtomicOrdering::SequentiallyConsistent;

6778

LexicalScope

Scope

(*

this

, S.getSourceRange());

6781

S.getV(), S.getR(), S.getExpr(), S.getUpdateExpr(),

6782

S.getD(), S.getCondExpr(), S.isXLHSInRHSPart(),

6783

S.isFailOnly(), S.getBeginLoc());

6794

OMPLexicalScope

Scope

(CGF, S, OMPD_target);

6797

CGF.

EmitStmt

(S.getInnermostCapturedStmt()->getCapturedStmt());

6803

llvm::Function *Fn =

nullptr

;

6804

llvm::Constant *FnID =

nullptr

;

6806 const Expr

*IfCond =

nullptr

;

6808 for

(

const auto

*

C

: S.getClausesOfKind<

OMPIfClause

>()) {

6809 if

(

C

->getNameModifier() == OMPD_unknown ||

6810 C

->getNameModifier() == OMPD_target) {

6811

IfCond =

C

->getCondition();

6817

llvm::PointerIntPair<const Expr *, 2, OpenMPDeviceClauseModifier>

Device

(

6820 Device

.setPointerAndInt(

C

->getDevice(),

C

->getModifier());

6825 bool

IsOffloadEntry =

true

;

6829

IsOffloadEntry =

false

;

6832

IsOffloadEntry =

false

;

6834 if

(

CGM

.

getLangOpts

().OpenMPOffloadMandatory && !IsOffloadEntry) {

6837 "No offloading entry generated while offloading is mandatory."

);

6841

assert(CGF.

CurFuncDecl

&&

"No parent declaration for target region!"

);

6842

StringRef ParentName;

6845 if

(

const auto

*

D

= dyn_cast<CXXConstructorDecl>(CGF.

CurFuncDecl

))

6847 else if

(

const auto

*

D

= dyn_cast<CXXDestructorDecl>(CGF.

CurFuncDecl

))

6855

IsOffloadEntry, CodeGen);

6856

OMPLexicalScope

Scope

(CGF, S, OMPD_task);

6857 auto

&&SizeEmitter =

6860 if

(IsOffloadEntry) {

6861

OMPLoopScope(CGF,

D

);

6863

llvm::Value *NumIterations = CGF.

EmitScalarExpr

(

D

.getNumIterations());

6864

NumIterations = CGF.

Builder

.CreateIntCast(NumIterations, CGF.

Int64Ty

,

6866 return

NumIterations;

6876

Action.

Enter

(CGF);

6877

CodeGenFunction::OMPPrivateScope PrivateScope(CGF);

6880

(void)PrivateScope.Privatize();

6884

CGF.

EmitStmt

(S.getCapturedStmt(OMPD_target)->getCapturedStmt());

6889

StringRef ParentName,

6894

llvm::Function *

Fn

;

6895

llvm::Constant *Addr;

6898

S, ParentName, Fn, Addr,

true

, CodeGen);

6899

assert(Fn && Addr &&

"Target device function emission failed."

);

6913 const CapturedStmt

*CS = S.getCapturedStmt(OMPD_teams);

6914

llvm::Function *OutlinedFn =

6922 const Expr

*NumTeams = NT ? NT->getNumTeams().front() :

nullptr

;

6923 const Expr

*ThreadLimit = TL ? TL->getThreadLimit().front() :

nullptr

;

6929

OMPTeamsScope

Scope

(CGF, S);

6940

OMPPrivateScope PrivateScope(CGF);

6944

(void)PrivateScope.Privatize();

6945

CGF.

EmitStmt

(S.getCapturedStmt(OMPD_teams)->getCapturedStmt());

6955 auto

*CS = S.getCapturedStmt(OMPD_teams);

6956

Action.

Enter

(CGF);

6959

Action.

Enter

(CGF);

6960

CodeGenFunction::OMPPrivateScope PrivateScope(CGF);

6964

(void)PrivateScope.Privatize();

6981

llvm::Function *

Fn

;

6982

llvm::Constant *Addr;

6985

S, ParentName, Fn, Addr,

true

, CodeGen);

6986

assert(Fn && Addr &&

"Target device function emission failed."

);

7000

Action.

Enter

(CGF);

7008

Action.

Enter

(CGF);

7009

CodeGenFunction::OMPPrivateScope PrivateScope(CGF);

7011

(void)PrivateScope.Privatize();

7027

llvm::Function *

Fn

;

7028

llvm::Constant *Addr;

7031

S, ParentName, Fn, Addr,

true

, CodeGen);

7032

assert(Fn && Addr &&

"Target device function emission failed."

);

7046

Action.

Enter

(CGF);

7054

Action.

Enter

(CGF);

7055

CodeGenFunction::OMPPrivateScope PrivateScope(CGF);

7057

(void)PrivateScope.Privatize();

7073

llvm::Function *

Fn

;

7074

llvm::Constant *Addr;

7077

S, ParentName, Fn, Addr,

true

, CodeGen);

7078

assert(Fn && Addr &&

"Target device function emission failed."

);

7100

OMPPrivateScope PrivateScope(CGF);

7101

CGF.EmitOMPReductionClauseInit(S, PrivateScope);

7102

(void)PrivateScope.Privatize();

7103

CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,

7105

CGF.EmitOMPReductionClauseFinal(S,

OMPD_teams);

7122

OMPPrivateScope PrivateScope(CGF);

7123

CGF.EmitOMPReductionClauseInit(S, PrivateScope);

7124

(void)PrivateScope.Privatize();

7125

CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd,

7127

CGF.EmitOMPReductionClauseFinal(S,

OMPD_teams);

7145

OMPPrivateScope PrivateScope(CGF);

7146

CGF.EmitOMPReductionClauseInit(S, PrivateScope);

7147

(void)PrivateScope.Privatize();

7148

CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,

7150

CGF.EmitOMPReductionClauseFinal(S,

OMPD_teams);

7168

OMPPrivateScope PrivateScope(CGF);

7169

CGF.EmitOMPReductionClauseInit(S, PrivateScope);

7170

(void)PrivateScope.Privatize();

7171

CGF.CGM.getOpenMPRuntime().emitInlinedDirective(

7172

CGF, OMPD_distribute, CodeGenDistribute,

false

);

7173

CGF.EmitOMPReductionClauseFinal(S,

OMPD_teams);

7183

llvm::Value *

Device

=

nullptr

;

7184

llvm::Value *NumDependences =

nullptr

;

7185

llvm::Value *DependenceList =

nullptr

;

7193 if

(!

Data

.Dependences.empty()) {

7195

std::tie(NumDependences, DependenciesArray) =

7205 "OMPNowaitClause clause is used separately in OMPInteropDirective."

);

7207 auto

ItOMPInitClause = S.getClausesOfKind<

OMPInitClause

>();

7208 if

(!ItOMPInitClause.empty()) {

7211

llvm::Value *InteropvarPtr =

7213

llvm::omp::OMPInteropType InteropType =

7214

llvm::omp::OMPInteropType::Unknown;

7215 if

(

C

->getIsTarget()) {

7216

InteropType = llvm::omp::OMPInteropType::Target;

7218

assert(

C

->getIsTargetSync() &&

7219 "Expected interop-type target/targetsync"

);

7220

InteropType = llvm::omp::OMPInteropType::TargetSync;

7222

OMPBuilder.createOMPInteropInit(

Builder

, InteropvarPtr, InteropType,

7223 Device

, NumDependences, DependenceList,

7224 Data

.HasNowaitClause);

7228 if

(!ItOMPDestroyClause.empty()) {

7231

llvm::Value *InteropvarPtr =

7233

OMPBuilder.createOMPInteropDestroy(

Builder

, InteropvarPtr,

Device

,

7234

NumDependences, DependenceList,

7235 Data

.HasNowaitClause);

7238 auto

ItOMPUseClause = S.getClausesOfKind<

OMPUseClause

>();

7239 if

(!ItOMPUseClause.empty()) {

7242

llvm::Value *InteropvarPtr =

7244

OMPBuilder.createOMPInteropUse(

Builder

, InteropvarPtr,

Device

,

7245

NumDependences, DependenceList,

7246 Data

.HasNowaitClause);

7254

Action.

Enter

(CGF);

7263

Action.

Enter

(CGF);

7264

CodeGenFunction::OMPPrivateScope PrivateScope(CGF);

7266

(void)PrivateScope.Privatize();

7268

CGF, OMPD_distribute, CodeGenDistribute,

false

);

7286

llvm::Function *

Fn

;

7287

llvm::Constant *Addr;

7290

S, ParentName, Fn, Addr,

true

, CodeGen);

7291

assert(Fn && Addr &&

"Target device function emission failed."

);

7306

Action.

Enter

(CGF);

7315

Action.

Enter

(CGF);

7316

CodeGenFunction::OMPPrivateScope PrivateScope(CGF);

7318

(void)PrivateScope.Privatize();

7320

CGF, OMPD_distribute, CodeGenDistribute,

false

);

7338

llvm::Function *

Fn

;

7339

llvm::Constant *Addr;

7342

S, ParentName, Fn, Addr,

true

, CodeGen);

7343

assert(Fn && Addr &&

"Target device function emission failed."

);

7357

S.getCancelRegion());

7361 const Expr

*IfCond =

nullptr

;

7362 for

(

const auto

*

C

: S.getClausesOfKind<

OMPIfClause

>()) {

7363 if

(

C

->getNameModifier() == OMPD_unknown ||

7364 C

->getNameModifier() == OMPD_cancel) {

7365

IfCond =

C

->getCondition();

7373 if

(S.getCancelRegion() == OMPD_parallel ||

7374

S.getCancelRegion() == OMPD_sections ||

7375

S.getCancelRegion() == OMPD_section) {

7376

llvm::Value *IfCondition =

nullptr

;

7380

llvm::OpenMPIRBuilder::InsertPointTy AfterIP = cantFail(

7381

OMPBuilder.createCancel(

Builder

, IfCondition, S.getCancelRegion()));

7382 return Builder

.restoreIP(AfterIP);

7387

S.getCancelRegion());

7390

CodeGenFunction::JumpDest

7392 if

(Kind == OMPD_parallel || Kind == OMPD_task ||

7393

Kind == OMPD_target_parallel || Kind == OMPD_taskloop ||

7394

Kind == OMPD_master_taskloop || Kind == OMPD_parallel_master_taskloop)

7396

assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||

7397

Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||

7398

Kind == OMPD_distribute_parallel_for ||

7399

Kind == OMPD_target_parallel_for ||

7400

Kind == OMPD_teams_distribute_parallel_for ||

7401

Kind == OMPD_target_teams_distribute_parallel_for);

7402 return

OMPCancelStack.getExitBlock();

7407 const

llvm::DenseMap<const ValueDecl *, llvm::Value *>

7408

CaptureDeviceAddrMap) {

7409

llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>, 4> Processed;

7410 for

(

const Expr

*OrigVarIt :

C

.varlist()) {

7411 const auto

*OrigVD = cast<VarDecl>(cast<DeclRefExpr>(OrigVarIt)->getDecl());

7412 if

(!Processed.insert(OrigVD).second)

7419 if

(

const auto

*OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {

7422 const auto

*ME = cast<MemberExpr>(OED->getInit());

7423

assert(isa<CXXThisExpr>(ME->getBase()->IgnoreImpCasts()) &&

7424 "Base should be the current struct!"

);

7425

MatchingVD = ME->getMemberDecl();

7430 auto

InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);

7431 if

(InitAddrIt == CaptureDeviceAddrMap.end())

7437 bool

IsRegistered = PrivateScope.addPrivate(

7439 Address

(InitAddrIt->second, Ty,

7441

assert(IsRegistered &&

"firstprivate var already registered as private"

);

7449 while

(

const auto

*OASE = dyn_cast<ArraySectionExpr>(

Base

))

7450 Base

= OASE->getBase()->IgnoreParenImpCasts();

7451 while

(

const auto

*ASE = dyn_cast<ArraySubscriptExpr>(

Base

))

7452 Base

= ASE->getBase()->IgnoreParenImpCasts();

7453 return

cast<VarDecl>(cast<DeclRefExpr>(

Base

)->getDecl());

7458 const

llvm::DenseMap<const ValueDecl *, llvm::Value *>

7459

CaptureDeviceAddrMap) {

7460

llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>, 4> Processed;

7461 for

(

const Expr

*Ref :

C

.varlist()) {

7463 if

(!Processed.insert(OrigVD).second)

7469 if

(

const auto

*OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {

7472 const auto

*ME = cast<MemberExpr>(OED->getInit());

7473

assert(isa<CXXThisExpr>(ME->getBase()) &&

7474 "Base should be the current struct!"

);

7475

MatchingVD = ME->getMemberDecl();

7480 auto

InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);

7481 if

(InitAddrIt == CaptureDeviceAddrMap.end())

7487 Address

(InitAddrIt->second, Ty,

7491 if

(isa<DeclRefExpr>(Ref->IgnoreParenImpCasts()) ||

7500

(void)PrivateScope.addPrivate(OrigVD, PrivAddr);

7513 bool

PrivatizeDevicePointers =

false

;

7515 bool

&PrivatizeDevicePointers;

7518 explicit

DevicePointerPrivActionTy(

bool

&PrivatizeDevicePointers)

7519

: PrivatizeDevicePointers(PrivatizeDevicePointers) {}

7521

PrivatizeDevicePointers =

true

;

7524

DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);

7528

CGF.

EmitStmt

(S.getInnermostCapturedStmt()->getCapturedStmt());

7534

PrivatizeDevicePointers =

false

;

7540 if

(PrivatizeDevicePointers) {

7541

OMPPrivateScope PrivateScope(CGF);

7545

Info.CaptureDeviceAddrMap);

7548

Info.CaptureDeviceAddrMap);

7549

(void)PrivateScope.Privatize();

7554

std::optional<OpenMPDirectiveKind> CaptureRegion;

7558 for

(

const Expr

*

E

:

C

->varlist()) {

7559 const Decl

*

D

= cast<DeclRefExpr>(

E

)->getDecl();

7560 if

(

const auto

*OED = dyn_cast<OMPCapturedExprDecl>(

D

))

7564 for

(

const Expr

*

E

:

C

->varlist()) {

7566 if

(

const auto

*OED = dyn_cast<OMPCapturedExprDecl>(

D

))

7570

CaptureRegion = OMPD_unknown;

7573

OMPLexicalScope

Scope

(CGF, S, CaptureRegion);

7580

PrivRCG.setAction(Action);

7585

OMPLexicalScope

Scope

(CGF, S);

7600 const Expr

*IfCond =

nullptr

;

7601 if

(

const auto

*

C

= S.getSingleClause<

OMPIfClause

>())

7602

IfCond =

C

->getCondition();

7610

RCG.setAction(PrivAction);

7625 const Expr

*IfCond =

nullptr

;

7626 if

(

const auto

*

C

= S.getSingleClause<

OMPIfClause

>())

7627

IfCond =

C

->getCondition();

7634

OMPLexicalScope

Scope

(*

this

, S, OMPD_task);

7646 const Expr

*IfCond =

nullptr

;

7647 if

(

const auto

*

C

= S.getSingleClause<

OMPIfClause

>())

7648

IfCond =

C

->getCondition();

7655

OMPLexicalScope

Scope

(*

this

, S, OMPD_task);

7663 const CapturedStmt

*CS = S.getCapturedStmt(OMPD_parallel);

7664

Action.

Enter

(CGF);

7666

Action.

Enter

(CGF);

7667

CodeGenFunction::OMPPrivateScope PrivateScope(CGF);

7671

(void)PrivateScope.Privatize();

7690

llvm::Function *

Fn

;

7691

llvm::Constant *Addr;

7694

S, ParentName, Fn, Addr,

true

, CodeGen);

7695

assert(Fn && Addr &&

"Target device function emission failed."

);

7709

Action.

Enter

(CGF);

7713

Action.

Enter

(CGF);

7714

CodeGenFunction::OMPCancelStackRAII CancelRegion(

7715

CGF, OMPD_target_parallel_for, S.hasCancel());

7730

llvm::Function *

Fn

;

7731

llvm::Constant *Addr;

7734

S, ParentName, Fn, Addr,

true

, CodeGen);

7735

assert(Fn && Addr &&

"Target device function emission failed."

);

7750

Action.

Enter

(CGF);

7754

Action.

Enter

(CGF);

7769

llvm::Function *

Fn

;

7770

llvm::Constant *Addr;

7773

S, ParentName, Fn, Addr,

true

, CodeGen);

7774

assert(Fn && Addr &&

"Target device function emission failed."

);

7788

CodeGenFunction::OMPPrivateScope &Privates) {

7789 const auto

*VDecl = cast<VarDecl>(Helper->

getDecl

());

7796 const CapturedStmt

*CS = S.getCapturedStmt(OMPD_taskloop);

7799

OMPLexicalScope

Scope

(*

this

, S, OMPD_taskloop,

false

);

7803 const Expr

*IfCond =

nullptr

;

7804 for

(

const auto

*

C

: S.getClausesOfKind<

OMPIfClause

>()) {

7805 if

(

C

->getNameModifier() == OMPD_unknown ||

7806 C

->getNameModifier() == OMPD_taskloop) {

7807

IfCond =

C

->getCondition();

7820 Data

.Schedule.setInt(

false

);

7823

(Clause->getModifier() == OMPC_GRAINSIZE_strict) ?

true

:

false

;

7826 Data

.Schedule.setInt(

true

);

7829

(Clause->getModifier() == OMPC_NUMTASKS_strict) ?

true

:

false

;

7843

llvm::BasicBlock *ContBlock =

nullptr

;

7844

OMPLoopScope PreInitScope(CGF, S);

7845 if

(CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {

7849

llvm::BasicBlock *ThenBlock = CGF.createBasicBlock(

"taskloop.if.then"

);

7850

ContBlock = CGF.createBasicBlock(

"taskloop.if.end"

);

7851 emitPreCond

(CGF, S, S.getPreCond(), ThenBlock, ContBlock,

7852

CGF.getProfileCount(&S));

7853

CGF.EmitBlock(ThenBlock);

7854

CGF.incrementProfileCounter(&S);

7857

(void)CGF.EmitOMPLinearClauseInit(S);

7859

OMPPrivateScope LoopScope(CGF);

7861 enum

{ LowerBound = 5, UpperBound, Stride, LastIter };

7863 auto

*LBP = std::next(I, LowerBound);

7864 auto

*UBP = std::next(I, UpperBound);

7865 auto

*STP = std::next(I, Stride);

7866 auto

*LIP = std::next(I, LastIter);

7867 mapParam

(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP,

7869 mapParam

(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP,

7871 mapParam

(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope);

7872 mapParam

(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP,

7874

CGF.EmitOMPPrivateLoopCounters(S, LoopScope);

7875

CGF.EmitOMPLinearClause(S, LoopScope);

7876 bool

HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);

7877

(void)LoopScope.Privatize();

7879 const Expr

*IVExpr = S.getIterationVariable();

7880 const auto

*IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());

7881

CGF.EmitVarDecl(*IVDecl);

7882

CGF.EmitIgnoredExpr(S.getInit());

7887 if

(

const auto

*LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {

7888

CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));

7890

CGF.EmitIgnoredExpr(S.getCalcLastIteration());

7894

OMPLexicalScope

Scope

(CGF, S, OMPD_taskloop,

false

);

7902

CGF.EmitOMPInnerLoop(

7903

S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),

7905

emitOMPLoopBodyWithStopPoint(CGF, S,

7906

CodeGenFunction::JumpDest());

7913

CGF.EmitBranch(ContBlock);

7914

CGF.EmitBlock(ContBlock,

true

);

7917 if

(HasLastprivateClause) {

7918

CGF.EmitOMPLastprivateClauseFinal(

7920

CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(

7921

CGF.GetAddrOfLocalVar(*LIP),

false

,

7922

(*LIP)->getType(), S.getBeginLoc())));

7924

LoopScope.restoreMap();

7926 return

CGF.

Builder

.CreateIsNotNull(

7928

(*LIP)->

getType

(), S.getBeginLoc()));

7931 auto

&&TaskGen = [&S, SharedsTy, CapturedStruct,

7934 auto

&&CodeGen = [&S, OutlinedFn, SharedsTy, CapturedStruct, IfCond,

7936

OMPLoopScope PreInitScope(CGF, S);

7937

CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getBeginLoc(), S,

7938

OutlinedFn, SharedsTy,

7939

CapturedStruct, IfCond,

Data

);

7941

CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,

7944 if

(

Data

.Nogroup) {

7951

Action.

Enter

(CGF);

7969

OMPLexicalScope

Scope

(*

this

, S);

7976

Action.

Enter

(CGF);

7981

OMPLexicalScope

Scope

(*

this

, S, std::nullopt,

false

);

7988

Action.

Enter

(CGF);

7993

OMPLexicalScope

Scope

(*

this

, S, std::nullopt,

false

);

8000

Action.

Enter

(CGF);

8005

OMPLexicalScope

Scope

(*

this

, S);

8012

Action.

Enter

(CGF);

8017

OMPLexicalScope

Scope

(*

this

, S);

8026

Action.

Enter

(CGF);

8029

OMPLexicalScope

Scope

(CGF, S, OMPD_parallel,

false

);

8044

Action.

Enter

(CGF);

8047

OMPLexicalScope

Scope

(CGF, S, OMPD_parallel,

false

);

8062

Action.

Enter

(CGF);

8065

OMPLexicalScope

Scope

(CGF, S, OMPD_parallel,

false

);

8080

Action.

Enter

(CGF);

8083

OMPLexicalScope

Scope

(CGF, S, OMPD_parallel,

false

);

8102 const Expr

*IfCond =

nullptr

;

8103 if

(

const auto

*

C

= S.getSingleClause<

OMPIfClause

>())

8104

IfCond =

C

->getCondition();

8111

OMPLexicalScope

Scope

(*

this

, S, OMPD_task);

8122

BindKind =

C

->getBindKind();

8125 case

OMPC_BIND_parallel:

8127 case

OMPC_BIND_teams:

8129 case

OMPC_BIND_thread:

8140 const auto

*ForS = dyn_cast<ForStmt>(CS);

8141 if

(ForS && !isa<DeclStmt>(ForS->getInit())) {

8142

OMPPrivateScope LoopScope(CGF);

8144

(void)LoopScope.Privatize();

8146

LoopScope.restoreMap();

8151

OMPLexicalScope

Scope

(*

this

, S, OMPD_unknown);

8160

Action.

Enter

(CGF);

8185

Action.

Enter

(CGF);

8186

OMPPrivateScope PrivateScope(CGF);

8187

CGF.EmitOMPReductionClauseInit(S, PrivateScope);

8188

(void)PrivateScope.Privatize();

8189

CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,

8191

CGF.EmitOMPReductionClauseFinal(S,

OMPD_teams);

8200

std::string StatusMsg,

8204

StatusMsg +=

": DEVICE"

;

8206

StatusMsg +=

": HOST"

;

8213

llvm::dbgs() << StatusMsg <<

": "

<<

FileName

<<

": "

<< LineNo <<

"\n"

;

8220

Action.

Enter

(CGF);

8231

Action.

Enter

(CGF);

8232

CodeGenFunction::OMPPrivateScope PrivateScope(CGF);

8234

(void)PrivateScope.Privatize();

8236

CGF, OMPD_distribute, CodeGenDistribute,

false

);

8251

Action.

Enter

(CGF);

8260

Action.

Enter

(CGF);

8261

CodeGenFunction::OMPPrivateScope PrivateScope(CGF);

8263

(void)PrivateScope.Privatize();

8265

CGF, OMPD_distribute, CodeGenDistribute,

false

);

8279 if

(S.canBeParallelFor())

8292 if

(S.canBeParallelFor())

8297

llvm::Function *

Fn

;

8298

llvm::Constant *Addr;

8301

S, ParentName, Fn, Addr,

true

, CodeGen);

8302

assert(Fn && Addr &&

8303 "Target device function emission failed for 'target teams loop'."

);

8309

Action.

Enter

(CGF);

8312

Action.

Enter

(CGF);

8313

CodeGenFunction::OMPCancelStackRAII CancelRegion(

8314

CGF, OMPD_target_parallel_loop,

false

);

8329

llvm::Function *

Fn

;

8330

llvm::Constant *Addr;

8333

S, ParentName, Fn, Addr,

true

, CodeGen);

8334

assert(Fn && Addr &&

"Target device function emission failed."

);

8349 if

(

const auto

*SD = dyn_cast<OMPScanDirective>(&

D

)) {

8353 if

(!

D

.hasAssociatedStmt() || !

D

.getAssociatedStmt())

8356

OMPPrivateScope GlobalsScope(CGF);

8360 for

(

const Expr

*Ref :

C

->varlist()) {

8361 const auto

*DRE = cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());

8364 const auto

*VD = dyn_cast<VarDecl>(DRE->getDecl());

8367 if

(!CGF.LocalDeclMap.count(VD)) {

8369

GlobalsScope.addPrivate(VD, GlobLVal.

getAddress

());

8375

(void)GlobalsScope.Privatize();

8376

ParentLoopDirectiveForScanRegion ScanRegion(CGF,

D

);

8379 if

(

const auto

*LD = dyn_cast<OMPLoopDirective>(&

D

)) {

8380 for

(

const Expr

*

E

: LD->counters()) {

8381 const auto

*VD = cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl());

8384

GlobalsScope.addPrivate(VD, GlobLVal.

getAddress

());

8386 if

(isa<OMPCapturedExprDecl>(VD)) {

8388 if

(!CGF.LocalDeclMap.count(VD))

8393 if

(!

C

->getNumForLoops())

8395 for

(

unsigned

I = LD->getLoopsNumber(),

8396 E

=

C

->getLoopNumIterations().size();

8398 if

(

const auto

*VD = dyn_cast<OMPCapturedExprDecl>(

8399

cast<DeclRefExpr>(

C

->getLoopCounter(I))->getDecl())) {

8401 if

(!CGF.LocalDeclMap.count(VD))

8407

(void)GlobalsScope.Privatize();

8408

CGF.

EmitStmt

(

D

.getInnermostCapturedStmt()->getCapturedStmt());

8411 if

(

D

.getDirectiveKind() == OMPD_atomic ||

8412 D

.getDirectiveKind() == OMPD_critical ||

8413 D

.getDirectiveKind() == OMPD_section ||

8414 D

.getDirectiveKind() == OMPD_master ||

8415 D

.getDirectiveKind() == OMPD_masked ||

8416 D

.getDirectiveKind() == OMPD_unroll ||

8417 D

.getDirectiveKind() == OMPD_assume) {

8422

OMPSimdLexicalScope

Scope

(*

this

,

D

);

8426

:

D

.getDirectiveKind(),

Defines the clang::ASTContext interface.

static bool isAllocatableDecl(const VarDecl *VD)

static const VarDecl * getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE)

static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S, PrePostActionTy &Action)

static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S, PrePostActionTy &Action)

static llvm::Function * emitOutlinedOrderedFunction(CodeGenModule &CGM, const CapturedStmt *S, SourceLocation Loc)

static const VarDecl * getBaseDecl(const Expr *Ref)

static void emitTargetTeamsGenericLoopRegionAsParallel(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsGenericLoopDirective &S)

static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, const Expr *X, const Expr *V, SourceLocation Loc)

static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, bool IsPostfixUpdate, const Expr *V, const Expr *X, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)

static void emitScanBasedDirective(CodeGenFunction &CGF, const OMPLoopDirective &S, llvm::function_ref< llvm::Value *(CodeGenFunction &)> NumIteratorsGen, llvm::function_ref< void(CodeGenFunction &)> FirstGen, llvm::function_ref< void(CodeGenFunction &)> SecondGen)

Emits the code for the directive with inscan reductions.

static void emitSimpleAtomicStore(CodeGenFunction &CGF, llvm::AtomicOrdering AO, LValue LVal, RValue RVal)

static bool isSupportedByOpenMPIRBuilder(const OMPTaskgroupDirective &T)

static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc, QualType DstType, StringRef Name, LValue AddrLV)

static void emitDistributeParallelForDistributeInnerBoundParams(CodeGenFunction &CGF, const OMPExecutableDirective &S, llvm::SmallVectorImpl< llvm::Value * > &CapturedVars)

static void emitScanBasedDirectiveFinals(CodeGenFunction &CGF, const OMPLoopDirective &S, llvm::function_ref< llvm::Value *(CodeGenFunction &)> NumIteratorsGen)

Copies final inscan reductions values to the original variables.

static void checkForLastprivateConditionalUpdate(CodeGenFunction &CGF, const OMPExecutableDirective &S)

static std::pair< LValue, LValue > emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S)

The following two functions generate expressions for the loop lower and upper bounds in case of stati...

static void emitTargetParallelForRegion(CodeGenFunction &CGF, const OMPTargetParallelForDirective &S, PrePostActionTy &Action)

static LValue EmitOMPHelperVar(CodeGenFunction &CGF, const DeclRefExpr *Helper)

Emit a helper variable and return corresponding lvalue.

static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, const Expr *X, const Expr *E, const Expr *UE, bool IsXLHSInRHSPart, SourceLocation Loc)

static llvm::Value * convertToScalarValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)

static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)

static std::pair< bool, RValue > emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X, RValue Update, BinaryOperatorKind BO, llvm::AtomicOrdering AO, bool IsXLHSInRHSPart)

static std::pair< LValue, LValue > emitDistributeParallelForInnerBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S)

static void emitTargetTeamsGenericLoopRegionAsDistribute(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsGenericLoopDirective &S)

static void emitTargetParallelRegion(CodeGenFunction &CGF, const OMPTargetParallelDirective &S, PrePostActionTy &Action)

static std::pair< llvm::Value *, llvm::Value * > emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S, Address LB, Address UB)

When dealing with dispatch schedules (e.g.

static void emitMaster(CodeGenFunction &CGF, const OMPExecutableDirective &S)

static void emitRestoreIP(CodeGenFunction &CGF, const T *C, llvm::OpenMPIRBuilder::InsertPointTy AllocaIP, llvm::OpenMPIRBuilder &OMPBuilder)

static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, const RegionCodeGenTy &CodeGen)

static void emitSimdlenSafelenClause(CodeGenFunction &CGF, const OMPExecutableDirective &D)

static void emitAlignedClause(CodeGenFunction &CGF, const OMPExecutableDirective &D)

static bool isSimdSupportedByOpenMPIRBuilder(const OMPLoopDirective &S)

static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, const CodeGenBoundParametersTy &CodeGenBoundParameters)

static bool emitWorksharingDirective(CodeGenFunction &CGF, const OMPLoopDirective &S, bool HasCancel)

static void emitPostUpdateForReductionClause(CodeGenFunction &CGF, const OMPExecutableDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> CondGen)

static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc, const unsigned IVSize, const bool IVSigned)

static void emitTargetTeamsLoopCodegenStatus(CodeGenFunction &CGF, std::string StatusMsg, const OMPExecutableDirective &D)

static bool isForSupportedByOpenMPIRBuilder(const OMPLoopDirective &S, bool HasCancel)

static RValue emitSimpleAtomicLoad(CodeGenFunction &CGF, llvm::AtomicOrdering AO, LValue LVal, SourceLocation Loc)

static std::pair< llvm::Value *, llvm::Value * > emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S, Address LB, Address UB)

if the 'for' loop has a dispatch schedule (e.g.

static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO, bool IsPostfixUpdate, const Expr *X, const Expr *V, const Expr *R, const Expr *E, const Expr *UE, const Expr *D, const Expr *CE, bool IsXLHSInRHSPart, bool IsFailOnly, SourceLocation Loc)

static CodeGenFunction::ComplexPairTy convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, QualType DestType, SourceLocation Loc)

static ImplicitParamDecl * createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data, QualType Ty, CapturedDecl *CD, SourceLocation Loc)

static EmittedClosureTy emitCapturedStmtFunc(CodeGenFunction &ParentCGF, const CapturedStmt *S)

Emit a captured statement and return the function as well as its captured closure context.

static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF, const OMPLoopDirective &S, CodeGenFunction::JumpDest LoopExit)

static void emitOMPDistributeDirective(const OMPLoopDirective &S, CodeGenFunction &CGF, CodeGenModule &CGM)

static void emitOMPCopyinClause(CodeGenFunction &CGF, const OMPExecutableDirective &S)

static void emitTargetTeamsDistributeParallelForRegion(CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S, PrePostActionTy &Action)

static llvm::CallInst * emitCapturedStmtCall(CodeGenFunction &ParentCGF, EmittedClosureTy Cap, llvm::ArrayRef< llvm::Value * > Args)

Emit a call to a previously captured closure.

static void emitMasked(CodeGenFunction &CGF, const OMPExecutableDirective &S)

static void emitBody(CodeGenFunction &CGF, const Stmt *S, const Stmt *NextLoop, int MaxLevel, int Level=0)

static void emitOMPForDirective(const OMPLoopDirective &S, CodeGenFunction &CGF, CodeGenModule &CGM, bool HasCancel)

static void emitEmptyBoundParameters(CodeGenFunction &, const OMPExecutableDirective &, llvm::SmallVectorImpl< llvm::Value * > &)

static void emitTargetParallelForSimdRegion(CodeGenFunction &CGF, const OMPTargetParallelForSimdDirective &S, PrePostActionTy &Action)

static void emitOMPSimdDirective(const OMPLoopDirective &S, CodeGenFunction &CGF, CodeGenModule &CGM)

static void emitOMPAtomicCompareExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO, const Expr *X, const Expr *V, const Expr *R, const Expr *E, const Expr *D, const Expr *CE, bool IsXBinopExpr, bool IsPostfixUpdate, bool IsFailOnly, SourceLocation Loc)

std::pair< llvm::Function *, llvm::Value * > EmittedClosureTy

static OpenMPDirectiveKind getEffectiveDirectiveKind(const OMPExecutableDirective &S)

static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDirective &S)

static void buildDependences(const OMPExecutableDirective &S, OMPTaskDataTy &Data)

static RValue convertToType(CodeGenFunction &CGF, RValue Value, QualType SourceType, QualType ResType, SourceLocation Loc)

static void emitScanBasedDirectiveDecls(CodeGenFunction &CGF, const OMPLoopDirective &S, llvm::function_ref< llvm::Value *(CodeGenFunction &)> NumIteratorsGen)

Emits internal temp array declarations for the directive with inscan reductions.

static void emitTargetTeamsDistributeParallelForSimdRegion(CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForSimdDirective &S, PrePostActionTy &Action)

static void emitTargetTeamsDistributeSimdRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDistributeSimdDirective &S)

static llvm::MapVector< llvm::Value *, llvm::Value * > GetAlignedMapping(const OMPLoopDirective &S, CodeGenFunction &CGF)

static llvm::omp::ScheduleKind convertClauseKindToSchedKind(OpenMPScheduleClauseKind ScheduleClauseKind)

static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper, const ImplicitParamDecl *PVD, CodeGenFunction::OMPPrivateScope &Privates)

Emit a helper variable and return corresponding lvalue.

static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF, const OMPExecutableDirective &S, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)

static void emitTargetParallelGenericLoopRegion(CodeGenFunction &CGF, const OMPTargetParallelGenericLoopDirective &S, PrePostActionTy &Action)

static QualType getCanonicalParamType(ASTContext &C, QualType T)

static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S, const RegionCodeGenTy &SimdInitGen, const RegionCodeGenTy &BodyCodeGen)

static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, const Twine &Name, llvm::Value *Init=nullptr)

static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO, const Expr *X, const Expr *E, SourceLocation Loc)

static llvm::Function * emitOutlinedFunctionPrologue(CodeGenFunction &CGF, FunctionArgList &Args, llvm::MapVector< const Decl *, std::pair< const VarDecl *, Address > > &LocalAddrs, llvm::DenseMap< const Decl *, std::pair< const Expr *, llvm::Value * > > &VLASizes, llvm::Value *&CXXThisValue, const FunctionOptions &FO)

static void emitInnerParallelForWhenCombined(CodeGenFunction &CGF, const OMPLoopDirective &S, CodeGenFunction::JumpDest LoopExit)

static void emitTargetTeamsDistributeRegion(CodeGenFunction &CGF, PrePostActionTy &Action, const OMPTargetTeamsDistributeDirective &S)

enum clang::sema::@1704::IndirectLocalPathEntry::EntryKind Kind

This file defines OpenMP nodes for declarative directives.

static const Decl * getCanonicalDecl(const Decl *D)

This file defines OpenMP AST classes for clauses.

Defines some OpenMP-specific enums and functions.

Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...

Defines the SourceManager interface.

This file defines OpenMP AST classes for executable directives and clauses.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

SourceManager & getSourceManager()

TranslationUnitDecl * getTranslationUnitDecl() const

QualType getRecordType(const RecordDecl *Decl) const

QualType getPointerType(QualType T) const

Return the uniqued reference to the type for a pointer to the specified type.

QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const

Return the unique reference to the type for a constant array of the specified element type.

QualType getUIntPtrType() const

Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.

QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const

getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...

TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const

Allocate a TypeSourceInfo where all locations have been initialized to a given location,...

unsigned getOpenMPDefaultSimdAlign(QualType T) const

Get default simd alignment of the specified complete type in bits.

CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const

Return a conservative estimate of the alignment of the specified decl D.

int64_t toBits(CharUnits CharSize) const

Convert a size in characters to a size in bits.

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const

Return a normal function type with a typed argument list.

const TargetInfo & getTargetInfo() const

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

Represents an array type, per C99 6.7.5.2 - Array Declarators.

Represents an attribute applied to a statement.

ArrayRef< const Attr * > getAttrs() const

A builtin binary operation expression such as "x + y" or "x <= y".

static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)

BlockExpr - Adaptor class for mixing a BlockDecl with expressions.

Represents the body of a CapturedStmt, and serves as its DeclContext.

unsigned getContextParamPosition() const

static CapturedDecl * Create(ASTContext &C, DeclContext *DC, unsigned NumParams)

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...

ImplicitParamDecl * getParam(unsigned i) const

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.

Stmt * getCapturedStmt()

Retrieve the statement being captured.

Expr *const * const_capture_init_iterator

Const iterator that walks over the capture initialization arguments.

CharUnits - This is an opaque type for sizes expressed in character units.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

CharUnits alignmentOfArrayElement(CharUnits elementSize) const

Given that this is the alignment of the first element of an array, return the minimum alignment of an...

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

CharUnits alignTo(const CharUnits &Align) const

alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...

bool hasReducedDebugInfo() const

Check if type and variable info should be emitted.

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...

CharUnits getAlignment() const

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.

Address withAlignment(CharUnits NewAlignment) const

Return address with different alignment, but same pointer and element type.

llvm::PointerType * getType() const

Return the type of the pointer value.

static AggValueSlot ignored()

ignored - Returns an aggregate value slot indicating that the aggregate value is being ignored.

static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)

Apply TemporaryLocation if it is valid.

llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")

Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")

llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")

Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")

CGFunctionInfo - Class to encapsulate the information about a function definition.

Manages list of lastprivate conditional decls for the specified directive.

static LastprivateConditionalRAII disable(CodeGenFunction &CGF, const OMPExecutableDirective &S)

Manages list of nontemporal decls for the specified directive.

Struct that keeps all the relevant information that should be kept throughout a 'target data' region.

Manages list of nontemporal decls for the specified directive.

virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D, llvm::Function *TaskFunction, QualType SharedsTy, Address Shareds, const Expr *IfCond, const OMPTaskDataTy &Data)

Emit task region for the task directive.

virtual llvm::Value * emitForNext(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned, Address IL, Address LB, Address UB, Address ST)

Call __kmpc_dispatch_next( ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter, kmp_int[32|64] *p_lowe...

virtual void emitTargetDataStandAloneCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device)

Emit the data mapping/movement code associated with the directive D that should be of the form 'targe...

virtual void emitNumThreadsClause(CodeGenFunction &CGF, llvm::Value *NumThreads, SourceLocation Loc)

Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_threads)...

virtual void emitSingleRegion(CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen, SourceLocation Loc, ArrayRef< const Expr * > CopyprivateVars, ArrayRef< const Expr * > DestExprs, ArrayRef< const Expr * > SrcExprs, ArrayRef< const Expr * > AssignmentOps)

Emits a single region.

virtual Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *ReductionsPtr, LValue SharedLVal)

Get the address of void * type of the privatue copy of the reduction item specified by the SharedLVal...

virtual void emitForDispatchDeinit(CodeGenFunction &CGF, SourceLocation Loc)

This is used for non static scheduled types and when the ordered clause is present on the loop constr...

virtual void getDefaultScheduleAndChunk(CodeGenFunction &CGF, const OMPLoopDirective &S, OpenMPScheduleClauseKind &ScheduleKind, const Expr *&ChunkExpr) const

Choose default schedule type and chunk value for the schedule clause.

virtual void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, SourceLocation Loc, llvm::Function *OutlinedFn, ArrayRef< llvm::Value * > CapturedVars)

Emits code for teams call of the OutlinedFn with variables captured in a record which address is stor...

virtual void emitCancellationPointCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind CancelRegion)

Emit code for 'cancellation point' construct.

virtual const VarDecl * translateParameter(const FieldDecl *FD, const VarDecl *NativeParam) const

Translates the native parameter of outlined function if this is required for target.

virtual llvm::Function * emitTeamsOutlinedFunction(CodeGenFunction &CGF, const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)

Emits outlined function for the specified OpenMP teams directive D.

virtual void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D, ArrayRef< Expr * > NumIterations)

Emit initialization for doacross loop nesting support.

virtual void adjustTargetSpecificDataForLambdas(CodeGenFunction &CGF, const OMPExecutableDirective &D) const

Adjust some parameters for the target-based directives, like addresses of the variables captured by r...

virtual void emitTargetDataCalls(CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond, const Expr *Device, const RegionCodeGenTy &CodeGen, CGOpenMPRuntime::TargetDataInfo &Info)

Emit the target data mapping code associated with D.

virtual Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam, const VarDecl *TargetParam) const

Gets the address of the native argument basing on the address of the target-specific parameter.

virtual void emitTaskgroupRegion(CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen, SourceLocation Loc)

Emit a taskgroup region.

virtual void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams, const Expr *ThreadLimit, SourceLocation Loc)

Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_teams,...

virtual llvm::Value * emitTaskReductionInit(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr * > LHSExprs, ArrayRef< const Expr * > RHSExprs, const OMPTaskDataTy &Data)

Emit a code for initialization of task reduction clause.

void emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal, OpenMPDependClauseKind NewDepKind, SourceLocation Loc)

Updates the dependency kind in the specified depobj object.

virtual void emitLastprivateConditionalFinalUpdate(CodeGenFunction &CGF, LValue PrivLVal, const VarDecl *VD, SourceLocation Loc)

Gets the address of the global copy used for lastprivate conditional update, if any.

virtual void emitErrorCall(CodeGenFunction &CGF, SourceLocation Loc, Expr *ME, bool IsFatal)

Emit __kmpc_error call for error directive extern void __kmpc_error(ident_t *loc, int severity,...

virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc)

Emits code for a taskyield directive.

virtual void emitFlush(CodeGenFunction &CGF, ArrayRef< const Expr * > Vars, SourceLocation Loc, llvm::AtomicOrdering AO)

Emit flush of the variables specified in 'omp flush' directive.

virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc, const OMPTaskDataTy &Data)

Emit code for 'taskwait' directive.

virtual void emitProcBindClause(CodeGenFunction &CGF, llvm::omp::ProcBindKind ProcBind, SourceLocation Loc)

Emit call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid, int proc_bind) to generat...

virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind Kind, bool EmitChecks=true, bool ForceSimpleCall=false)

Emit an implicit/explicit barrier for OpenMP threads.

virtual void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values)

virtual void emitForStaticFinish(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind)

Call the appropriate runtime routine to notify that we finished all the work with current loop.

void emitIfClause(CodeGenFunction &CGF, const Expr *Cond, const RegionCodeGenTy &ThenGen, const RegionCodeGenTy &ElseGen)

Emits code for OpenMP 'if' clause using specified CodeGen function.

Address emitDepobjDependClause(CodeGenFunction &CGF, const OMPTaskDataTy::DependData &Dependencies, SourceLocation Loc)

Emits list of dependecies based on the provided data (array of dependence/expression pairs) for depob...

virtual llvm::Function * emitParallelOutlinedFunction(CodeGenFunction &CGF, const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen)

Emits outlined function for the specified OpenMP parallel directive D.

virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind, const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values)

Call the appropriate runtime routine to initialize it before start of loop.

llvm::AtomicOrdering getDefaultMemoryOrdering() const

Gets default memory ordering as specified in requires directive.

virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind, bool Chunked) const

Check if the specified ScheduleKind is static non-chunked.

virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc, const Expr *IfCond, OpenMPDirectiveKind CancelRegion)

Emit code for 'cancel' construct.

virtual void emitMasterRegion(CodeGenFunction &CGF, const RegionCodeGenTy &MasterOpGen, SourceLocation Loc)

Emits a master region.

virtual llvm::Function * emitTaskOutlinedFunction(const OMPExecutableDirective &D, const VarDecl *ThreadIDVar, const VarDecl *PartIDVar, const VarDecl *TaskTVar, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool Tied, unsigned &NumberOfParts)

Emits outlined function for the OpenMP task directive D.

void emitDestroyClause(CodeGenFunction &CGF, LValue DepobjLVal, SourceLocation Loc)

Emits the code to destroy the dependency object provided in depobj directive.

virtual void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc, ReductionCodeGen &RCG, unsigned N)

Required to resolve existing problems in the runtime.

virtual void emitDoacrossOrdered(CodeGenFunction &CGF, const OMPDependClause *C)

Emit code for doacross ordered directive with 'depend' clause.

virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)

Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...

virtual void getDefaultDistScheduleAndChunk(CodeGenFunction &CGF, const OMPLoopDirective &S, OpenMPDistScheduleClauseKind &ScheduleKind, llvm::Value *&Chunk) const

Choose default schedule type and chunk value for the dist_schedule clause.

llvm::OpenMPIRBuilder & getOMPBuilder()

virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D, StringRef ParentName, llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID, bool IsOffloadEntry, const RegionCodeGenTy &CodeGen)

Emit outilined function for 'target' directive.

virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName, const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc, const Expr *Hint=nullptr)

Emits a critical region.

virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF, SourceLocation Loc, unsigned IVSize, bool IVSigned)

Call the appropriate runtime routine to notify that we finished iteration of the ordered loop with th...

virtual void emitOutlinedFunctionCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::FunctionCallee OutlinedFn, ArrayRef< llvm::Value * > Args={}) const

Emits call of the outlined function with the provided arguments, translating these arguments to corre...

virtual void checkAndEmitSharedLastprivateConditional(CodeGenFunction &CGF, const OMPExecutableDirective &D, const llvm::DenseSet< CanonicalDeclPtr< const VarDecl > > &IgnoredDecls)

Checks if the lastprivate conditional was updated in inner region and writes the value.

virtual void emitInlinedDirective(CodeGenFunction &CGF, OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, bool HasCancel=false)

Emit code for the directive that does not require outlining.

virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Function *OutlinedFn, ArrayRef< llvm::Value * > CapturedVars, const Expr *IfCond, llvm::Value *NumThreads)

Emits code for parallel or serial call of the OutlinedFn with variables captured in a record which ad...

virtual bool isStaticChunked(OpenMPScheduleClauseKind ScheduleKind, bool Chunked) const

Check if the specified ScheduleKind is static chunked.

virtual void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D, llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond, llvm::PointerIntPair< const Expr *, 2, OpenMPDeviceClauseModifier > Device, llvm::function_ref< llvm::Value *(CodeGenFunction &CGF, const OMPLoopDirective &D)> SizeEmitter)

Emit the target offloading code associated with D.

virtual void emitReduction(CodeGenFunction &CGF, SourceLocation Loc, ArrayRef< const Expr * > Privates, ArrayRef< const Expr * > LHSExprs, ArrayRef< const Expr * > RHSExprs, ArrayRef< const Expr * > ReductionOps, ReductionOptionsTy Options)

Emit a code for reduction clause.

std::pair< llvm::Value *, Address > emitDependClause(CodeGenFunction &CGF, ArrayRef< OMPTaskDataTy::DependData > Dependencies, SourceLocation Loc)

Emits list of dependecies based on the provided data (array of dependence/expression pairs).

virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const

Check if the specified ScheduleKind is dynamic.

Address emitLastprivateConditionalInit(CodeGenFunction &CGF, const VarDecl *VD)

Create specialized alloca to handle lastprivate conditionals.

virtual void emitOrderedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &OrderedOpGen, SourceLocation Loc, bool IsThreads)

Emit an ordered region.

virtual void emitTaskReductionFini(CodeGenFunction &CGF, SourceLocation Loc, bool IsWorksharingReduction)

Emits the following code for reduction clause with task modifier:

virtual void emitMaskedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &MaskedOpGen, SourceLocation Loc, const Expr *Filter=nullptr)

Emits a masked region.

virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc, const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned, bool Ordered, const DispatchRTInput &DispatchValues)

Call the appropriate runtime routine to initialize it before start of loop.

virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S)

Emit the captured statement body.

virtual StringRef getHelperName() const

Get the name of the capture helper.

virtual const FieldDecl * lookup(const VarDecl *VD) const

Lookup the captured field decl for a variable.

RAII for preserving necessary info during inlined region body codegen.

Cleanup action for allocate support.

RAII for preserving necessary info during Outlined region body codegen.

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, const OpenMPDirectiveKind CapturedRegion, const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen, OMPTaskDataTy &Data)

void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S)

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

void EmitOMPParallelGenericLoopDirective(const OMPLoopDirective &S)

void EmitOMPAggregateAssign(Address DestAddr, Address SrcAddr, QualType OriginalType, const llvm::function_ref< void(Address, Address)> CopyGen)

Perform element by element copying of arrays with type OriginalType from SrcAddr to DestAddr using co...

void EmitOMPMaskedTaskLoopSimdDirective(const OMPMaskedTaskLoopSimdDirective &S)

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)

EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.

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...

void EmitOMPCopy(QualType OriginalType, Address DestAddr, Address SrcAddr, const VarDecl *DestVD, const VarDecl *SrcVD, const Expr *Copy)

Emit proper copying of data from one variable to another.

void EmitOMPOrderedDirective(const OMPOrderedDirective &S)

void EmitOMPTargetDirective(const OMPTargetDirective &S)

bool EmitOMPFirstprivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)

void EmitOMPReductionClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope, bool ForInscan=false)

Emit initial code for reduction variables.

void EmitOMPAtomicDirective(const OMPAtomicDirective &S)

void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S)

void EmitOMPParallelMasterTaskLoopDirective(const OMPParallelMasterTaskLoopDirective &S)

void EmitAutoVarDecl(const VarDecl &D)

EmitAutoVarDecl - Emit an auto variable declaration.

void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)

EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...

static void EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDirective &S)

Emit device code for the target teams directive.

void EmitOMPReverseDirective(const OMPReverseDirective &S)

static bool hasScalarEvaluationKind(QualType T)

llvm::function_ref< std::pair< llvm::Value *, llvm::Value * >(CodeGenFunction &, const OMPExecutableDirective &S, Address LB, Address UB)> CodeGenDispatchBoundsTy

CGCapturedStmtInfo * CapturedStmtInfo

void EmitDecl(const Decl &D)

EmitDecl - Emit a declaration.

static void EmitOMPTargetTeamsDistributeDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeDirective &S)

Emit device code for the target teams distribute directive.

Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)

Load a pointer with type PtrTy stored at address Ptr.

static void EmitOMPTargetParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForSimdDirective &S)

Emit device code for the target parallel for simd directive.

llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)

emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...

VlaSizePair getVLASize(const VariableArrayType *vla)

Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...

const OMPExecutableDirective * OMPParentLoopDirectiveForScan

Parent loop-based directive for scan directive.

void EmitOMPTeamsDistributeParallelForDirective(const OMPTeamsDistributeParallelForDirective &S)

void EmitOMPTaskDirective(const OMPTaskDirective &S)

void EmitOMPScanDirective(const OMPScanDirective &S)

void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S)

JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind)

void EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S)

void EmitOMPUseDevicePtrClause(const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope, const llvm::DenseMap< const ValueDecl *, llvm::Value * > CaptureDeviceAddrMap)

LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

EmitLValue - Emit code to compute a designator that specifies the location of the expression.

RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())

void EmitOMPDistributeLoop(const OMPLoopDirective &S, const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr)

Emit code for the distribute loop-based directive.

void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S)

static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetDirective &S)

Emit device code for the target directive.

llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)

createBasicBlock - Create an LLVM basic block.

void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO, const llvm::function_ref< RValue(RValue)> &UpdateOp, bool IsVolatile)

const LangOptions & getLangOpts() const

static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S)

Emit device code for the target simd directive.

void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S)

void EmitOMPPrivateLoopCounters(const OMPLoopDirective &S, OMPPrivateScope &LoopScope)

Emit initial code for loop counters of loop-based directives.

void EmitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective &S)

void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D, bool NoFinals, llvm::Value *IsLastIterCond=nullptr)

Emit final copying of lastprivate values to original variables at the end of the worksharing or simd ...

void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S)

void EmitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &S)

void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S)

Address EmitLoadOfReference(LValue RefLVal, LValueBaseInfo *PointeeBaseInfo=nullptr, TBAAAccessInfo *PointeeTBAAInfo=nullptr)

void EmitOMPParallelMaskedTaskLoopDirective(const OMPParallelMaskedTaskLoopDirective &S)

void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)

EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...

void EmitOMPParallelDirective(const OMPParallelDirective &S)

void EmitOMPSimdFinal(const OMPLoopDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> CondGen)

void EmitIgnoredExpr(const Expr *E)

EmitIgnoredExpr - Emit an expression in a context which ignores the result.

llvm::Type * ConvertTypeForMem(QualType T)

void EmitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective &S)

const Decl * CurCodeDecl

CurCodeDecl - This is the inner-most code context, which includes blocks.

void EmitOMPForSimdDirective(const OMPForSimdDirective &S)

llvm::AssertingVH< llvm::Instruction > AllocaInsertPt

AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...

void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy)

Emit an aggregate assignment.

void GenerateOpenMPCapturedVars(const CapturedStmt &S, SmallVectorImpl< llvm::Value * > &CapturedVars)

CodeGenFunction * ParentCGF

JumpDest ReturnBlock

ReturnBlock - Unified return block.

const llvm::function_ref< void(CodeGenFunction &, llvm::Function *, const OMPTaskDataTy &)> TaskGenTy

static void EmitOMPTargetTeamsGenericLoopDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsGenericLoopDirective &S)

Emit device code for the target teams loop directive.

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 EmitOMPFlushDirective(const OMPFlushDirective &S)

void EmitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective &S)

llvm::BasicBlock * OMPBeforeScanBlock

void EmitOMPCancelDirective(const OMPCancelDirective &S)

void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S)

void EmitOMPTargetTeamsDistributeDirective(const OMPTargetTeamsDistributeDirective &S)

ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)

void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S)

static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForDirective &S)

void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy, SourceLocation Loc)

void EmitOMPInnerLoop(const OMPExecutableDirective &S, bool RequiresCleanup, const Expr *LoopCond, const Expr *IncExpr, const llvm::function_ref< void(CodeGenFunction &)> BodyGen, const llvm::function_ref< void(CodeGenFunction &)> PostIncGen)

Emit inner loop of the worksharing/simd construct.

llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)

Converts Location to a DebugLoc, if debug information is enabled.

llvm::Value * getTypeSize(QualType Ty)

Returns calculated size of the specified type.

void EmitOMPDepobjDirective(const OMPDepobjDirective &S)

void EmitOMPSingleDirective(const OMPSingleDirective &S)

void EmitOMPTargetTeamsGenericLoopDirective(const OMPTargetTeamsGenericLoopDirective &S)

llvm::CanonicalLoopInfo * EmitOMPCollapsedCanonicalLoopNest(const Stmt *S, int Depth)

Emit the Stmt S and return its topmost canonical loop, if any.

void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D)

Emit simple code for OpenMP directives in Simd-only mode.

void EmitOMPDistributeDirective(const OMPDistributeDirective &S)

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 EmitOMPParallelForDirective(const OMPParallelForDirective &S)

void EmitOMPTeamsDirective(const OMPTeamsDirective &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 EmitOMPUnrollDirective(const OMPUnrollDirective &S)

void EmitOMPParallelMasterTaskLoopSimdDirective(const OMPParallelMasterTaskLoopSimdDirective &S)

void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S)

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)

Emit a conversion from the specified complex type to the specified destination type,...

bool isTrivialInitializer(const Expr *Init)

Determine whether the given initializer is trivial in the sense that it requires no code to be genera...

CGDebugInfo * getDebugInfo()

void EmitOMPTargetTeamsDistributeParallelForSimdDirective(const OMPTargetTeamsDistributeParallelForSimdDirective &S)

void EmitOMPTeamsDistributeParallelForSimdDirective(const OMPTeamsDistributeParallelForSimdDirective &S)

void EmitBranch(llvm::BasicBlock *Block)

EmitBranch - Emit a branch to the specified basic block from the current insert block,...

llvm::Function * GenerateCapturedStmtFunction(const CapturedStmt &S)

void EmitOMPInteropDirective(const OMPInteropDirective &S)

void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind)

Emit final update of reduction values to original variables at the end of the directive.

llvm::BasicBlock * OMPScanDispatch

llvm::function_ref< std::pair< LValue, LValue >(CodeGenFunction &, const OMPExecutableDirective &S)> CodeGenLoopBoundsTy

void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)

void EmitOMPTargetTaskBasedDirective(const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen, OMPTargetDataInfo &InputInfo)

void EmitOMPScopeDirective(const OMPScopeDirective &S)

void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S)

void EmitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &S)

static void EmitOMPTargetParallelForDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelForDirective &S)

Emit device code for the target parallel for directive.

void EmitOMPSimdInit(const OMPLoopDirective &D)

Helpers for the OpenMP loop directives.

int ExpectedOMPLoopDepth

Number of nested loop to be consumed by the last surrounding loop-associated directive.

void EmitVarDecl(const VarDecl &D)

EmitVarDecl - Emit a local variable declaration.

void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S)

ASTContext & getContext() const

llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)

EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...

const Decl * CurFuncDecl

CurFuncDecl - Holds the Decl for the current outermost non-closure context.

static void EmitOMPTargetTeamsDistributeSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeSimdDirective &S)

Emit device code for the target teams distribute simd directive.

SmallVector< llvm::CanonicalLoopInfo *, 4 > OMPLoopNestStack

List of recently emitted OMPCanonicalLoops.

bool EmitOMPWorksharingLoop(const OMPLoopDirective &S, Expr *EUB, const CodeGenLoopBoundsTy &CodeGenLoopBounds, const CodeGenDispatchBoundsTy &CGDispatchBounds)

Emit code for the worksharing loop-based directive.

void EmitOMPLinearClause(const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope)

Emit initial code for linear clauses.

void EmitBranchThroughCleanup(JumpDest Dest)

EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...

AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)

bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)

ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...

void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})

EmitStmt - Emit the code for the statement.

void EmitAutoVarCleanups(const AutoVarEmission &emission)

void EmitOMPTileDirective(const OMPTileDirective &S)

bool EmitOMPLinearClauseInit(const OMPLoopDirective &D)

Emit initial code for linear variables.

llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields

void EmitOMPParallelMaskedTaskLoopSimdDirective(const OMPParallelMaskedTaskLoopSimdDirective &S)

void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit)

Helper for the OpenMP loop directives.

void EmitOMPLinearClauseFinal(const OMPLoopDirective &D, const llvm::function_ref< llvm::Value *(CodeGenFunction &)> CondGen)

Emit final code for linear clauses.

void EmitOMPSectionsDirective(const OMPSectionsDirective &S)

llvm::BasicBlock * OMPScanExitBlock

static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetTeamsDistributeParallelForSimdDirective &S)

Emit device code for the target teams distribute parallel for simd directive.

void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst)

void EmitOMPUseDeviceAddrClause(const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope, const llvm::DenseMap< const ValueDecl *, llvm::Value * > CaptureDeviceAddrMap)

void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S)

void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)

void EmitOMPSimdDirective(const OMPSimdDirective &S)

void EmitOMPCriticalDirective(const OMPCriticalDirective &S)

void EmitOMPForDirective(const OMPForDirective &S)

void EmitOMPMetaDirective(const OMPMetaDirective &S)

llvm::Value * EvaluateExprAsBool(const Expr *E)

EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...

void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S)

LValue InitCapturedStruct(const CapturedStmt &S)

void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S)

void EmitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective &S)

void processInReduction(const OMPExecutableDirective &S, OMPTaskDataTy &Data, CodeGenFunction &CGF, const CapturedStmt *CS, OMPPrivateScope &Scope)

void EmitOMPMasterDirective(const OMPMasterDirective &S)

void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S)

void EmitOMPTargetParallelGenericLoopDirective(const OMPTargetParallelGenericLoopDirective &S)

void EmitOMPAssumeDirective(const OMPAssumeDirective &S)

bool EmitOMPCopyinClause(const OMPExecutableDirective &D)

Emit code for copyin clause in D directive.

void EmitOMPMaskedDirective(const OMPMaskedDirective &S)

uint64_t getProfileCount(const Stmt *S)

Get the profiler's count for the given statement.

void EmitOMPPrivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)

void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S)

llvm::Function * GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, SourceLocation Loc)

void EmitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective &S)

LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)

void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)

EmitStoreOfComplex - Store a complex number into the specified l-value.

Address GenerateCapturedStmtArgument(const CapturedStmt &S)

static void EmitOMPTargetParallelGenericLoopDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelGenericLoopDirective &S)

Emit device code for the target parallel loop directive.

llvm::function_ref< void(CodeGenFunction &, SourceLocation, const unsigned, const bool)> CodeGenOrderedTy

LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

Address GetAddrOfLocalVar(const VarDecl *VD)

GetAddrOfLocalVar - Return the address of a local variable.

void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)

llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)

Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...

llvm::BasicBlock * OMPAfterScanBlock

std::pair< llvm::Value *, llvm::Value * > ComplexPairTy

void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S)

void EmitOMPErrorDirective(const OMPErrorDirective &S)

void EmitOMPSectionDirective(const OMPSectionDirective &S)

static void EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName, const OMPTargetParallelDirective &S)

llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)

Emit an atomicrmw instruction, and applying relevant metadata when applicable.

void EmitOMPBarrierDirective(const OMPBarrierDirective &S)

void EmitStopPoint(const Stmt *S)

EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.

void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)

void EnsureInsertPoint()

EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.

llvm::LLVMContext & getLLVMContext()

void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S)

llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)

EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...

void EmitOMPTargetTeamsDistributeParallelForDirective(const OMPTargetTeamsDistributeParallelForDirective &S)

void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)

Increment the profiler's counter for the given statement by StepV.

bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope)

Emit initial code for lastprivate variables.

void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S)

llvm::function_ref< void(CodeGenFunction &, const OMPLoopDirective &, JumpDest)> CodeGenLoopTy

void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S)

Emit an OMPCanonicalLoop using the OpenMPIRBuilder.

void EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S)

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 EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S)

std::pair< bool, RValue > EmitOMPAtomicSimpleUpdateExpr(LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart, llvm::AtomicOrdering AO, SourceLocation Loc, const llvm::function_ref< RValue(RValue)> CommonGen)

Emit atomic update code for constructs: X = X BO E or X = E BO E.

This class organizes the cross-function state that is used while generating LLVM code.

void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)

Set the attributes on the LLVM function for the given decl and function info.

llvm::Module & getModule() const

CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const

Return the store size, in character units, of the given LLVM type.

DiagnosticsEngine & getDiags() const

const LangOptions & getLangOpts() const

CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)

CodeGenTypes & getTypes()

const llvm::DataLayout & getDataLayout() const

CGOpenMPRuntime & getOpenMPRuntime()

Return a reference to the configured OpenMP runtime.

llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)

ASTContext & getContext() const

const CodeGenOptions & getCodeGenOpts() const

StringRef getMangledName(GlobalDecl GD)

llvm::Constant * getStaticLocalDeclAddress(const VarDecl *D)

llvm::ConstantInt * getSize(CharUnits numChars)

Emit the given number of characters as a value of type size_t.

void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)

Assign counters to regions and configure them for PGO of a given function.

llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)

GetFunctionType - Get the LLVM function type for.

const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)

A builtin function is a freestanding function using the default C conventions.

llvm::Type * ConvertTypeForMem(QualType T)

ConvertTypeForMem - Convert type T into a llvm::Type.

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

void setAddress(Address address)

void setUnrollCount(unsigned C)

Set the unroll count for the next loop pushed.

void setVectorizeWidth(unsigned W)

Set the vectorize width for the next loop pushed.

void setParallel(bool Enable=true)

Set the next pushed loop as parallel.

void setUnrollState(const LoopAttributes::LVEnableState &State)

Set the next pushed loop unroll state.

void pop()

End the current loop.

void push(llvm::BasicBlock *Header, const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)

Begin a new structured loop.

void setVectorizeEnable(bool Enable=true)

Set the next pushed loop 'vectorize.enable'.

A basic class for pre|post-action for advanced codegen sequence for OpenMP region.

virtual void Enter(CodeGenFunction &CGF)

RValue - This trivial value class is used to represent the result of an expression that is evaluated.

static RValue get(llvm::Value *V)

static RValue getComplex(llvm::Value *V1, llvm::Value *V2)

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.

An abstract representation of an aligned address.

llvm::PointerType * getType() const

Return the type of the pointer value.

llvm::Value * getPointer() const

Class intended to support codegen of all kind of the reduction clauses.

void emitAggregateType(CodeGenFunction &CGF, unsigned N)

Emits the code for the variable-modified type, if required.

void emitSharedOrigLValue(CodeGenFunction &CGF, unsigned N)

Emits lvalue for the shared and original reduction item.

Class provides a way to call simple version of codegen for OpenMP region, or an advanced with possibl...

Complex values, per C99 6.2.5p11.

CompoundStmt - This represents a group of statements like { stmt stmt }.

ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.

DeclContext * getParent()

getParent - Returns the containing DeclContext.

A reference to a declared variable, function, enum, etc.

static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

Decl - This represents one declaration (or definition), e.g.

SourceLocation getEndLoc() const LLVM_READONLY

virtual Stmt * getBody() const

getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...

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

SourceLocation getBeginLoc() const LLVM_READONLY

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

The name of a declaration.

SourceLocation getBeginLoc() const LLVM_READONLY

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

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 * IgnoreParenImpCasts() LLVM_READONLY

Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...

Expr * IgnoreImplicitAsWritten() LLVM_READONLY

Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

Represents difference between two FPOptions values.

Represents a member of a struct/union/class.

Represents a function declaration or definition.

static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, Expr *TrailingRequiresClause=nullptr)

GlobalDecl - represents a global declaration.

One of these records is kept for each identifier that is lexed.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)

static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)

Create implicit parameter.

A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...

std::vector< llvm::Triple > OMPTargetTriples

Triples of the OpenMP targets that the host code codegen should take into account in order to generat...

Represents a point when we exit a loop.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

A C++ nested-name-specifier augmented with source location information.

This represents 'acq_rel' clause in the '#pragma omp atomic|flush' directives.

This represents 'acquire' clause in the '#pragma omp atomic|flush' directives.

This represents clause 'aligned' in the '#pragma omp ...' directives.

This represents '#pragma omp atomic' directive.

This represents '#pragma omp barrier' directive.

This represents 'bind' clause in the '#pragma omp ...' directives.

This represents '#pragma omp cancel' directive.

This represents '#pragma omp cancellation point' directive.

Representation of an OpenMP canonical loop.

static OMPClauseWithPreInit * get(OMPClause *C)

This is a basic class for representing single OpenMP clause.

This represents clause 'copyin' in the '#pragma omp ...' directives.

This represents clause 'copyprivate' in the '#pragma omp ...' directives.

This represents '#pragma omp critical' directive.

This represents implicit clause 'depend' for the '#pragma omp task' directive.

This represents implicit clause 'depobj' for the '#pragma omp depobj' directive.

This represents '#pragma omp depobj' directive.

This represents 'destroy' clause in the '#pragma omp depobj' directive or the '#pragma omp interop' d...

This represents 'device' clause in the '#pragma omp ...' directive.

This represents 'dist_schedule' clause in the '#pragma omp ...' directive.

This represents '#pragma omp distribute' directive.

This represents '#pragma omp distribute parallel for' composite directive.

This represents '#pragma omp distribute parallel for simd' composite directive.

This represents '#pragma omp distribute simd' composite directive.

This represents the 'doacross' clause for the '#pragma omp ordered' directive.

This represents '#pragma omp error' directive.

This is a basic class for representing single OpenMP executable directive.

OpenMPDirectiveKind getDirectiveKind() const

SourceLocation getEndLoc() const

Returns ending location of directive.

static llvm::iterator_range< specific_clause_iterator< SpecificClause > > getClausesOfKind(ArrayRef< OMPClause * > Clauses)

This represents 'fail' clause in the '#pragma omp atomic' directive.

OpenMPClauseKind getFailParameter() const

Gets the parameter (type memory-order-clause) in Fail clause.

This represents 'filter' clause in the '#pragma omp ...' directive.

This represents 'final' clause in the '#pragma omp ...' directive.

This represents clause 'firstprivate' in the '#pragma omp ...' directives.

This represents implicit clause 'flush' for the '#pragma omp flush' directive.

This represents '#pragma omp flush' directive.

This represents '#pragma omp for' directive.

This represents '#pragma omp for simd' directive.

Representation of the 'full' clause of the '#pragma omp unroll' directive.

This represents '#pragma omp loop' directive.

This represents 'grainsize' clause in the '#pragma omp ...' directive.

This represents 'hint' clause in the '#pragma omp ...' directive.

This represents 'if' clause in the '#pragma omp ...' directive.

This represents clause 'in_reduction' in the '#pragma omp task' directives.

This represents clause 'inclusive' in the '#pragma omp scan' directive.

This represents the 'init' clause in '#pragma omp ...' directives.

Represents the '#pragma omp interchange' loop transformation directive.

This represents '#pragma omp interop' directive.

This represents clause 'lastprivate' in the '#pragma omp ...' directives.

This represents clause 'linear' in the '#pragma omp ...' directives.

The base class for all loop-based directives, including loop transformation directives.

static Stmt * tryToFindNextInnerLoop(Stmt *CurStmt, bool TryImperfectlyNestedLoops)

Try to find the next loop sub-statement in the specified statement CurStmt.

static bool doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, llvm::function_ref< bool(unsigned, Stmt *)> Callback, llvm::function_ref< void(OMPLoopTransformationDirective *)> OnTransformationCallback)

Calls the specified callback function for all the loops in CurStmt, from the outermost to the innermo...

This is a common base class for loop directives ('omp simd', 'omp for', 'omp for simd' etc....

Expr * getPrevUpperBoundVariable() const

Expr * getPrevLowerBoundVariable() const

Expr * getIterationVariable() const

Expr * getUpperBoundVariable() const

Expr * getLowerBoundVariable() const

This represents '#pragma omp masked' directive.

This represents '#pragma omp masked taskloop' directive.

This represents '#pragma omp masked taskloop simd' directive.

This represents '#pragma omp master' directive.

This represents '#pragma omp master taskloop' directive.

This represents '#pragma omp master taskloop simd' directive.

This represents 'message' clause in the '#pragma omp error' directive.

Expr * getMessageString() const

Returns message string of the clause.

This represents 'nogroup' clause in the '#pragma omp ...' directive.

This represents 'nowait' clause in the '#pragma omp ...' directive.

This represents 'num_tasks' clause in the '#pragma omp ...' directive.

This represents 'num_teams' clause in the '#pragma omp ...' directive.

This represents 'num_threads' clause in the '#pragma omp ...' directive.

This represents 'order' clause in the '#pragma omp ...' directive.

This represents 'ordered' clause in the '#pragma omp ...' directive.

This represents '#pragma omp ordered' directive.

This represents '#pragma omp parallel' directive.

This represents '#pragma omp parallel for' directive.

This represents '#pragma omp parallel for simd' directive.

This represents '#pragma omp parallel masked' directive.

This represents '#pragma omp parallel masked taskloop' directive.

This represents '#pragma omp parallel masked taskloop simd' directive.

This represents '#pragma omp parallel master' directive.

This represents '#pragma omp parallel master taskloop' directive.

This represents '#pragma omp parallel master taskloop simd' directive.

This represents '#pragma omp parallel sections' directive.

Representation of the 'partial' clause of the '#pragma omp unroll' directive.

This represents 'priority' clause in the '#pragma omp ...' directive.

This represents clause 'private' in the '#pragma omp ...' directives.

This represents 'proc_bind' clause in the '#pragma omp ...' directive.

This represents clause 'reduction' in the '#pragma omp ...' directives.

This represents 'relaxed' clause in the '#pragma omp atomic' directives.

This represents 'release' clause in the '#pragma omp atomic|flush' directives.

Represents the '#pragma omp reverse' loop transformation directive.

This represents 'simd' clause in the '#pragma omp ...' directive.

This represents 'safelen' clause in the '#pragma omp ...' directive.

This represents '#pragma omp scan' directive.

This represents 'schedule' clause in the '#pragma omp ...' directive.

This represents '#pragma omp scope' directive.

This represents '#pragma omp section' directive.

This represents '#pragma omp sections' directive.

This represents 'seq_cst' clause in the '#pragma omp atomic|flush' directives.

This represents 'severity' clause in the '#pragma omp error' directive.

OpenMPSeverityClauseKind getSeverityKind() const

Returns kind of the clause.

This represents '#pragma omp simd' directive.

This represents 'simdlen' clause in the '#pragma omp ...' directive.

This represents '#pragma omp single' directive.

This represents '#pragma omp target data' directive.

This represents '#pragma omp target' directive.

This represents '#pragma omp target enter data' directive.

This represents '#pragma omp target exit data' directive.

This represents '#pragma omp target parallel' directive.

This represents '#pragma omp target parallel for' directive.

This represents '#pragma omp target parallel for simd' directive.

This represents '#pragma omp target parallel loop' directive.

This represents '#pragma omp target simd' directive.

This represents '#pragma omp target teams' directive.

This represents '#pragma omp target teams distribute' combined directive.

This represents '#pragma omp target teams distribute parallel for' combined directive.

This represents '#pragma omp target teams distribute parallel for simd' combined directive.

This represents '#pragma omp target teams distribute simd' combined directive.

This represents '#pragma omp target teams loop' directive.

This represents '#pragma omp target update' directive.

This represents '#pragma omp task' directive.

This represents '#pragma omp taskloop' directive.

This represents '#pragma omp taskloop simd' directive.

This represents clause 'task_reduction' in the '#pragma omp taskgroup' directives.

This represents '#pragma omp taskgroup' directive.

This represents '#pragma omp taskwait' directive.

This represents '#pragma omp taskyield' directive.

This represents '#pragma omp teams' directive.

This represents '#pragma omp teams distribute' directive.

This represents '#pragma omp teams distribute parallel for' composite directive.

This represents '#pragma omp teams distribute parallel for simd' composite directive.

This represents '#pragma omp teams distribute simd' combined directive.

This represents '#pragma omp teams loop' directive.

This represents 'thread_limit' clause in the '#pragma omp ...' directive.

This represents the '#pragma omp tile' loop transformation directive.

This represents the '#pragma omp unroll' loop transformation directive.

This represents 'untied' clause in the '#pragma omp ...' directive.

This represents 'update' clause in the '#pragma omp atomic' directive.

This represents the 'use' clause in '#pragma omp ...' directives.

This represents clause 'use_device_addr' in the '#pragma omp ...' directives.

This represents clause 'use_device_ptr' in the '#pragma omp ...' directives.

OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.

static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)

PointerType - C99 6.7.5.1 - Pointer Declarators.

Represents an unpacked "presumed" location which can be presented to the user.

const char * getFilename() const

Return the presumed filename of this location.

unsigned getLine() const

Return the presumed line number of this location.

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 isVolatileQualified() const

Determine whether this type is volatile-qualified.

QualType getNonReferenceType() const

If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...

Represents a struct/union/class.

field_range fields() const

field_iterator field_begin() const

Base for LValueReferenceType and RValueReferenceType.

Scope - A scope is a transient data structure that is used while parsing the program.

Encodes a location in the source.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

Stmt - This represents one statement.

SourceLocation getBeginLoc() const LLVM_READONLY

SwitchStmt - This represents a 'switch' stmt.

virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits, uint64_t AlignmentInBits) const

Returns true if the given target supports lock-free atomic operations at the specified width and alig...

bool isTLSSupported() const

Whether the target supports thread-local storage.

The base class of the type hierarchy.

bool isPointerType() const

const T * castAs() const

Member-template castAs<specific type>.

bool isReferenceType() const

bool isScalarType() const

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isLValueReferenceType() const

bool isAnyComplexType() const

bool hasSignedIntegerRepresentation() const

Determine whether this type has an signed integer representation of some sort, e.g....

bool isVariablyModifiedType() const

Whether this type is a variably-modified type (C99 6.7.5).

const ArrayType * getAsArrayTypeUnsafe() const

A variant of getAs<> for array types which silently discards qualifiers from the outermost type.

bool isAnyPointerType() const

bool isRecordType() const

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)

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.

TLSKind getTLSKind() const

VarDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

@ CInit

C-style initialization with assignment.

bool hasGlobalStorage() const

Returns true for all variables that do not have local storage.

bool isStaticLocal() const

Returns true if a variable with function scope is a static local variable.

const Expr * getInit() const

bool hasLocalStorage() const

Returns true if a variable with function scope is a non-static local variable.

@ TLS_None

Not a TLS variable.

Represents a C array with a specified size that is not an integer-constant-expression.

Expr * getSizeExpr() const

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

bool Inc(InterpState &S, CodePtr OpPC)

1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...

The JSON file list parser is used to communicate input to InstallAPI.

bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a worksharing directive.

bool needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind)

Checks if the specified target directive, combined or not, needs task based thread_limit.

@ Ctor_Complete

Complete object ctor.

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

llvm::omp::Directive OpenMPDirectiveKind

OpenMP directives.

@ OK_Ordinary

An ordinary object is located at an address in memory.

bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a distribute directive.

@ Tile

'tile' clause, allowed on 'loop' and Combined constructs.

OpenMPScheduleClauseModifier

OpenMP modifiers for 'schedule' clause.

@ OMPC_SCHEDULE_MODIFIER_unknown

llvm::omp::Clause OpenMPClauseKind

OpenMP clauses.

bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a parallel-kind directive.

OpenMPDistScheduleClauseKind

OpenMP attributes for 'dist_schedule' clause.

@ OMPC_DIST_SCHEDULE_unknown

bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)

Checks if the specified directive kind is one of tasking directives - task, taskloop,...

bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a target code offload directive.

@ Result

The result type of a method or function.

bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a teams-kind directive.

bool isOpenMPGenericLoopDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive constitutes a 'loop' directive in the outermost nest.

OpenMPBindClauseKind

OpenMP bindings for the 'bind' clause.

OpenMPDependClauseKind

OpenMP attributes for 'depend' clause.

@ Dtor_Complete

Complete object dtor.

bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)

Checks if the specified directive kind is one of the composite or combined directives that need loop ...

bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a simd directive.

@ VK_PRValue

A pr-value expression (in the C++11 taxonomy) produces a temporary value.

@ VK_LValue

An l-value expression is a reference to an object with independent storage.

const FunctionProtoType * T

void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)

Return the captured regions of an OpenMP directive.

@ ThreadPrivateVar

Parameter for Thread private variable.

@ Other

Other implicit parameter.

OpenMPScheduleClauseKind

OpenMP attributes for 'schedule' clause.

bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)

Checks if the specified directive is a taskloop directive.

Diagnostic wrappers for TextAPI types for error reporting.

struct with the values to be passed to the dispatch runtime function

llvm::Value * Chunk

Chunk size specified using 'schedule' clause (nullptr if chunk was not specified)

Struct with the values to be passed to the static runtime function.

static Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, SourceLocation Loc)

Returns address of the threadprivate variable for the current thread.

llvm::OpenMPIRBuilder::InsertPointTy InsertPointTy

static void EmitOMPOutlinedRegionBody(CodeGenFunction &CGF, const Stmt *RegionBodyStmt, InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Twine RegionName)

Emit the body of an OMP region that will be outlined in OpenMPIRBuilder::finalize().

static Address getAddressOfLocalVariable(CodeGenFunction &CGF, const VarDecl *VD)

Gets the OpenMP-specific address of the local variable /p VD.

static void EmitCaptureStmt(CodeGenFunction &CGF, InsertPointTy CodeGenIP, llvm::BasicBlock &FiniBB, llvm::Function *Fn, ArrayRef< llvm::Value * > Args)

static std::string getNameWithSeparators(ArrayRef< StringRef > Parts, StringRef FirstSeparator=".", StringRef Separator=".")

Get the platform-specific name separator.

static void FinalizeOMPRegion(CodeGenFunction &CGF, InsertPointTy IP)

Emit the Finalization for an OMP region.

static void EmitOMPInlinedRegionBody(CodeGenFunction &CGF, const Stmt *RegionBodyStmt, InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Twine RegionName)

Emit the body of an OMP region.

llvm::PointerType * VoidPtrTy

llvm::IntegerType * Int64Ty

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

llvm::IntegerType * SizeTy

llvm::IntegerType * Int32Ty

llvm::IntegerType * IntPtrTy

llvm::PointerType * Int8PtrTy

SmallVector< const Expr *, 4 > DepExprs

EvalResult is a struct with detailed info about an evaluated expression.

Extra information about a function prototype.

Scheduling data for loop-based OpenMP directives.

OpenMPScheduleClauseModifier M2

OpenMPScheduleClauseModifier M1

OpenMPScheduleClauseKind Schedule


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4