//===--- DeserializeSIL.h - Read SIL ----------------------------*- 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 // //===----------------------------------------------------------------------===// #include "SILFormat.h" #include "ModuleFile.h" #include "swift/SIL/SILModule.h" #include "swift/Serialization/SerializedSILLoader.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/SaveAndRestore.h" namespace llvm { template class OnDiskIterableChainedHashTable; } namespace swift { class SILDeserializer { using TypeID = serialization::TypeID; ModuleFile *MF; SILModule &SILMod; DeserializationNotificationHandlerSet *Callback; /// The cursor used to lazily load SILFunctions. llvm::BitstreamCursor SILCursor; llvm::BitstreamCursor SILIndexCursor; class FuncTableInfo; using SerializedFuncTable = llvm::OnDiskIterableChainedHashTable; std::unique_ptr FuncTable; MutableArrayRef> Funcs; std::unique_ptr VTableList; MutableArrayRef> VTables; std::unique_ptr GlobalVarList; MutableArrayRef> GlobalVars; std::unique_ptr WitnessTableList; MutableArrayRef> WitnessTables; std::unique_ptr DefaultWitnessTableList; MutableArrayRef> DefaultWitnessTables; MutableArrayRef> Properties; std::unique_ptr DifferentiabilityWitnessList; MutableArrayRef< ModuleFile::PartiallySerialized> DifferentiabilityWitnesses; /// A declaration will only llvm::DenseMap ConformanceToWitnessTableMap; /// Data structures used to perform name lookup for local values. llvm::DenseMap LocalValues; llvm::DenseMap ForwardLocalValues; /// The first two local values are reserved for SILUndef. serialization::ValueID LastValueID = 1; /// Data structures used to perform lookup of basic blocks. llvm::DenseMap BlocksByID; llvm::DenseMap UndefinedBlocks; unsigned BasicBlockID = 0; /// Return the SILBasicBlock of a given ID. SILBasicBlock *getBBForReference(SILFunction *Fn, unsigned ID); SILBasicBlock *getBBForDefinition(SILFunction *Fn, SILBasicBlock *Prev, unsigned ID); /// Read a SIL function. SILFunction *readSILFunction(serialization::DeclID, SILFunction *InFunc, StringRef Name, bool declarationOnly, bool errorIfEmptyBody = true); /// Read a SIL function. llvm::Expected readSILFunctionChecked(serialization::DeclID, SILFunction *InFunc, StringRef Name, bool declarationOnly, bool errorIfEmptyBody = true); /// Read a SIL basic block within a given SIL function. SILBasicBlock *readSILBasicBlock(SILFunction *Fn, SILBasicBlock *Prev, SmallVectorImpl &scratch); /// Read a SIL instruction within a given SIL basic block. bool readSILInstruction(SILFunction *Fn, SILBasicBlock *BB, SILBuilder &Builder, unsigned RecordKind, SmallVectorImpl &scratch); /// Read the SIL function table. std::unique_ptr readFuncTable(ArrayRef fields, StringRef blobData); /// When an instruction or block argument is defined, this method is used to /// register it and update our symbol table. void setLocalValue(ValueBase *Value, serialization::ValueID Id); /// Get a reference to a local value with the specified ID and type. SILValue getLocalValue(serialization::ValueID Id, SILType Type); SILType getSILType(Type ty, SILValueCategory category, SILFunction *inContext); SILDifferentiabilityWitness * getSILDifferentiabilityWitnessForReference(StringRef mangledKey); SILFunction *getFuncForReference(StringRef Name, SILType Ty); SILFunction *getFuncForReference(StringRef Name); SILVTable *readVTable(serialization::DeclID); SILGlobalVariable *getGlobalForReference(StringRef Name); SILGlobalVariable *readGlobalVar(StringRef Name); /// Read and return the witness table identified with \p WId. SILWitnessTable *readWitnessTable(serialization::DeclID WId, SILWitnessTable *existingWt); /// Read the witness table identified with \p WId, return the table or /// the first error if any. llvm::Expected readWitnessTableChecked(serialization::DeclID WId, SILWitnessTable *existingWt); void readWitnessTableEntries( llvm::BitstreamEntry &entry, std::vector &witnessEntries, std::vector &conditionalConformances); SILProperty *readProperty(serialization::DeclID); SILDefaultWitnessTable * readDefaultWitnessTable(serialization::DeclID, SILDefaultWitnessTable *existingWt); SILDifferentiabilityWitness * readDifferentiabilityWitness(serialization::DeclID); Optional readKeyPathComponent(ArrayRef ListOfValues, unsigned &nextValue); public: Identifier getModuleIdentifier() const { return MF->getAssociatedModule()->getName(); } FileUnit *getFile() const { return MF->getFile(); } SILFunction *lookupSILFunction(SILFunction *InFunc, bool onlyUpdateLinkage); SILFunction *lookupSILFunction(StringRef Name, bool declarationOnly = false); bool hasSILFunction(StringRef Name, Optional Linkage = None); SILVTable *lookupVTable(StringRef MangledClassName); SILWitnessTable *lookupWitnessTable(SILWitnessTable *wt); SILDefaultWitnessTable * lookupDefaultWitnessTable(SILDefaultWitnessTable *wt); SILDifferentiabilityWitness * lookupDifferentiabilityWitness(StringRef mangledDiffWitnessKey); /// Invalidate all cached SILFunctions. void invalidateFunctionCache(); /// Invalidate a specific cached SILFunction. bool invalidateFunction(SILFunction *F); /// Deserialize all SILFunctions, VTables, WitnessTables, and /// DefaultWitnessTables inside the module, and add them to SILMod. /// /// TODO: Globals. void getAll(bool UseCallback = true) { llvm::SaveAndRestore SaveCB( Callback); if (!UseCallback) Callback = nullptr; getAllSILFunctions(); getAllSILGlobalVariables(); getAllVTables(); getAllWitnessTables(); getAllDefaultWitnessTables(); getAllProperties(); getAllDifferentiabilityWitnesses(); } /// Deserialize all SILFunctions inside the module and add them to SILMod. void getAllSILFunctions(); /// Deserialize all SILGlobalVariables inside the module and add them to /// SILMod. void getAllSILGlobalVariables(); /// Deserialize all VTables inside the module and add them to SILMod. void getAllVTables(); /// Deserialize all WitnessTables inside the module and add them to SILMod. void getAllWitnessTables(); /// Deserialize all DefaultWitnessTables inside the module and add them /// to SILMod. void getAllDefaultWitnessTables(); /// Deserialize all Property descriptors inside the module and add them /// to SILMod. void getAllProperties(); /// Deserialize all DifferentiabilityWitnesses inside the module and add /// them to SILMod. void getAllDifferentiabilityWitnesses(); SILDeserializer(ModuleFile *MF, SILModule &M, DeserializationNotificationHandlerSet *callback); // Out of line to avoid instantiation OnDiskChainedHashTable here. ~SILDeserializer(); }; } // end namespace swift