Skip to content

Commit 73e5208

Browse files
author
Dwight Guth
authored
--hidden-visibility flag to llvm-kompile (#1060)
This flag is used to assist with the process of building an application that links against more than one llvm backend semantics. It can be used in roughly the following way: 1. Compile the llvm backend with the `clang++` flag `-fvisibility=hidden`. 2. Run `llvm-kompile definition.kore dt library --hidden-visibility -- -shared entry.cpp -o definition.so` in the kompiled directory. 3. Link `definition.so` into your application. It will have all the symbols of `entry.cpp` and `entry.cpp` will be able to access any symbol in the semantics, but those internal symbols will not be visible to the application. The application can do this with multiple semantics and there will be no linker issue. I have tested some basic examples that show that each semantics can separately apply its own rewrite rules. There is no test in this PR because the test harness does not allow us to rebuild the llvm backend with a particular set of build flags just for one test, and it didn't seem worth it to put all that effort in just for one test. When we create downstream projects that use this feature, we will be sure to include tests for this feature in those repositories.
1 parent 6757d77 commit 73e5208

File tree

10 files changed

+158
-4
lines changed

10 files changed

+158
-4
lines changed

bin/llvm-kompile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Options:
4040
--mutable-bytes Use the faster, unsound (mutable) semantics for objects of sort
4141
Bytes at run time, rather than the slower, sound
4242
(immutable) that are enabled by default.
43+
--hidden-visibility Set the visibility of all global symbols in generated code to "hidden"
4344
-O[0123] Set the optimization level for code generation.
4445
4546
Any option not listed above will be passed through to clang; use '--' to
@@ -181,6 +182,11 @@ while [[ $# -gt 0 ]]; do
181182
codegen_flags+=("--mutable-bytes")
182183
shift
183184
;;
185+
--hidden-visibility)
186+
codegen_flags+=("--hidden-visibility")
187+
kompile_clang_flags+=("--hidden-visibility")
188+
shift
189+
;;
184190
-O*)
185191
codegen_flags+=("$1")
186192
kompile_clang_flags+=("$1")

bin/llvm-kompile-clang

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ shift; shift; shift
1414
flags=()
1515
llc_flags=()
1616
llc_opt_flags="-O0"
17+
visibility_hidden=false
1718
link=true
1819
export verbose=false
1920
export profile=false
@@ -96,6 +97,10 @@ while [[ $# -gt 0 ]]; do
9697
python_output_dir="$2";
9798
shift; shift;
9899
;;
100+
--hidden-visibility)
101+
visibility_hidden=true
102+
shift
103+
;;
99104
*)
100105
;;
101106
esac
@@ -146,6 +151,12 @@ if ! $save_temps; then
146151
trap 'rm -rf "$tmpdir"' INT TERM EXIT
147152
fi
148153

154+
if [[ "$OSTYPE" == "darwin"* ]]; then
155+
set_visibility_hidden="$LIBDIR/libSetVisibilityHidden.dylib"
156+
else
157+
set_visibility_hidden="$LIBDIR/libSetVisibilityHidden.so"
158+
fi
159+
149160
# When building the Python AST module, there's no runtime and no main file, so
150161
# we skip this entire step. The library code is just C++, so we can skip
151162
# straight to invoking the C++ compiler.
@@ -160,6 +171,11 @@ if [ "$main" != "python_ast" ]; then
160171
if ! $link; then
161172
modasm="$output_file"
162173
fi
174+
if $visibility_hidden; then
175+
modhidden="$tmpdir/hidden.bc"
176+
run @OPT@ "$modopt" -load-pass-plugin "$set_visibility_hidden" -set-visibility-hidden -o "$modhidden"
177+
modopt="$modhidden"
178+
fi
163179
run @LLC@ \
164180
"$modopt" -mtriple=@BACKEND_TARGET_TRIPLE@ \
165181
-filetype=obj "$llc_opt_flags" "${llc_flags[@]}" -o "$modasm"
@@ -168,6 +184,11 @@ if [ "$main" != "python_ast" ]; then
168184
if $link; then
169185
for file in "$LIBDIR"/llvm/*.ll; do
170186
tmp="$tmpdir/$(basename "$file").o"
187+
if $visibility_hidden; then
188+
tmphidden="$tmpdir/$(basename "$file").hidden.bc"
189+
run @OPT@ "$file" -load-pass-plugin "$set_visibility_hidden" -set-visibility-hidden -o "$tmphidden"
190+
file="$tmphidden"
191+
fi
171192
run @LLC@ \
172193
"$file" -mtriple=@BACKEND_TARGET_TRIPLE@ \
173194
-filetype=obj "$llc_opt_flags" "${llc_flags[@]}" -o "$tmp"

include/kllvm/codegen/ApplyPasses.h

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

77
namespace kllvm {
88

9-
void apply_kllvm_opt_passes(llvm::Module &);
9+
void apply_kllvm_opt_passes(llvm::Module &, bool hidden_visibility);
1010

1111
void generate_object_file(llvm::Module &, llvm::raw_ostream &);
1212

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef SET_VISIBILITY_HIDDEN_H
2+
#define SET_VISIBILITY_HIDDEN_H
3+
4+
#include "llvm/IR/Function.h"
5+
#include "llvm/IR/LegacyPassManager.h"
6+
#include "llvm/Pass.h"
7+
#include "llvm/Passes/PassBuilder.h"
8+
#include "llvm/Passes/PassPlugin.h"
9+
#include "llvm/Support/CommandLine.h"
10+
#include "llvm/Support/raw_ostream.h"
11+
12+
namespace kllvm {
13+
14+
bool run_set_visibility_hidden(llvm::Module &m);
15+
16+
struct legacy_set_visibility_hidden : llvm::ModulePass {
17+
// NOLINTNEXTLINE(*-identifier-naming)
18+
static char ID;
19+
legacy_set_visibility_hidden()
20+
: llvm::ModulePass(ID) { }
21+
bool runOnModule(llvm::Module &m) override {
22+
return run_set_visibility_hidden(m);
23+
}
24+
};
25+
26+
struct set_visibility_hidden : llvm::PassInfoMixin<set_visibility_hidden> {
27+
static llvm::PreservedAnalyses
28+
run(llvm::Module &m, llvm::ModuleAnalysisManager &) {
29+
if (!run_set_visibility_hidden(m)) {
30+
return llvm::PreservedAnalyses::all();
31+
}
32+
return llvm::PreservedAnalyses::none();
33+
}
34+
};
35+
36+
} // namespace kllvm
37+
38+
#endif

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_subdirectory(ast)
33
add_subdirectory(binary)
44
add_subdirectory(codegen)
55
add_subdirectory(printer)
6+
add_subdirectory(set-visibility-hidden)
67

78
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
89
add_definitions(${LLVM_DEFINITIONS_LIST})

lib/codegen/ApplyPasses.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <kllvm/codegen/ApplyPasses.h>
22
#include <kllvm/codegen/Options.h>
3+
#include <kllvm/codegen/SetVisibilityHidden.h>
34

45
#include "runtime/header.h"
56

@@ -35,11 +36,14 @@ CodeGenOpt::Level get_opt_level() {
3536
}
3637
}
3738

38-
void apply_kllvm_opt_passes(llvm::Module &mod) {
39+
void apply_kllvm_opt_passes(llvm::Module &mod, bool hidden_visibility) {
3940
auto pm = legacy::PassManager();
4041

4142
pm.add(createPromoteMemoryToRegisterPass());
4243
pm.add(createTailCallEliminationPass());
44+
if (hidden_visibility) {
45+
pm.add(new legacy_set_visibility_hidden());
46+
}
4347

4448
pm.run(mod);
4549
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
add_library(SetVisibilityHiddenInternal
2+
SetVisibilityHidden.cpp
3+
)
4+
5+
add_library(SetVisibilityHidden MODULE
6+
SetVisibilityHidden.cpp
7+
)
8+
9+
install(
10+
TARGETS SetVisibilityHiddenInternal SetVisibilityHidden
11+
LIBRARY DESTINATION lib/kllvm
12+
)
13+
14+
llvm_config(SetVisibilityHidden
15+
USE_SHARED true
16+
core irreader passes
17+
)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <kllvm/codegen/SetVisibilityHidden.h>
2+
3+
using namespace llvm;
4+
5+
namespace kllvm {
6+
__attribute__((visibility("default"))) bool
7+
run_set_visibility_hidden(Module &m) {
8+
bool dirty = false;
9+
for (auto &global : m.globals()) {
10+
if (!global.isDeclaration()) {
11+
global.setVisibility(GlobalValue::HiddenVisibility);
12+
dirty = true;
13+
}
14+
}
15+
for (auto &func : m.functions()) {
16+
if (!func.isDeclaration()) {
17+
func.setVisibility(GlobalValue::HiddenVisibility);
18+
dirty = true;
19+
}
20+
}
21+
return dirty;
22+
}
23+
24+
} // namespace kllvm
25+
26+
using namespace kllvm;
27+
28+
__attribute__((visibility("default"))) char legacy_set_visibility_hidden::ID
29+
= 0;
30+
31+
static RegisterPass<legacy_set_visibility_hidden>
32+
x("set-visibility-hidden", "Set visibility of all global values to hidden",
33+
false /* Only looks at CFG */, false /* Analysis Pass */);
34+
35+
/* New PM Registration */
36+
llvm::PassPluginLibraryInfo get_set_visibility_hidden_plugin_info() {
37+
return {
38+
LLVM_PLUGIN_API_VERSION, "SetVisibilityHidden", LLVM_VERSION_STRING,
39+
[](PassBuilder &pb) {
40+
pb.registerPipelineStartEPCallback(
41+
[](llvm::ModulePassManager &pm, OptimizationLevel level) {
42+
pm.addPass(set_visibility_hidden());
43+
});
44+
pb.registerPipelineParsingCallback(
45+
[](StringRef name, llvm::ModulePassManager &pm,
46+
ArrayRef<llvm::PassBuilder::PipelineElement>) {
47+
if (name == "set-visibility-hidden") {
48+
pm.addPass(set_visibility_hidden());
49+
return true;
50+
}
51+
return false;
52+
});
53+
}};
54+
}
55+
56+
#ifndef LLVM_BYE_LINK_INTO_TOOLS
57+
extern "C" __attribute__((visibility("default")))
58+
LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
59+
llvmGetPassPluginInfo() {
60+
return get_set_visibility_hidden_plugin_info();
61+
}
62+
#endif

tools/llvm-kompile-codegen/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ kllvm_add_tool(llvm-kompile-codegen
22
main.cpp
33
)
44

5-
target_link_libraries(llvm-kompile-codegen PUBLIC Codegen Parser AST gmp mpfr yaml)
5+
target_link_libraries(llvm-kompile-codegen PUBLIC Codegen Parser AST SetVisibilityHiddenInternal gmp mpfr yaml)
66

77
install(
88
TARGETS llvm-kompile-codegen

tools/llvm-kompile-codegen/main.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ cl::opt<bool> mutable_bytes(
6666
cl::desc("Enable unsound reference semantics for objects of sort Bytes"),
6767
cl::init(false), cl::cat(codegen_tool_cat));
6868

69+
cl::opt<bool> hidden_visibility(
70+
"hidden-visibility",
71+
cl::desc("Set visibility of all global symbols to hidden"), cl::init(false),
72+
cl::cat(codegen_tool_cat));
73+
6974
cl::opt<bool> safe_partial(
7075
"safe-partial",
7176
cl::desc("Do not terminate the process when a partial function is "
@@ -225,7 +230,7 @@ int main(int argc, char **argv) {
225230
}
226231

227232
if (!no_optimize) {
228-
apply_kllvm_opt_passes(*mod);
233+
apply_kllvm_opt_passes(*mod, hidden_visibility);
229234
}
230235

231236
perform_output([&](auto &os) {

0 commit comments

Comments
 (0)