|
23 | 23 | #include "clang/AST/StmtOpenMP.h"
|
24 | 24 | #include "clang/Basic/OpenMPKinds.h"
|
25 | 25 | #include "clang/Basic/PrettyStackTrace.h"
|
| 26 | +#include "llvm/Frontend/OpenMP/OMPConstants.h" |
26 | 27 | #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
|
27 | 28 | #include "llvm/IR/Constants.h"
|
28 | 29 | #include "llvm/IR/Instructions.h"
|
@@ -1564,6 +1565,96 @@ static void emitEmptyBoundParameters(CodeGenFunction &,
|
1564 | 1565 | const OMPExecutableDirective &,
|
1565 | 1566 | llvm::SmallVectorImpl<llvm::Value *> &) {}
|
1566 | 1567 |
|
| 1568 | +Address CodeGenFunction::OMPBuilderCBHelpers::getAddressOfLocalVariable( |
| 1569 | + CodeGenFunction &CGF, const VarDecl *VD) { |
| 1570 | + CodeGenModule &CGM = CGF.CGM; |
| 1571 | + auto OMPBuilder = CGM.getOpenMPIRBuilder(); |
| 1572 | + assert(OMPBuilder && "OMPIRBuilder does not exist!"); |
| 1573 | + |
| 1574 | + if (!VD) |
| 1575 | + return Address::invalid(); |
| 1576 | + const VarDecl *CVD = VD->getCanonicalDecl(); |
| 1577 | + if (!CVD->hasAttr<OMPAllocateDeclAttr>()) |
| 1578 | + return Address::invalid(); |
| 1579 | + const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>(); |
| 1580 | + // Use the default allocation. |
| 1581 | + if (AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc && |
| 1582 | + !AA->getAllocator()) |
| 1583 | + return Address::invalid(); |
| 1584 | + llvm::Value *Size; |
| 1585 | + CharUnits Align = CGM.getContext().getDeclAlign(CVD); |
| 1586 | + if (CVD->getType()->isVariablyModifiedType()) { |
| 1587 | + Size = CGF.getTypeSize(CVD->getType()); |
| 1588 | + // Align the size: ((size + align - 1) / align) * align |
| 1589 | + Size = CGF.Builder.CreateNUWAdd( |
| 1590 | + Size, CGM.getSize(Align - CharUnits::fromQuantity(1))); |
| 1591 | + Size = CGF.Builder.CreateUDiv(Size, CGM.getSize(Align)); |
| 1592 | + Size = CGF.Builder.CreateNUWMul(Size, CGM.getSize(Align)); |
| 1593 | + } else { |
| 1594 | + CharUnits Sz = CGM.getContext().getTypeSizeInChars(CVD->getType()); |
| 1595 | + Size = CGM.getSize(Sz.alignTo(Align)); |
| 1596 | + } |
| 1597 | + |
| 1598 | + assert(AA->getAllocator() && |
| 1599 | + "Expected allocator expression for non-default allocator."); |
| 1600 | + llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator()); |
| 1601 | + // According to the standard, the original allocator type is a enum (integer). |
| 1602 | + // Convert to pointer type, if required. |
| 1603 | + if (Allocator->getType()->isIntegerTy()) |
| 1604 | + Allocator = CGF.Builder.CreateIntToPtr(Allocator, CGM.VoidPtrTy); |
| 1605 | + else if (Allocator->getType()->isPointerTy()) |
| 1606 | + Allocator = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Allocator, |
| 1607 | + CGM.VoidPtrTy); |
| 1608 | + |
| 1609 | + llvm::Value *Addr = OMPBuilder->CreateOMPAlloc( |
| 1610 | + CGF.Builder, Size, Allocator, |
| 1611 | + getNameWithSeparators({CVD->getName(), ".void.addr"}, ".", ".")); |
| 1612 | + llvm::CallInst *FreeCI = |
| 1613 | + OMPBuilder->CreateOMPFree(CGF.Builder, Addr, Allocator); |
| 1614 | + |
| 1615 | + CGF.EHStack.pushCleanup<OMPAllocateCleanupTy>(NormalAndEHCleanup, FreeCI); |
| 1616 | + Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( |
| 1617 | + Addr, |
| 1618 | + CGF.ConvertTypeForMem(CGM.getContext().getPointerType(CVD->getType())), |
| 1619 | + getNameWithSeparators({CVD->getName(), ".addr"}, ".", ".")); |
| 1620 | + return Address(Addr, Align); |
| 1621 | +} |
| 1622 | + |
| 1623 | +Address CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate( |
| 1624 | + CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, |
| 1625 | + SourceLocation Loc) { |
| 1626 | + CodeGenModule &CGM = CGF.CGM; |
| 1627 | + if (CGM.getLangOpts().OpenMPUseTLS && |
| 1628 | + CGM.getContext().getTargetInfo().isTLSSupported()) |
| 1629 | + return VDAddr; |
| 1630 | + |
| 1631 | + llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder(); |
| 1632 | + assert(OMPBuilder && "OpenMPIRBuilder is not initialized or used."); |
| 1633 | + |
| 1634 | + llvm::Type *VarTy = VDAddr.getElementType(); |
| 1635 | + llvm::Value *Data = |
| 1636 | + CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.Int8PtrTy); |
| 1637 | + llvm::ConstantInt *Size = CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)); |
| 1638 | + std::string Suffix = getNameWithSeparators({"cache", ""}); |
| 1639 | + llvm::Twine CacheName = Twine(CGM.getMangledName(VD)).concat(Suffix); |
| 1640 | + |
| 1641 | + llvm::CallInst *ThreadPrivateCacheCall = |
| 1642 | + OMPBuilder->CreateCachedThreadPrivate(CGF.Builder, Data, Size, CacheName); |
| 1643 | + |
| 1644 | + return Address(ThreadPrivateCacheCall, VDAddr.getAlignment()); |
| 1645 | +} |
| 1646 | + |
| 1647 | +std::string CodeGenFunction::OMPBuilderCBHelpers::getNameWithSeparators( |
| 1648 | + ArrayRef<StringRef> Parts, StringRef FirstSeparator, StringRef Separator) { |
| 1649 | + SmallString<128> Buffer; |
| 1650 | + llvm::raw_svector_ostream OS(Buffer); |
| 1651 | + StringRef Sep = FirstSeparator; |
| 1652 | + for (StringRef Part : Parts) { |
| 1653 | + OS << Sep << Part; |
| 1654 | + Sep = Separator; |
| 1655 | + } |
| 1656 | + return OS.str().str(); |
| 1657 | +} |
1567 | 1658 | void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
|
1568 | 1659 | if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder()) {
|
1569 | 1660 | // Check if we have any if clause associated with the directive.
|
|
0 commit comments