Skip to content

Commit 27fa14d

Browse files
authored
Merge branch 'main' into fmv-features-metadata
2 parents e028f19 + 0adab6b commit 27fa14d

File tree

548 files changed

+23318
-26539
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

548 files changed

+23318
-26539
lines changed

bolt/lib/Passes/VeneerElimination.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,17 @@ Error VeneerElimination::runOnFunctions(BinaryContext &BC) {
4646
if (BF.isIgnored())
4747
continue;
4848

49+
MCInst &FirstInstruction = *(BF.begin()->begin());
4950
const MCSymbol *VeneerTargetSymbol = 0;
5051
uint64_t TargetAddress;
51-
if (BC.MIB->matchAbsLongVeneer(BF, TargetAddress)) {
52+
if (BC.MIB->isTailCall(FirstInstruction)) {
53+
VeneerTargetSymbol = BC.MIB->getTargetSymbol(FirstInstruction);
54+
} else if (BC.MIB->matchAbsLongVeneer(BF, TargetAddress)) {
5255
if (BinaryFunction *TargetBF =
5356
BC.getBinaryFunctionAtAddress(TargetAddress))
5457
VeneerTargetSymbol = TargetBF->getSymbol();
55-
} else {
56-
MCInst &FirstInstruction = *(BF.begin()->begin());
57-
if (BC.MIB->hasAnnotation(FirstInstruction, "AArch64Veneer"))
58-
VeneerTargetSymbol = BC.MIB->getTargetSymbol(FirstInstruction, 1);
58+
} else if (BC.MIB->hasAnnotation(FirstInstruction, "AArch64Veneer")) {
59+
VeneerTargetSymbol = BC.MIB->getTargetSymbol(FirstInstruction, 1);
5960
}
6061

6162
if (!VeneerTargetSymbol)

bolt/test/AArch64/veneer-lld-abs.s

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
## Check that llvm-bolt correctly recognizes long absolute thunks generated
2-
## by LLD.
1+
## Check that llvm-bolt correctly recognizes veneers/thunks for absolute code
2+
## generated by LLD.
33

44
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
55
# RUN: %clang %cflags -fno-PIC -no-pie %t.o -o %t.exe -nostdlib \
@@ -12,40 +12,63 @@
1212

1313
.text
1414
.balign 4
15-
.global foo
16-
.type foo, %function
17-
foo:
18-
adrp x1, foo
15+
.global far_function
16+
.type far_function, %function
17+
far_function:
1918
ret
20-
.size foo, .-foo
19+
.size far_function, .-far_function
20+
21+
.global near_function
22+
.type near_function, %function
23+
near_function:
24+
ret
25+
.size near_function, .-near_function
26+
27+
## Force relocations against .text.
28+
.reloc 0, R_AARCH64_NONE
2129

2230
.section ".mytext", "ax"
2331
.balign 4
2432

25-
.global __AArch64AbsLongThunk_foo
26-
.type __AArch64AbsLongThunk_foo, %function
27-
__AArch64AbsLongThunk_foo:
33+
## This version of a thunk is always generated by LLD for function calls
34+
## spanning more than 256MB.
35+
.global __AArch64AbsLongThunk_far_function
36+
.type __AArch64AbsLongThunk_far_function, %function
37+
__AArch64AbsLongThunk_far_function:
2838
ldr x16, .L1
2939
br x16
30-
# CHECK-INPUT-LABEL: <__AArch64AbsLongThunk_foo>:
40+
# CHECK-INPUT-LABEL: <__AArch64AbsLongThunk_far_function>:
3141
# CHECK-INPUT-NEXT: ldr
3242
# CHECK-INPUT-NEXT: br
3343
.L1:
34-
.quad foo
35-
.size __AArch64AbsLongThunk_foo, .-__AArch64AbsLongThunk_foo
44+
.quad far_function
45+
.size __AArch64AbsLongThunk_far_function, .-__AArch64AbsLongThunk_far_function
46+
47+
## If a callee is closer than 256MB away, LLD may generate a thunk with a direct
48+
## jump to the callee. Note, that the name might still include "AbsLong".
49+
.global __AArch64AbsLongThunk_near_function
50+
.type __AArch64AbsLongThunk_near_function, %function
51+
__AArch64AbsLongThunk_near_function:
52+
b near_function
53+
# CHECK-INPUT-LABEL: <__AArch64AbsLongThunk_near_function>:
54+
# CHECK-INPUT-NEXT: b {{.*}} <near_function>
55+
.size __AArch64AbsLongThunk_near_function, .-__AArch64AbsLongThunk_near_function
3656

37-
## Check that the thunk was removed from .text and _start() calls foo()
57+
## Check that thunks were removed from .text, and _start calls functions
3858
## directly.
3959

40-
# CHECK-OUTPUT-NOT: __AArch64AbsLongThunk_foo
60+
# CHECK-OUTPUT-NOT: __AArch64AbsLongThunk_{{.*}}
4161

4262
.global _start
4363
.type _start, %function
4464
_start:
4565
# CHECK-INPUT-LABEL: <_start>:
4666
# CHECK-OUTPUT-LABEL: <_start>:
47-
bl __AArch64AbsLongThunk_foo
48-
# CHECK-INPUT-NEXT: bl {{.*}} <__AArch64AbsLongThunk_foo>
49-
# CHECK-OUTPUT-NEXT: bl {{.*}} <foo>
67+
bl __AArch64AbsLongThunk_far_function
68+
bl __AArch64AbsLongThunk_near_function
69+
# CHECK-INPUT-NEXT: bl {{.*}} <__AArch64AbsLongThunk_far_function>
70+
# CHECK-INPUT-NEXT: bl {{.*}} <__AArch64AbsLongThunk_near_function>
71+
# CHECK-OUTPUT-NEXT: bl {{.*}} <far_function>
72+
# CHECK-OUTPUT-NEXT: bl {{.*}} <near_function>
5073
ret
5174
.size _start, .-_start

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,12 @@ void ClangdLSPServer::onInlayHint(const InlayHintsParams &Params,
14151415
std::move(Reply));
14161416
}
14171417

1418+
void ClangdLSPServer::onCallHierarchyOutgoingCalls(
1419+
const CallHierarchyOutgoingCallsParams &Params,
1420+
Callback<std::vector<CallHierarchyOutgoingCall>> Reply) {
1421+
Server->outgoingCalls(Params.item, std::move(Reply));
1422+
}
1423+
14181424
void ClangdLSPServer::applyConfiguration(
14191425
const ConfigurationSettings &Settings) {
14201426
// Per-file update to the compilation database.
@@ -1693,6 +1699,8 @@ void ClangdLSPServer::bindMethods(LSPBinder &Bind,
16931699
Bind.method("typeHierarchy/subtypes", this, &ClangdLSPServer::onSubTypes);
16941700
Bind.method("textDocument/prepareCallHierarchy", this, &ClangdLSPServer::onPrepareCallHierarchy);
16951701
Bind.method("callHierarchy/incomingCalls", this, &ClangdLSPServer::onCallHierarchyIncomingCalls);
1702+
if (Opts.EnableOutgoingCalls)
1703+
Bind.method("callHierarchy/outgoingCalls", this, &ClangdLSPServer::onCallHierarchyOutgoingCalls);
16961704
Bind.method("textDocument/selectionRange", this, &ClangdLSPServer::onSelectionRange);
16971705
Bind.method("textDocument/documentLink", this, &ClangdLSPServer::onDocumentLink);
16981706
Bind.method("textDocument/semanticTokens/full", this, &ClangdLSPServer::onSemanticTokens);

clang-tools-extra/clangd/ClangdLSPServer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ class ClangdLSPServer : private ClangdServer::Callbacks,
156156
void onCallHierarchyIncomingCalls(
157157
const CallHierarchyIncomingCallsParams &,
158158
Callback<std::vector<CallHierarchyIncomingCall>>);
159+
void onCallHierarchyOutgoingCalls(
160+
const CallHierarchyOutgoingCallsParams &,
161+
Callback<std::vector<CallHierarchyOutgoingCall>>);
159162
void onClangdInlayHints(const InlayHintsParams &,
160163
Callback<llvm::json::Value>);
161164
void onInlayHint(const InlayHintsParams &, Callback<std::vector<InlayHint>>);

clang-tools-extra/clangd/ClangdServer.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
215215
const ThreadsafeFS &TFS, const Options &Opts,
216216
Callbacks *Callbacks)
217217
: FeatureModules(Opts.FeatureModules), CDB(CDB), TFS(TFS),
218-
DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr),
218+
DynamicIdx(Opts.BuildDynamicSymbolIndex
219+
? new FileIndex(Opts.EnableOutgoingCalls)
220+
: nullptr),
219221
ModulesManager(Opts.ModulesManager),
220222
ClangTidyProvider(Opts.ClangTidyProvider),
221223
UseDirtyHeaders(Opts.UseDirtyHeaders),
@@ -256,6 +258,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
256258
Callbacks->onBackgroundIndexProgress(S);
257259
};
258260
BGOpts.ContextProvider = Opts.ContextProvider;
261+
BGOpts.SupportContainedRefs = Opts.EnableOutgoingCalls;
259262
BackgroundIdx = std::make_unique<BackgroundIndex>(
260263
TFS, CDB,
261264
BackgroundIndexStorage::createDiskBackedStorageFactory(
@@ -912,6 +915,15 @@ void ClangdServer::inlayHints(PathRef File, std::optional<Range> RestrictRange,
912915
WorkScheduler->runWithAST("InlayHints", File, std::move(Action), Transient);
913916
}
914917

918+
void ClangdServer::outgoingCalls(
919+
const CallHierarchyItem &Item,
920+
Callback<std::vector<CallHierarchyOutgoingCall>> CB) {
921+
WorkScheduler->run("Outgoing Calls", "",
922+
[CB = std::move(CB), Item, this]() mutable {
923+
CB(clangd::outgoingCalls(Item, Index));
924+
});
925+
}
926+
915927
void ClangdServer::onFileEvent(const DidChangeWatchedFilesParams &Params) {
916928
// FIXME: Do nothing for now. This will be used for indexing and potentially
917929
// invalidating other caches.

clang-tools-extra/clangd/ClangdServer.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ class ClangdServer {
110110
/// Cached preambles are potentially large. If false, store them on disk.
111111
bool StorePreamblesInMemory = true;
112112

113+
/// Call hierarchy's outgoing calls feature requires additional index
114+
/// serving structures which increase memory usage. If false, these are
115+
/// not created and the feature is not enabled.
116+
bool EnableOutgoingCalls = true;
117+
113118
/// This throttler controls which preambles may be built at a given time.
114119
clangd::PreambleThrottler *PreambleThrottler = nullptr;
115120

@@ -292,6 +297,10 @@ class ClangdServer {
292297
void incomingCalls(const CallHierarchyItem &Item,
293298
Callback<std::vector<CallHierarchyIncomingCall>>);
294299

300+
/// Resolve outgoing calls for a given call hierarchy item.
301+
void outgoingCalls(const CallHierarchyItem &Item,
302+
Callback<std::vector<CallHierarchyOutgoingCall>>);
303+
295304
/// Resolve inlay hints for a given document.
296305
void inlayHints(PathRef File, std::optional<Range> RestrictRange,
297306
Callback<std::vector<InlayHint>>);

clang-tools-extra/clangd/XRefs.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,6 +1702,7 @@ declToHierarchyItem(const NamedDecl &ND, llvm::StringRef TUPath) {
17021702

17031703
HierarchyItem HI;
17041704
HI.name = printName(Ctx, ND);
1705+
// FIXME: Populate HI.detail the way we do in symbolToHierarchyItem?
17051706
HI.kind = SK;
17061707
HI.range = Range{sourceLocToPosition(SM, DeclRange->getBegin()),
17071708
sourceLocToPosition(SM, DeclRange->getEnd())};
@@ -1753,6 +1754,7 @@ static std::optional<HierarchyItem> symbolToHierarchyItem(const Symbol &S,
17531754
}
17541755
HierarchyItem HI;
17551756
HI.name = std::string(S.Name);
1757+
HI.detail = (S.Scope + S.Name).str();
17561758
HI.kind = indexSymbolKindToSymbolKind(S.SymInfo.Kind);
17571759
HI.selectionRange = Loc->range;
17581760
// FIXME: Populate 'range' correctly
@@ -2319,6 +2321,65 @@ incomingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
23192321
return Results;
23202322
}
23212323

2324+
std::vector<CallHierarchyOutgoingCall>
2325+
outgoingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
2326+
std::vector<CallHierarchyOutgoingCall> Results;
2327+
if (!Index || Item.data.empty())
2328+
return Results;
2329+
auto ID = SymbolID::fromStr(Item.data);
2330+
if (!ID) {
2331+
elog("outgoingCalls failed to find symbol: {0}", ID.takeError());
2332+
return Results;
2333+
}
2334+
// In this function, we find outgoing calls based on the index only.
2335+
ContainedRefsRequest Request;
2336+
Request.ID = *ID;
2337+
// Initially store the ranges in a map keyed by SymbolID of the callee.
2338+
// This allows us to group different calls to the same function
2339+
// into the same CallHierarchyOutgoingCall.
2340+
llvm::DenseMap<SymbolID, std::vector<Range>> CallsOut;
2341+
// We can populate the ranges based on a refs request only. As we do so, we
2342+
// also accumulate the callee IDs into a lookup request.
2343+
LookupRequest CallsOutLookup;
2344+
Index->containedRefs(Request, [&](const auto &R) {
2345+
auto Loc = indexToLSPLocation(R.Location, Item.uri.file());
2346+
if (!Loc) {
2347+
elog("outgoingCalls failed to convert location: {0}", Loc.takeError());
2348+
return;
2349+
}
2350+
auto It = CallsOut.try_emplace(R.Symbol, std::vector<Range>{}).first;
2351+
It->second.push_back(Loc->range);
2352+
2353+
CallsOutLookup.IDs.insert(R.Symbol);
2354+
});
2355+
// Perform the lookup request and combine its results with CallsOut to
2356+
// get complete CallHierarchyOutgoingCall objects.
2357+
Index->lookup(CallsOutLookup, [&](const Symbol &Callee) {
2358+
// The containedRefs request should only return symbols which are
2359+
// function-like, i.e. symbols for which references to them can be "calls".
2360+
using SK = index::SymbolKind;
2361+
auto Kind = Callee.SymInfo.Kind;
2362+
assert(Kind == SK::Function || Kind == SK::InstanceMethod ||
2363+
Kind == SK::ClassMethod || Kind == SK::StaticMethod ||
2364+
Kind == SK::Constructor || Kind == SK::Destructor ||
2365+
Kind == SK::ConversionFunction);
2366+
(void)Kind;
2367+
(void)SK::Function;
2368+
2369+
auto It = CallsOut.find(Callee.ID);
2370+
assert(It != CallsOut.end());
2371+
if (auto CHI = symbolToCallHierarchyItem(Callee, Item.uri.file()))
2372+
Results.push_back(
2373+
CallHierarchyOutgoingCall{std::move(*CHI), std::move(It->second)});
2374+
});
2375+
// Sort results by name of the callee.
2376+
llvm::sort(Results, [](const CallHierarchyOutgoingCall &A,
2377+
const CallHierarchyOutgoingCall &B) {
2378+
return A.to.name < B.to.name;
2379+
});
2380+
return Results;
2381+
}
2382+
23222383
llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST,
23232384
const FunctionDecl *FD) {
23242385
if (!FD->hasBody())

clang-tools-extra/clangd/XRefs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ prepareCallHierarchy(ParsedAST &AST, Position Pos, PathRef TUPath);
150150
std::vector<CallHierarchyIncomingCall>
151151
incomingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index);
152152

153+
std::vector<CallHierarchyOutgoingCall>
154+
outgoingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index);
155+
153156
/// Returns all decls that are referenced in the \p FD except local symbols.
154157
llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST,
155158
const FunctionDecl *FD);

clang-tools-extra/clangd/index/Background.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ BackgroundIndex::BackgroundIndex(
9696
: SwapIndex(std::make_unique<MemIndex>()), TFS(TFS), CDB(CDB),
9797
IndexingPriority(Opts.IndexingPriority),
9898
ContextProvider(std::move(Opts.ContextProvider)),
99-
IndexedSymbols(IndexContents::All),
99+
IndexedSymbols(IndexContents::All, Opts.SupportContainedRefs),
100100
Rebuilder(this, &IndexedSymbols, Opts.ThreadPoolSize),
101101
IndexStorageFactory(std::move(IndexStorageFactory)),
102102
Queue(std::move(Opts.OnProgress)),

clang-tools-extra/clangd/index/Background.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ class BackgroundIndex : public SwapIndex {
145145
// file. Called with the empty string for other tasks.
146146
// (When called, the context from BackgroundIndex construction is active).
147147
std::function<Context(PathRef)> ContextProvider = nullptr;
148+
// Whether the index needs to support the containedRefs() operation.
149+
// May use extra memory.
150+
bool SupportContainedRefs = true;
148151
};
149152

150153
/// Creates a new background index and starts its threads.

0 commit comments

Comments
 (0)