[llvm] 1483659 - [GC] Use `MapVector` for `GCStrategyMap` (#132729)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 14 02:51:22 PDT 2025
Author: paperchalice
Date: 2025-05-14T17:51:18+08:00
New Revision: 14836597f5d86ab16f426bc256dbcf7b2af0af71
URL: https://github.com/llvm/llvm-project/commit/14836597f5d86ab16f426bc256dbcf7b2af0af71
DIFF: https://github.com/llvm/llvm-project/commit/14836597f5d86ab16f426bc256dbcf7b2af0af71.diff
LOG: [GC] Use `MapVector` for `GCStrategyMap` (#132729)
Use `MapVector` so `GCStrategyMap` can support forward and reverse
iterator, which is required in `AsmPrinter`.
Added:
llvm/unittests/CodeGen/GCMetadata.cpp
Modified:
llvm/include/llvm/CodeGen/GCMetadata.h
llvm/include/llvm/IR/GCStrategy.h
llvm/lib/CodeGen/GCMetadata.cpp
llvm/lib/CodeGen/ShadowStackGCLowering.cpp
llvm/unittests/CodeGen/CMakeLists.txt
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GCMetadata.h b/llvm/include/llvm/CodeGen/GCMetadata.h
index ca6a511185c7c..88e3377dd77b8 100644
--- a/llvm/include/llvm/CodeGen/GCMetadata.h
+++ b/llvm/include/llvm/CodeGen/GCMetadata.h
@@ -33,6 +33,7 @@
#define LLVM_CODEGEN_GCMETADATA_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -151,15 +152,49 @@ class GCFunctionInfo {
size_t live_size(const iterator &p) const { return roots_size(); }
};
-struct GCStrategyMap {
- StringMap<std::unique_ptr<GCStrategy>> StrategyMap;
+class GCStrategyMap {
+ using MapT =
+ MapVector<StringRef, std::unique_ptr<GCStrategy>, StringMap<unsigned>>;
+ MapT Strategies;
+public:
GCStrategyMap() = default;
GCStrategyMap(GCStrategyMap &&) = default;
/// Handle invalidation explicitly.
bool invalidate(Module &M, const PreservedAnalyses &PA,
ModuleAnalysisManager::Invalidator &Inv);
+
+ using iterator = MapT::iterator;
+ using const_iterator = MapT::const_iterator;
+ using reverse_iterator = MapT::reverse_iterator;
+ using const_reverse_iterator = MapT::const_reverse_iterator;
+
+ iterator begin() { return Strategies.begin(); }
+ const_iterator begin() const { return Strategies.begin(); }
+ iterator end() { return Strategies.end(); }
+ const_iterator end() const { return Strategies.end(); }
+
+ reverse_iterator rbegin() { return Strategies.rbegin(); }
+ const_reverse_iterator rbegin() const { return Strategies.rbegin(); }
+ reverse_iterator rend() { return Strategies.rend(); }
+ const_reverse_iterator rend() const { return Strategies.rend(); }
+
+ bool empty() const { return Strategies.empty(); }
+
+ const GCStrategy &operator[](StringRef GCName) const {
+ auto I = Strategies.find(GCName);
+ assert(I != Strategies.end() && "Required strategy doesn't exist!");
+ return *I->second;
+ }
+
+ std::pair<iterator, bool> try_emplace(StringRef GCName) {
+ return Strategies.try_emplace(GCName);
+ }
+
+ bool contains(StringRef GCName) const {
+ return Strategies.find(GCName) != Strategies.end();
+ }
};
/// An analysis pass which caches information about the entire Module.
diff --git a/llvm/include/llvm/IR/GCStrategy.h b/llvm/include/llvm/IR/GCStrategy.h
index cbfbe23aaa068..6b813554d6544 100644
--- a/llvm/include/llvm/IR/GCStrategy.h
+++ b/llvm/include/llvm/IR/GCStrategy.h
@@ -63,6 +63,7 @@ class Type;
class GCStrategy {
private:
friend class GCModuleInfo;
+ friend class CollectorMetadataAnalysis;
std::string Name;
diff --git a/llvm/lib/CodeGen/GCMetadata.cpp b/llvm/lib/CodeGen/GCMetadata.cpp
index fa87b14e708e1..85e07efcdcfc7 100644
--- a/llvm/lib/CodeGen/GCMetadata.cpp
+++ b/llvm/lib/CodeGen/GCMetadata.cpp
@@ -26,7 +26,7 @@ bool GCStrategyMap::invalidate(Module &M, const PreservedAnalyses &PA,
for (const auto &F : M) {
if (F.isDeclaration() || !F.hasGC())
continue;
- if (!StrategyMap.contains(F.getGC()))
+ if (!contains(F.getGC()))
return true;
}
return false;
@@ -36,17 +36,18 @@ AnalysisKey CollectorMetadataAnalysis::Key;
CollectorMetadataAnalysis::Result
CollectorMetadataAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
- Result R;
- auto &Map = R.StrategyMap;
+ Result StrategyMap;
for (auto &F : M) {
if (F.isDeclaration() || !F.hasGC())
continue;
- auto GCName = F.getGC();
- auto [It, Inserted] = Map.try_emplace(GCName);
- if (Inserted)
+ StringRef GCName = F.getGC();
+ auto [It, Inserted] = StrategyMap.try_emplace(GCName);
+ if (Inserted) {
It->second = getGCStrategy(GCName);
+ It->second->Name = GCName;
+ }
}
- return R;
+ return StrategyMap;
}
AnalysisKey GCFunctionAnalysis::Key;
@@ -61,9 +62,9 @@ GCFunctionAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
MAMProxy.cachedResultExists<CollectorMetadataAnalysis>(*F.getParent()) &&
"This pass need module analysis `collector-metadata`!");
auto &Map =
- MAMProxy.getCachedResult<CollectorMetadataAnalysis>(*F.getParent())
- ->StrategyMap;
- GCFunctionInfo Info(F, *Map[F.getGC()]);
+ *MAMProxy.getCachedResult<CollectorMetadataAnalysis>(*F.getParent());
+ GCStrategy &S = *Map.try_emplace(F.getGC()).first->second;
+ GCFunctionInfo Info(F, S);
return Info;
}
diff --git a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
index 60c8372577a93..1f9beb84ef62d 100644
--- a/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
+++ b/llvm/lib/CodeGen/ShadowStackGCLowering.cpp
@@ -109,7 +109,7 @@ class ShadowStackGCLowering : public FunctionPass {
PreservedAnalyses ShadowStackGCLoweringPass::run(Module &M,
ModuleAnalysisManager &MAM) {
auto &Map = MAM.getResult<CollectorMetadataAnalysis>(M);
- if (Map.StrategyMap.contains("shadow-stack"))
+ if (!Map.contains("shadow-stack"))
return PreservedAnalyses::all();
ShadowStackGCLoweringImpl Impl;
diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt
index a972dc32c40a2..d1677cdaeceac 100644
--- a/llvm/unittests/CodeGen/CMakeLists.txt
+++ b/llvm/unittests/CodeGen/CMakeLists.txt
@@ -29,6 +29,7 @@ add_llvm_unittest(CodeGenTests
DIETest.cpp
DroppedVariableStatsMIRTest.cpp
DwarfStringPoolEntryRefTest.cpp
+ GCMetadata.cpp
InstrRefLDVTest.cpp
LowLevelTypeTest.cpp
LexicalScopesTest.cpp
diff --git a/llvm/unittests/CodeGen/GCMetadata.cpp b/llvm/unittests/CodeGen/GCMetadata.cpp
new file mode 100644
index 0000000000000..a5d8a63d9b555
--- /dev/null
+++ b/llvm/unittests/CodeGen/GCMetadata.cpp
@@ -0,0 +1,76 @@
+//===- llvm/unittest/CodeGen/GCMetadata.cpp -------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/GCMetadata.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Analysis.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) {
+ SMDiagnostic Err;
+ return parseAssemblyString(IR, Err, Context);
+}
+
+class GCMetadataTest : public ::testing::Test {
+protected:
+ LLVMContext Context;
+ std::unique_ptr<Module> M;
+
+public:
+ GCMetadataTest()
+ : M(parseIR(Context, R"(
+%Env = type ptr
+
+define void @.main(%Env) gc "shadow-stack" {
+ %Root = alloca %Env
+ call void @llvm.gcroot( ptr %Root, %Env null )
+ unreachable
+}
+
+define void @g() gc "erlang" {
+entry:
+ ret void
+}
+
+declare void @llvm.gcroot(ptr, %Env)
+)")) {}
+};
+
+TEST_F(GCMetadataTest, Basic) {
+ LoopAnalysisManager LAM;
+ FunctionAnalysisManager FAM;
+ CGSCCAnalysisManager CGAM;
+ ModuleAnalysisManager MAM;
+ PassBuilder PB;
+ PB.registerModuleAnalyses(MAM);
+ PB.registerCGSCCAnalyses(CGAM);
+ PB.registerFunctionAnalyses(FAM);
+ PB.registerLoopAnalyses(LAM);
+ PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+
+ ModulePassManager MPM;
+ FunctionPassManager FPM;
+ GCStrategyMap &StrategyMap = MAM.getResult<CollectorMetadataAnalysis>(*M);
+ for (auto &[GCName, Strategy] : StrategyMap)
+ EXPECT_EQ(GCName, Strategy->getName());
+ for (auto &[GCName, Strategy] : llvm::reverse(StrategyMap))
+ EXPECT_EQ(GCName, Strategy->getName());
+}
+
+} // namespace
More information about the llvm-commits
mailing list