Skip to content

Commit eff1444

Browse files
seanyoungdmakarov
authored andcommitted
[SOL] Fixes required for Solang (#10)
* [SOL] Make lld thread-safe with llvm when used in-process Every time Solang tries to link a web-assembly file in-process, the linker re-inits llvm which is not thread-safe with the rest of solang. Signed-off-by: Sean Young <sean@mess.org> * [SOL][BPF] Enable the _ExtInt extension on the BPF Target for Solana Signed-off-by: Sean Young <sean@mess.org>
1 parent eee9310 commit eff1444

File tree

6 files changed

+28
-36
lines changed

6 files changed

+28
-36
lines changed

clang/lib/Basic/Targets/BPF.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace clang {
2222
namespace targets {
2323

2424
class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
25+
bool HasSolanaFeature = false;
2526
static const Builtin::Info BuiltinInfo[];
2627

2728
public:
@@ -34,21 +35,20 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
3435
IntMaxType = SignedLong;
3536
Int64Type = SignedLong;
3637
RegParmMax = 5;
37-
auto isSolana = false;
3838
for (auto& it : Opts.FeaturesAsWritten) {
3939
if (it == "+solana") {
40-
isSolana = true;
40+
HasSolanaFeature = true;
4141
break;
4242
}
4343
}
4444
if (Triple.getArch() == llvm::Triple::bpfeb) {
45-
if (isSolana) {
45+
if (HasSolanaFeature) {
4646
resetDataLayout("E-m:e-p:64:64-i64:64-n32:64-S128");
4747
} else {
4848
resetDataLayout("E-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
4949
}
5050
} else {
51-
if (isSolana) {
51+
if (HasSolanaFeature) {
5252
resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128");
5353
} else {
5454
resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
@@ -112,6 +112,8 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
112112
StringRef CPUName(Name);
113113
return isValidCPUName(CPUName);
114114
}
115+
116+
bool hasExtIntType() const override { return HasSolanaFeature; }
115117
};
116118
} // namespace targets
117119
} // namespace clang

clang/test/CodeGen/ext-int-cc.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
// RUN: %clang_cc1 -triple arm64_32-apple-ios -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64
2929
// RUN: %clang_cc1 -triple arm64_32-apple-ios -target-abi darwinpcs -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=AARCH64DARWIN
3030
// RUN: %clang_cc1 -triple arm -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=ARM
31+
// RUN: %clang_cc1 -triple bpf -target-feature +solana -O3 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=BPF
3132

3233
// Make sure 128 and 64 bit versions are passed like integers, and that >128
3334
// is passed indirectly.
@@ -59,6 +60,7 @@ void ParamPassing(_ExtInt(129) a, _ExtInt(128) b, _ExtInt(64) c) {}
5960
// AARCH64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
6061
// AARCH64DARWIN: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
6162
// ARM: define arm_aapcscc void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}})
63+
// BPF: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}})
6264

6365
void ParamPassing2(_ExtInt(129) a, _ExtInt(127) b, _ExtInt(63) c) {}
6466
// LIN64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i64 %{{.+}})
@@ -88,6 +90,7 @@ void ParamPassing2(_ExtInt(129) a, _ExtInt(127) b, _ExtInt(63) c) {}
8890
// AARCH64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
8991
// AARCH64DARWIN: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
9092
// ARM: define arm_aapcscc void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}})
93+
// BPF: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}})
9194

9295
// Make sure we follow the signext rules for promotable integer types.
9396
void ParamPassing3(_ExtInt(15) a, _ExtInt(31) b) {}
@@ -118,6 +121,7 @@ void ParamPassing3(_ExtInt(15) a, _ExtInt(31) b) {}
118121
// AARCH64: define void @ParamPassing3(i15 %{{.+}}, i31 %{{.+}})
119122
// AARCH64DARWIN: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
120123
// ARM: define arm_aapcscc void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
124+
// BPF: define void @ParamPassing3(i15 signext %{{.+}}, i31 signext %{{.+}})
121125

122126
_ExtInt(63) ReturnPassing(){}
123127
// LIN64: define i64 @ReturnPassing(
@@ -147,6 +151,7 @@ _ExtInt(63) ReturnPassing(){}
147151
// AARCH64: define i63 @ReturnPassing(
148152
// AARCH64DARWIN: define i63 @ReturnPassing(
149153
// ARM: define arm_aapcscc i63 @ReturnPassing(
154+
// BPF: define i63 @ReturnPassing(
150155

151156
_ExtInt(64) ReturnPassing2(){}
152157
// LIN64: define i64 @ReturnPassing2(
@@ -176,6 +181,7 @@ _ExtInt(64) ReturnPassing2(){}
176181
// AARCH64: define i64 @ReturnPassing2(
177182
// AARCH64DARWIN: define i64 @ReturnPassing2(
178183
// ARM: define arm_aapcscc i64 @ReturnPassing2(
184+
// BPF: define i64 @ReturnPassing2(
179185

180186
_ExtInt(127) ReturnPassing3(){}
181187
// LIN64: define { i64, i64 } @ReturnPassing3(
@@ -207,6 +213,7 @@ _ExtInt(127) ReturnPassing3(){}
207213
// AARCH64: define i127 @ReturnPassing3(
208214
// AARCH64DARWIN: define i127 @ReturnPassing3(
209215
// ARM: define arm_aapcscc void @ReturnPassing3(i127* noalias sret
216+
// BPF: define i127 @ReturnPassing3(
210217

211218
_ExtInt(128) ReturnPassing4(){}
212219
// LIN64: define { i64, i64 } @ReturnPassing4(
@@ -236,6 +243,7 @@ _ExtInt(128) ReturnPassing4(){}
236243
// AARCH64: define i128 @ReturnPassing4(
237244
// AARCH64DARWIN: define i128 @ReturnPassing4(
238245
// ARM: define arm_aapcscc void @ReturnPassing4(i128* noalias sret
246+
// BPF: define i128 @ReturnPassing4(
239247

240248
_ExtInt(129) ReturnPassing5(){}
241249
// LIN64: define void @ReturnPassing5(i129* noalias sret
@@ -265,6 +273,7 @@ _ExtInt(129) ReturnPassing5(){}
265273
// AARCH64: define void @ReturnPassing5(i129* noalias sret
266274
// AARCH64DARWIN: define void @ReturnPassing5(i129* noalias sret
267275
// ARM: define arm_aapcscc void @ReturnPassing5(i129* noalias sret
276+
// BPF: define void @ReturnPassing5(i129* noalias sret
268277

269278
// SparcV9 is odd in that it has a return-size limit of 256, not 128 or 64
270279
// like other platforms, so test to make sure this behavior will still work.

lld/COFF/Driver.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,13 +1110,6 @@ Optional<std::string> getReproduceFile(const opt::InputArgList &args) {
11101110
void LinkerDriver::link(ArrayRef<const char *> argsArr) {
11111111
ScopedTimer rootTimer(Timer::root());
11121112

1113-
// Needed for LTO.
1114-
InitializeAllTargetInfos();
1115-
InitializeAllTargets();
1116-
InitializeAllTargetMCs();
1117-
InitializeAllAsmParsers();
1118-
InitializeAllAsmPrinters();
1119-
11201113
// If the first command line argument is "/lib", link.exe acts like lib.exe.
11211114
// We call our own implementation of lib.exe that understands bitcode files.
11221115
if (argsArr.size() > 1 && StringRef(argsArr[1]).equals_lower("/lib")) {

lld/ELF/Driver.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -281,17 +281,6 @@ void LinkerDriver::addLibrary(StringRef name) {
281281
error("unable to find library -l" + name);
282282
}
283283

284-
// This function is called on startup. We need this for LTO since
285-
// LTO calls LLVM functions to compile bitcode files to native code.
286-
// Technically this can be delayed until we read bitcode files, but
287-
// we don't bother to do lazily because the initialization is fast.
288-
static void initLLVM() {
289-
InitializeAllTargets();
290-
InitializeAllTargetMCs();
291-
InitializeAllAsmPrinters();
292-
InitializeAllAsmParsers();
293-
}
294-
295284
// Some command line options or some combinations of them are not allowed.
296285
// This function checks for such errors.
297286
static void checkOptions() {
@@ -518,7 +507,6 @@ void LinkerDriver::main(ArrayRef<const char *> argsArr) {
518507
{
519508
llvm::TimeTraceScope timeScope("ExecuteLinker");
520509

521-
initLLVM();
522510
createFiles(args);
523511
if (errorCount())
524512
return;

lld/tools/lld/lld.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "llvm/Support/InitLLVM.h"
3838
#include "llvm/Support/Path.h"
3939
#include "llvm/Support/PluginLoader.h"
40+
#include "llvm/Support/TargetSelect.h"
4041
#include <cstdlib>
4142

4243
using namespace lld;
@@ -136,10 +137,22 @@ static Flavor parseFlavor(std::vector<const char *> &v) {
136137
// and we use it to detect whether we are running tests or not.
137138
static bool canExitEarly() { return StringRef(getenv("LLD_IN_TEST")) != "1"; }
138139

140+
// This function is called on startup. We need this for LTO since
141+
// LTO calls LLVM functions to compile bitcode files to native code.
142+
// Technically this can be delayed until we read bitcode files, but
143+
// we don't bother to do lazily because the initialization is fast.
144+
static void initLLVM() {
145+
InitializeAllTargets();
146+
InitializeAllTargetMCs();
147+
InitializeAllAsmPrinters();
148+
InitializeAllAsmParsers();
149+
}
150+
139151
/// Universal linker main(). This linker emulates the gnu, darwin, or
140152
/// windows linker based on the argv[0] or -flavor option.
141153
int main(int argc, const char **argv) {
142154
InitLLVM x(argc, argv);
155+
initLLVM();
143156

144157
std::vector<const char *> args(argv, argv + argc);
145158
switch (parseFlavor(args)) {

lld/wasm/Driver.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,6 @@ enum {
5353
#undef OPTION
5454
};
5555

56-
// This function is called on startup. We need this for LTO since
57-
// LTO calls LLVM functions to compile bitcode files to native code.
58-
// Technically this can be delayed until we read bitcode files, but
59-
// we don't bother to do lazily because the initialization is fast.
60-
static void initLLVM() {
61-
InitializeAllTargets();
62-
InitializeAllTargetMCs();
63-
InitializeAllAsmPrinters();
64-
InitializeAllAsmParsers();
65-
}
66-
6756
class LinkerDriver {
6857
public:
6958
void link(ArrayRef<const char *> argsArr);
@@ -94,7 +83,6 @@ bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &stdoutOS,
9483
config = make<Configuration>();
9584
symtab = make<SymbolTable>();
9685

97-
initLLVM();
9886
LinkerDriver().link(args);
9987

10088
// Exit immediately if we don't need to return to the caller.
@@ -568,7 +556,6 @@ static void createSyntheticSymbols() {
568556
make<SyntheticFunction>(nullSignature, "__wasm_apply_relocs"));
569557
}
570558

571-
572559
if (config->isPic) {
573560
WasmSym::stackPointer = createUndefinedGlobal(
574561
"__stack_pointer",

0 commit comments

Comments
 (0)