Skip to content

Commit e976aa9

Browse files
authored
Merge pull request #29111 from gottesmm/pr-d5a69902a451af42884c0e9cc4b6f18ecf246ada
[passmanager] Change SIL pass pipeline plan to use an LLVM YAML representation.
2 parents cdd798b + 52c5f72 commit e976aa9

File tree

4 files changed

+85
-88
lines changed

4 files changed

+85
-88
lines changed

lib/SILOptimizer/PassManager/PassPipeline.cpp

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -765,82 +765,82 @@ SILPassPipelinePlan::getPassPipelineForKinds(const SILOptions &Options,
765765
// Dumping And Loading Pass Pipelines from Yaml
766766
//===----------------------------------------------------------------------===//
767767

768+
namespace {
769+
770+
struct YAMLPassPipeline {
771+
std::string name;
772+
std::vector<PassKind> passes;
773+
774+
YAMLPassPipeline() {}
775+
YAMLPassPipeline(const SILPassPipeline &pipeline,
776+
SILPassPipelinePlan::PipelineKindRange pipelineKinds)
777+
: name(pipeline.Name), passes() {
778+
llvm::copy(pipelineKinds, std::back_inserter(passes));
779+
}
780+
};
781+
782+
} // end anonymous namespace
783+
784+
namespace llvm {
785+
namespace yaml {
786+
787+
template <> struct ScalarEnumerationTraits<PassKind> {
788+
static void enumeration(IO &io, PassKind &value) {
789+
#define PASS(ID, TAG, NAME) io.enumCase(value, #TAG, PassKind::ID);
790+
#include "swift/SILOptimizer/PassManager/Passes.def"
791+
}
792+
};
793+
794+
template <> struct MappingTraits<YAMLPassPipeline> {
795+
static void mapping(IO &io, YAMLPassPipeline &info) {
796+
io.mapRequired("name", info.name);
797+
io.mapRequired("passes", info.passes);
798+
}
799+
};
800+
801+
} // namespace yaml
802+
} // namespace llvm
803+
804+
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(PassKind)
805+
LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YAMLPassPipeline)
806+
768807
void SILPassPipelinePlan::dump() {
769808
print(llvm::errs());
770809
llvm::errs() << '\n';
771810
}
772811

773812
void SILPassPipelinePlan::print(llvm::raw_ostream &os) {
774-
// Our pipelines yaml representation is simple, we just output it ourselves
775-
// rather than use the yaml writer interface. We want to use the yaml reader
776-
// interface to be resilient against slightly different forms of yaml.
777-
os << "[\n";
778-
interleave(getPipelines(),
779-
[&](const SILPassPipeline &Pipeline) {
780-
os << " [\n";
781-
782-
os << " \"" << Pipeline.Name << "\"";
783-
for (PassKind Kind : getPipelinePasses(Pipeline)) {
784-
os << ",\n [\"" << PassKindID(Kind) << "\","
785-
<< "\"" << PassKindTag(Kind) << "\"]";
786-
}
787-
},
788-
[&] { os << "\n ],\n"; });
789-
os << "\n ]\n";
790-
os << ']';
813+
llvm::yaml::Output out(os);
814+
std::vector<YAMLPassPipeline> data;
815+
transform(getPipelines(), std::back_inserter(data),
816+
[&](const SILPassPipeline &pipeline) {
817+
return YAMLPassPipeline(pipeline, getPipelinePasses(pipeline));
818+
});
819+
out << data;
791820
}
792821

793822
SILPassPipelinePlan
794-
SILPassPipelinePlan::getPassPipelineFromFile(const SILOptions &Options,
795-
StringRef Filename) {
796-
namespace yaml = llvm::yaml;
797-
LLVM_DEBUG(llvm::dbgs() << "Parsing Pass Pipeline from " << Filename << "\n");
798-
799-
// Load the input file.
800-
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
801-
llvm::MemoryBuffer::getFileOrSTDIN(Filename);
802-
if (!FileBufOrErr) {
803-
llvm_unreachable("Failed to read yaml file");
804-
}
805-
806-
StringRef Buffer = FileBufOrErr->get()->getBuffer();
807-
llvm::SourceMgr SM;
808-
yaml::Stream Stream(Buffer, SM);
809-
yaml::document_iterator DI = Stream.begin();
810-
assert(DI != Stream.end() && "Failed to read a document");
811-
yaml::Node *N = DI->getRoot();
812-
assert(N && "Failed to find a root");
823+
SILPassPipelinePlan::getPassPipelineFromFile(const SILOptions &options,
824+
StringRef filename) {
825+
std::vector<YAMLPassPipeline> yamlPipelines;
826+
{
827+
// Load the input file.
828+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
829+
llvm::MemoryBuffer::getFileOrSTDIN(filename);
830+
if (!fileBufOrErr) {
831+
llvm_unreachable("Failed to read yaml file");
832+
}
813833

814-
SILPassPipelinePlan P(Options);
834+
llvm::yaml::Input in(fileBufOrErr->get()->getBuffer());
835+
in >> yamlPipelines;
836+
}
815837

816-
auto *RootList = cast<yaml::SequenceNode>(N);
817-
llvm::SmallVector<PassKind, 32> Passes;
818-
for (yaml::Node &PipelineNode :
819-
make_range(RootList->begin(), RootList->end())) {
820-
Passes.clear();
821-
LLVM_DEBUG(llvm::dbgs() << "New Pipeline:\n");
822-
823-
auto *Desc = cast<yaml::SequenceNode>(&PipelineNode);
824-
yaml::SequenceNode::iterator DescIter = Desc->begin();
825-
StringRef Name = cast<yaml::ScalarNode>(&*DescIter)->getRawValue();
826-
LLVM_DEBUG(llvm::dbgs() << " Name: \"" << Name << "\"\n");
827-
++DescIter;
828-
829-
for (auto DescEnd = Desc->end(); DescIter != DescEnd; ++DescIter) {
830-
auto *InnerPassList = cast<yaml::SequenceNode>(&*DescIter);
831-
auto *FirstNode = &*InnerPassList->begin();
832-
StringRef PassName = cast<yaml::ScalarNode>(FirstNode)->getRawValue();
833-
unsigned Size = PassName.size() - 2;
834-
PassName = PassName.substr(1, Size);
835-
LLVM_DEBUG(llvm::dbgs() << " Pass: \"" << PassName << "\"\n");
836-
auto Kind = PassKindFromString(PassName);
837-
assert(Kind != PassKind::invalidPassKind && "Found invalid pass kind?!");
838-
Passes.push_back(Kind);
839-
}
838+
SILPassPipelinePlan silPlan(options);
840839

841-
P.startPipeline(Name);
842-
P.addPasses(Passes);
840+
for (auto &pipeline : yamlPipelines) {
841+
silPlan.startPipeline(pipeline.name);
842+
silPlan.addPasses(pipeline.passes);
843843
}
844844

845-
return P;
845+
return silPlan;
846846
}

lib/Serialization/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ add_swift_host_library(swiftSerialization STATIC
1212
BitstreamReader
1313
)
1414
target_link_libraries(swiftSerialization PRIVATE
15-
swiftClangImporter)
15+
swiftClangImporter
16+
swiftSIL)
1617

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
// RUN: %sil-passpipeline-dumper -Onone | %FileCheck %s
2-
// RUN: %sil-passpipeline-dumper -Onone | %{python} -c 'import json; import sys; json.load(sys.stdin)'
32

4-
// CHECK: [
5-
// CHECK: [
6-
// CHECK: "Serialization",
7-
// CHECK: ["SerializeSILPass","serialize-sil"]
8-
// CHECK: ],
9-
// CHECK: [
10-
// CHECK: "Rest of Onone",
11-
// CHECK: ["UsePrespecialized","use-prespecialized"],
12-
// CHECK: ["AssumeSingleThreaded","sil-assume-single-threaded"],
13-
// CHECK: ["SILDebugInfoGenerator","sil-debuginfo-gen"]
14-
// CHECK: ]
15-
// CHECK: ]
3+
// CHECK: ---
4+
// CHECK: name: Mandatory Combines
5+
// CHECK: passes: [ "for-each-loop-unroll", "mandatory-combine" ]
6+
// CHECK: ---
7+
// CHECK: name: Serialization
8+
// CHECK: passes: [ "serialize-sil", "ownership-model-eliminator" ]
9+
// CHECK: ---
10+
// CHECK: name: Rest of Onone
11+
// CHECK: passes: [ "use-prespecialized", "sil-assume-single-threaded",
12+
// CHECK: "sil-debuginfo-gen" ]
13+
// CHECK: ...

tools/sil-passpipeline-dumper/CMakeLists.txt

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ add_swift_host_tool(sil-passpipeline-dumper
22
SILPassPipelineDumper.cpp
33
SWIFT_COMPONENT tools
44
)
5-
target_link_libraries(sil-passpipeline-dumper
6-
PRIVATE
7-
swiftClangImporter
8-
swiftFrontend
9-
swiftSerialization
10-
swiftSILGen
11-
swiftSILOptimizer
12-
# FIXME: Circular dependencies require re-listing these libraries.
13-
swiftAST
14-
swiftSema)
5+
target_link_libraries(sil-passpipeline-dumper PRIVATE
6+
swiftFrontend
7+
swiftIRGen
8+
swiftSILGen
9+
swiftSILOptimizer
10+
# Clang libraries included to appease the linker on linux.
11+
clangBasic
12+
clangCodeGen)

0 commit comments

Comments
 (0)