[llvm] [polly] Slightly improve the getenv("bar") linking problem (PR #150020)
Luke Drummond via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 22 08:45:36 PDT 2025
https://github.com/ldrumm updated https://github.com/llvm/llvm-project/pull/150020
>From d4e422b09b6e77957f55a56e87ba51308304af3a Mon Sep 17 00:00:00 2001
From: Luke Drummond <luke.drummond at codeplay.com>
Date: Thu, 13 Oct 2022 16:57:43 +0100
Subject: [PATCH 1/6] Slightly improve the getenv("bar") linking problem
There's been a variation of the following in the code since 2005:
if (unoptimizable_true)
return;
use_this_symbol_to_force_linking(); // unreachable but never removed
Way back in 00d5508496c it was the win32 call `GetCurrentProcess`
but switched to `getenv("bar")` fairly soon after in 63e504ff43. While
that pulled in fewer dependencies and made the code portable, it's a
bit of a weird construct. The environment variable used for the `getenv`
call is "bar", which is particularly weird to see fly past when you run
`ltrace` on a binary linked against LLVM.
In this patch I don't try to replace this construct wholesale - it's
still required for architectural reasons I'm not able to tackle right
now, but I did try and make it slightly less weird and opaque:
- It gives the construct a name
- The environment variable hints where this comes from and that its
value is ignored
Combined, this should be a bit of improvement for the next person who
wonders what LLVM is up to when they trace their process or see
smatterings of `getenv("bar")` dotted around the source.
---
.../llvm/CodeGen/LinkAllAsmWriterComponents.h | 10 ++++-----
.../llvm/CodeGen/LinkAllCodegenComponents.h | 10 ++++-----
llvm/include/llvm/ExecutionEngine/MCJIT.h | 12 +++++-----
llvm/include/llvm/LinkAllIR.h | 6 ++---
llvm/include/llvm/LinkAllPasses.h | 22 ++++++++++++-------
llvm/tools/bugpoint/bugpoint.cpp | 2 +-
polly/include/polly/LinkAllPasses.h | 9 ++++----
7 files changed, 34 insertions(+), 37 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
index c22f9d49f374b..8e0f2da33114a 100644
--- a/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
+++ b/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
@@ -22,12 +22,10 @@ namespace {
ForceAsmWriterLinking() {
// We must reference the plug-ins in such a way that compilers will not
// delete it all as dead code, even with whole program optimization,
- // yet is effectively a NO-OP. As the compiler isn't smart enough
- // to know that getenv() never returns -1, this will do the job.
- // This is so that globals in the translation units where these functions
- // are defined are forced to be initialized, populating various
- // registries.
- if (std::getenv("bar") != (char*) -1)
+ // yet is effectively a NO-OP. This is so that globals in the translation
+ // units where these functions are defined are forced to be initialized,
+ // populating various registries.
+ if (llvm::getNonFoldableAlwaysTrue())
return;
llvm::linkOcamlGCPrinter();
diff --git a/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h b/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h
index 6f56682dce5fa..176addb397382 100644
--- a/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -24,12 +24,10 @@ namespace {
ForceCodegenLinking() {
// We must reference the passes in such a way that compilers will not
// delete it all as dead code, even with whole program optimization,
- // yet is effectively a NO-OP. As the compiler isn't smart enough
- // to know that getenv() never returns -1, this will do the job.
- // This is so that globals in the translation units where these functions
- // are defined are forced to be initialized, populating various
- // registries.
- if (std::getenv("bar") != (char*) -1)
+ // yet is effectively a NO-OP. This is so that globals in the translation
+ // units where these functions are defined are forced to be initialized,
+ // populating various registries.
+ if (llvm::getNonFoldableAlwaysTrue())
return;
(void) llvm::createFastRegisterAllocator();
diff --git a/llvm/include/llvm/ExecutionEngine/MCJIT.h b/llvm/include/llvm/ExecutionEngine/MCJIT.h
index c836c06813fc6..21fb7fff2e228 100644
--- a/llvm/include/llvm/ExecutionEngine/MCJIT.h
+++ b/llvm/include/llvm/ExecutionEngine/MCJIT.h
@@ -24,13 +24,11 @@ namespace {
struct ForceMCJITLinking {
ForceMCJITLinking() {
// We must reference MCJIT in such a way that compilers will not
- // delete it all as dead code, even with whole program optimization,
- // yet is effectively a NO-OP. As the compiler isn't smart enough
- // to know that getenv() never returns -1, this will do the job.
- // This is so that globals in the translation units where these functions
- // are defined are forced to be initialized, populating various
- // registries.
- if (std::getenv("bar") != (char*) -1)
+ // delete it all as dead code, even with whole program optimization, yet
+ // is effectively a NO-OP. This is so that globals in the translation
+ // units where these functions are defined are forced to be initialized,
+ // populating various registries.
+ if (llvm::getNonFoldableAlwaysTrue())
return;
LLVMLinkInMCJIT();
diff --git a/llvm/include/llvm/LinkAllIR.h b/llvm/include/llvm/LinkAllIR.h
index ceed784d557de..8ea346f567ee9 100644
--- a/llvm/include/llvm/LinkAllIR.h
+++ b/llvm/include/llvm/LinkAllIR.h
@@ -35,13 +35,11 @@ namespace {
struct ForceVMCoreLinking {
ForceVMCoreLinking() {
// We must reference VMCore in such a way that compilers will not
- // delete it all as dead code, even with whole program optimization,
- // yet is effectively a NO-OP. As the compiler isn't smart enough
- // to know that getenv() never returns -1, this will do the job.
+ // delete it all as dead code, even with whole program optimization.
// This is so that globals in the translation units where these functions
// are defined are forced to be initialized, populating various
// registries.
- if (std::getenv("bar") != (char*) -1)
+ if (llvm::getNonFoldableAlwaysTrue())
return;
llvm::LLVMContext Context;
(void)new llvm::Module("", Context);
diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h
index bae7f0da7022c..0860600ba1550 100644
--- a/llvm/include/llvm/LinkAllPasses.h
+++ b/llvm/include/llvm/LinkAllPasses.h
@@ -48,20 +48,26 @@
#include <cstdlib>
namespace llvm {
+inline bool getNonFoldableAlwaysTrue() {
+ // Some parts of the codebase require a "constant true value" used as a
+ // predicate. These cases require that even with LTO and static linking,
+ // it's not possible to for the compiler to fold the value. As compilers
+ // aren't smart enough to know that getenv() never returns -1, this will do
+ // the job.
+ return std::getenv("LLVM_IGNORED_ENV_VAR") != (char *)-1;
+}
class Triple;
}
namespace {
struct ForcePassLinking {
ForcePassLinking() {
- // We must reference the passes in such a way that compilers will not
- // delete it all as dead code, even with whole program optimization,
- // yet is effectively a NO-OP. As the compiler isn't smart enough
- // to know that getenv() never returns -1, this will do the job.
- // This is so that globals in the translation units where these functions
- // are defined are forced to be initialized, populating various
- // registries.
- if (std::getenv("bar") != (char *)-1)
+ // We must reference the passes in such a way that compilers will not delete
+ // it all as dead code, even with whole program optimization, yet is
+ // effectively a NO-OP. // This is so that globals in the translation units
+ // where these functions are defined are forced to be initialized,
+ // populating various registries.
+ if (llvm::getNonFoldableAlwaysTrue())
return;
(void)llvm::createAtomicExpandLegacyPass();
diff --git a/llvm/tools/bugpoint/bugpoint.cpp b/llvm/tools/bugpoint/bugpoint.cpp
index e49efdfe7c8e0..b046e5802e0ad 100644
--- a/llvm/tools/bugpoint/bugpoint.cpp
+++ b/llvm/tools/bugpoint/bugpoint.cpp
@@ -111,7 +111,7 @@ int main(int argc, char **argv) {
initializeInstCombine(Registry);
initializeTarget(Registry);
- if (std::getenv("bar") == (char*) -1) {
+ if (!llvm::getNonFoldableAlwaysTrue())
InitializeAllTargets();
InitializeAllTargetMCs();
InitializeAllAsmPrinters();
diff --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h
index a2f8f33299918..905867d05c199 100644
--- a/polly/include/polly/LinkAllPasses.h
+++ b/polly/include/polly/LinkAllPasses.h
@@ -72,11 +72,10 @@ extern char &CodePreparationID;
namespace {
struct PollyForcePassLinking {
PollyForcePassLinking() {
- // We must reference the passes in such a way that compilers will not
- // delete it all as dead code, even with whole program optimization,
- // yet is effectively a NO-OP. As the compiler isn't smart enough
- // to know that getenv() never returns -1, this will do the job.
- if (std::getenv("bar") != (char *)-1)
+ // We must reference the passes in such a way that compilers will not delete
+ // it all as dead code, even with whole program optimization, yet is
+ // effectively a NO-OP.
+ if (llvm::getNonFoldableAlwaysTrue())
return;
polly::createCodePreparationPass();
>From bbd56b8c1fd0ec926202bacca6b9b7b13f334a8b Mon Sep 17 00:00:00 2001
From: Luke Drummond <luke.drummond at codeplay.com>
Date: Tue, 22 Jul 2025 14:53:47 +0100
Subject: [PATCH 2/6] fixup! Slightly improve the getenv("bar") linking problem
---
llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
index 8e0f2da33114a..b4989d07f39b7 100644
--- a/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
+++ b/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
@@ -15,7 +15,7 @@
#define LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
#include "llvm/IR/BuiltinGCs.h"
-#include <cstdlib>
+#include "llvm/LinkAllPasses.h"
namespace {
struct ForceAsmWriterLinking {
>From 077beafca040a6051d3d7d844de7e5b0f4272908 Mon Sep 17 00:00:00 2001
From: Luke Drummond <luke.drummond at codeplay.com>
Date: Tue, 22 Jul 2025 16:17:12 +0100
Subject: [PATCH 3/6] fixup! Slightly improve the getenv("bar") linking problem
---
llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h | 2 +-
llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h | 2 +-
llvm/include/llvm/ExecutionEngine/MCJIT.h | 2 +-
llvm/include/llvm/LinkAllIR.h | 2 +-
llvm/include/llvm/LinkAllPasses.h | 9 +--------
llvm/tools/bugpoint/bugpoint.cpp | 1 +
polly/include/polly/LinkAllPasses.h | 2 +-
7 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
index b4989d07f39b7..c70413d72ebfd 100644
--- a/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
+++ b/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
@@ -15,7 +15,7 @@
#define LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
#include "llvm/IR/BuiltinGCs.h"
-#include "llvm/LinkAllPasses.h"
+#include "llvm/Support/AlwaysTrue.h"
namespace {
struct ForceAsmWriterLinking {
diff --git a/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h b/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h
index 176addb397382..f0a01d2baf0e0 100644
--- a/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -16,8 +16,8 @@
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
+#include "llvm/Support/AlwaysTrue.h"
#include "llvm/Target/TargetMachine.h"
-#include <cstdlib>
namespace {
struct ForceCodegenLinking {
diff --git a/llvm/include/llvm/ExecutionEngine/MCJIT.h b/llvm/include/llvm/ExecutionEngine/MCJIT.h
index 21fb7fff2e228..1e035c0008fbd 100644
--- a/llvm/include/llvm/ExecutionEngine/MCJIT.h
+++ b/llvm/include/llvm/ExecutionEngine/MCJIT.h
@@ -15,8 +15,8 @@
#define LLVM_EXECUTIONENGINE_MCJIT_H
#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/Support/AlwaysTrue.h"
#include "llvm/Support/Compiler.h"
-#include <cstdlib>
extern "C" LLVM_ABI void LLVMLinkInMCJIT();
diff --git a/llvm/include/llvm/LinkAllIR.h b/llvm/include/llvm/LinkAllIR.h
index 8ea346f567ee9..894a8dd5bd926 100644
--- a/llvm/include/llvm/LinkAllIR.h
+++ b/llvm/include/llvm/LinkAllIR.h
@@ -21,6 +21,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
+#include "llvm/Support/AlwaysTrue.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Memory.h"
@@ -29,7 +30,6 @@
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
-#include <cstdlib>
namespace {
struct ForceVMCoreLinking {
diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h
index 0860600ba1550..eb976661b05b9 100644
--- a/llvm/include/llvm/LinkAllPasses.h
+++ b/llvm/include/llvm/LinkAllPasses.h
@@ -34,6 +34,7 @@
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/Support/AlwaysTrue.h"
#include "llvm/Support/Valgrind.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
@@ -48,14 +49,6 @@
#include <cstdlib>
namespace llvm {
-inline bool getNonFoldableAlwaysTrue() {
- // Some parts of the codebase require a "constant true value" used as a
- // predicate. These cases require that even with LTO and static linking,
- // it's not possible to for the compiler to fold the value. As compilers
- // aren't smart enough to know that getenv() never returns -1, this will do
- // the job.
- return std::getenv("LLVM_IGNORED_ENV_VAR") != (char *)-1;
-}
class Triple;
}
diff --git a/llvm/tools/bugpoint/bugpoint.cpp b/llvm/tools/bugpoint/bugpoint.cpp
index b046e5802e0ad..1b4cae45f518b 100644
--- a/llvm/tools/bugpoint/bugpoint.cpp
+++ b/llvm/tools/bugpoint/bugpoint.cpp
@@ -22,6 +22,7 @@
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/Passes/PassPlugin.h"
+#include "llvm/Support/AlwaysTrue.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/PluginLoader.h"
diff --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h
index 905867d05c199..d2e10d1a7acc6 100644
--- a/polly/include/polly/LinkAllPasses.h
+++ b/polly/include/polly/LinkAllPasses.h
@@ -18,7 +18,7 @@
#include "polly/Support/DumpFunctionPass.h"
#include "polly/Support/DumpModulePass.h"
#include "llvm/ADT/StringRef.h"
-#include <cstdlib>
+#include "llvm/Support/AlwaysTrue.h"
namespace llvm {
class Pass;
>From b6a53470dad4032f530df43da2757cf172e8c126 Mon Sep 17 00:00:00 2001
From: Luke Drummond <luke.drummond at codeplay.com>
Date: Tue, 22 Jul 2025 16:20:10 +0100
Subject: [PATCH 4/6] fixup! Slightly improve the getenv("bar") linking problem
---
llvm/include/llvm/LinkAllPasses.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h
index eb976661b05b9..f82a43967e67a 100644
--- a/llvm/include/llvm/LinkAllPasses.h
+++ b/llvm/include/llvm/LinkAllPasses.h
@@ -57,7 +57,7 @@ struct ForcePassLinking {
ForcePassLinking() {
// We must reference the passes in such a way that compilers will not delete
// it all as dead code, even with whole program optimization, yet is
- // effectively a NO-OP. // This is so that globals in the translation units
+ // effectively a NO-OP. This is so that globals in the translation units
// where these functions are defined are forced to be initialized,
// populating various registries.
if (llvm::getNonFoldableAlwaysTrue())
>From fd06f4e9d39b97494aa35f4d535481b2094b7496 Mon Sep 17 00:00:00 2001
From: Luke Drummond <luke.drummond at codeplay.com>
Date: Tue, 22 Jul 2025 16:31:45 +0100
Subject: [PATCH 5/6] fixup! Slightly improve the getenv("bar") linking problem
---
llvm/include/llvm/Support/AlwaysTrue.h | 29 ++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 llvm/include/llvm/Support/AlwaysTrue.h
diff --git a/llvm/include/llvm/Support/AlwaysTrue.h b/llvm/include/llvm/Support/AlwaysTrue.h
new file mode 100644
index 0000000000000..733596af3e17e
--- /dev/null
+++ b/llvm/include/llvm/Support/AlwaysTrue.h
@@ -0,0 +1,29 @@
+//===--- AlwaysTrue.h - Helper for oqaque truthy values --*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the getNonFoldableAlwaysTrue helper funtion
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALWAYS_TRUE_H
+#define LLVM_SUPPORT_ALWAYS_TRUE_H
+
+#include <cstdlib>
+
+namespace llvm {
+inline bool getNonFoldableAlwaysTrue() {
+ // Some parts of the codebase require a "constant true value" used as a
+ // predicate. These cases require that even with LTO and static linking,
+ // it's not possible for the compiler to fold the value. As compilers
+ // aren't smart enough to know that getenv() never returns -1, this will do
+ // the job.
+ return std::getenv("LLVM_IGNORED_ENV_VAR") != (char *)-1;
+}
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_ALWAYS_TRUE_H
>From 7bfbb7e03f3f3313cd1a5a8b46e0cea5c6c22a59 Mon Sep 17 00:00:00 2001
From: Luke Drummond <luke.drummond at codeplay.com>
Date: Tue, 22 Jul 2025 16:45:21 +0100
Subject: [PATCH 6/6] fixup! Slightly improve the getenv("bar") linking problem
---
llvm/tools/bugpoint/bugpoint.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/tools/bugpoint/bugpoint.cpp b/llvm/tools/bugpoint/bugpoint.cpp
index 1b4cae45f518b..87581e80a2496 100644
--- a/llvm/tools/bugpoint/bugpoint.cpp
+++ b/llvm/tools/bugpoint/bugpoint.cpp
@@ -112,7 +112,7 @@ int main(int argc, char **argv) {
initializeInstCombine(Registry);
initializeTarget(Registry);
- if (!llvm::getNonFoldableAlwaysTrue())
+ if (!llvm::getNonFoldableAlwaysTrue()) {
InitializeAllTargets();
InitializeAllTargetMCs();
InitializeAllAsmPrinters();
More information about the llvm-commits
mailing list