Skip to content

Commit

Permalink
Merged main:202d359753d1 into amd-gfx:e2ab3cde433e
Browse files Browse the repository at this point in the history
Local branch amd-gfx e2ab3cd Merged main:7c9c2a2ea5e3 into amd-gfx:357c325e0649
Remote branch main 202d359 [X86] Add the FSRM feature (Fast Short Rep Mov) to Zen3.
  • Loading branch information
Sw authored and Sw committed Jan 14, 2021
2 parents e2ab3cd + 202d359 commit 47ed92e
Show file tree
Hide file tree
Showing 53 changed files with 1,237 additions and 248 deletions.
42 changes: 42 additions & 0 deletions clang-tools-extra/clangd/ASTSignals.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//===--- ASTSignals.cpp ------------------------------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ASTSignals.h"
#include "AST.h"
#include "FindTarget.h"

namespace clang {
namespace clangd {
ASTSignals ASTSignals::derive(const ParsedAST &AST) {
ASTSignals Signals;
const SourceManager &SM = AST.getSourceManager();
findExplicitReferences(AST.getASTContext(), [&](ReferenceLoc Ref) {
for (const NamedDecl *ND : Ref.Targets) {
if (!isInsideMainFile(Ref.NameLoc, SM))
continue;
SymbolID ID = getSymbolID(ND);
if (!ID)
continue;
unsigned &SymbolCount = Signals.ReferencedSymbols[ID];
SymbolCount++;
// Process namespace only when we see the symbol for the first time.
if (SymbolCount != 1)
continue;
if (const auto *NSD = dyn_cast<NamespaceDecl>(ND->getDeclContext())) {
if (NSD->isAnonymousNamespace())
continue;
std::string NS = printNamespaceScope(*NSD);
if (!NS.empty())
Signals.RelatedNamespaces[NS]++;
}
}
});
return Signals;
}
} // namespace clangd
} // namespace clang
39 changes: 39 additions & 0 deletions clang-tools-extra/clangd/ASTSignals.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//===--- ASTSignals.h --------------------------------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_ASTSIGNALS_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_ASTSIGNALS_H

#include "ParsedAST.h"
#include "index/SymbolID.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"

namespace clang {
namespace clangd {

/// Signals derived from a valid AST of a file.
/// Provides information that can only be extracted from the AST to actions that
/// can't access an AST. The signals are computed and updated asynchronously by
/// the ASTWorker and thus they are always stale and also can be absent.
/// Example usage: Information about the declarations used in a file affects
/// code-completion ranking in that file.
struct ASTSignals {
/// Number of occurrences of each symbol present in the file.
llvm::DenseMap<SymbolID, unsigned> ReferencedSymbols;
/// Namespaces whose symbols are used in the file, and the number of such
/// distinct symbols.
llvm::StringMap<unsigned> RelatedNamespaces;

static ASTSignals derive(const ParsedAST &AST);
};

} // namespace clangd
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_ASTSIGNALS_H
1 change: 1 addition & 0 deletions clang-tools-extra/clangd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}/../clang-tidy")

add_clang_library(clangDaemon
AST.cpp
ASTSignals.cpp
ClangdLSPServer.cpp
ClangdServer.cpp
CodeComplete.cpp
Expand Down
73 changes: 46 additions & 27 deletions clang-tools-extra/clangd/TUScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,8 @@ class ASTWorker {
TUScheduler::ASTActionInvalidation);
bool blockUntilIdle(Deadline Timeout) const;

std::shared_ptr<const PreambleData> getPossiblyStalePreamble() const;
std::shared_ptr<const PreambleData> getPossiblyStalePreamble(
std::shared_ptr<const ASTSignals> *ASTSignals = nullptr) const;

/// Used to inform ASTWorker about a new preamble build by PreambleThread.
/// Diagnostics are only published through this callback. This ensures they
Expand Down Expand Up @@ -437,6 +438,8 @@ class ASTWorker {
void generateDiagnostics(std::unique_ptr<CompilerInvocation> Invocation,
ParseInputs Inputs, std::vector<Diag> CIDiags);

void updateASTSignals(ParsedAST &AST);

// Must be called exactly once on processing thread. Will return after
// stop() is called on a separate thread and all pending requests are
// processed.
Expand Down Expand Up @@ -499,6 +502,7 @@ class ASTWorker {
/// Signalled whenever a new request has been scheduled or processing of a
/// request has completed.
mutable std::condition_variable RequestsCV;
std::shared_ptr<const ASTSignals> LatestASTSignals; /* GUARDED_BY(Mutex) */
/// Latest build preamble for current TU.
/// None means no builds yet, null means there was an error while building.
/// Only written by ASTWorker's thread.
Expand Down Expand Up @@ -830,6 +834,16 @@ void ASTWorker::updatePreamble(std::unique_ptr<CompilerInvocation> CI,
RequestsCV.notify_all();
}

void ASTWorker::updateASTSignals(ParsedAST &AST) {
auto Signals = std::make_shared<const ASTSignals>(ASTSignals::derive(AST));
// Existing readers of ASTSignals will have their copy preserved until the
// read is completed. The last reader deletes the old ASTSignals.
{
std::lock_guard<std::mutex> Lock(Mutex);
std::swap(LatestASTSignals, Signals);
}
}

void ASTWorker::generateDiagnostics(
std::unique_ptr<CompilerInvocation> Invocation, ParseInputs Inputs,
std::vector<Diag> CIDiags) {
Expand Down Expand Up @@ -908,6 +922,7 @@ void ASTWorker::generateDiagnostics(
if (*AST) {
trace::Span Span("Running main AST callback");
Callbacks.onMainAST(FileName, **AST, RunPublish);
updateASTSignals(**AST);
} else {
// Failed to build the AST, at least report diagnostics from the
// command line if there were any.
Expand All @@ -925,9 +940,11 @@ void ASTWorker::generateDiagnostics(
}
}

std::shared_ptr<const PreambleData>
ASTWorker::getPossiblyStalePreamble() const {
std::shared_ptr<const PreambleData> ASTWorker::getPossiblyStalePreamble(
std::shared_ptr<const ASTSignals> *ASTSignals) const {
std::lock_guard<std::mutex> Lock(Mutex);
if (ASTSignals)
*ASTSignals = LatestASTSignals;
return LatestPreamble ? *LatestPreamble : nullptr;
}

Expand Down Expand Up @@ -1364,38 +1381,40 @@ void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File,
if (!PreambleTasks) {
trace::Span Tracer(Name);
SPAN_ATTACH(Tracer, "file", File);
std::shared_ptr<const ASTSignals> Signals;
std::shared_ptr<const PreambleData> Preamble =
It->second->Worker->getPossiblyStalePreamble();
It->second->Worker->getPossiblyStalePreamble(&Signals);
WithContext WithProvidedContext(Opts.ContextProvider(File));
Action(InputsAndPreamble{It->second->Contents,
It->second->Worker->getCurrentCompileCommand(),
Preamble.get()});
Preamble.get(), Signals.get()});
return;
}

std::shared_ptr<const ASTWorker> Worker = It->second->Worker.lock();
auto Task =
[Worker, Consistency, Name = Name.str(), File = File.str(),
Contents = It->second->Contents,
Command = Worker->getCurrentCompileCommand(),
Ctx = Context::current().derive(kFileBeingProcessed, std::string(File)),
Action = std::move(Action), this]() mutable {
std::shared_ptr<const PreambleData> Preamble;
if (Consistency == PreambleConsistency::Stale) {
// Wait until the preamble is built for the first time, if preamble
// is required. This avoids extra work of processing the preamble
// headers in parallel multiple times.
Worker->waitForFirstPreamble();
}
Preamble = Worker->getPossiblyStalePreamble();

std::lock_guard<Semaphore> BarrierLock(Barrier);
WithContext Guard(std::move(Ctx));
trace::Span Tracer(Name);
SPAN_ATTACH(Tracer, "file", File);
WithContext WithProvidedContext(Opts.ContextProvider(File));
Action(InputsAndPreamble{Contents, Command, Preamble.get()});
};
auto Task = [Worker, Consistency, Name = Name.str(), File = File.str(),
Contents = It->second->Contents,
Command = Worker->getCurrentCompileCommand(),
Ctx = Context::current().derive(kFileBeingProcessed,
std::string(File)),
Action = std::move(Action), this]() mutable {
std::shared_ptr<const PreambleData> Preamble;
if (Consistency == PreambleConsistency::Stale) {
// Wait until the preamble is built for the first time, if preamble
// is required. This avoids extra work of processing the preamble
// headers in parallel multiple times.
Worker->waitForFirstPreamble();
}
std::shared_ptr<const ASTSignals> Signals;
Preamble = Worker->getPossiblyStalePreamble(&Signals);

std::lock_guard<Semaphore> BarrierLock(Barrier);
WithContext Guard(std::move(Ctx));
trace::Span Tracer(Name);
SPAN_ATTACH(Tracer, "file", File);
WithContext WithProvidedContext(Opts.ContextProvider(File));
Action(InputsAndPreamble{Contents, Command, Preamble.get(), Signals.get()});
};

PreambleTasks->runAsync("task:" + llvm::sys::path::filename(File),
std::move(Task));
Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clangd/TUScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TUSCHEDULER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TUSCHEDULER_H

#include "ASTSignals.h"
#include "Compiler.h"
#include "Diagnostics.h"
#include "GlobalCompilationDatabase.h"
Expand Down Expand Up @@ -43,6 +44,8 @@ struct InputsAndPreamble {
const tooling::CompileCommand &Command;
// This can be nullptr if no preamble is available.
const PreambleData *Preamble;
// This can be nullptr if no ASTSignals are available.
const ASTSignals *Signals;
};

/// Determines whether diagnostics should be generated for a file snapshot.
Expand Down
75 changes: 75 additions & 0 deletions clang-tools-extra/clangd/unittests/ASTSignalsTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//===-- ASTSignalsTests.cpp -------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "AST.h"

#include "ParsedAST.h"
#include "TestIndex.h"
#include "TestTU.h"
#include "llvm/ADT/StringRef.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace clang {
namespace clangd {
namespace {

using ::testing::_;
using ::testing::Pair;
using ::testing::UnorderedElementsAre;

TEST(ASTSignals, Derive) {
TestTU TU = TestTU::withCode(R"cpp(
namespace ns1 {
namespace ns2 {
namespace {
int func() {
tar::X a;
a.Y = 1;
return ADD(tar::kConst, a.Y, tar::foo()) + fooInNS2() + tar::foo();
}
} // namespace
} // namespace ns2
} // namespace ns1
)cpp");

TU.HeaderCode = R"cpp(
#define ADD(x, y, z) (x + y + z)
namespace tar { // A related namespace.
int kConst = 5;
int foo();
void bar(); // Unused symbols are not recorded.
class X {
public: int Y;
};
} // namespace tar
namespace ns1::ns2 { int fooInNS2(); }}
)cpp";
ASTSignals Signals = ASTSignals::derive(TU.build());
std::vector<std::pair<StringRef, int>> NS;
for (const auto &P : Signals.RelatedNamespaces)
NS.emplace_back(P.getKey(), P.getValue());
EXPECT_THAT(NS, UnorderedElementsAre(Pair("ns1::", 1), Pair("ns1::ns2::", 1),
Pair("tar::", /*foo, kConst, X*/ 3)));

std::vector<std::pair<SymbolID, int>> Sym;
for (const auto &P : Signals.ReferencedSymbols)
Sym.emplace_back(P.getFirst(), P.getSecond());
EXPECT_THAT(
Sym,
UnorderedElementsAre(
Pair(ns("tar").ID, 4), Pair(ns("ns1").ID, 1),
Pair(ns("ns1::ns2").ID, 1), Pair(_ /*int func();*/, 1),
Pair(cls("tar::X").ID, 1), Pair(var("tar::kConst").ID, 1),
Pair(func("tar::foo").ID, 2), Pair(func("ns1::ns2::fooInNS2").ID, 1),
Pair(sym("Y", index::SymbolKind::Variable, "@N@tar@S@X@FI@\\0").ID,
2),
Pair(_ /*a*/, 3)));
}
} // namespace
} // namespace clangd
} // namespace clang
1 change: 1 addition & 0 deletions clang-tools-extra/clangd/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ add_custom_target(ClangdUnitTests)
add_unittest(ClangdUnitTests ClangdTests
Annotations.cpp
ASTTests.cpp
ASTSignalsTests.cpp
BackgroundIndexTests.cpp
CallHierarchyTests.cpp
CanonicalIncludesTests.cpp
Expand Down
Loading

0 comments on commit 47ed92e

Please sign in to comment.