[llvm] r335565 - [ORC] Add a symbolAliases function to the Core APIs.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 25 18:22:29 PDT 2018
Author: lhames
Date: Mon Jun 25 18:22:29 2018
New Revision: 335565
URL: http://llvm.org/viewvc/llvm-project?rev=335565&view=rev
Log:
[ORC] Add a symbolAliases function to the Core APIs.
symbolAliases can be used to define symbol aliases within a VSO.
Modified:
llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h?rev=335565&r1=335564&r2=335565&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Core.h Mon Jun 25 18:22:29 2018
@@ -245,6 +245,46 @@ absoluteSymbols(SymbolMap Symbols) {
std::move(Symbols));
}
+struct SymbolAliasMapEntry {
+ SymbolStringPtr Aliasee;
+ JITSymbolFlags AliasFlags;
+};
+
+/// A map of Symbols to (Symbol, Flags) pairs.
+using SymbolAliasMap = std::map<SymbolStringPtr, SymbolAliasMapEntry>;
+
+/// A materialization unit for symbol aliases. Allows existing symbols to be
+/// aliased with alternate flags.
+class SymbolAliasesMaterializationUnit : public MaterializationUnit {
+public:
+ SymbolAliasesMaterializationUnit(SymbolAliasMap Aliases);
+
+private:
+ void materialize(MaterializationResponsibility R) override;
+ void discard(const VSO &V, SymbolStringPtr Name) override;
+ static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases);
+
+ SymbolAliasMap Aliases;
+};
+
+/// Create a SymbolAliasesMaterializationUnit with the given aliases.
+/// Useful for defining symbol aliases.: E.g., given a VSO V containing symbols
+/// "foo" and "bar", we can define aliases "baz" (for "foo") and "qux" (for
+/// "bar") with:
+/// \code{.cpp}
+/// SymbolStringPtr Baz = ...;
+/// SymbolStringPtr Qux = ...;
+/// if (auto Err = V.define(symbolAliases({
+/// {Baz, { Foo, JITSymbolFlags::Exported }},
+/// {Qux, { Bar, JITSymbolFlags::Weak }}}))
+/// return Err;
+/// \endcode
+inline std::unique_ptr<SymbolAliasesMaterializationUnit>
+symbolAliases(SymbolAliasMap Aliases) {
+ return llvm::make_unique<SymbolAliasesMaterializationUnit>(
+ std::move(Aliases));
+}
+
/// Base utilities for ExecutionSession.
class ExecutionSessionBase {
public:
Modified: llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp?rev=335565&r1=335564&r2=335565&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/Core.cpp Mon Jun 25 18:22:29 2018
@@ -344,6 +344,69 @@ AbsoluteSymbolsMaterializationUnit::extr
return Flags;
}
+SymbolAliasesMaterializationUnit::SymbolAliasesMaterializationUnit(
+ SymbolAliasMap Aliases)
+ : MaterializationUnit(extractFlags(Aliases)), Aliases(std::move(Aliases)) {}
+
+void SymbolAliasesMaterializationUnit::materialize(
+ MaterializationResponsibility R) {
+ auto &V = R.getTargetVSO();
+ auto &ES = V.getExecutionSession();
+
+ // FIXME: Use a unique_ptr when we move to C++14 and have generalized lambda
+ // capture.
+ auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R));
+
+ auto OnResolve = [this, SharedR](
+ Expected<AsynchronousSymbolQuery::ResolutionResult> RR) {
+ if (RR) {
+ SymbolMap ResolutionMap;
+ for (auto &KV : Aliases) {
+ assert(RR->Symbols.count(KV.second.Aliasee) &&
+ "Result map missing entry?");
+ ResolutionMap[KV.first] = JITEvaluatedSymbol(
+ RR->Symbols[KV.second.Aliasee].getAddress(), KV.second.AliasFlags);
+ }
+
+ SharedR->resolve(ResolutionMap);
+ SharedR->finalize();
+ } else {
+ auto &ES = SharedR->getTargetVSO().getExecutionSession();
+ ES.reportError(RR.takeError());
+ SharedR->failMaterialization();
+ }
+ };
+
+ auto OnReady = [&ES](Error Err) { ES.reportError(std::move(Err)); };
+
+ SymbolNameSet Aliasees;
+ for (auto &KV : Aliases)
+ Aliasees.insert(KV.second.Aliasee);
+
+ auto Q = std::make_shared<AsynchronousSymbolQuery>(
+ Aliasees, std::move(OnResolve), std::move(OnReady));
+ auto Unresolved = V.lookup(Q, Aliasees);
+
+ if (!Unresolved.empty())
+ ES.failQuery(*Q, make_error<SymbolsNotFound>(std::move(Unresolved)));
+}
+
+void SymbolAliasesMaterializationUnit::discard(const VSO &V,
+ SymbolStringPtr Name) {
+ assert(Aliases.count(Name) &&
+ "Symbol not covered by this MaterializationUnit");
+ Aliases.erase(Name);
+}
+
+SymbolFlagsMap
+SymbolAliasesMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {
+ SymbolFlagsMap SymbolFlags;
+ for (auto &KV : Aliases)
+ SymbolFlags[KV.first] = KV.second.AliasFlags;
+
+ return SymbolFlags;
+}
+
Error VSO::defineMaterializing(const SymbolFlagsMap &SymbolFlags) {
return ES.runSessionLocked([&]() -> Error {
std::vector<SymbolMap::iterator> AddedSyms;
@@ -858,7 +921,13 @@ void VSO::dump(raw_ostream &OS) {
Error VSO::defineImpl(MaterializationUnit &MU) {
SymbolNameSet Duplicates;
SymbolNameSet MUDefsOverridden;
- std::vector<SymbolMap::iterator> ExistingDefsOverridden;
+
+ struct ExistingDefOverriddenEntry {
+ SymbolMap::iterator ExistingDefItr;
+ JITSymbolFlags NewFlags;
+ };
+ std::vector<ExistingDefOverriddenEntry> ExistingDefsOverridden;
+
for (auto &KV : MU.getSymbols()) {
assert(!KV.second.isLazy() && "Lazy flag should be managed internally.");
assert(!KV.second.isMaterializing() &&
@@ -879,7 +948,7 @@ Error VSO::defineImpl(MaterializationUni
(EntryItr->second.getFlags() & JITSymbolFlags::Materializing))
Duplicates.insert(KV.first);
else
- ExistingDefsOverridden.push_back(EntryItr);
+ ExistingDefsOverridden.push_back({EntryItr, NewFlags});
} else
MUDefsOverridden.insert(KV.first);
}
@@ -892,8 +961,8 @@ Error VSO::defineImpl(MaterializationUni
continue;
bool Found = false;
- for (const auto &I : ExistingDefsOverridden)
- if (I->first == KV.first)
+ for (const auto &EDO : ExistingDefsOverridden)
+ if (EDO.ExistingDefItr->first == KV.first)
Found = true;
if (!Found)
@@ -905,16 +974,18 @@ Error VSO::defineImpl(MaterializationUni
}
// Update flags on existing defs and call discard on their materializers.
- for (auto &ExistingDefItr : ExistingDefsOverridden) {
- assert(ExistingDefItr->second.getFlags().isLazy() &&
- !ExistingDefItr->second.getFlags().isMaterializing() &&
+ for (auto &EDO : ExistingDefsOverridden) {
+ assert(EDO.ExistingDefItr->second.getFlags().isLazy() &&
+ !EDO.ExistingDefItr->second.getFlags().isMaterializing() &&
"Overridden existing def should be in the Lazy state");
- auto UMII = UnmaterializedInfos.find(ExistingDefItr->first);
+ EDO.ExistingDefItr->second.setFlags(EDO.NewFlags);
+
+ auto UMII = UnmaterializedInfos.find(EDO.ExistingDefItr->first);
assert(UMII != UnmaterializedInfos.end() &&
"Overridden existing def should have an UnmaterializedInfo");
- UMII->second->MU->doDiscard(*this, ExistingDefItr->first);
+ UMII->second->MU->doDiscard(*this, EDO.ExistingDefItr->first);
}
// Discard overridden symbols povided by MU.
Modified: llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp?rev=335565&r1=335564&r2=335565&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp Mon Jun 25 18:22:29 2018
@@ -259,6 +259,35 @@ TEST(CoreAPIsTest, LookupFlagsTest) {
EXPECT_EQ(SymbolFlags[Bar], BarFlags) << "Incorrect flags returned for Bar";
}
+TEST(CoreAPIsTest, TestAliases) {
+ ExecutionSession ES;
+ auto &V = ES.createVSO("V");
+
+ auto Foo = ES.getSymbolStringPool().intern("foo");
+ auto FooSym = JITEvaluatedSymbol(1U, JITSymbolFlags::Exported);
+ auto Bar = ES.getSymbolStringPool().intern("bar");
+ auto BarSym = JITEvaluatedSymbol(2U, JITSymbolFlags::Exported);
+
+ auto Baz = ES.getSymbolStringPool().intern("baz");
+ auto Qux = ES.getSymbolStringPool().intern("qux");
+
+ auto QuxSym = JITEvaluatedSymbol(3U, JITSymbolFlags::Exported);
+
+ cantFail(V.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
+ cantFail(V.define(symbolAliases({{Baz, {Foo, JITSymbolFlags::Exported}},
+ {Qux, {Bar, JITSymbolFlags::Weak}}})));
+ cantFail(V.define(absoluteSymbols({{Qux, QuxSym}})));
+
+ auto Result = lookup({&V}, {Baz, Qux});
+ EXPECT_TRUE(!!Result) << "Unexpected lookup failure";
+ EXPECT_EQ(Result->count(Baz), 1U) << "No result for \"baz\"";
+ EXPECT_EQ(Result->count(Qux), 1U) << "No result for \"qux\"";
+ EXPECT_EQ((*Result)[Baz].getAddress(), FooSym.getAddress())
+ << "\"Baz\"'s address should match \"Foo\"'s";
+ EXPECT_EQ((*Result)[Qux].getAddress(), QuxSym.getAddress())
+ << "The \"Qux\" alias should have been overriden";
+}
+
TEST(CoreAPIsTest, TestTrivialCircularDependency) {
ExecutionSession ES;
More information about the llvm-commits
mailing list