Skip to content

Commit

Permalink
Merged master:c7c05b0c8a0 into amd-gfx:f946f65516c
Browse files Browse the repository at this point in the history
Local branch amd-gfx f946f65 Merged master:e40ac74dacd into amd-gfx:45c4cfde3cf
Remote branch master c7c05b0 [AMDGPU] Don't create MachinePointerInfos with an UndefValue pointer
  • Loading branch information
Sw authored and Sw committed Dec 23, 2019
2 parents f946f65 + c7c05b0 commit c64ea04
Show file tree
Hide file tree
Showing 40 changed files with 526 additions and 418 deletions.
23 changes: 23 additions & 0 deletions clang/include/clang/AST/OpenMPClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -6275,6 +6275,15 @@ class OMPNontemporalClause final
OMPC_nontemporal, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}

/// Get the list of privatied copies if the member expression was captured by
/// one of the privatization clauses.
MutableArrayRef<Expr *> getPrivateRefs() {
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateRefs() const {
return llvm::makeArrayRef(varlist_end(), varlist_size());
}

public:
/// Creates clause with a list of variables \a VL.
///
Expand All @@ -6293,6 +6302,10 @@ class OMPNontemporalClause final
/// \param N The number of variables.
static OMPNontemporalClause *CreateEmpty(const ASTContext &C, unsigned N);

/// Sets the list of references to private copies created in private clauses.
/// \param VL List of references.
void setPrivateRefs(ArrayRef<Expr *> VL);

child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
Expand All @@ -6303,6 +6316,16 @@ class OMPNontemporalClause final
return const_child_range(Children.begin(), Children.end());
}

child_range private_refs() {
return child_range(reinterpret_cast<Stmt **>(getPrivateRefs().begin()),
reinterpret_cast<Stmt **>(getPrivateRefs().end()));
}

const_child_range private_refs() const {
auto Children = const_cast<OMPNontemporalClause *>(this)->private_refs();
return const_child_range(Children.begin(), Children.end());
}

child_range used_children() {
return child_range(child_iterator(), child_iterator());
}
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -3378,6 +3378,9 @@ template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause(
OMPNontemporalClause *C) {
TRY_TO(VisitOMPClauseList(C));
for (auto *E : C->private_refs()) {
TRY_TO(TraverseStmt(E));
}
return true;
}

Expand Down
12 changes: 9 additions & 3 deletions clang/lib/AST/OpenMPClause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1162,8 +1162,8 @@ OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,
SourceLocation LParenLoc,
SourceLocation EndLoc,
ArrayRef<Expr *> VL) {
// Allocate space for nontemporal variables.
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
// Allocate space for nontemporal variables + private references.
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
auto *Clause =
new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
Expand All @@ -1172,10 +1172,16 @@ OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,

OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C,
unsigned N) {
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
return new (Mem) OMPNontemporalClause(N);
}

void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) {
assert(VL.size() == varlist_size() && "Number of private references is not "
"the same as the preallocated buffer");
std::copy(VL.begin(), VL.end(), varlist_end());
}

//===----------------------------------------------------------------------===//
// OpenMP clauses printing methods
//===----------------------------------------------------------------------===//
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/AST/StmtProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,10 +769,13 @@ void OMPClauseProfiler::VisitOMPIsDevicePtrClause(
const OMPIsDevicePtrClause *C) {
VisitOMPClauseList(C);
}
void OMPClauseProfiler::VisitOMPNontemporalClause(const OMPNontemporalClause *C) {
void OMPClauseProfiler::VisitOMPNontemporalClause(
const OMPNontemporalClause *C) {
VisitOMPClauseList(C);
for (auto *E : C->private_refs())
Profiler->VisitStmt(E);
}
}
} // namespace

void
StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
Expand Down
33 changes: 28 additions & 5 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2566,21 +2566,35 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
VD = VD->getCanonicalDecl();
if (auto *FD = LambdaCaptureFields.lookup(VD))
return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue);
else if (CapturedStmtInfo) {
if (CapturedStmtInfo) {
auto I = LocalDeclMap.find(VD);
if (I != LocalDeclMap.end()) {
LValue CapLVal;
if (VD->getType()->isReferenceType())
return EmitLoadOfReferenceLValue(I->second, VD->getType(),
AlignmentSource::Decl);
return MakeAddrLValue(I->second, T);
CapLVal = EmitLoadOfReferenceLValue(I->second, VD->getType(),
AlignmentSource::Decl);
else
CapLVal = MakeAddrLValue(I->second, T);
// Mark lvalue as nontemporal if the variable is marked as nontemporal
// in simd context.
if (getLangOpts().OpenMP &&
CGM.getOpenMPRuntime().isNontemporalDecl(VD))
CapLVal.setNontemporal(/*Value=*/true);
return CapLVal;
}
LValue CapLVal =
EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD),
CapturedStmtInfo->getContextValue());
return MakeAddrLValue(
CapLVal = MakeAddrLValue(
Address(CapLVal.getPointer(*this), getContext().getDeclAlign(VD)),
CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl),
CapLVal.getTBAAInfo());
// Mark lvalue as nontemporal if the variable is marked as nontemporal
// in simd context.
if (getLangOpts().OpenMP &&
CGM.getOpenMPRuntime().isNontemporalDecl(VD))
CapLVal.setNontemporal(/*Value=*/true);
return CapLVal;
}

assert(isa<BlockDecl>(CurCodeDecl));
Expand Down Expand Up @@ -3929,6 +3943,15 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
if (auto *Field = dyn_cast<FieldDecl>(ND)) {
LValue LV = EmitLValueForField(BaseLV, Field);
setObjCGCLValueClass(getContext(), E, LV);
if (getLangOpts().OpenMP) {
// If the member was explicitly marked as nontemporal, mark it as
// nontemporal. If the base lvalue is marked as nontemporal, mark access
// to children as nontemporal too.
if ((IsWrappedCXXThis(BaseExpr) &&
CGM.getOpenMPRuntime().isNontemporalDecl(Field)) ||
BaseLV.isNontemporal())
LV.setNontemporal(/*Value=*/true);
}
return LV;
}

Expand Down
41 changes: 41 additions & 0 deletions clang/lib/CodeGen/CGOpenMPRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "CodeGenFunction.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/Basic/BitmaskEnum.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
Expand Down Expand Up @@ -11341,6 +11342,46 @@ bool CGOpenMPRuntime::emitDeclareVariant(GlobalDecl GD, bool IsForDefinition) {
return true;
}

CGOpenMPRuntime::NontemporalDeclsRAII::NontemporalDeclsRAII(
CodeGenModule &CGM, const OMPLoopDirective &S)
: CGM(CGM), NeedToPush(S.hasClausesOfKind<OMPNontemporalClause>()) {
assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.");
if (!NeedToPush)
return;
NontemporalDeclsSet &DS =
CGM.getOpenMPRuntime().NontemporalDeclsStack.emplace_back();
for (const auto *C : S.getClausesOfKind<OMPNontemporalClause>()) {
for (const Stmt *Ref : C->private_refs()) {
const auto *SimpleRefExpr = cast<Expr>(Ref)->IgnoreParenImpCasts();
const ValueDecl *VD;
if (const auto *DRE = dyn_cast<DeclRefExpr>(SimpleRefExpr)) {
VD = DRE->getDecl();
} else {
const auto *ME = cast<MemberExpr>(SimpleRefExpr);
assert((ME->isImplicitCXXThis() ||
isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) &&
"Expected member of current class.");
VD = ME->getMemberDecl();
}
DS.insert(VD);
}
}
}

CGOpenMPRuntime::NontemporalDeclsRAII::~NontemporalDeclsRAII() {
if (!NeedToPush)
return;
CGM.getOpenMPRuntime().NontemporalDeclsStack.pop_back();
}

bool CGOpenMPRuntime::isNontemporalDecl(const ValueDecl *VD) const {
assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.");

return llvm::any_of(
CGM.getOpenMPRuntime().NontemporalDeclsStack,
[VD](const NontemporalDeclsSet &Set) { return Set.count(VD) > 0; });
}

llvm::Function *CGOpenMPSIMDRuntime::emitParallelOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/CodeGen/CGOpenMPRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,16 @@ class CGOpenMPRuntime {
~DisableAutoDeclareTargetRAII();
};

/// Manages list of nontemporal decls for the specified directive.
class NontemporalDeclsRAII {
CodeGenModule &CGM;
const bool NeedToPush;

public:
NontemporalDeclsRAII(CodeGenModule &CGM, const OMPLoopDirective &S);
~NontemporalDeclsRAII();
};

protected:
CodeGenModule &CGM;
StringRef FirstSeparator, Separator;
Expand Down Expand Up @@ -650,6 +660,11 @@ class CGOpenMPRuntime {
std::pair<GlobalDecl, GlobalDecl>>
DeferredVariantFunction;

using NontemporalDeclsSet = llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>>;
/// Stack for list of declarations in current context marked as nontemporal.
/// The set is the union of all current stack elements.
llvm::SmallVector<NontemporalDeclsSet, 4> NontemporalDeclsStack;

/// Flag for keeping track of weather a requires unified_shared_memory
/// directive is present.
bool HasRequiresUnifiedSharedMemory = false;
Expand Down Expand Up @@ -1663,6 +1678,10 @@ class CGOpenMPRuntime {

/// Emits the definition of the declare variant function.
virtual bool emitDeclareVariant(GlobalDecl GD, bool IsForDefinition);

/// Checks if the \p VD variable is marked as nontemporal declaration in
/// current context.
bool isNontemporalDecl(const ValueDecl *VD) const;
};

/// Class supports emissionof SIMD-only code.
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/CodeGen/CGStmtOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1803,8 +1803,9 @@ static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S,
const RegionCodeGenTy &SimdInitGen,
const RegionCodeGenTy &BodyCodeGen) {
auto &&ThenGen = [&SimdInitGen, &BodyCodeGen](CodeGenFunction &CGF,
PrePostActionTy &) {
auto &&ThenGen = [&S, &SimdInitGen, &BodyCodeGen](CodeGenFunction &CGF,
PrePostActionTy &) {
CGOpenMPRuntime::NontemporalDeclsRAII NontemporalsRegion(CGF.CGM, S);
CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
SimdInitGen(CGF);

Expand Down
46 changes: 35 additions & 11 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2230,6 +2230,11 @@ void Sema::EndOpenMPClause() {

static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
ArrayRef<OMPClause *> Clauses);
static std::pair<ValueDecl *, bool>
getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
SourceRange &ERange, bool AllowArraySection = false);
static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
bool WithInit);

void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
// OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
Expand Down Expand Up @@ -2274,6 +2279,31 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
}
}
Clause->setPrivateCopies(PrivateCopies);
continue;
}
// Finalize nontemporal clause by handling private copies, if any.
if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
SmallVector<Expr *, 8> PrivateRefs;
for (Expr *RefExpr : Clause->varlists()) {
assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
SourceLocation ELoc;
SourceRange ERange;
Expr *SimpleRefExpr = RefExpr;
auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
if (Res.second)
// It will be analyzed later.
PrivateRefs.push_back(RefExpr);
ValueDecl *D = Res.first;
if (!D)
continue;

const DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D, /*FromParent=*/false);
PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
: SimpleRefExpr);
}
Clause->setPrivateRefs(PrivateRefs);
continue;
}
}
// Check allocate clauses.
Expand Down Expand Up @@ -4262,9 +4292,10 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
return ErrorFound;
}

static std::pair<ValueDecl *, bool>
getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
SourceRange &ERange, bool AllowArraySection = false) {
static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
SourceLocation &ELoc,
SourceRange &ERange,
bool AllowArraySection) {
if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
RefExpr->containsUnexpandedParameterPack())
return std::make_pair(nullptr, true);
Expand Down Expand Up @@ -17172,8 +17203,6 @@ OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
if (!D)
continue;

auto *VD = dyn_cast<VarDecl>(D);

// OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
// A list-item cannot appear in more than one nontemporal clause.
if (const Expr *PrevRef =
Expand All @@ -17185,12 +17214,7 @@ OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
continue;
}

DeclRefExpr *Ref = nullptr;
if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
Vars.push_back((VD || !Ref || CurContext->isDependentContext())
? RefExpr->IgnoreParens()
: Ref);
Vars.push_back(RefExpr);
}

if (Vars.empty())
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12466,4 +12466,9 @@ void OMPClauseReader::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
for (unsigned i = 0; i != NumVars; ++i)
Vars.push_back(Record.readSubExpr());
C->setVarRefs(Vars);
Vars.clear();
Vars.reserve(NumVars);
for (unsigned i = 0; i != NumVars; ++i)
Vars.push_back(Record.readSubExpr());
C->setPrivateRefs(Vars);
}
2 changes: 2 additions & 0 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6544,4 +6544,6 @@ void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
Record.AddSourceLocation(C->getLParenLoc());
for (auto *VE : C->varlists())
Record.AddStmt(VE);
for (auto *E : C->private_refs())
Record.AddStmt(E);
}
Loading

0 comments on commit c64ea04

Please sign in to comment.