Skip to content

Commit c05126b

Browse files
authored
[LLVM][LTO] Factor out RTLib calls and allow them to be dropped (#98512)
Summary: The LTO pass and LLD linker have logic in them that forces extraction and prevent internalization of needed runtime calls. However, these currently take all RTLibcalls into account, even if the target does not support them. The target opts-out of a libcall if it sets its name to nullptr. This patch pulls this logic out into a class in the header so that LTO / lld can use it to determine if a symbol actually needs to be kept. This is important for targets like AMDGPU that want to be able to use `lld` to perform the final link step, but does not want the overhead of uncalled functions. (This adds like a second to the link time trivially)
1 parent c878399 commit c05126b

37 files changed

+676
-568
lines changed

lld/COFF/Driver.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,9 +2428,12 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
24282428
// file's symbol table. If any of those library functions are defined in a
24292429
// bitcode file in an archive member, we need to arrange to use LTO to
24302430
// compile those archive members by adding them to the link beforehand.
2431-
if (!ctx.bitcodeFileInstances.empty())
2432-
for (auto *s : lto::LTO::getRuntimeLibcallSymbols())
2431+
if (!ctx.bitcodeFileInstances.empty()) {
2432+
llvm::Triple TT(
2433+
ctx.bitcodeFileInstances.front()->obj->getTargetTriple());
2434+
for (auto *s : lto::LTO::getRuntimeLibcallSymbols(TT))
24332435
ctx.symtab.addLibcall(s);
2436+
}
24342437

24352438
// Windows specific -- if __load_config_used can be resolved, resolve it.
24362439
if (ctx.symtab.findUnderscore("_load_config_used"))

lld/ELF/Driver.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2883,9 +2883,11 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
28832883
// to, i.e. if the symbol's definition is in bitcode. Any other required
28842884
// libcall symbols will be added to the link after LTO when we add the LTO
28852885
// object file to the link.
2886-
if (!ctx.bitcodeFiles.empty())
2887-
for (auto *s : lto::LTO::getRuntimeLibcallSymbols())
2886+
if (!ctx.bitcodeFiles.empty()) {
2887+
llvm::Triple TT(ctx.bitcodeFiles.front()->obj->getTargetTriple());
2888+
for (auto *s : lto::LTO::getRuntimeLibcallSymbols(TT))
28882889
handleLibcall(s);
2890+
}
28892891

28902892
// Archive members defining __wrap symbols may be extracted.
28912893
std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);

lld/wasm/Driver.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,9 +1320,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
13201320
// We only need to add libcall symbols to the link before LTO if the symbol's
13211321
// definition is in bitcode. Any other required libcall symbols will be added
13221322
// to the link after LTO when we add the LTO object file to the link.
1323-
if (!ctx.bitcodeFiles.empty())
1324-
for (auto *s : lto::LTO::getRuntimeLibcallSymbols())
1323+
if (!ctx.bitcodeFiles.empty()) {
1324+
llvm::Triple TT(ctx.bitcodeFiles.front()->obj->getTargetTriple());
1325+
for (auto *s : lto::LTO::getRuntimeLibcallSymbols(TT))
13251326
handleLibcall(s);
1327+
}
13261328
if (errorCount())
13271329
return;
13281330

llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
2424
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
25-
#include "llvm/CodeGen/RuntimeLibcalls.h"
25+
#include "llvm/CodeGen/RuntimeLibcallUtil.h"
2626
#include "llvm/CodeGen/TargetOpcodes.h"
2727

2828
namespace llvm {
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
//===-- CodeGen/RuntimeLibcallUtil.h - Runtime Library Calls ----*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines some helper functions for runtime library calls.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CODEGEN_RUNTIMELIBCALLS_H
14+
#define LLVM_CODEGEN_RUNTIMELIBCALLS_H
15+
16+
#include "llvm/CodeGen/ValueTypes.h"
17+
#include "llvm/IR/RuntimeLibcalls.h"
18+
#include "llvm/Support/AtomicOrdering.h"
19+
20+
namespace llvm {
21+
namespace RTLIB {
22+
23+
/// GetFPLibCall - Helper to return the right libcall for the given floating
24+
/// point type, or UNKNOWN_LIBCALL if there is none.
25+
Libcall getFPLibCall(EVT VT, Libcall Call_F32, Libcall Call_F64,
26+
Libcall Call_F80, Libcall Call_F128, Libcall Call_PPCF128);
27+
28+
/// getFPEXT - Return the FPEXT_*_* value for the given types, or
29+
/// UNKNOWN_LIBCALL if there is none.
30+
Libcall getFPEXT(EVT OpVT, EVT RetVT);
31+
32+
/// getFPROUND - Return the FPROUND_*_* value for the given types, or
33+
/// UNKNOWN_LIBCALL if there is none.
34+
Libcall getFPROUND(EVT OpVT, EVT RetVT);
35+
36+
/// getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or
37+
/// UNKNOWN_LIBCALL if there is none.
38+
Libcall getFPTOSINT(EVT OpVT, EVT RetVT);
39+
40+
/// getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or
41+
/// UNKNOWN_LIBCALL if there is none.
42+
Libcall getFPTOUINT(EVT OpVT, EVT RetVT);
43+
44+
/// getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or
45+
/// UNKNOWN_LIBCALL if there is none.
46+
Libcall getSINTTOFP(EVT OpVT, EVT RetVT);
47+
48+
/// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or
49+
/// UNKNOWN_LIBCALL if there is none.
50+
Libcall getUINTTOFP(EVT OpVT, EVT RetVT);
51+
52+
/// getPOWI - Return the POWI_* value for the given types, or
53+
/// UNKNOWN_LIBCALL if there is none.
54+
Libcall getPOWI(EVT RetVT);
55+
56+
/// getLDEXP - Return the LDEXP_* value for the given types, or
57+
/// UNKNOWN_LIBCALL if there is none.
58+
Libcall getLDEXP(EVT RetVT);
59+
60+
/// getFREXP - Return the FREXP_* value for the given types, or
61+
/// UNKNOWN_LIBCALL if there is none.
62+
Libcall getFREXP(EVT RetVT);
63+
64+
/// Return the SYNC_FETCH_AND_* value for the given opcode and type, or
65+
/// UNKNOWN_LIBCALL if there is none.
66+
Libcall getSYNC(unsigned Opc, MVT VT);
67+
68+
/// Return the outline atomics value for the given atomic ordering, access
69+
/// size and set of libcalls for a given atomic, or UNKNOWN_LIBCALL if there
70+
/// is none.
71+
Libcall getOutlineAtomicHelper(const Libcall (&LC)[5][4], AtomicOrdering Order,
72+
uint64_t MemSize);
73+
74+
/// Return the outline atomics value for the given opcode, atomic ordering
75+
/// and type, or UNKNOWN_LIBCALL if there is none.
76+
Libcall getOUTLINE_ATOMIC(unsigned Opc, AtomicOrdering Order, MVT VT);
77+
78+
/// getMEMCPY_ELEMENT_UNORDERED_ATOMIC - Return
79+
/// MEMCPY_ELEMENT_UNORDERED_ATOMIC_* value for the given element size or
80+
/// UNKNOW_LIBCALL if there is none.
81+
Libcall getMEMCPY_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize);
82+
83+
/// getMEMMOVE_ELEMENT_UNORDERED_ATOMIC - Return
84+
/// MEMMOVE_ELEMENT_UNORDERED_ATOMIC_* value for the given element size or
85+
/// UNKNOW_LIBCALL if there is none.
86+
Libcall getMEMMOVE_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize);
87+
88+
/// getMEMSET_ELEMENT_UNORDERED_ATOMIC - Return
89+
/// MEMSET_ELEMENT_UNORDERED_ATOMIC_* value for the given element size or
90+
/// UNKNOW_LIBCALL if there is none.
91+
Libcall getMEMSET_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize);
92+
93+
} // namespace RTLIB
94+
} // namespace llvm
95+
96+
#endif

llvm/include/llvm/CodeGen/RuntimeLibcalls.h

Lines changed: 0 additions & 113 deletions
This file was deleted.

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include "llvm/CodeGen/ISDOpcodes.h"
3232
#include "llvm/CodeGen/LowLevelTypeUtils.h"
3333
#include "llvm/CodeGen/MachineRegisterInfo.h"
34-
#include "llvm/CodeGen/RuntimeLibcalls.h"
34+
#include "llvm/CodeGen/RuntimeLibcallUtil.h"
3535
#include "llvm/CodeGen/SelectionDAG.h"
3636
#include "llvm/CodeGen/SelectionDAGNodes.h"
3737
#include "llvm/CodeGen/TargetCallingConv.h"
@@ -45,6 +45,7 @@
4545
#include "llvm/IR/InlineAsm.h"
4646
#include "llvm/IR/Instruction.h"
4747
#include "llvm/IR/Instructions.h"
48+
#include "llvm/IR/RuntimeLibcalls.h"
4849
#include "llvm/IR/Type.h"
4950
#include "llvm/Support/Alignment.h"
5051
#include "llvm/Support/AtomicOrdering.h"
@@ -3410,44 +3411,40 @@ class TargetLoweringBase {
34103411
return nullptr;
34113412
}
34123413

3413-
//===--------------------------------------------------------------------===//
3414-
// Runtime Library hooks
3415-
//
3416-
34173414
/// Rename the default libcall routine name for the specified libcall.
34183415
void setLibcallName(RTLIB::Libcall Call, const char *Name) {
3419-
LibcallRoutineNames[Call] = Name;
3416+
Libcalls.setLibcallName(Call, Name);
34203417
}
3418+
34213419
void setLibcallName(ArrayRef<RTLIB::Libcall> Calls, const char *Name) {
3422-
for (auto Call : Calls)
3423-
setLibcallName(Call, Name);
3420+
Libcalls.setLibcallName(Calls, Name);
34243421
}
34253422

34263423
/// Get the libcall routine name for the specified libcall.
34273424
const char *getLibcallName(RTLIB::Libcall Call) const {
3428-
return LibcallRoutineNames[Call];
3425+
return Libcalls.getLibcallName(Call);
34293426
}
34303427

34313428
/// Override the default CondCode to be used to test the result of the
34323429
/// comparison libcall against zero.
34333430
void setCmpLibcallCC(RTLIB::Libcall Call, ISD::CondCode CC) {
3434-
CmpLibcallCCs[Call] = CC;
3431+
Libcalls.setCmpLibcallCC(Call, CC);
34353432
}
34363433

34373434
/// Get the CondCode that's to be used to test the result of the comparison
34383435
/// libcall against zero.
34393436
ISD::CondCode getCmpLibcallCC(RTLIB::Libcall Call) const {
3440-
return CmpLibcallCCs[Call];
3437+
return Libcalls.getCmpLibcallCC(Call);
34413438
}
34423439

34433440
/// Set the CallingConv that should be used for the specified libcall.
34443441
void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
3445-
LibcallCallingConvs[Call] = CC;
3442+
Libcalls.setLibcallCallingConv(Call, CC);
34463443
}
34473444

34483445
/// Get the CallingConv that should be used for the specified libcall.
34493446
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
3450-
return LibcallCallingConvs[Call];
3447+
return Libcalls.getLibcallCallingConv(Call);
34513448
}
34523449

34533450
/// Execute target specific actions to finalize target lowering.
@@ -3626,18 +3623,8 @@ class TargetLoweringBase {
36263623
std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>
36273624
PromoteToType;
36283625

3629-
/// Stores the name each libcall.
3630-
const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1];
3631-
3632-
/// The ISD::CondCode that should be used to test the result of each of the
3633-
/// comparison libcall against zero.
3634-
ISD::CondCode CmpLibcallCCs[RTLIB::UNKNOWN_LIBCALL];
3635-
3636-
/// Stores the CallingConv that should be used for each libcall.
3637-
CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL];
3638-
3639-
/// Set default libcall names and calling conventions.
3640-
void InitLibcalls(const Triple &TT);
3626+
/// The list of libcalls that the target will use.
3627+
RTLIB::RuntimeLibcallsInfo Libcalls;
36413628

36423629
/// The bits of IndexedModeActions used to store the legalisation actions
36433630
/// We store the data as | ML | MS | L | S | each taking 4 bits.

0 commit comments

Comments
 (0)