708 changes: 708 additions & 0 deletions bolt/test/X86/dwarf5-debug-names-skip-forward-decl.s

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,35 @@ void RedundantMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {

void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) {
auto ConstructorMatcher =
cxxConstructExpr(argumentCountIs(0),
hasDeclaration(cxxConstructorDecl(ofClass(cxxRecordDecl(
unless(isTriviallyDefaultConstructible()))))))
cxxConstructExpr(
argumentCountIs(0),
hasDeclaration(cxxConstructorDecl(
ofClass(cxxRecordDecl(unless(isTriviallyDefaultConstructible()))
.bind("class")))))
.bind("construct");

auto HasUnionAsParent = hasParent(recordDecl(isUnion()));

auto HasTypeEqualToConstructorClass = hasType(qualType(
hasCanonicalType(qualType(hasDeclaration(equalsBoundNode("class"))))));

Finder->addMatcher(
cxxConstructorDecl(
unless(isDelegatingConstructor()), ofClass(unless(isUnion())),
forEachConstructorInitializer(
cxxCtorInitializer(withInitializer(ConstructorMatcher),
unless(forField(fieldDecl(
anyOf(hasType(isConstQualified()),
hasParent(recordDecl(isUnion())))))))
cxxCtorInitializer(
withInitializer(ConstructorMatcher),
anyOf(isBaseInitializer(),
forField(fieldDecl(unless(hasType(isConstQualified())),
unless(HasUnionAsParent),
HasTypeEqualToConstructorClass))))
.bind("init")))
.bind("constructor"),
this);

Finder->addMatcher(fieldDecl(hasInClassInitializer(ConstructorMatcher),
unless(hasParent(recordDecl(isUnion()))))
HasTypeEqualToConstructorClass,
unless(HasUnionAsParent))
.bind("field"),
this);
}
Expand Down
5 changes: 5 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,11 @@ Changes in existing checks
<clang-tidy/checks/readability/redundant-inline-specifier>` check to properly
emit warnings for static data member with an in-class initializer.

- Improved :doc:`readability-redundant-member-init
<clang-tidy/checks/readability/redundant-member-init>` check to avoid
false-positives when type of the member does not match the type of the
initializer.

- Improved :doc:`readability-static-accessed-through-instance
<clang-tidy/checks/readability/static-accessed-through-instance>` check to
support calls to overloaded operators as base expression and provide fixes to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,3 +302,19 @@ struct D7 {

D7<int> d7i;
D7<S> d7s;

struct SS {
SS() = default;
SS(S s) : s(s) {}

S s;
};

struct D8 {
SS ss = S();
};

struct D9 {
D9() : ss(S()) {}
SS ss;
};
2 changes: 1 addition & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ CUDA/HIP Language Changes

CUDA Support
^^^^^^^^^^^^
- Clang now supports CUDA SDK up to 12.4
- Clang now supports CUDA SDK up to 12.5

AIX Support
^^^^^^^^^^^
Expand Down
143 changes: 143 additions & 0 deletions clang/include/clang/AST/OpenACCClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,149 @@ class OpenACCClause {
virtual ~OpenACCClause() = default;
};

// Represents the 'auto' clause.
class OpenACCAutoClause : public OpenACCClause {
protected:
OpenACCAutoClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Auto, BeginLoc, EndLoc) {}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Auto;
}

static OpenACCAutoClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

// Represents the 'independent' clause.
class OpenACCIndependentClause : public OpenACCClause {
protected:
OpenACCIndependentClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Independent, BeginLoc, EndLoc) {}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Independent;
}

static OpenACCIndependentClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};
// Represents the 'seq' clause.
class OpenACCSeqClause : public OpenACCClause {
protected:
OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Seq, BeginLoc, EndLoc) {}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Seq;
}

static OpenACCSeqClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so
// this provides a basic, do-nothing implementation. We still need to add this
// type to the visitors/etc, as well as get it to take its proper arguments.
class OpenACCGangClause : public OpenACCClause {
protected:
OpenACCGangClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) {
llvm_unreachable("Not yet implemented");
}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Gang;
}

static OpenACCGangClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so
// this provides a basic, do-nothing implementation. We still need to add this
// type to the visitors/etc, as well as get it to take its proper arguments.
class OpenACCVectorClause : public OpenACCClause {
protected:
OpenACCVectorClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Vector, BeginLoc, EndLoc) {
llvm_unreachable("Not yet implemented");
}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Gang;
}

static OpenACCVectorClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so
// this provides a basic, do-nothing implementation. We still need to add this
// type to the visitors/etc, as well as get it to take its proper arguments.
class OpenACCWorkerClause : public OpenACCClause {
protected:
OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation EndLoc)
: OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) {
llvm_unreachable("Not yet implemented");
}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Gang;
}

static OpenACCWorkerClause *
Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc);

child_range children() {
return child_range(child_iterator(), child_iterator());
}
const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

/// Represents a clause that has a list of parameters.
class OpenACCClauseWithParams : public OpenACCClause {
/// Location of the '('.
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Basic/BuiltinsNVPTX.def
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@
#pragma push_macro("PTX82")
#pragma push_macro("PTX83")
#pragma push_macro("PTX84")
#define PTX84 "ptx84"
#pragma push_macro("PTX85")
#define PTX85 "ptx85"
#define PTX84 "ptx84|" PTX85
#define PTX83 "ptx83|" PTX84
#define PTX82 "ptx82|" PTX83
#define PTX81 "ptx81|" PTX82
Expand Down Expand Up @@ -1094,3 +1096,4 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", "", AND(SM_90,PTX78))
#pragma pop_macro("PTX82")
#pragma pop_macro("PTX83")
#pragma pop_macro("PTX84")
#pragma pop_macro("PTX85")
8 changes: 7 additions & 1 deletion clang/include/clang/Basic/Cuda.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ enum class CudaVersion {
CUDA_122,
CUDA_123,
CUDA_124,
CUDA_125,
FULLY_SUPPORTED = CUDA_123,
PARTIALLY_SUPPORTED =
CUDA_124, // Partially supported. Proceed with a warning.
CUDA_125, // Partially supported. Proceed with a warning.
NEW = 10000, // Too new. Issue a warning, but allow using it.
};
const char *CudaVersionToString(CudaVersion V);
Expand Down Expand Up @@ -91,6 +92,7 @@ enum class CudaArch {
GFX803,
GFX805,
GFX810,
GFX9_GENERIC,
GFX900,
GFX902,
GFX904,
Expand All @@ -102,23 +104,27 @@ enum class CudaArch {
GFX940,
GFX941,
GFX942,
GFX10_1_GENERIC,
GFX1010,
GFX1011,
GFX1012,
GFX1013,
GFX10_3_GENERIC,
GFX1030,
GFX1031,
GFX1032,
GFX1033,
GFX1034,
GFX1035,
GFX1036,
GFX11_GENERIC,
GFX1100,
GFX1101,
GFX1102,
GFX1103,
GFX1150,
GFX1151,
GFX12_GENERIC,
GFX1200,
GFX1201,
Generic, // A processor model named 'generic' if the target backend defines a
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -12399,6 +12399,9 @@ def note_acc_expected_pointer_var : Note<"expected variable of pointer type">;
def err_acc_clause_after_device_type
: Error<"OpenACC clause '%0' may not follow a '%1' clause in a "
"%select{'%3'|compute}2 construct">;
def err_acc_clause_cannot_combine
: Error<"OpenACC clause '%0' may not appear on the same construct as a "
"'%1' clause on a 'loop' construct">;
def err_acc_reduction_num_gangs_conflict
: Error<
"OpenACC 'reduction' clause may not appear on a 'parallel' construct "
Expand All @@ -12416,6 +12419,9 @@ def note_acc_reduction_composite_member_loc : Note<"invalid field is here">;
def err_acc_loop_not_for_loop
: Error<"OpenACC 'loop' construct can only be applied to a 'for' loop">;
def note_acc_construct_here : Note<"'%0' construct is here">;
def err_acc_loop_spec_conflict
: Error<"OpenACC clause '%0' on '%1' construct conflicts with previous "
"data dependence clause">;

// AMDGCN builtins diagnostics
def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/OpenACCClauses.def
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME)
#endif

VISIT_CLAUSE(Auto)
VISIT_CLAUSE(Async)
VISIT_CLAUSE(Attach)
VISIT_CLAUSE(Copy)
Expand All @@ -41,13 +42,15 @@ VISIT_CLAUSE(DeviceType)
CLAUSE_ALIAS(DType, DeviceType)
VISIT_CLAUSE(FirstPrivate)
VISIT_CLAUSE(If)
VISIT_CLAUSE(Independent)
VISIT_CLAUSE(NoCreate)
VISIT_CLAUSE(NumGangs)
VISIT_CLAUSE(NumWorkers)
VISIT_CLAUSE(Present)
VISIT_CLAUSE(Private)
VISIT_CLAUSE(Reduction)
VISIT_CLAUSE(Self)
VISIT_CLAUSE(Seq)
VISIT_CLAUSE(VectorLength)
VISIT_CLAUSE(Wait)

Expand Down
55 changes: 55 additions & 0 deletions clang/lib/AST/OpenACCClause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,48 @@ OpenACCReductionClause *OpenACCReductionClause::Create(
OpenACCReductionClause(BeginLoc, LParenLoc, Operator, VarList, EndLoc);
}

OpenACCAutoClause *OpenACCAutoClause::Create(const ASTContext &C,
SourceLocation BeginLoc,
SourceLocation EndLoc) {
void *Mem = C.Allocate(sizeof(OpenACCAutoClause));
return new (Mem) OpenACCAutoClause(BeginLoc, EndLoc);
}

OpenACCIndependentClause *
OpenACCIndependentClause::Create(const ASTContext &C, SourceLocation BeginLoc,
SourceLocation EndLoc) {
void *Mem = C.Allocate(sizeof(OpenACCIndependentClause));
return new (Mem) OpenACCIndependentClause(BeginLoc, EndLoc);
}

OpenACCSeqClause *OpenACCSeqClause::Create(const ASTContext &C,
SourceLocation BeginLoc,
SourceLocation EndLoc) {
void *Mem = C.Allocate(sizeof(OpenACCSeqClause));
return new (Mem) OpenACCSeqClause(BeginLoc, EndLoc);
}

OpenACCGangClause *OpenACCGangClause::Create(const ASTContext &C,
SourceLocation BeginLoc,
SourceLocation EndLoc) {
void *Mem = C.Allocate(sizeof(OpenACCGangClause));
return new (Mem) OpenACCGangClause(BeginLoc, EndLoc);
}

OpenACCWorkerClause *OpenACCWorkerClause::Create(const ASTContext &C,
SourceLocation BeginLoc,
SourceLocation EndLoc) {
void *Mem = C.Allocate(sizeof(OpenACCWorkerClause));
return new (Mem) OpenACCWorkerClause(BeginLoc, EndLoc);
}

OpenACCVectorClause *OpenACCVectorClause::Create(const ASTContext &C,
SourceLocation BeginLoc,
SourceLocation EndLoc) {
void *Mem = C.Allocate(sizeof(OpenACCVectorClause));
return new (Mem) OpenACCVectorClause(BeginLoc, EndLoc);
}

//===----------------------------------------------------------------------===//
// OpenACC clauses printing methods
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -495,3 +537,16 @@ void OpenACCClausePrinter::VisitDeviceTypeClause(
});
OS << ")";
}

void OpenACCClausePrinter::VisitAutoClause(const OpenACCAutoClause &C) {
OS << "auto";
}

void OpenACCClausePrinter::VisitIndependentClause(
const OpenACCIndependentClause &C) {
OS << "independent";
}

void OpenACCClausePrinter::VisitSeqClause(const OpenACCSeqClause &C) {
OS << "seq";
}
7 changes: 7 additions & 0 deletions clang/lib/AST/StmtProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2589,6 +2589,13 @@ void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) {
void OpenACCClauseProfiler::VisitDeviceTypeClause(
const OpenACCDeviceTypeClause &Clause) {}

void OpenACCClauseProfiler::VisitAutoClause(const OpenACCAutoClause &Clause) {}

void OpenACCClauseProfiler::VisitIndependentClause(
const OpenACCIndependentClause &Clause) {}

void OpenACCClauseProfiler::VisitSeqClause(const OpenACCSeqClause &Clause) {}

void OpenACCClauseProfiler::VisitReductionClause(
const OpenACCReductionClause &Clause) {
for (auto *E : Clause.getVarList())
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/TextNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,13 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
OS << '(' << cast<OpenACCDefaultClause>(C)->getDefaultClauseKind() << ')';
break;
case OpenACCClauseKind::Async:
case OpenACCClauseKind::Auto:
case OpenACCClauseKind::Attach:
case OpenACCClauseKind::Copy:
case OpenACCClauseKind::PCopy:
case OpenACCClauseKind::PresentOrCopy:
case OpenACCClauseKind::If:
case OpenACCClauseKind::Independent:
case OpenACCClauseKind::DevicePtr:
case OpenACCClauseKind::FirstPrivate:
case OpenACCClauseKind::NoCreate:
Expand All @@ -411,6 +413,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) {
case OpenACCClauseKind::Present:
case OpenACCClauseKind::Private:
case OpenACCClauseKind::Self:
case OpenACCClauseKind::Seq:
case OpenACCClauseKind::VectorLength:
// The condition expression will be printed as a part of the 'children',
// but print 'clause' here so it is clear what is happening from the dump.
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Basic/Cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ static const CudaVersionMapEntry CudaNameVersionMap[] = {
CUDA_ENTRY(12, 2),
CUDA_ENTRY(12, 3),
CUDA_ENTRY(12, 4),
CUDA_ENTRY(12, 5),
{"", CudaVersion::NEW, llvm::VersionTuple(std::numeric_limits<int>::max())},
{"unknown", CudaVersion::UNKNOWN, {}} // End of list tombstone.
};
Expand Down Expand Up @@ -111,6 +112,7 @@ static const CudaArchToStringMap arch_names[] = {
GFX(803), // gfx803
GFX(805), // gfx805
GFX(810), // gfx810
{CudaArch::GFX9_GENERIC, "gfx9-generic", "compute_amdgcn"},
GFX(900), // gfx900
GFX(902), // gfx902
GFX(904), // gfx903
Expand All @@ -122,23 +124,27 @@ static const CudaArchToStringMap arch_names[] = {
GFX(940), // gfx940
GFX(941), // gfx941
GFX(942), // gfx942
{CudaArch::GFX10_1_GENERIC, "gfx10-1-generic", "compute_amdgcn"},
GFX(1010), // gfx1010
GFX(1011), // gfx1011
GFX(1012), // gfx1012
GFX(1013), // gfx1013
{CudaArch::GFX10_3_GENERIC, "gfx10-3-generic", "compute_amdgcn"},
GFX(1030), // gfx1030
GFX(1031), // gfx1031
GFX(1032), // gfx1032
GFX(1033), // gfx1033
GFX(1034), // gfx1034
GFX(1035), // gfx1035
GFX(1036), // gfx1036
{CudaArch::GFX11_GENERIC, "gfx11-generic", "compute_amdgcn"},
GFX(1100), // gfx1100
GFX(1101), // gfx1101
GFX(1102), // gfx1102
GFX(1103), // gfx1103
GFX(1150), // gfx1150
GFX(1151), // gfx1151
{CudaArch::GFX12_GENERIC, "gfx12-generic", "compute_amdgcn"},
GFX(1200), // gfx1200
GFX(1201), // gfx1201
{CudaArch::Generic, "generic", ""},
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Basic/Targets/NVPTX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
case CudaArch::GFX803:
case CudaArch::GFX805:
case CudaArch::GFX810:
case CudaArch::GFX9_GENERIC:
case CudaArch::GFX900:
case CudaArch::GFX902:
case CudaArch::GFX904:
Expand All @@ -207,23 +208,27 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
case CudaArch::GFX940:
case CudaArch::GFX941:
case CudaArch::GFX942:
case CudaArch::GFX10_1_GENERIC:
case CudaArch::GFX1010:
case CudaArch::GFX1011:
case CudaArch::GFX1012:
case CudaArch::GFX1013:
case CudaArch::GFX10_3_GENERIC:
case CudaArch::GFX1030:
case CudaArch::GFX1031:
case CudaArch::GFX1032:
case CudaArch::GFX1033:
case CudaArch::GFX1034:
case CudaArch::GFX1035:
case CudaArch::GFX1036:
case CudaArch::GFX11_GENERIC:
case CudaArch::GFX1100:
case CudaArch::GFX1101:
case CudaArch::GFX1102:
case CudaArch::GFX1103:
case CudaArch::GFX1150:
case CudaArch::GFX1151:
case CudaArch::GFX12_GENERIC:
case CudaArch::GFX1200:
case CudaArch::GFX1201:
case CudaArch::Generic:
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3505,6 +3505,7 @@ void CGOpenMPRuntimeGPU::processRequiresDirective(
case CudaArch::GFX803:
case CudaArch::GFX805:
case CudaArch::GFX810:
case CudaArch::GFX9_GENERIC:
case CudaArch::GFX900:
case CudaArch::GFX902:
case CudaArch::GFX904:
Expand All @@ -3516,23 +3517,27 @@ void CGOpenMPRuntimeGPU::processRequiresDirective(
case CudaArch::GFX940:
case CudaArch::GFX941:
case CudaArch::GFX942:
case CudaArch::GFX10_1_GENERIC:
case CudaArch::GFX1010:
case CudaArch::GFX1011:
case CudaArch::GFX1012:
case CudaArch::GFX1013:
case CudaArch::GFX10_3_GENERIC:
case CudaArch::GFX1030:
case CudaArch::GFX1031:
case CudaArch::GFX1032:
case CudaArch::GFX1033:
case CudaArch::GFX1034:
case CudaArch::GFX1035:
case CudaArch::GFX1036:
case CudaArch::GFX11_GENERIC:
case CudaArch::GFX1100:
case CudaArch::GFX1101:
case CudaArch::GFX1102:
case CudaArch::GFX1103:
case CudaArch::GFX1150:
case CudaArch::GFX1151:
case CudaArch::GFX12_GENERIC:
case CudaArch::GFX1200:
case CudaArch::GFX1201:
case CudaArch::Generic:
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ CudaVersion getCudaVersion(uint32_t raw_version) {
return CudaVersion::CUDA_123;
if (raw_version < 12050)
return CudaVersion::CUDA_124;
if (raw_version < 12060)
return CudaVersion::CUDA_125;
return CudaVersion::NEW;
}

Expand Down Expand Up @@ -690,6 +692,7 @@ void NVPTX::getNVPTXTargetFeatures(const Driver &D, const llvm::Triple &Triple,
case CudaVersion::CUDA_##CUDA_VER: \
PtxFeature = "+ptx" #PTX_VER; \
break;
CASE_CUDA_VERSION(125, 85);
CASE_CUDA_VERSION(124, 84);
CASE_CUDA_VERSION(123, 83);
CASE_CUDA_VERSION(122, 82);
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Parse/ParseOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,8 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
// clause, as we are a 'single token' clause.
ParsedClause.setEndLoc(ClauseLoc);
}
} else {
ParsedClause.setEndLoc(ClauseLoc);
}
return OpenACCSuccess(
Actions.OpenACC().ActOnClause(ExistingClauses, ParsedClause));
Expand Down
133 changes: 129 additions & 4 deletions clang/lib/Sema/SemaOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,30 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
return false;
}

case OpenACCClauseKind::Seq:
switch (DirectiveKind) {
case OpenACCDirectiveKind::Loop:
case OpenACCDirectiveKind::Routine:
case OpenACCDirectiveKind::ParallelLoop:
case OpenACCDirectiveKind::SerialLoop:
case OpenACCDirectiveKind::KernelsLoop:
return true;
default:
return false;
}

case OpenACCClauseKind::Independent:
case OpenACCClauseKind::Auto:
switch (DirectiveKind) {
case OpenACCDirectiveKind::Loop:
case OpenACCDirectiveKind::ParallelLoop:
case OpenACCDirectiveKind::SerialLoop:
case OpenACCDirectiveKind::KernelsLoop:
return true;
default:
return false;
}

case OpenACCClauseKind::Reduction:
switch (DirectiveKind) {
case OpenACCDirectiveKind::Parallel:
Expand Down Expand Up @@ -651,10 +675,12 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
Clause.getEndLoc());
}
case OpenACCClauseKind::Private: {
// Restrictions only properly implemented on 'compute' constructs, and
// 'compute' constructs are the only construct that can do anything with
// this yet, so skip/treat as unimplemented in this case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
// Restrictions only properly implemented on 'compute' and 'loop'
// constructs, and 'compute'/'loop' constructs are the only construct that
// can do anything with this yet, so skip/treat as unimplemented in this
// case.
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
break;

// ActOnVar ensured that everything is a valid variable reference, so there
Expand Down Expand Up @@ -866,6 +892,102 @@ SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
Clause.getLParenLoc(), Clause.getDeviceTypeArchitectures(),
Clause.getEndLoc());
}
case OpenACCClauseKind::Auto: {
// Restrictions only properly implemented on 'loop' constructs, and it is
// the only construct that can do anything with this, so skip/treat as
// unimplemented for the combined constructs.
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
break;

// OpenACC 3.3 2.9:
// Only one of the seq, independent, and auto clauses may appear.
const auto *Itr = llvm::find_if(
ExistingClauses,
llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);
if (Itr != ExistingClauses.end()) {
Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
<< Clause.getClauseKind() << Clause.getDirectiveKind();
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
}

return OpenACCAutoClause::Create(getASTContext(), Clause.getBeginLoc(),
Clause.getEndLoc());
}
case OpenACCClauseKind::Independent: {
// Restrictions only properly implemented on 'loop' constructs, and it is
// the only construct that can do anything with this, so skip/treat as
// unimplemented for the combined constructs.
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
break;

// OpenACC 3.3 2.9:
// Only one of the seq, independent, and auto clauses may appear.
const auto *Itr = llvm::find_if(
ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);
if (Itr != ExistingClauses.end()) {
Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
<< Clause.getClauseKind() << Clause.getDirectiveKind();
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
}

return OpenACCIndependentClause::Create(
getASTContext(), Clause.getBeginLoc(), Clause.getEndLoc());
}
case OpenACCClauseKind::Seq: {
// Restrictions only properly implemented on 'loop' constructs, and it is
// the only construct that can do anything with this, so skip/treat as
// unimplemented for the combined constructs.
if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
break;

// OpenACC 3.3 2.9:
// Only one of the seq, independent, and auto clauses may appear.
const auto *Itr = llvm::find_if(
ExistingClauses,
llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);
if (Itr != ExistingClauses.end()) {
Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
<< Clause.getClauseKind() << Clause.getDirectiveKind();
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
}

// OpenACC 3.3 2.9:
// A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
// appears.
Itr = llvm::find_if(ExistingClauses,
llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,
OpenACCVectorClause>);

if (Itr != ExistingClauses.end()) {
Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
<< Clause.getClauseKind() << (*Itr)->getClauseKind();
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
}

// TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some
// restrictions when there is a 'seq' clause in place. We probably need to
// implement that.
return OpenACCSeqClause::Create(getASTContext(), Clause.getBeginLoc(),
Clause.getEndLoc());
}
case OpenACCClauseKind::Gang:
case OpenACCClauseKind::Worker:
case OpenACCClauseKind::Vector: {
// OpenACC 3.3 2.9:
// A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
// appears.
const auto *Itr =
llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);

if (Itr != ExistingClauses.end()) {
Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
<< Clause.getClauseKind() << (*Itr)->getClauseKind();
Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
}
// Not yet implemented, so immediately drop to the 'not yet implemented'
// diagnostic.
break;
}
case OpenACCClauseKind::Reduction: {
// Restrictions only properly implemented on 'compute' constructs, and
// 'compute' constructs are the only construct that can do anything with
Expand Down Expand Up @@ -1461,6 +1583,9 @@ StmtResult SemaOpenACC::ActOnAssociatedStmt(SourceLocation DirectiveLoc,
Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
return StmtError();
}
// TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some
// restrictions when there is a 'seq' clause in place. We probably need to
// implement that, including piping in the clauses here.
return AssocStmt;
}
llvm_unreachable("Invalid associated statement application");
Expand Down
25 changes: 25 additions & 0 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -11496,6 +11496,31 @@ void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
C.getArchitectures(), ParsedClause.getEndLoc());
}

template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitAutoClause(
const OpenACCAutoClause &C) {
// Nothing to do, so just create a new node.
NewClause = OpenACCAutoClause::Create(Self.getSema().getASTContext(),
ParsedClause.getBeginLoc(),
ParsedClause.getEndLoc());
}

template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitIndependentClause(
const OpenACCIndependentClause &C) {
NewClause = OpenACCIndependentClause::Create(Self.getSema().getASTContext(),
ParsedClause.getBeginLoc(),
ParsedClause.getEndLoc());
}

template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitSeqClause(
const OpenACCSeqClause &C) {
NewClause = OpenACCSeqClause::Create(Self.getSema().getASTContext(),
ParsedClause.getBeginLoc(),
ParsedClause.getEndLoc());
}

template <typename Derived>
void OpenACCClauseTransform<Derived>::VisitReductionClause(
const OpenACCReductionClause &C) {
Expand Down
9 changes: 6 additions & 3 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11944,12 +11944,15 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() {
return OpenACCReductionClause::Create(getContext(), BeginLoc, LParenLoc, Op,
VarList, EndLoc);
}

case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Seq:
return OpenACCSeqClause::Create(getContext(), BeginLoc, EndLoc);
case OpenACCClauseKind::Independent:
return OpenACCIndependentClause::Create(getContext(), BeginLoc, EndLoc);
case OpenACCClauseKind::Auto:
return OpenACCAutoClause::Create(getContext(), BeginLoc, EndLoc);

case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Worker:
case OpenACCClauseKind::Vector:
case OpenACCClauseKind::NoHost:
Expand Down
9 changes: 6 additions & 3 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7975,12 +7975,15 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
writeOpenACCVarList(RC);
return;
}

case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Seq:
case OpenACCClauseKind::Independent:
case OpenACCClauseKind::Auto:
// Nothing to do here, there is no additional information beyond the
// begin/end loc and clause kind.
return;

case OpenACCClauseKind::Finalize:
case OpenACCClauseKind::IfPresent:
case OpenACCClauseKind::Worker:
case OpenACCClauseKind::Vector:
case OpenACCClauseKind::NoHost:
Expand Down
25 changes: 25 additions & 0 deletions clang/test/AST/ast-print-openacc-loop-construct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,29 @@ void foo() {
// CHECK-NEXT: ;
#pragma acc loop dtype(AnotherIdent)
for(;;);

// CHECK: #pragma acc loop independent
// CHECK-NEXT: for (;;)
// CHECK-NEXT: ;
#pragma acc loop independent
for(;;);
// CHECK: #pragma acc loop seq
// CHECK-NEXT: for (;;)
// CHECK-NEXT: ;
#pragma acc loop seq
for(;;);
// CHECK: #pragma acc loop auto
// CHECK-NEXT: for (;;)
// CHECK-NEXT: ;
#pragma acc loop auto
for(;;);

int i;
float array[5];

// CHECK: #pragma acc loop private(i, array[1], array, array[1:2])
// CHECK-NEXT: for (;;)
// CHECK-NEXT: ;
#pragma acc loop private(i, array[1], array, array[1:2])
for(;;);
}
2 changes: 1 addition & 1 deletion clang/test/Misc/target-invalid-cpu-note.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

// RUN: not %clang_cc1 -triple nvptx--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix NVPTX
// NVPTX: error: unknown target CPU 'not-a-cpu'
// NVPTX-NEXT: note: valid target CPU values are: sm_20, sm_21, sm_30, sm_32, sm_35, sm_37, sm_50, sm_52, sm_53, sm_60, sm_61, sm_62, sm_70, sm_72, sm_75, sm_80, sm_86, sm_87, sm_89, sm_90, sm_90a, gfx600, gfx601, gfx602, gfx700, gfx701, gfx702, gfx703, gfx704, gfx705, gfx801, gfx802, gfx803, gfx805, gfx810, gfx900, gfx902, gfx904, gfx906, gfx908, gfx909, gfx90a, gfx90c, gfx940, gfx941, gfx942, gfx1010, gfx1011, gfx1012, gfx1013, gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1200, gfx1201{{$}}
// NVPTX-NEXT: note: valid target CPU values are: sm_20, sm_21, sm_30, sm_32, sm_35, sm_37, sm_50, sm_52, sm_53, sm_60, sm_61, sm_62, sm_70, sm_72, sm_75, sm_80, sm_86, sm_87, sm_89, sm_90, sm_90a, gfx600, gfx601, gfx602, gfx700, gfx701, gfx702, gfx703, gfx704, gfx705, gfx801, gfx802, gfx803, gfx805, gfx810, gfx9-generic, gfx900, gfx902, gfx904, gfx906, gfx908, gfx909, gfx90a, gfx90c, gfx940, gfx941, gfx942, gfx10-1-generic, gfx1010, gfx1011, gfx1012, gfx1013, gfx10-3-generic, gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx11-generic, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx12-generic, gfx1200, gfx1201{{$}}

// RUN: not %clang_cc1 -triple r600--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix R600
// R600: error: unknown target CPU 'not-a-cpu'
Expand Down
478 changes: 199 additions & 279 deletions clang/test/ParserOpenACC/parse-clauses.c

Large diffs are not rendered by default.

26 changes: 12 additions & 14 deletions clang/test/SemaOpenACC/compute-construct-default-clause.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,31 @@ void SingleOnly() {
#pragma acc parallel default(none)
while(0);

// expected-warning@+3{{OpenACC clause 'seq' not yet implemented}}
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'serial' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc serial default(present) seq default(none)
#pragma acc serial default(present) self default(none)
while(0);

// expected-warning@+5{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+4{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+3{{OpenACC clause 'seq' not yet implemented}}
int i;

// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'kernels' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc kernels seq default(present) seq default(none) seq
#pragma acc kernels self default(present) present(i) default(none) copy(i)
while(0);

// expected-warning@+6{{OpenACC construct 'parallel loop' not yet implemented}}
// expected-warning@+5{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+4{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+3{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+5{{OpenACC clause 'self' not yet implemented}}
// expected-warning@+4{{OpenACC clause 'default' not yet implemented}}
// expected-warning@+3{{OpenACC clause 'private' not yet implemented}}
// expected-warning@+2{{OpenACC clause 'default' not yet implemented}}
// expected-warning@+1{{OpenACC clause 'default' not yet implemented}}
#pragma acc parallel loop seq default(present) seq default(none) seq
// expected-warning@+1{{OpenACC clause 'copy' not yet implemented}}
#pragma acc parallel loop self default(present) private(i) default(none) copy(i)
while(0);

// expected-warning@+3{{OpenACC construct 'serial loop' not yet implemented}}
// expected-warning@+2{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+3{{OpenACC clause 'self' not yet implemented, clause ignored}}
// expected-warning@+2{{OpenACC construct 'serial loop' not yet implemented}}
// expected-error@+1{{expected '('}}
#pragma acc serial loop seq default seq default(none) seq
#pragma acc serial loop self default private(i) default(none) if(i)
while(0);

// expected-warning@+2{{OpenACC construct 'kernels loop' not yet implemented}}
Expand Down
19 changes: 6 additions & 13 deletions clang/test/SemaOpenACC/compute-construct-default-clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,25 @@ void SingleOnly() {
#pragma acc parallel default(none)
while(false);

// expected-warning@+3{{OpenACC clause 'seq' not yet implemented}}
int i;

// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'parallel' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc parallel default(present) seq default(none)
#pragma acc parallel default(present) async default(none)
while(false);

// expected-warning@+5{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+4{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+3{{OpenACC clause 'seq' not yet implemented}}
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'serial' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc serial seq default(present) seq default(none) seq
#pragma acc serial async default(present) copy(i) default(none) self
while(false);

// expected-warning@+5{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+4{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+3{{OpenACC clause 'seq' not yet implemented}}
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'kernels' directive}}
// expected-note@+1{{previous clause is here}}
#pragma acc kernels seq default(present) seq default(none) seq
#pragma acc kernels async default(present) copy(i) default(none) self
while(false);

// expected-warning@+3{{OpenACC clause 'seq' not yet implemented}}
// expected-warning@+2{{OpenACC clause 'seq' not yet implemented}}
// expected-error@+1{{expected '('}}
#pragma acc parallel seq default(none) seq default seq
#pragma acc parallel async default(none) copy(i) default self
while(false);
}

Expand Down
9 changes: 3 additions & 6 deletions clang/test/SemaOpenACC/compute-construct-device_type-clause.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,13 @@ void uses() {
// expected-note@+1{{previous clause is here}}
#pragma acc kernels device_type(*) if_present
while(1);
// expected-error@+2{{OpenACC clause 'seq' may not follow a 'device_type' clause in a compute construct}}
// expected-note@+1{{previous clause is here}}
// expected-error@+1{{OpenACC 'seq' clause is not valid on 'kernels' directive}}
#pragma acc kernels device_type(*) seq
while(1);
// expected-error@+2{{OpenACC clause 'independent' may not follow a 'device_type' clause in a compute construct}}
// expected-note@+1{{previous clause is here}}
// expected-error@+1{{OpenACC 'independent' clause is not valid on 'kernels' directive}}
#pragma acc kernels device_type(*) independent
while(1);
// expected-error@+2{{OpenACC clause 'auto' may not follow a 'device_type' clause in a compute construct}}
// expected-note@+1{{previous clause is here}}
// expected-error@+1{{OpenACC 'auto' clause is not valid on 'kernels' directive}}
#pragma acc kernels device_type(*) auto
while(1);
// expected-error@+2{{OpenACC clause 'worker' may not follow a 'device_type' clause in a compute construct}}
Expand Down
124 changes: 124 additions & 0 deletions clang/test/SemaOpenACC/loop-construct-auto_seq_independent-ast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s

// Test this with PCH.
// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s
// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s
#ifndef PCH_HELPER
#define PCH_HELPER

void NormalUses() {
// CHECK: FunctionDecl{{.*}}NormalUses
// CHECK-NEXT: CompoundStmt

#pragma acc loop auto
for(;;){}
// CHECK-NEXT: OpenACCLoopConstruct{{.*}}
// CHECK-NEXT: auto clause
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: CompoundStmt

#pragma acc loop seq
for(;;){}
// CHECK-NEXT: OpenACCLoopConstruct{{.*}}
// CHECK-NEXT: seq clause
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: CompoundStmt

#pragma acc loop independent
for(;;){}
// CHECK-NEXT: OpenACCLoopConstruct{{.*}}
// CHECK-NEXT: independent clause
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: CompoundStmt
}

template<typename T>
void TemplUses() {
// CHECK: FunctionTemplateDecl{{.*}}TemplUses
// CHECK-NEXT: TemplateTypeParmDecl
// CHECK-NEXT: FunctionDecl{{.*}} TemplUses
// CHECK-NEXT: CompoundStmt

#pragma acc loop auto
for(;;){}
// CHECK-NEXT: OpenACCLoopConstruct{{.*}}
// CHECK-NEXT: auto clause
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: CompoundStmt

#pragma acc loop seq
for(;;){}
// CHECK-NEXT: OpenACCLoopConstruct{{.*}}
// CHECK-NEXT: seq clause
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: CompoundStmt

#pragma acc loop independent
for(;;){}
// CHECK-NEXT: OpenACCLoopConstruct{{.*}}
// CHECK-NEXT: independent clause
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: CompoundStmt

// Instantiations.
// CHECK-NEXT: FunctionDecl{{.*}}TemplUses 'void ()' implicit_instantiation
// CHECK-NEXT: TemplateArgument
// CHECK-NEXT: BuiltinType
// CHECK-NEXT: CompoundStmt

// CHECK-NEXT: OpenACCLoopConstruct{{.*}}
// CHECK-NEXT: auto clause
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: CompoundStmt

// CHECK-NEXT: OpenACCLoopConstruct{{.*}}
// CHECK-NEXT: seq clause
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: CompoundStmt

// CHECK-NEXT: OpenACCLoopConstruct{{.*}}
// CHECK-NEXT: independent clause
// CHECK-NEXT: ForStmt
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: <<<NULL>>>
// CHECK-NEXT: CompoundStmt
}

void Inst() {
TemplUses<int>();
}
#endif // PCH_HELPER
890 changes: 890 additions & 0 deletions clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions clang/test/SemaOpenACC/loop-construct-device_type-clause.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,10 @@ void uses() {
// expected-note@+1{{previous clause is here}}
#pragma acc loop device_type(*) if_present
for(;;);
// expected-warning@+1{{OpenACC clause 'seq' not yet implemented, clause ignored}}
#pragma acc loop device_type(*) seq
for(;;);
// expected-warning@+1{{OpenACC clause 'independent' not yet implemented, clause ignored}}
#pragma acc loop device_type(*) independent
for(;;);
// expected-warning@+1{{OpenACC clause 'auto' not yet implemented, clause ignored}}
#pragma acc loop device_type(*) auto
for(;;);
// expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}}
Expand Down
132 changes: 132 additions & 0 deletions clang/test/SemaOpenACC/loop-construct-private-clause.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// RUN: %clang_cc1 %s -fopenacc -verify

struct Incomplete;
enum SomeE{ A };
typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
enum SomeE EnumMember;
void *PointerMember;
} Complete;

int GlobalInt;
float GlobalArray[5];
short *GlobalPointer;
Complete GlobalComposite;

void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
int LocalInt;
short *LocalPointer;
float LocalArray[5];
Complete LocalComposite;

// Check Appertainment:
#pragma acc loop private(LocalInt)
for(;;);

// Valid cases:
#pragma acc loop private(LocalInt, LocalPointer, LocalArray)
for(;;);
#pragma acc loop private(LocalArray)
for(;;);
#pragma acc loop private(LocalArray[:])
for(;;);
#pragma acc loop private(LocalArray[:5])
for(;;);
#pragma acc loop private(LocalArray[2:])
for(;;);
#pragma acc loop private(LocalArray[2:1])
for(;;);
#pragma acc loop private(LocalArray[2])
for(;;);
#pragma acc loop private(LocalComposite)
for(;;);
#pragma acc loop private(LocalComposite.EnumMember)
for(;;);
#pragma acc loop private(LocalComposite.ScalarMember)
for(;;);
#pragma acc loop private(LocalComposite.ArrayMember)
for(;;);
#pragma acc loop private(LocalComposite.ArrayMember[5])
for(;;);
#pragma acc loop private(LocalComposite.PointerMember)
for(;;);
#pragma acc loop private(GlobalInt, GlobalArray, GlobalPointer, GlobalComposite)
for(;;);
#pragma acc loop private(GlobalArray[2], GlobalPointer[2], GlobalComposite.CompositeMember.A)
for(;;);
#pragma acc loop private(LocalComposite, GlobalComposite)
for(;;);
#pragma acc loop private(IntParam, PointerParam, ArrayParam, CompositeParam)
for(;;);
#pragma acc loop private(PointerParam[IntParam], ArrayParam[IntParam], CompositeParam.CompositeMember.A)
for(;;);

#pragma acc loop private(LocalArray) private(LocalArray[2])
for(;;);

#pragma acc loop private(LocalArray, LocalArray[2])
for(;;);

#pragma acc loop private(LocalComposite, LocalComposite.ScalarMember)
for(;;);

#pragma acc loop private(LocalComposite.CompositeMember.A, LocalComposite.ScalarMember)
for(;;);

#pragma acc loop private(LocalComposite.CompositeMember.A) private(LocalComposite.ScalarMember)
for(;;);

Complete LocalComposite2;
#pragma acc loop private(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
for(;;);

// Invalid cases, arbitrary expressions.
struct Incomplete *I;
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private(*I)
for(;;);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private(GlobalInt + IntParam)
for(;;);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private(+GlobalInt)
for(;;);

// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc loop private(PointerParam[:])
for(;;);
#pragma acc loop private(PointerParam[:5])
for(;;);
#pragma acc loop private(PointerParam[:IntParam])
for(;;);
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc loop private(PointerParam[2:])
for(;;);
#pragma acc loop private(PointerParam[2:5])
for(;;);
#pragma acc loop private(PointerParam[2])
for(;;);
#pragma acc loop private(ArrayParam[:])
for(;;);
#pragma acc loop private(ArrayParam[:5])
for(;;);
#pragma acc loop private(ArrayParam[:IntParam])
for(;;);
#pragma acc loop private(ArrayParam[2:])
for(;;);
// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
#pragma acc loop private(ArrayParam[2:5])
for(;;);
#pragma acc loop private(ArrayParam[2])
for(;;);

// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private((float*)ArrayParam[2:5])
for(;;);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private((float)ArrayParam[2])
for(;;);
}
155 changes: 155 additions & 0 deletions clang/test/SemaOpenACC/loop-construct-private-clause.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// RUN: %clang_cc1 %s -fopenacc -verify

struct Incomplete;
enum SomeE{};
typedef struct IsComplete {
struct S { int A; } CompositeMember;
int ScalarMember;
float ArrayMember[5];
SomeE EnumMember;
char *PointerMember;
} Complete;

int GlobalInt;
float GlobalArray[5];
char *GlobalPointer;
Complete GlobalComposite;

void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
int LocalInt;
char *LocalPointer;
float LocalArray[5];
Complete LocalComposite;

// Check Appertainment:

#pragma acc loop private(LocalInt)
for(;;);

// Valid cases:
#pragma acc loop private(LocalInt, LocalPointer, LocalArray)
for(;;);
#pragma acc loop private(LocalArray)
for(;;);
#pragma acc loop private(LocalArray[2])
for(;;);
#pragma acc loop private(LocalComposite)
for(;;);
#pragma acc loop private(LocalComposite.EnumMember)
for(;;);
#pragma acc loop private(LocalComposite.ScalarMember)
for(;;);
#pragma acc loop private(LocalComposite.ArrayMember)
for(;;);
#pragma acc loop private(LocalComposite.ArrayMember[5])
for(;;);
#pragma acc loop private(LocalComposite.PointerMember)
for(;;);
#pragma acc loop private(GlobalInt, GlobalArray, GlobalPointer, GlobalComposite)
for(;;);
#pragma acc loop private(GlobalArray[2], GlobalPointer[2], GlobalComposite.CompositeMember.A)
for(;;);
#pragma acc loop private(LocalComposite, GlobalComposite)
for(;;);
#pragma acc loop private(IntParam, PointerParam, ArrayParam, CompositeParam) private(IntParamRef)
for(;;);
#pragma acc loop private(PointerParam[IntParam], ArrayParam[IntParam], CompositeParam.CompositeMember.A)
for(;;);


// Invalid cases, arbitrary expressions.
Incomplete *I;
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private(*I)
for(;;);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private(GlobalInt + IntParam)
for(;;);
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private(+GlobalInt)
for(;;);
}

template<typename T, unsigned I, typename V>
void TemplUses(T t, T (&arrayT)[I], V TemplComp) {
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private(+t)
for(;;);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private(+I)
for(;;);

// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#TEMPL_USES_INST{{in instantiation of}}
#pragma acc loop private(I)
for(;;);

// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
#pragma acc loop private(t, I)
for(;;);

#pragma acc loop private(arrayT)
for(;;);

#pragma acc loop private(TemplComp)
for(;;);

#pragma acc loop private(TemplComp.PointerMember[5])
for(;;);

#pragma acc loop private(TemplComp.PointerMember[5]) private(TemplComp)
for(;;);

int *Pointer;
#pragma acc loop private(Pointer[:I])
for(;;);
#pragma acc loop private(Pointer[:t])
for(;;);
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
#pragma acc loop private(Pointer[1:])
for(;;);
}

template<unsigned I, auto &NTTP_REF>
void NTTP() {
// NTTP's are only valid if it is a reference to something.
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
// expected-note@#NTTP_INST{{in instantiation of}}
#pragma acc loop private(I)
for(;;);

#pragma acc loop private(NTTP_REF)
for(;;);
}

struct S {
int ThisMember;
int ThisMemberArray[5];

void foo();
};

void S::foo() {
#pragma acc loop private(ThisMember, this->ThisMemberArray[1])
for(;;);

#pragma acc loop private(ThisMemberArray[1:2])
for(;;);

#pragma acc loop private(this)
for(;;);

#pragma acc loop private(ThisMember, this->ThisMember)
for(;;);
}

void Inst() {
static constexpr int NTTP_REFed = 1;
int i;
int Arr[5];
Complete C;
TemplUses(i, Arr, C); // #TEMPL_USES_INST
NTTP<5, NTTP_REFed>(); // #NTTP_INST
}
4 changes: 4 additions & 0 deletions clang/tools/libclang/CIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2860,6 +2860,10 @@ void OpenACCClauseEnqueue::VisitReductionClause(
const OpenACCReductionClause &C) {
VisitVarList(C);
}
void OpenACCClauseEnqueue::VisitAutoClause(const OpenACCAutoClause &C) {}
void OpenACCClauseEnqueue::VisitIndependentClause(
const OpenACCIndependentClause &C) {}
void OpenACCClauseEnqueue::VisitSeqClause(const OpenACCSeqClause &C) {}
} // namespace

void EnqueueVisitor::EnqueueChildren(const OpenACCClause *C) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ llvm::MutableArrayRef<int> MutableArrayRef(Array);
llvm::DenseMap<int, int> DenseMap = {{4, 5}, {6, 7}};
llvm::StringMap<int> StringMap = {{"foo", 123}, {"bar", 456}};
llvm::Expected<int> ExpectedValue(8);
llvm::Expected<int> ExpectedError(llvm::createStringError({}, ""));
llvm::Expected<int> ExpectedError(llvm::createStringError(""));
std::optional<int> OptionalValue(9);
std::optional<int> OptionalNone(std::nullopt);
llvm::SmallVector<int, 5> SmallVector = {10, 11, 12};
Expand Down
13 changes: 6 additions & 7 deletions lldb/include/lldb/Expression/DWARFExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,12 @@ class DWARFExpression {
/// \return
/// True on success; false otherwise. If error_ptr is non-NULL,
/// details of the failure are provided through it.
static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
const plugin::dwarf::DWARFUnit *dwarf_cu,
const lldb::RegisterKind reg_set,
const Value *initial_value_ptr,
const Value *object_address_ptr, Value &result,
Status *error_ptr);
static llvm::Expected<Value>
Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
const plugin::dwarf::DWARFUnit *dwarf_cu,
const lldb::RegisterKind reg_set, const Value *initial_value_ptr,
const Value *object_address_ptr);

static bool ParseDWARFLocationList(const plugin::dwarf::DWARFUnit *dwarf_cu,
const DataExtractor &data,
Expand Down
10 changes: 6 additions & 4 deletions lldb/include/lldb/Expression/DWARFExpressionList.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
#define LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H

#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Utility/RangeMap.h"
#include "lldb/lldb-private.h"
Expand Down Expand Up @@ -113,10 +114,11 @@ class DWARFExpressionList {

void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }

bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::addr_t func_load_addr, const Value *initial_value_ptr,
const Value *object_address_ptr, Value &result,
Status *error_ptr) const;
llvm::Expected<Value> Evaluate(ExecutionContext *exe_ctx,
RegisterContext *reg_ctx,
lldb::addr_t func_load_addr,
const Value *initial_value_ptr,
const Value *object_address_ptr) const;

private:
// RangeDataVector requires a comparator for DWARFExpression, but it doesn't
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Core/ValueObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ bool ValueObject::UpdateFormatsIfNeeded() {
m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
any_change = true;

SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
SetValueFormat(DataVisualization::GetFormat(*this, GetDynamicValueType()));
SetSummaryFormat(
DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
SetSyntheticChildren(
Expand Down
8 changes: 6 additions & 2 deletions lldb/source/Core/ValueObjectVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,11 @@ bool ValueObjectVariable::UpdateValue() {
target);
}
Value old_value(m_value);
if (expr_list.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
nullptr, m_value, &m_error)) {
llvm::Expected<Value> maybe_value = expr_list.Evaluate(
&exe_ctx, nullptr, loclist_base_load_addr, nullptr, nullptr);

if (maybe_value) {
m_value = *maybe_value;
m_resolved_value = m_value;
m_value.SetContext(Value::ContextType::Variable, variable);

Expand Down Expand Up @@ -246,6 +249,7 @@ bool ValueObjectVariable::UpdateValue() {

SetValueIsValid(m_error.Success());
} else {
m_error = maybe_value.takeError();
// could not find location, won't allow editing
m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
}
Expand Down
743 changes: 279 additions & 464 deletions lldb/source/Expression/DWARFExpression.cpp

Large diffs are not rendered by default.

28 changes: 10 additions & 18 deletions lldb/source/Expression/DWARFExpressionList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,10 @@ void DWARFExpressionList::GetDescription(Stream *s,
}
}

bool DWARFExpressionList::Evaluate(ExecutionContext *exe_ctx,
RegisterContext *reg_ctx,
lldb::addr_t func_load_addr,
const Value *initial_value_ptr,
const Value *object_address_ptr,
Value &result, Status *error_ptr) const {
llvm::Expected<Value> DWARFExpressionList::Evaluate(
ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::addr_t func_load_addr, const Value *initial_value_ptr,
const Value *object_address_ptr) const {
ModuleSP module_sp = m_module_wp.lock();
DataExtractor data;
RegisterKind reg_kind;
Expand All @@ -217,32 +215,26 @@ bool DWARFExpressionList::Evaluate(ExecutionContext *exe_ctx,
if (exe_ctx)
frame = exe_ctx->GetFramePtr();
if (!frame)
return false;
return llvm::createStringError("no frame");
RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
if (!reg_ctx_sp)
return false;
return llvm::createStringError("no register context");
reg_ctx_sp->GetPCForSymbolication(pc);
}

if (!pc.IsValid()) {
if (error_ptr)
error_ptr->SetErrorString("Invalid PC in frame.");
return false;
return llvm::createStringError("Invalid PC in frame.");
}
addr_t pc_load_addr = pc.GetLoadAddress(exe_ctx->GetTargetPtr());
const DWARFExpression *entry =
GetExpressionAtAddress(func_load_addr, pc_load_addr);
if (!entry) {
if (error_ptr) {
error_ptr->SetErrorString("variable not available");
}
return false;
}
if (!entry)
return llvm::createStringError("variable not available");
expr = *entry;
}
expr.GetExpressionData(data);
reg_kind = expr.GetRegisterKind();
return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, data,
m_dwarf_cu, reg_kind, initial_value_ptr,
object_address_ptr, result, error_ptr);
object_address_ptr);
}
20 changes: 12 additions & 8 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,28 +572,32 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
static std::optional<uint32_t>
ExtractDataMemberLocation(DWARFDIE const &die, DWARFFormValue const &form_value,
ModuleSP module_sp) {
Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);

// With DWARF 3 and later, if the value is an integer constant,
// this form value is the offset in bytes from the beginning of
// the containing entity.
if (!form_value.BlockData())
return form_value.Unsigned();

Value initialValue(0);
Value memberOffset(0);
const DWARFDataExtractor &debug_info_data = die.GetData();
uint32_t block_length = form_value.Unsigned();
uint32_t block_offset =
form_value.BlockData() - debug_info_data.GetDataStart();
if (!DWARFExpression::Evaluate(
nullptr, // ExecutionContext *
nullptr, // RegisterContext *
module_sp, DataExtractor(debug_info_data, block_offset, block_length),
die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, memberOffset,
nullptr)) {

llvm::Expected<Value> memberOffset = DWARFExpression::Evaluate(
/*ExecutionContext=*/nullptr,
/*RegisterContext=*/nullptr, module_sp,
DataExtractor(debug_info_data, block_offset, block_length), die.GetCU(),
eRegisterKindDWARF, &initialValue, nullptr);
if (!memberOffset) {
LLDB_LOG_ERROR(log, memberOffset.takeError(),
"ExtractDataMemberLocation failed: {0}");
return {};
}

return memberOffset.ResolveValue(nullptr).UInt();
return memberOffset->ResolveValue(nullptr).UInt();
}

static TypePayloadClang GetPtrAuthMofidierPayload(const DWARFDIE &die) {
Expand Down
16 changes: 9 additions & 7 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2105,23 +2105,25 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
if (var_sp && !var_sp->GetLocationIsConstantValueData()) {
const DWARFExpressionList &location =
var_sp->LocationExpressionList();
Value location_result;
Status error;
ExecutionContext exe_ctx;
if (location.Evaluate(&exe_ctx, nullptr, LLDB_INVALID_ADDRESS,
nullptr, nullptr, location_result,
&error)) {
if (location_result.GetValueType() ==
llvm::Expected<Value> location_result = location.Evaluate(
&exe_ctx, nullptr, LLDB_INVALID_ADDRESS, nullptr, nullptr);
if (location_result) {
if (location_result->GetValueType() ==
Value::ValueType::FileAddress) {
lldb::addr_t file_addr =
location_result.GetScalar().ULongLong();
location_result->GetScalar().ULongLong();
lldb::addr_t byte_size = 1;
if (var_sp->GetType())
byte_size =
var_sp->GetType()->GetByteSize(nullptr).value_or(0);
m_global_aranges_up->Append(GlobalVariableMap::Entry(
file_addr, byte_size, var_sp.get()));
}
} else {
LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols),
location_result.takeError(),
"location expression failed to execute: {0}");
}
}
}
Expand Down
17 changes: 9 additions & 8 deletions lldb/source/Symbol/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,17 +220,18 @@ Function *IndirectCallEdge::GetCallee(ModuleList &images,
ExecutionContext &exe_ctx) {
Log *log = GetLog(LLDBLog::Step);
Status error;
Value callee_addr_val;
if (!call_target.Evaluate(
&exe_ctx, exe_ctx.GetRegisterContext(), LLDB_INVALID_ADDRESS,
/*initial_value_ptr=*/nullptr,
/*object_address_ptr=*/nullptr, callee_addr_val, &error)) {
LLDB_LOGF(log, "IndirectCallEdge: Could not evaluate expression: %s",
error.AsCString());
llvm::Expected<Value> callee_addr_val = call_target.Evaluate(
&exe_ctx, exe_ctx.GetRegisterContext(), LLDB_INVALID_ADDRESS,
/*initial_value_ptr=*/nullptr,
/*object_address_ptr=*/nullptr);
if (!callee_addr_val) {
LLDB_LOG_ERROR(log, callee_addr_val.takeError(),
"IndirectCallEdge: Could not evaluate expression: {0}");
return nullptr;
}

addr_t raw_addr = callee_addr_val.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
addr_t raw_addr =
callee_addr_val->GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (raw_addr == LLDB_INVALID_ADDRESS) {
LLDB_LOG(log, "IndirectCallEdge: Could not extract address from scalar");
return nullptr;
Expand Down
23 changes: 12 additions & 11 deletions lldb/source/Target/RegisterContextUnwind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1661,12 +1661,14 @@ RegisterContextUnwind::SavedLocationForRegister(
unwindplan_registerkind);
Value cfa_val = Scalar(m_cfa);
cfa_val.SetValueType(Value::ValueType::LoadAddress);
Value result;
Status error;
if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result,
&error)) {
llvm::Expected<Value> result =
dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr);
if (!result) {
LLDB_LOG_ERROR(log, result.takeError(),
"DWARF expression failed to evaluate: {0}");
} else {
addr_t val;
val = result.GetScalar().ULongLong();
val = result->GetScalar().ULongLong();
if (unwindplan_regloc.IsDWARFExpression()) {
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = val;
Expand Down Expand Up @@ -2029,11 +2031,10 @@ bool RegisterContextUnwind::ReadFrameAddress(
DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr);
dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind(
row_register_kind);
Value result;
Status error;
if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
&error)) {
address = result.GetScalar().ULongLong();
llvm::Expected<Value> result =
dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr);
if (result) {
address = result->GetScalar().ULongLong();
if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
address = abi_sp->FixCodeAddress(address);

Expand All @@ -2042,7 +2043,7 @@ bool RegisterContextUnwind::ReadFrameAddress(
return true;
}
UnwindLogMsg("Failed to set CFA value via DWARF expression: %s",
error.AsCString());
llvm::toString(result.takeError()).c_str());
break;
}
case UnwindPlan::Row::FAValue::isRaSearch: {
Expand Down
19 changes: 7 additions & 12 deletions lldb/source/Target/StackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1091,24 +1091,19 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) {

m_flags.Set(GOT_FRAME_BASE);
ExecutionContext exe_ctx(shared_from_this());
Value expr_value;
addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
if (!m_sc.function->GetFrameBaseExpression().IsAlwaysValidSingleExpr())
loclist_base_addr =
m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
exe_ctx.GetTargetPtr());

if (!m_sc.function->GetFrameBaseExpression().Evaluate(
&exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr,
expr_value, &m_frame_base_error)) {
// We should really have an error if evaluate returns, but in case we
// don't, lets set the error to something at least.
if (m_frame_base_error.Success())
m_frame_base_error.SetErrorString(
"Evaluation of the frame base expression failed.");
} else {
m_frame_base = expr_value.ResolveValue(&exe_ctx);
}
llvm::Expected<Value> expr_value =
m_sc.function->GetFrameBaseExpression().Evaluate(
&exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr);
if (!expr_value)
m_frame_base_error = expr_value.takeError();
else
m_frame_base = expr_value->ResolveValue(&exe_ctx);
} else {
m_frame_base_error.SetErrorString("No function in symbol context.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ __attribute__((noinline)) void func4_amb(int &sink, int x) {
//% expect_cmd_failure=True)
//% self.filecheck("expr sink", "main.cpp","-check-prefix=FUNC4-EXPR",
//% expect_cmd_failure=True)
// FUNC4-EXPR-FAIL: couldn't get the value of variable x: Could not evaluate
// DW_OP_entry_value. FUNC4-EXPR: couldn't get the value of variable sink:
// Could not evaluate DW_OP_entry_value.
// clang-format off
// FUNC4-EXPR-FAIL: couldn't get the value of variable x: could not evaluate DW_OP_entry_value: no matching call site param found
// FUNC4-EXPR: couldn't get the value of variable sink: could not evaluate DW_OP_entry_value: no matching call site param found
// clang-format on
}

__attribute__((noinline)) void func5_amb() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ def test_optimized_variable(self):
self.assertTrue(optimized_variable["value"].startswith("<error:"))
error_msg = optimized_variable["$__lldb_extensions"]["error"]
self.assertTrue(
("Could not evaluate DW_OP_entry_value" in error_msg)
("could not evaluate DW_OP_entry_value: no parent function" in error_msg)
or ("variable not available" in error_msg)
)
78 changes: 38 additions & 40 deletions lldb/unittests/Expression/DWARFExpressionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,23 @@ static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
ExecutionContext *exe_ctx = nullptr) {
DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle,
/*addr_size*/ 4);
Value result;
Status status;
if (!DWARFExpression::Evaluate(exe_ctx, /*reg_ctx*/ nullptr, module_sp,
extractor, unit, lldb::eRegisterKindLLDB,
/*initial_value_ptr*/ nullptr,
/*object_address_ptr*/ nullptr, result,
&status))
return status.ToError();

switch (result.GetValueType()) {

llvm::Expected<Value> result =
DWARFExpression::Evaluate(exe_ctx, /*reg_ctx*/ nullptr, module_sp,
extractor, unit, lldb::eRegisterKindLLDB,
/*initial_value_ptr*/ nullptr,
/*object_address_ptr*/ nullptr);
if (!result)
return result.takeError();

switch (result->GetValueType()) {
case Value::ValueType::Scalar:
return result.GetScalar();
return result->GetScalar();
case Value::ValueType::LoadAddress:
return LLDB_INVALID_ADDRESS;
case Value::ValueType::HostAddress: {
// Convert small buffers to scalars to simplify the tests.
DataBufferHeap &buf = result.GetBuffer();
DataBufferHeap &buf = result->GetBuffer();
if (buf.GetByteSize() <= 8) {
uint64_t val = 0;
memcpy(&val, buf.GetBytes(), buf.GetByteSize());
Expand All @@ -58,8 +58,9 @@ static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
}
[[fallthrough]];
default:
return status.ToError();
break;
}
return llvm::createStringError("unsupported value type");
}

class DWARFExpressionTester : public YAMLModuleTester {
Expand Down Expand Up @@ -454,16 +455,15 @@ TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr) {
uint8_t expr[] = {DW_OP_addr, 0x40, 0x0, 0x0, 0x0};
DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
/*addr_size*/ 4);
Value result;
Status status;
ASSERT_TRUE(DWARFExpression::Evaluate(

llvm::Expected<Value> result = DWARFExpression::Evaluate(
&exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor,
/*unit*/ nullptr, lldb::eRegisterKindLLDB,
/*initial_value_ptr*/ nullptr,
/*object_address_ptr*/ nullptr, result, &status))
<< status.ToError();
/*object_address_ptr*/ nullptr);

ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress);
ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
ASSERT_EQ(result->GetValueType(), Value::ValueType::LoadAddress);
}

TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr_index) {
Expand Down Expand Up @@ -530,14 +530,14 @@ TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr_index) {

ExecutionContext exe_ctx(target_sp, false);

auto evaluate = [&](DWARFExpression &expr, Status &status, Value &result) {
auto evaluate = [&](DWARFExpression &expr) -> llvm::Expected<Value> {
DataExtractor extractor;
expr.GetExpressionData(extractor);
return DWARFExpression::Evaluate(
&exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor, dwarf_cu,
lldb::eRegisterKindLLDB,
/*initial_value_ptr*/ nullptr,
/*object_address_ptr*/ nullptr, result, &status);
return DWARFExpression::Evaluate(&exe_ctx, /*reg_ctx*/ nullptr,
/*module_sp*/ {}, extractor, dwarf_cu,
lldb::eRegisterKindLLDB,
/*initial_value_ptr*/ nullptr,
/*object_address_ptr*/ nullptr);
};

// DW_OP_addrx takes a single leb128 operand, the index in the addr table:
Expand All @@ -546,16 +546,16 @@ TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr_index) {
/*addr_size*/ 4);
DWARFExpression expr(extractor);

Status status;
Value result;
ASSERT_TRUE(evaluate(expr, status, result)) << status.ToError();
ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress);
ASSERT_EQ(result.GetScalar().UInt(), 0x5678u);
llvm::Expected<Value> result = evaluate(expr);
ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
ASSERT_EQ(result->GetValueType(), Value::ValueType::LoadAddress);
ASSERT_EQ(result->GetScalar().UInt(), 0x5678u);

ASSERT_TRUE(expr.Update_DW_OP_addr(dwarf_cu, 0xdeadbeef));
ASSERT_TRUE(evaluate(expr, status, result)) << status.ToError();
ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress);
ASSERT_EQ(result.GetScalar().UInt(), 0xdeadbeefu);
result = evaluate(expr);
ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
ASSERT_EQ(result->GetValueType(), Value::ValueType::LoadAddress);
ASSERT_EQ(result->GetScalar().UInt(), 0xdeadbeefu);
}

class CustomSymbolFileDWARF : public SymbolFileDWARF {
Expand Down Expand Up @@ -825,15 +825,13 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_piece_file_addr) {
DW_OP_addr, 0x50, 0x0, 0x0, 0x0, DW_OP_piece, 1};
DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
/*addr_size*/ 4);
Value result;
Status status;
ASSERT_TRUE(DWARFExpression::Evaluate(
llvm::Expected<Value> result = DWARFExpression::Evaluate(
&exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor,
/*unit*/ nullptr, lldb::eRegisterKindLLDB,
/*initial_value_ptr*/ nullptr,
/*object_address_ptr*/ nullptr, result, &status))
<< status.ToError();
/*object_address_ptr*/ nullptr);

ASSERT_EQ(result.GetValueType(), Value::ValueType::HostAddress);
ASSERT_THAT(result.GetBuffer().GetData(), ElementsAre(0x11, 0x22));
ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
ASSERT_EQ(result->GetValueType(), Value::ValueType::HostAddress);
ASSERT_THAT(result->GetBuffer().GetData(), ElementsAre(0x11, 0x22));
}
9 changes: 3 additions & 6 deletions llvm/include/llvm/Bitcode/BitcodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ class BitcodeWriter {

void writeIndex(
const ModuleSummaryIndex *Index,
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
const GVSummaryPtrSet *DecSummaries);
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex);
};

/// Write the specified module to the specified raw output stream.
Expand Down Expand Up @@ -148,12 +147,10 @@ void writeThinLinkBitcodeToFile(const Module &M, raw_ostream &Out,
/// where it will be written in a new bitcode block. This is used when
/// writing the combined index file for ThinLTO. When writing a subset of the
/// index for a distributed backend, provide the \p ModuleToSummariesForIndex
/// map. \p DecSummaries specifies the set of summaries for which the
/// corresponding value should be imported as a declaration (prototype).
/// map.
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out,
const std::map<std::string, GVSummaryMapTy>
*ModuleToSummariesForIndex = nullptr,
const GVSummaryPtrSet *DecSummaries = nullptr);
*ModuleToSummariesForIndex = nullptr);

/// If EmbedBitcode is set, save a copy of the llvm IR as data in the
/// __LLVM,__bitcode section (.llvmbc on non-MacOS).
Expand Down
26 changes: 18 additions & 8 deletions llvm/include/llvm/CodeGen/SelectionDAGNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,17 +479,12 @@ class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
/// The operation that this node performs.
int32_t NodeType;

public:
/// Unique and persistent id per SDNode in the DAG. Used for debug printing.
/// We do not place that under `#if LLVM_ENABLE_ABI_BREAKING_CHECKS`
/// intentionally because it adds unneeded complexity without noticeable
/// benefits (see discussion with @thakis in D120714).
uint16_t PersistentId = 0xffff;
SDNodeFlags Flags;

protected:
// We define a set of mini-helper classes to help us interpret the bits in our
// SubclassData. These are designed to fit within a uint16_t so they pack
// with PersistentId.
// with SDNodeFlags.

#if defined(_AIX) && (!defined(__GNUC__) || defined(__clang__))
// Except for GCC; by default, AIX compilers store bit-fields in 4-byte words
Expand Down Expand Up @@ -611,6 +606,14 @@ END_TWO_BYTE_PACK()
static_assert(sizeof(LoadSDNodeBitfields) <= 2, "field too wide");
static_assert(sizeof(StoreSDNodeBitfields) <= 2, "field too wide");

public:
/// Unique and persistent id per SDNode in the DAG. Used for debug printing.
/// We do not place that under `#if LLVM_ENABLE_ABI_BREAKING_CHECKS`
/// intentionally because it adds unneeded complexity without noticeable
/// benefits (see discussion with @thakis in D120714). Currently, there are
/// two padding bytes after this field.
uint16_t PersistentId = 0xffff;

private:
friend class SelectionDAG;
// TODO: unfriend HandleSDNode once we fix its operand handling.
Expand Down Expand Up @@ -646,7 +649,8 @@ END_TWO_BYTE_PACK()
/// Return a pointer to the specified value type.
static const EVT *getValueTypeList(EVT VT);

SDNodeFlags Flags;
/// Index in worklist of DAGCombiner, or -1.
int CombinerWorklistIndex = -1;

uint32_t CFIType = 0;

Expand Down Expand Up @@ -747,6 +751,12 @@ END_TWO_BYTE_PACK()
/// Set unique node id.
void setNodeId(int Id) { NodeId = Id; }

/// Get worklist index for DAGCombiner
int getCombinerWorklistIndex() const { return CombinerWorklistIndex; }

/// Set worklist index for DAGCombiner
void setCombinerWorklistIndex(int Index) { CombinerWorklistIndex = Index; }

/// Return the node ordering.
unsigned getIROrder() const { return IROrder; }

Expand Down
7 changes: 0 additions & 7 deletions llvm/include/llvm/IR/ModuleSummaryIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,10 +587,6 @@ class GlobalValueSummary {

void setImportKind(ImportKind IK) { Flags.ImportType = IK; }

GlobalValueSummary::ImportKind importType() const {
return static_cast<ImportKind>(Flags.ImportType);
}

GlobalValue::VisibilityTypes getVisibility() const {
return (GlobalValue::VisibilityTypes)Flags.Visibility;
}
Expand Down Expand Up @@ -1276,9 +1272,6 @@ using ModulePathStringTableTy = StringMap<ModuleHash>;
/// a particular module, and provide efficient access to their summary.
using GVSummaryMapTy = DenseMap<GlobalValue::GUID, GlobalValueSummary *>;

/// A set of global value summary pointers.
using GVSummaryPtrSet = SmallPtrSet<GlobalValueSummary *, 4>;

/// Map of a type GUID to type id string and summary (multimap used
/// in case of GUID conflicts).
using TypeIdSummaryMapTy =
Expand Down
5 changes: 2 additions & 3 deletions llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,12 @@ class ThinLTOCodeGenerator {
const lto::InputFile &File);

/**
* Compute the list of summaries and the subset of declaration summaries
* needed for importing into module.
* Compute the list of summaries needed for importing into module.
*/
void gatherImportedSummariesForModule(
Module &Module, ModuleSummaryIndex &Index,
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
GVSummaryPtrSet &DecSummaries, const lto::InputFile &File);
const lto::InputFile &File);

/**
* Perform internalization. Index is updated to reflect linkage changes.
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/Support/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,11 @@ inline Error createStringError(const Twine &S) {
return createStringError(llvm::inconvertibleErrorCode(), S);
}

template <typename... Ts>
inline Error createStringError(char const *Fmt, const Ts &...Vals) {
return createStringError(llvm::inconvertibleErrorCode(), Fmt, Vals...);
}

template <typename... Ts>
inline Error createStringError(std::errc EC, char const *Fmt,
const Ts &... Vals) {
Expand Down
12 changes: 3 additions & 9 deletions llvm/include/llvm/Transforms/IPO/Attributor.h
Original file line number Diff line number Diff line change
Expand Up @@ -5143,9 +5143,7 @@ struct DenormalFPMathState : public AbstractState {
return Mode != Other.Mode || ModeF32 != Other.ModeF32;
}

bool isValid() const {
return Mode.isValid() && ModeF32.isValid();
}
bool isValid() const { return Mode.isValid() && ModeF32.isValid(); }

static DenormalMode::DenormalModeKind
unionDenormalKind(DenormalMode::DenormalModeKind Callee,
Expand Down Expand Up @@ -5185,9 +5183,7 @@ struct DenormalFPMathState : public AbstractState {
// state.
DenormalState getAssumed() const { return Known; }

bool isValidState() const override {
return Known.isValid();
}
bool isValidState() const override { return Known.isValid(); }

/// Return true if there are no dynamic components to the denormal mode worth
/// specializing.
Expand All @@ -5198,9 +5194,7 @@ struct DenormalFPMathState : public AbstractState {
Known.ModeF32.Output != DenormalMode::Dynamic;
}

bool isAtFixpoint() const override {
return IsAtFixedpoint;
}
bool isAtFixpoint() const override { return IsAtFixedpoint; }

ChangeStatus indicateFixpoint() {
bool Changed = !IsAtFixedpoint;
Expand Down
21 changes: 6 additions & 15 deletions llvm/include/llvm/Transforms/IPO/FunctionImport.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class Module;
/// based on the provided summary informations.
class FunctionImporter {
public:
/// The functions to import from a source module and their import type.
using FunctionsToImportTy =
DenseMap<GlobalValue::GUID, GlobalValueSummary::ImportKind>;
/// Set of functions to import from a source module. Each entry is a set
/// containing all the GUIDs of all functions to import for a source module.
using FunctionsToImportTy = std::unordered_set<GlobalValue::GUID>;

/// The different reasons selectCallee will chose not to import a
/// candidate.
Expand Down Expand Up @@ -99,13 +99,8 @@ class FunctionImporter {
/// index's module path string table).
using ImportMapTy = DenseMap<StringRef, FunctionsToImportTy>;

/// The map contains an entry for every global value the module exports.
/// The key is ValueInfo, and the value indicates whether the definition
/// or declaration is visible to another module. If a function's definition is
/// visible to other modules, the global values this function referenced are
/// visible and shouldn't be internalized.
/// TODO: Rename to `ExportMapTy`.
using ExportSetTy = DenseMap<ValueInfo, GlobalValueSummary::ImportKind>;
/// The set contains an entry for every global value the module exports.
using ExportSetTy = DenseSet<ValueInfo>;

/// A function of this type is used to load modules referenced by the index.
using ModuleLoaderTy =
Expand Down Expand Up @@ -212,15 +207,11 @@ bool convertToDeclaration(GlobalValue &GV);
/// \p ModuleToSummariesForIndex will be populated with the needed summaries
/// from each required module path. Use a std::map instead of StringMap to get
/// stable order for bitcode emission.
///
/// \p DecSummaries will be popluated with the subset of of summary pointers
/// that have 'declaration' import type among all summaries the module need.
void gatherImportedSummariesForModule(
StringRef ModulePath,
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
const FunctionImporter::ImportMapTy &ImportList,
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
GVSummaryPtrSet &DecSummaries);
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);

/// Emit into \p OutputFilename the files module \p ModulePath will import from.
std::error_code EmitImportsFiles(
Expand Down
38 changes: 8 additions & 30 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,11 +424,6 @@ class IndexBitcodeWriter : public BitcodeWriterBase {
/// The combined index to write to bitcode.
const ModuleSummaryIndex &Index;

/// When writing combined summaries, provides the set of global value
/// summaries for which the value (function, function alias, etc) should be
/// imported as a declaration.
const GVSummaryPtrSet *DecSummaries = nullptr;

/// When writing a subset of the index for distributed backends, client
/// provides a map of modules to the corresponding GUIDs/summaries to write.
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex;
Expand Down Expand Up @@ -457,16 +452,11 @@ class IndexBitcodeWriter : public BitcodeWriterBase {
/// Constructs a IndexBitcodeWriter object for the given combined index,
/// writing to the provided \p Buffer. When writing a subset of the index
/// for a distributed backend, provide a \p ModuleToSummariesForIndex map.
/// If provided, \p ModuleToDecSummaries specifies the set of summaries for
/// which the corresponding functions or aliased functions should be imported
/// as a declaration (but not definition) for each module.
IndexBitcodeWriter(BitstreamWriter &Stream, StringTableBuilder &StrtabBuilder,
const ModuleSummaryIndex &Index,
const GVSummaryPtrSet *DecSummaries = nullptr,
const std::map<std::string, GVSummaryMapTy>
*ModuleToSummariesForIndex = nullptr)
: BitcodeWriterBase(Stream, StrtabBuilder), Index(Index),
DecSummaries(DecSummaries),
ModuleToSummariesForIndex(ModuleToSummariesForIndex) {

// See if the StackIdIndex was already added to the StackId map and
Expand Down Expand Up @@ -1221,8 +1211,7 @@ static uint64_t getEncodedFFlags(FunctionSummary::FFlags Flags) {

// Decode the flags for GlobalValue in the summary. See getDecodedGVSummaryFlags
// in BitcodeReader.cpp.
static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags,
bool ImportAsDecl = false) {
static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
uint64_t RawFlags = 0;

RawFlags |= Flags.NotEligibleToImport; // bool
Expand All @@ -1237,8 +1226,7 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags,

RawFlags |= (Flags.Visibility << 8); // 2 bits

unsigned ImportType = Flags.ImportType | ImportAsDecl;
RawFlags |= (ImportType << 10); // 1 bit
RawFlags |= (Flags.ImportType << 10); // 1 bit

return RawFlags;
}
Expand Down Expand Up @@ -4565,12 +4553,6 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv));

auto shouldImportValueAsDecl = [&](GlobalValueSummary *GVS) -> bool {
if (DecSummaries == nullptr)
return false;
return DecSummaries->contains(GVS);
};

// The aliases are emitted as a post-pass, and will point to the value
// id of the aliasee. Save them in a vector for post-processing.
SmallVector<AliasSummary *, 64> Aliases;
Expand Down Expand Up @@ -4681,8 +4663,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
NameVals.push_back(*ValueId);
assert(ModuleIdMap.count(FS->modulePath()));
NameVals.push_back(ModuleIdMap[FS->modulePath()]);
NameVals.push_back(
getEncodedGVSummaryFlags(FS->flags(), shouldImportValueAsDecl(FS)));
NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
NameVals.push_back(FS->instCount());
NameVals.push_back(getEncodedFFlags(FS->fflags()));
NameVals.push_back(FS->entryCount());
Expand Down Expand Up @@ -4731,8 +4712,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
NameVals.push_back(AliasValueId);
assert(ModuleIdMap.count(AS->modulePath()));
NameVals.push_back(ModuleIdMap[AS->modulePath()]);
NameVals.push_back(
getEncodedGVSummaryFlags(AS->flags(), shouldImportValueAsDecl(AS)));
NameVals.push_back(getEncodedGVSummaryFlags(AS->flags()));
auto AliaseeValueId = SummaryToValueIdMap[&AS->getAliasee()];
assert(AliaseeValueId);
NameVals.push_back(AliaseeValueId);
Expand Down Expand Up @@ -5073,9 +5053,8 @@ void BitcodeWriter::writeModule(const Module &M,

void BitcodeWriter::writeIndex(
const ModuleSummaryIndex *Index,
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
const GVSummaryPtrSet *DecSummaries) {
IndexBitcodeWriter IndexWriter(*Stream, StrtabBuilder, *Index, DecSummaries,
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex) {
IndexBitcodeWriter IndexWriter(*Stream, StrtabBuilder, *Index,
ModuleToSummariesForIndex);
IndexWriter.write();
}
Expand Down Expand Up @@ -5130,13 +5109,12 @@ void IndexBitcodeWriter::write() {
// index for a distributed backend, provide a \p ModuleToSummariesForIndex map.
void llvm::writeIndexToFile(
const ModuleSummaryIndex &Index, raw_ostream &Out,
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex,
const GVSummaryPtrSet *DecSummaries) {
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex) {
SmallVector<char, 0> Buffer;
Buffer.reserve(256 * 1024);

BitcodeWriter Writer(Buffer);
Writer.writeIndex(&Index, ModuleToSummariesForIndex, DecSummaries);
Writer.writeIndex(&Index, ModuleToSummariesForIndex);
Writer.writeStrtab();

Out.write((char *)&Buffer.front(), Buffer.size());
Expand Down
28 changes: 12 additions & 16 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,11 @@ namespace {
/// back and when processing we pop off of the back.
///
/// The worklist will not contain duplicates but may contain null entries
/// due to nodes being deleted from the underlying DAG.
/// due to nodes being deleted from the underlying DAG. For fast lookup and
/// deduplication, the index of the node in this vector is stored in the
/// node in SDNode::CombinerWorklistIndex.
SmallVector<SDNode *, 64> Worklist;

/// Mapping from an SDNode to its position on the worklist.
///
/// This is used to find and remove nodes from the worklist (by nulling
/// them) when they are deleted from the underlying DAG. It relies on
/// stable indices of nodes within the worklist.
DenseMap<SDNode *, unsigned> WorklistMap;

/// This records all nodes attempted to be added to the worklist since we
/// considered a new worklist entry. As we keep do not add duplicate nodes
/// in the worklist, this is different from the tail of the worklist.
Expand Down Expand Up @@ -238,10 +233,9 @@ namespace {
}

if (N) {
bool GoodWorklistEntry = WorklistMap.erase(N);
(void)GoodWorklistEntry;
assert(GoodWorklistEntry &&
assert(N->getCombinerWorklistIndex() >= 0 &&
"Found a worklist entry without a corresponding map entry!");
N->setCombinerWorklistIndex(-1);
}
return N;
}
Expand Down Expand Up @@ -285,8 +279,10 @@ namespace {
if (IsCandidateForPruning)
ConsiderForPruning(N);

if (WorklistMap.insert(std::make_pair(N, Worklist.size())).second)
if (N->getCombinerWorklistIndex() == -1) {
N->setCombinerWorklistIndex(Worklist.size());
Worklist.push_back(N);
}
}

/// Remove all instances of N from the worklist.
Expand All @@ -295,13 +291,13 @@ namespace {
PruningList.remove(N);
StoreRootCountMap.erase(N);

auto It = WorklistMap.find(N);
if (It == WorklistMap.end())
int WorklistIndex = N->getCombinerWorklistIndex();
if (WorklistIndex == -1)
return; // Not in the worklist.

// Null out the entry rather than erasing it to avoid a linear operation.
Worklist[It->second] = nullptr;
WorklistMap.erase(It);
Worklist[WorklistIndex] = nullptr;
N->setCombinerWorklistIndex(-1);
}

void deleteAndRecombine(SDNode *N);
Expand Down
38 changes: 14 additions & 24 deletions llvm/lib/LTO/LTO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,6 @@ void llvm::computeLTOCacheKey(
support::endian::write64le(Data, I);
Hasher.update(Data);
};
auto AddUint8 = [&](const uint8_t I) {
Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&I, 1));
};
AddString(Conf.CPU);
// FIXME: Hash more of Options. For now all clients initialize Options from
// command-line flags (which is unsupported in production), but may set
Expand Down Expand Up @@ -159,18 +156,18 @@ void llvm::computeLTOCacheKey(
auto ModHash = Index.getModuleHash(ModuleID);
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));

std::vector<std::pair<uint64_t, uint8_t>> ExportsGUID;
std::vector<uint64_t> ExportsGUID;
ExportsGUID.reserve(ExportList.size());
for (const auto &[VI, ExportType] : ExportList)
ExportsGUID.push_back(
std::make_pair(VI.getGUID(), static_cast<uint8_t>(ExportType)));
for (const auto &VI : ExportList) {
auto GUID = VI.getGUID();
ExportsGUID.push_back(GUID);
}

// Sort the export list elements GUIDs.
llvm::sort(ExportsGUID);
for (auto [GUID, ExportType] : ExportsGUID) {
for (uint64_t GUID : ExportsGUID) {
// The export list can impact the internalization, be conservative here
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&GUID, sizeof(GUID)));
AddUint8(ExportType);
}

// Include the hash for every module we import functions from. The set of
Expand Down Expand Up @@ -202,21 +199,19 @@ void llvm::computeLTOCacheKey(
[](const ImportModule &Lhs, const ImportModule &Rhs) -> bool {
return Lhs.getHash() < Rhs.getHash();
});
std::vector<std::pair<uint64_t, uint8_t>> ImportedGUIDs;
std::vector<uint64_t> ImportedGUIDs;
for (const ImportModule &Entry : ImportModulesVector) {
auto ModHash = Entry.getHash();
Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));

AddUint64(Entry.getFunctions().size());

ImportedGUIDs.clear();
for (auto &[Fn, ImportType] : Entry.getFunctions())
ImportedGUIDs.push_back(std::make_pair(Fn, ImportType));
for (auto &Fn : Entry.getFunctions())
ImportedGUIDs.push_back(Fn);
llvm::sort(ImportedGUIDs);
for (auto &[GUID, Type] : ImportedGUIDs) {
for (auto &GUID : ImportedGUIDs)
AddUint64(GUID);
AddUint8(Type);
}
}

// Include the hash for the resolved ODR.
Expand Down Expand Up @@ -286,9 +281,9 @@ void llvm::computeLTOCacheKey(
// Imported functions may introduce new uses of type identifier resolutions,
// so we need to collect their used resolutions as well.
for (const ImportModule &ImpM : ImportModulesVector)
for (auto &[GUID, UnusedImportType] : ImpM.getFunctions()) {
for (auto &ImpF : ImpM.getFunctions()) {
GlobalValueSummary *S =
Index.findSummaryInModule(GUID, ImpM.getIdentifier());
Index.findSummaryInModule(ImpF, ImpM.getIdentifier());
AddUsedThings(S);
// If this is an alias, we also care about any types/etc. that the aliasee
// may reference.
Expand Down Expand Up @@ -1400,20 +1395,15 @@ class lto::ThinBackendProc {
llvm::StringRef ModulePath,
const std::string &NewModulePath) {
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
GVSummaryPtrSet DeclarationSummaries;

std::error_code EC;
gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
ImportList, ModuleToSummariesForIndex,
DeclarationSummaries);
ImportList, ModuleToSummariesForIndex);

raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,
sys::fs::OpenFlags::OF_None);
if (EC)
return errorCodeToError(EC);

writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex,
&DeclarationSummaries);
writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex);

if (ShouldEmitImportsFiles) {
EC = EmitImportsFiles(ModulePath, NewModulePath + ".imports",
Expand Down
9 changes: 1 addition & 8 deletions llvm/lib/LTO/LTOBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,14 +720,7 @@ bool lto::initImportList(const Module &M,
if (Summary->modulePath() == M.getModuleIdentifier())
continue;
// Add an entry to provoke importing by thinBackend.
// Try emplace the entry first. If an entry with the same key already
// exists, set the value to 'std::min(existing-value, new-value)' to make
// sure a definition takes precedence over a declaration.
auto [Iter, Inserted] = ImportList[Summary->modulePath()].try_emplace(
GUID, Summary->importType());

if (!Inserted)
Iter->second = std::min(Iter->second, Summary->importType());
ImportList[Summary->modulePath()].insert(GUID);
}
}
return true;
Expand Down
10 changes: 3 additions & 7 deletions llvm/lib/LTO/ThinLTOCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
Module &TheModule, ModuleSummaryIndex &Index,
std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
GVSummaryPtrSet &DecSummaries, const lto::InputFile &File) {
const lto::InputFile &File) {
auto ModuleCount = Index.modulePaths().size();
auto ModuleIdentifier = TheModule.getModuleIdentifier();

Expand Down Expand Up @@ -796,7 +796,7 @@ void ThinLTOCodeGenerator::gatherImportedSummariesForModule(

llvm::gatherImportedSummariesForModule(
ModuleIdentifier, ModuleToDefinedGVSummaries,
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);
}

/**
Expand Down Expand Up @@ -832,14 +832,10 @@ void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
IsPrevailing(PrevailingCopy), ImportLists,
ExportLists);

// 'EmitImportsFiles' emits the list of modules from which to import from, and
// the set of keys in `ModuleToSummariesForIndex` should be a superset of keys
// in `DecSummaries`, so no need to use `DecSummaries` in `EmitImportFiles`.
GVSummaryPtrSet DecSummaries;
std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
llvm::gatherImportedSummariesForModule(
ModuleIdentifier, ModuleToDefinedGVSummaries,
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex);

std::error_code EC;
if ((EC = EmitImportsFiles(ModuleIdentifier, OutputName,
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/NVPTX/NVPTX.td
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ foreach sm = [20, 21, 30, 32, 35, 37, 50, 52, 53,
def SM90a: FeatureSM<"90a", 901>;

foreach version = [32, 40, 41, 42, 43, 50, 60, 61, 62, 63, 64, 65,
70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84] in
70, 71, 72, 73, 74, 75, 76, 77, 78,
80, 81, 82, 83, 84, 85] in
def PTX#version: FeaturePTX<version>;

//===----------------------------------------------------------------------===//
Expand Down
Loading