//===--- SpecializationMangler.h - mangling of specializations --*- 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_SILOPTIMIZER_UTILS_SPECIALIZATIONMANGLER_H #define SWIFT_SILOPTIMIZER_UTILS_SPECIALIZATIONMANGLER_H #include "swift/Demangling/Demangler.h" #include "swift/Basic/NullablePtr.h" #include "swift/AST/ASTMangler.h" #include "swift/SIL/SILLinkage.h" #include "swift/SIL/SILFunction.h" namespace swift { namespace Mangle { enum class SpecializationKind : uint8_t { Generic, NotReAbstractedGeneric, FunctionSignature, }; /// Inject SpecializationPass into the Mangle namespace. using SpecializationPass = Demangle::SpecializationPass; /// The base class for specialization mangles. class SpecializationMangler : public Mangle::ASTMangler { protected: /// The specialization pass. SpecializationPass Pass; IsSerialized_t Serialized; /// The original function which is specialized. SILFunction *Function; llvm::SmallVector ArgOpStorage; llvm::raw_svector_ostream ArgOpBuffer; protected: SpecializationMangler(SpecializationPass P, IsSerialized_t Serialized, SILFunction *F) : Pass(P), Serialized(Serialized), Function(F), ArgOpBuffer(ArgOpStorage) {} SILFunction *getFunction() const { return Function; } void beginMangling(); /// Finish the mangling of the symbol and return the mangled name. std::string finalize(); void appendSpecializationOperator(StringRef Op) { appendOperator(Op, StringRef(ArgOpStorage.data(), ArgOpStorage.size())); } }; // The mangler for specialized generic functions. class GenericSpecializationMangler : public SpecializationMangler { SubstitutionList Subs; bool isReAbstracted; public: GenericSpecializationMangler(SILFunction *F, SubstitutionList Subs, IsSerialized_t Serialized, bool isReAbstracted) : SpecializationMangler(SpecializationPass::GenericSpecializer, Serialized, F), Subs(Subs), isReAbstracted(isReAbstracted) {} std::string mangle(); }; class PartialSpecializationMangler : public SpecializationMangler { CanSILFunctionType SpecializedFnTy; bool isReAbstracted; public: PartialSpecializationMangler(SILFunction *F, CanSILFunctionType SpecializedFnTy, IsSerialized_t Serialized, bool isReAbstracted) : SpecializationMangler(SpecializationPass::GenericSpecializer, Serialized, F), SpecializedFnTy(SpecializedFnTy), isReAbstracted(isReAbstracted) {} std::string mangle(); }; // The mangler for functions where arguments are specialized. class FunctionSignatureSpecializationMangler : public SpecializationMangler { using ReturnValueModifierIntBase = uint16_t; enum class ReturnValueModifier : ReturnValueModifierIntBase { // Option Space 4 bits (i.e. 16 options). Unmodified=0, First_Option=0, Last_Option=31, // Option Set Space. 12 bits (i.e. 12 option). Dead=32, OwnedToUnowned=64, First_OptionSetEntry=32, LastOptionSetEntry=32768, }; // We use this private typealias to make it easy to expand ArgumentModifier's // size if we need to. using ArgumentModifierIntBase = uint16_t; enum class ArgumentModifier : ArgumentModifierIntBase { // Option Space 4 bits (i.e. 16 options). Unmodified=0, ConstantProp=1, ClosureProp=2, BoxToValue=3, BoxToStack=4, First_Option=0, Last_Option=31, // Option Set Space. 12 bits (i.e. 12 option). Dead=32, OwnedToGuaranteed=64, SROA=128, First_OptionSetEntry=32, LastOptionSetEntry=32768, }; using ArgInfo = std::pair>; // Information for each SIL argument in the original function before // specialization. This includes SIL indirect result argument required for // the original function type at the current stage of compilation. llvm::SmallVector OrigArgs; ReturnValueModifierIntBase ReturnValue; public: FunctionSignatureSpecializationMangler(SpecializationPass Pass, IsSerialized_t Serialized, SILFunction *F); void setArgumentConstantProp(unsigned OrigArgIdx, LiteralInst *LI); void setArgumentClosureProp(unsigned OrigArgIdx, PartialApplyInst *PAI); void setArgumentClosureProp(unsigned OrigArgIdx, ThinToThickFunctionInst *TTTFI); void setArgumentDead(unsigned OrigArgIdx); void setArgumentOwnedToGuaranteed(unsigned OrigArgIdx); void setArgumentSROA(unsigned OrigArgIdx); void setArgumentBoxToValue(unsigned OrigArgIdx); void setArgumentBoxToStack(unsigned OrigArgIdx); void setReturnValueOwnedToUnowned(); std::string mangle(int UniqueID = 0); private: void mangleConstantProp(LiteralInst *LI); void mangleClosureProp(SILInstruction *Inst); void mangleArgument(ArgumentModifierIntBase ArgMod, NullablePtr Inst); void mangleReturnValue(ReturnValueModifierIntBase RetMod); }; } // end namespace Mangle } // end namespace swift #endif