Files
swift-mirror/lib/SIL/IR/Linker.h
Michael Gottesman e1a19e4173 [sil] Split library into subfolders, while still building as a single library still.
Specifically, I split it into 3 initial categories: IR, Utils, Verifier. I just
did this quickly, we can always split it more later if we want.

I followed the model that we use in SILOptimizer: ./lib/SIL/CMakeLists.txt vends
 a macro (sil_register_sources) to the sub-folders that register the sources of
 the subdirectory with a global state variable that ./lib/SIL/CMakeLists.txt
 defines. Then after including those subdirs, the parent cmake declares the SIL
 library. So the output is the same, but we have the flexibility of having
 subdirectories to categorize source files.
2020-03-30 11:01:00 -07:00

99 lines
3.5 KiB
C++

//===--- Linker.h -----------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SIL_LINKER_H
#define SWIFT_SIL_LINKER_H
#include "swift/SIL/SILDebugScope.h"
#include "swift/SIL/SILVisitor.h"
#include "swift/SIL/SILModule.h"
#include <functional>
namespace swift {
/// Visitor that knows how to link in dependencies of SILInstructions.
class SILLinkerVisitor : public SILInstructionVisitor<SILLinkerVisitor, void> {
using LinkingMode = SILModule::LinkingMode;
/// The SILModule that we are loading from.
SILModule &Mod;
/// Break cycles visiting recursive protocol conformances.
llvm::DenseSet<ProtocolConformance *> VisitedConformances;
/// Worklist of SILFunctions we are processing.
llvm::SmallVector<SILFunction *, 128> Worklist;
/// The current linking mode.
LinkingMode Mode;
/// Whether any functions were deserialized.
bool Changed;
public:
SILLinkerVisitor(SILModule &M, SILModule::LinkingMode LinkingMode)
: Mod(M), Worklist(), Mode(LinkingMode), Changed(false) {}
/// Process F, recursively deserializing any thing F may reference.
/// Returns true if any deserialization was performed.
bool processFunction(SILFunction *F);
/// Deserialize the VTable mapped to C if it exists and all SIL the VTable
/// transitively references.
///
/// This method assumes that the caller made sure that no vtable existed in
/// Mod.
SILVTable *processClassDecl(const ClassDecl *C);
/// We do not want to visit callee functions if we just have a value base.
void visitSILInstruction(SILInstruction *I) { }
void visitApplyInst(ApplyInst *AI);
void visitTryApplyInst(TryApplyInst *TAI);
void visitPartialApplyInst(PartialApplyInst *PAI);
void visitFunctionRefInst(FunctionRefInst *FRI);
void visitDynamicFunctionRefInst(DynamicFunctionRefInst *FRI);
void visitPreviousDynamicFunctionRefInst(PreviousDynamicFunctionRefInst *FRI);
void visitProtocolConformance(ProtocolConformanceRef C,
const Optional<SILDeclRef> &Member);
void visitApplySubstitutions(SubstitutionMap subs);
void visitWitnessMethodInst(WitnessMethodInst *WMI) {
visitProtocolConformance(WMI->getConformance(), WMI->getMember());
}
void visitInitExistentialAddrInst(InitExistentialAddrInst *IEI);
void visitInitExistentialRefInst(InitExistentialRefInst *IERI);
void visitAllocRefInst(AllocRefInst *ARI);
void visitMetatypeInst(MetatypeInst *MI);
private:
/// Cause a function to be deserialized, and visit all other functions
/// referenced from this function according to the linking mode.
void addFunctionToWorklist(SILFunction *F);
/// Consider a function for deserialization if the current linking mode
/// requires it.
void maybeAddFunctionToWorklist(SILFunction *F);
/// Is the current mode link all? Link all implies we should try and link
/// everything, not just transparent/shared functions.
bool isLinkAll() const { return Mode == LinkingMode::LinkAll; }
void linkInVTable(ClassDecl *D);
// Main loop of the visitor. Called by one of the other *visit* methods.
void process();
};
} // end namespace swift
#endif