Files
swift-mirror/lib/SILOptimizer/UtilityPasses/SerializeSILPass.cpp
T
Slava Pestov 1831b5471e SIL: Clean up 'early serialization' a bit
- Clear the 'serialized' flag on witness tables and vtables
  after serialization, not just functions. This fixes SIL
  verifier failures if post-serialization SIL is printed
  out and parsed back in.

- Clear the 'serialized' flag when deserializing functions,
  witness tables and vtables in a module that has already
  been serialized. This fixes SIL verifier failures if
  we deserialize more declarations after serializing SIL.

We were seeing SIL verifier failures on bots that run the
tests with the stdlib built with non-standard flags.

Unfortunately I don't have a reduced test case that would
fail in PR testing without these fixes.

Fixes <rdar://problem/36682929>.
2018-01-21 01:35:13 -08:00

62 lines
2.1 KiB
C++

//===--- SerializeSILPass.cpp ---------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "serialize-sil"
#include "swift/Strings.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
using namespace swift;
/// A utility pass to serialize a SILModule at any place inside the optimization
/// pipeline.
class SerializeSILPass : public SILModuleTransform {
/// Removes [serialized] from all functions. This allows for more
/// optimizations and for a better dead function elimination.
void removeSerializedFlagFromAllFunctions(SILModule &M) {
for (auto &F : M) {
F.setSerialized(IsNotSerialized);
}
for (auto &WT : M.getWitnessTables()) {
WT.setSerialized(IsNotSerialized);
}
for (auto &VT : M.getVTables()) {
VT.setSerialized(IsNotSerialized);
}
}
public:
SerializeSILPass() {}
void run() override {
auto &M = *getModule();
// Nothing to do if the module was serialized already.
if (M.isSerialized())
return;
// Mark all reachable functions as "anchors" so that they are not
// removed later by the dead function elimination pass. This
// is required, because clients may reference any of the
// serialized functions or anything referenced from them. Therefore,
// to avoid linker errors, the object file of the current module should
// contain all the symbols which were alive at the time of serialization.
DEBUG(llvm::dbgs() << "Serializing SILModule in SerializeSILPass\n");
getModule()->serialize();
removeSerializedFlagFromAllFunctions(M);
}
};
SILTransform *swift::createSerializeSILPass() {
return new SerializeSILPass();
}