mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This patch adds SIL-level debug info support for variables whose static type is rewritten by an optimizer transformation. When a function is (generic-)specialized or inlined, the static types of inlined variables my change as they are remapped into the generic environment of the inlined call site. With this patch all inlined SILDebugScopes that point to functions with a generic signature are recursively rewritten to point to clones of the original function with new unique mangled names. The new mangled names consist of the old mangled names plus the new substituions, similar (or exactly, respectively) to how generic specialization is handled. On libSwiftCore.dylib (x86_64), this yields a 17% increase in unique source vars and a ~24% increase in variables with a debug location. rdar://problem/28859432 rdar://problem/34526036
176 lines
5.8 KiB
C++
176 lines
5.8 KiB
C++
//===--- 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<char, 32> 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 {
|
|
|
|
SubstitutionMap SubMap;
|
|
bool isReAbstracted;
|
|
bool isInlined;
|
|
|
|
public:
|
|
GenericSpecializationMangler(SILFunction *F, SubstitutionMap SubMap,
|
|
IsSerialized_t Serialized, bool isReAbstracted,
|
|
bool isInlined = false)
|
|
: SpecializationMangler(SpecializationPass::GenericSpecializer,
|
|
Serialized, F),
|
|
SubMap(SubMap), isReAbstracted(isReAbstracted), isInlined(isInlined) {}
|
|
|
|
std::string mangle(GenericSignature *Sig = nullptr);
|
|
};
|
|
|
|
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,
|
|
GuaranteedToOwned=256,
|
|
ExistentialToGeneric=512,
|
|
First_OptionSetEntry=32, LastOptionSetEntry=32768,
|
|
};
|
|
|
|
using ArgInfo = std::pair<ArgumentModifierIntBase,
|
|
NullablePtr<SILInstruction>>;
|
|
// 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<ArgInfo, 8> 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 setArgumentGuaranteedToOwned(unsigned OrigArgIdx);
|
|
void setArgumentExistentialToGeneric(unsigned OrigArgIdx);
|
|
void setArgumentSROA(unsigned OrigArgIdx);
|
|
void setArgumentBoxToValue(unsigned OrigArgIdx);
|
|
void setArgumentBoxToStack(unsigned OrigArgIdx);
|
|
void setReturnValueOwnedToUnowned();
|
|
|
|
std::string mangle();
|
|
|
|
private:
|
|
void mangleConstantProp(LiteralInst *LI);
|
|
void mangleClosureProp(SILInstruction *Inst);
|
|
void mangleArgument(ArgumentModifierIntBase ArgMod,
|
|
NullablePtr<SILInstruction> Inst);
|
|
void mangleReturnValue(ReturnValueModifierIntBase RetMod);
|
|
};
|
|
|
|
} // end namespace Mangle
|
|
} // end namespace swift
|
|
|
|
#endif
|