Author: dalmurii
Date: 2025-08-29T08:21:08-07:00
New Revision: f4665b7825c875f8d79c30642b3f1989f0ade0ee

URL: 
https://github.com/llvm/llvm-project/commit/f4665b7825c875f8d79c30642b3f1989f0ade0ee
DIFF: 
https://github.com/llvm/llvm-project/commit/f4665b7825c875f8d79c30642b3f1989f0ade0ee.diff

LOG: Singleton hack of fixing static initialisation order fiasco (#154541)

https://github.com/llvm/llvm-project/issues/154528

# Brief
Indirect linking of llvm as a shared library is causing a "free()
invalid size abortion". In my case, my project depends on google/clspv
which in turn pulls `llvm`. Note that the issue does not occur when
`clspv` and `llvm` is all statically linked.

# Structure of a project which might be causing an error
[google/clspv](https://github.com/google/clspv) has been depending on
this project (llvm-project), as a static library.
My personal project has been depending on
[google/clspv](https://github.com/google/clspv) as a shared library.
So `MyProject` was linked to shared object `clspv_core.so` which is
containing `llvm-project` as its component.

# Problem
Linking `llvm-project` indirectly to `MyProject` via `clspv_core` was
causing the `free() invalid size` abortion.
> When library is all statically linked, this problem did not occur.

[This issue](https://github.com/llvm/llvm-project/issues/154528) has a
full log of the programme running with valgrind.

# Reason in my expectation
`KnownAssumptionStrings` from
[clang/lib/Sema/SemaOpenMP.cpp](https://github.com/llvm/llvm-project/pull/154541/files#diff-032b46da5a8b94f6d8266072e296726c361066e32139024c86dcba5bf64960fc),
[llvm/include/llvm/IR/Assumptions.h](https://github.com/llvm/llvm-project/pull/154541/files#diff-ebb09639e5957c2e4d27be9dcb1b1475da67d88db829d24ed8039f351a63ccff),
[llvm/lib/IR/Assumptions.cpp](https://github.com/llvm/llvm-project/pull/154541/files#diff-1b490dd29304c875364871e35e1cc8e47bf71898affe3a4dbde6eb91c4016d06)
and `FeatureMap` from
[llvm/lib/Analysis/MLInlineAdvisor.cpp](https://github.com/llvm/llvm-project/pull/154541/files#diff-26c738eb291410ed83595a4162de617e8cbebddb46331f56d39d193868e29857),
[llvm/include/llvm/Analysis/InlineModelFeatureMaps.h](https://github.com/llvm/llvm-project/pull/154541/files#diff-3b5a3359b2a0784186fb3f90dfabf905e8640b6adfd7d2c75259a6835751a6a7)
which have been placed on global scope, causing static initialisation
order ficasso when indirectly linked by `Myproject`.

# Fix trial
Changing those global instances I've mentioned ~
`KnownAssumptionStrings` and `FeatureMap` ~ to functions which return a
static variable's left value ~ `getKnownAssumptionStrings()`,
`getFeatureMap()` ~ has solved my personal problem, so I am pulling a
request of it.

Added: 
    

Modified: 
    clang/lib/Sema/SemaOpenMP.cpp
    llvm/include/llvm/Analysis/InlineModelFeatureMaps.h
    llvm/include/llvm/IR/Assumptions.h
    llvm/lib/Analysis/MLInlineAdvisor.cpp
    llvm/lib/IR/Assumptions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index bbf2b2ac69d66..4b030a265fa66 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -24834,12 +24834,12 @@ ExprResult SemaOpenMP::ActOnOMPIteratorExpr(Scope *S,
 /// Check if \p AssumptionStr is a known assumption and warn if not.
 static void checkOMPAssumeAttr(Sema &S, SourceLocation Loc,
                                StringRef AssumptionStr) {
-  if (llvm::KnownAssumptionStrings.count(AssumptionStr))
+  if (llvm::getKnownAssumptionStrings().count(AssumptionStr))
     return;
 
   unsigned BestEditDistance = 3;
   StringRef Suggestion;
-  for (const auto &KnownAssumptionIt : llvm::KnownAssumptionStrings) {
+  for (const auto &KnownAssumptionIt : llvm::getKnownAssumptionStrings()) {
     unsigned EditDistance =
         AssumptionStr.edit_distance(KnownAssumptionIt.getKey());
     if (EditDistance < BestEditDistance) {

diff  --git a/llvm/include/llvm/Analysis/InlineModelFeatureMaps.h 
b/llvm/include/llvm/Analysis/InlineModelFeatureMaps.h
index 25a35df3efe2c..5c6aee3ab38ab 100644
--- a/llvm/include/llvm/Analysis/InlineModelFeatureMaps.h
+++ b/llvm/include/llvm/Analysis/InlineModelFeatureMaps.h
@@ -160,7 +160,7 @@ inlineCostFeatureToMlFeature(InlineCostFeatureIndex 
Feature) {
   return static_cast<FeatureIndex>(static_cast<size_t>(Feature));
 }
 
-LLVM_ABI extern std::vector<TensorSpec> FeatureMap;
+LLVM_ABI extern std::vector<TensorSpec> &getFeatureMap();
 
 LLVM_ABI extern const char *const DecisionName;
 LLVM_ABI extern const TensorSpec InlineDecisionSpec;

diff  --git a/llvm/include/llvm/IR/Assumptions.h 
b/llvm/include/llvm/IR/Assumptions.h
index f1663f3d6d2bd..ebc55921e73d3 100644
--- a/llvm/include/llvm/IR/Assumptions.h
+++ b/llvm/include/llvm/IR/Assumptions.h
@@ -30,18 +30,18 @@ constexpr StringRef AssumptionAttrKey = "llvm.assume";
 
 /// A set of known assumption strings that are accepted without warning and
 /// which can be recommended as typo correction.
-LLVM_ABI extern StringSet<> KnownAssumptionStrings;
+LLVM_ABI extern StringSet<> &getKnownAssumptionStrings();
 
 /// Helper that allows to insert a new assumption string in the known 
assumption
 /// set by creating a (static) object.
 struct KnownAssumptionString {
   KnownAssumptionString(const char *AssumptionStr)
       : AssumptionStr(AssumptionStr) {
-    KnownAssumptionStrings.insert(AssumptionStr);
+    getKnownAssumptionStrings().insert(AssumptionStr);
   }
   KnownAssumptionString(StringRef AssumptionStr)
       : AssumptionStr(AssumptionStr) {
-    KnownAssumptionStrings.insert(AssumptionStr);
+    getKnownAssumptionStrings().insert(AssumptionStr);
   }
   operator StringRef() const { return AssumptionStr; }
 

diff  --git a/llvm/lib/Analysis/MLInlineAdvisor.cpp 
b/llvm/lib/Analysis/MLInlineAdvisor.cpp
index 8853a13972bea..7854c19088ad3 100644
--- a/llvm/lib/Analysis/MLInlineAdvisor.cpp
+++ b/llvm/lib/Analysis/MLInlineAdvisor.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Analysis/ProfileSummaryInfo.h"
 #include "llvm/Analysis/ReleaseModeModelRunner.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TensorSpec.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/InstIterator.h"
 #include "llvm/IR/Module.h"
@@ -77,10 +78,10 @@ llvm::getReleaseModeAdvisor(Module &M, 
ModuleAnalysisManager &MAM,
   std::unique_ptr<MLModelRunner> AOTRunner;
   if (InteractiveChannelBaseName.empty())
     AOTRunner = std::make_unique<ReleaseModeModelRunner<CompiledModelType>>(
-        M.getContext(), FeatureMap, DecisionName,
+        M.getContext(), getFeatureMap(), DecisionName,
         EmbeddedModelRunnerOptions().setModelSelector(ModelSelector));
   else {
-    auto Features = FeatureMap;
+    auto Features = getFeatureMap();
     if (InteractiveIncludeDefault)
       Features.push_back(DefaultDecisionSpec);
     AOTRunner = std::make_unique<InteractiveModelRunner>(
@@ -106,8 +107,9 @@ static cl::opt<bool> KeepFPICache(
         "For test - keep the ML Inline advisor's FunctionPropertiesInfo 
cache"),
     cl::init(false));
 
-// clang-format off
-std::vector<TensorSpec> llvm::FeatureMap{
+std::vector<TensorSpec> &llvm::getFeatureMap() {
+  // clang-format off
+static std::vector<TensorSpec> FeatureMap{
 #define POPULATE_NAMES(DTYPE, SHAPE, NAME, __) 
TensorSpec::createSpec<DTYPE>(#NAME, SHAPE),
 // InlineCost features - these must come first
   INLINE_COST_FEATURE_ITERATOR(POPULATE_NAMES)
@@ -116,7 +118,9 @@ std::vector<TensorSpec> llvm::FeatureMap{
   INLINE_FEATURE_ITERATOR(POPULATE_NAMES)
 #undef POPULATE_NAMES
 };
-// clang-format on
+  // clang-format on
+  return FeatureMap;
+}
 
 const char *const llvm::DecisionName = "inlining_decision";
 const TensorSpec llvm::InlineDecisionSpec =
@@ -195,9 +199,9 @@ MLInlineAdvisor::MLInlineAdvisor(
     }
     // Add the IR2Vec features to the feature map
     auto IR2VecDim = IR2VecVocabResult->getDimension();
-    FeatureMap.push_back(
+    getFeatureMap().push_back(
         TensorSpec::createSpec<float>("callee_embedding", {IR2VecDim}));
-    FeatureMap.push_back(
+    getFeatureMap().push_back(
         TensorSpec::createSpec<float>("caller_embedding", {IR2VecDim}));
   }
 }
@@ -471,7 +475,8 @@ std::unique_ptr<InlineAdvice> 
MLInlineAdvisor::getAdviceImpl(CallBase &CB) {
   }
   // This one would have been set up to be right at the end.
   if (!InteractiveChannelBaseName.empty() && InteractiveIncludeDefault)
-    *ModelRunner->getTensor<int64_t>(FeatureMap.size()) = GetDefaultAdvice(CB);
+    *ModelRunner->getTensor<int64_t>(getFeatureMap().size()) =
+        GetDefaultAdvice(CB);
   return getAdviceFromModel(CB, ORE);
 }
 
@@ -549,8 +554,8 @@ void MLInlineAdvice::reportContextForRemark(
     DiagnosticInfoOptimizationBase &OR) {
   using namespace ore;
   OR << NV("Callee", Callee->getName());
-  for (size_t I = 0; I < FeatureMap.size(); ++I)
-    OR << NV(FeatureMap[I].name(),
+  for (size_t I = 0; I < getFeatureMap().size(); ++I)
+    OR << NV(getFeatureMap()[I].name(),
              *getAdvisor()->getModelRunner().getTensor<int64_t>(I));
   OR << NV("ShouldInline", isInliningRecommended());
 }

diff  --git a/llvm/lib/IR/Assumptions.cpp b/llvm/lib/IR/Assumptions.cpp
index 6adbbc4a63b0a..f8bbcb32231cb 100644
--- a/llvm/lib/IR/Assumptions.cpp
+++ b/llvm/lib/IR/Assumptions.cpp
@@ -101,12 +101,16 @@ bool llvm::addAssumptions(CallBase &CB,
   return ::addAssumptionsImpl(CB, Assumptions);
 }
 
-StringSet<> llvm::KnownAssumptionStrings({
-    "omp_no_openmp",            // OpenMP 5.1
-    "omp_no_openmp_routines",   // OpenMP 5.1
-    "omp_no_parallelism",       // OpenMP 5.1
-    "omp_no_openmp_constructs", // OpenMP 6.0
-    "ompx_spmd_amenable",       // OpenMPOpt extension
-    "ompx_no_call_asm",         // OpenMPOpt extension
-    "ompx_aligned_barrier",     // OpenMPOpt extension
-});
+StringSet<> &llvm::getKnownAssumptionStrings() {
+  static StringSet<> Object({
+      "omp_no_openmp",            // OpenMP 5.1
+      "omp_no_openmp_routines",   // OpenMP 5.1
+      "omp_no_parallelism",       // OpenMP 5.1
+      "omp_no_openmp_constructs", // OpenMP 6.0
+      "ompx_spmd_amenable",       // OpenMPOpt extension
+      "ompx_no_call_asm",         // OpenMPOpt extension
+      "ompx_aligned_barrier",     // OpenMPOpt extension
+  });
+
+  return Object;
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to