mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This reorganization allows adding attributes that refer to types. I need this for a @_specialize attribute with a type list. PrintOptions.h and other headers depend on these enums. But Attr.h defines a lot of classes that almost never need to be included.
306 lines
9.2 KiB
C++
306 lines
9.2 KiB
C++
//===--- Mangle.cpp - SIL specific name Mangling --------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See http://swift.org/LICENSE.txt for license information
|
|
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements declaration specialized name mangling for SIL.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/SIL/Mangle.h"
|
|
#include "swift/AST/ASTContext.h"
|
|
#include "swift/AST/ASTVisitor.h"
|
|
#include "swift/AST/Initializer.h"
|
|
#include "swift/AST/Mangle.h"
|
|
#include "swift/AST/Module.h"
|
|
#include "swift/AST/ProtocolConformance.h"
|
|
#include "swift/Basic/Punycode.h"
|
|
#include "swift/SIL/SILArgument.h"
|
|
#include "swift/SIL/SILType.h"
|
|
#include "swift/SIL/SILGlobalVariable.h"
|
|
#include "clang/AST/Decl.h"
|
|
#include "clang/AST/DeclObjC.h"
|
|
#include "clang/Basic/CharInfo.h"
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/ADT/SmallString.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/MD5.h"
|
|
#include "llvm/Support/SaveAndRestore.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
using namespace swift;
|
|
using namespace Mangle;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Generic Specialization
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
static void mangleSubstitution(Mangler &M, Substitution Sub) {
|
|
M.mangleType(Sub.getReplacement()->getCanonicalType(), 0);
|
|
for (auto C : Sub.getConformances()) {
|
|
if (C.isAbstract())
|
|
return;
|
|
M.mangleProtocolConformance(C.getConcrete());
|
|
}
|
|
}
|
|
|
|
void GenericSpecializationMangler::mangleSpecialization() {
|
|
Mangler &M = getMangler();
|
|
|
|
for (auto &Sub : Subs) {
|
|
mangleSubstitution(M, Sub);
|
|
M.append('_');
|
|
}
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Function Signature Optimizations
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
FunctionSignatureSpecializationMangler::
|
|
FunctionSignatureSpecializationMangler(SpecializationPass P, Mangler &M,
|
|
SILFunction *F)
|
|
: SpecializationMangler(SpecializationKind::FunctionSignature, P, M, F) {
|
|
for (unsigned i = 0, e = F->getLoweredFunctionType()->getNumSILArguments();
|
|
i != e; ++i) {
|
|
(void)i;
|
|
Args.push_back({ArgumentModifierIntBase(ArgumentModifier::Unmodified), nullptr});
|
|
}
|
|
ReturnValue = ReturnValueModifierIntBase(ReturnValueModifier::Unmodified);
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
setArgumentDead(unsigned ArgNo) {
|
|
Args[ArgNo].first = ArgumentModifierIntBase(ArgumentModifier::Dead);
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
setArgumentClosureProp(unsigned ArgNo, PartialApplyInst *PAI) {
|
|
auto &Info = Args[ArgNo];
|
|
Info.first = ArgumentModifierIntBase(ArgumentModifier::ClosureProp);
|
|
Info.second = PAI;
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
setArgumentClosureProp(unsigned ArgNo, ThinToThickFunctionInst *TTTFI) {
|
|
auto &Info = Args[ArgNo];
|
|
Info.first = ArgumentModifierIntBase(ArgumentModifier::ClosureProp);
|
|
Info.second = TTTFI;
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
setArgumentConstantProp(unsigned ArgNo, LiteralInst *LI) {
|
|
auto &Info = Args[ArgNo];
|
|
Info.first = ArgumentModifierIntBase(ArgumentModifier::ConstantProp);
|
|
Info.second = LI;
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
setArgumentOwnedToGuaranteed(unsigned ArgNo) {
|
|
Args[ArgNo].first |= ArgumentModifierIntBase(ArgumentModifier::OwnedToGuaranteed);
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
setArgumentSROA(unsigned ArgNo) {
|
|
Args[ArgNo].first |= ArgumentModifierIntBase(ArgumentModifier::SROA);
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
setArgumentBoxToValue(unsigned ArgNo) {
|
|
Args[ArgNo].first = ArgumentModifierIntBase(ArgumentModifier::BoxToValue);
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
setArgumentBoxToStack(unsigned ArgNo) {
|
|
Args[ArgNo].first = ArgumentModifierIntBase(ArgumentModifier::BoxToStack);
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
setReturnValueOwnedToUnowned() {
|
|
ReturnValue |= ReturnValueModifierIntBase(ReturnValueModifier::OwnedToUnowned);
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::mangleConstantProp(LiteralInst *LI) {
|
|
Mangler &M = getMangler();
|
|
|
|
// Append the prefix for constant propagation 'cp'.
|
|
M.append("cp");
|
|
|
|
// Then append the unique identifier of our literal.
|
|
switch (LI->getKind()) {
|
|
default:
|
|
llvm_unreachable("unknown literal");
|
|
case ValueKind::FunctionRefInst: {
|
|
SILFunction *F = cast<FunctionRefInst>(LI)->getReferencedFunction();
|
|
M.append("fr");
|
|
M.mangleIdentifierSymbol(F->getName());
|
|
break;
|
|
}
|
|
case ValueKind::GlobalAddrInst: {
|
|
SILGlobalVariable *G = cast<GlobalAddrInst>(LI)->getReferencedGlobal();
|
|
M.append("g");
|
|
M.mangleIdentifierSymbol(G->getName());
|
|
break;
|
|
}
|
|
case ValueKind::IntegerLiteralInst: {
|
|
APInt apint = cast<IntegerLiteralInst>(LI)->getValue();
|
|
M.append("i");
|
|
M.mangleNatural(apint);
|
|
break;
|
|
}
|
|
case ValueKind::FloatLiteralInst: {
|
|
APInt apint = cast<FloatLiteralInst>(LI)->getBits();
|
|
M.append("fl");
|
|
M.mangleNatural(apint);
|
|
break;
|
|
}
|
|
case ValueKind::StringLiteralInst: {
|
|
StringLiteralInst *SLI = cast<StringLiteralInst>(LI);
|
|
StringRef V = SLI->getValue();
|
|
|
|
assert(V.size() <= 32 && "Cannot encode string of length > 32");
|
|
|
|
llvm::SmallString<33> Str;
|
|
Str += "u";
|
|
Str += V;
|
|
M.append("se");
|
|
M.mangleNatural(APInt(32, unsigned(SLI->getEncoding())));
|
|
M.append("v");
|
|
M.mangleIdentifier(Str);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
FunctionSignatureSpecializationMangler::
|
|
mangleClosureProp(PartialApplyInst *PAI) {
|
|
Mangler &M = getMangler();
|
|
M.append("cl");
|
|
|
|
// Add in the partial applies function name if we can find one. Assert
|
|
// otherwise. The reason why this is ok to do is currently we only perform
|
|
// closure specialization if we know the function_ref in question. When this
|
|
// restriction is removed, the assert here will fire.
|
|
auto *FRI = cast<FunctionRefInst>(PAI->getCallee());
|
|
M.mangleIdentifierSymbol(FRI->getReferencedFunction()->getName());
|
|
|
|
// Then we mangle the types of the arguments that the partial apply is
|
|
// specializing.
|
|
for (auto &Op : PAI->getArgumentOperands()) {
|
|
SILType Ty = Op.get()->getType();
|
|
M.mangleType(Ty.getSwiftRValueType(), 0);
|
|
}
|
|
}
|
|
|
|
void FunctionSignatureSpecializationMangler::mangleClosureProp(
|
|
ThinToThickFunctionInst *TTTFI) {
|
|
Mangler &M = getMangler();
|
|
M.append("cl");
|
|
|
|
// Add in the partial applies function name if we can find one. Assert
|
|
// otherwise. The reason why this is ok to do is currently we only perform
|
|
// closure specialization if we know the function_ref in question. When this
|
|
// restriction is removed, the assert here will fire.
|
|
auto *FRI = cast<FunctionRefInst>(TTTFI->getCallee());
|
|
M.mangleIdentifierSymbol(FRI->getReferencedFunction()->getName());
|
|
}
|
|
|
|
void FunctionSignatureSpecializationMangler::mangleArgument(
|
|
ArgumentModifierIntBase ArgMod, NullablePtr<SILInstruction> Inst) {
|
|
if (ArgMod == ArgumentModifierIntBase(ArgumentModifier::ConstantProp)) {
|
|
mangleConstantProp(cast<LiteralInst>(Inst.get()));
|
|
return;
|
|
}
|
|
|
|
if (ArgMod == ArgumentModifierIntBase(ArgumentModifier::ClosureProp)) {
|
|
if (auto *PAI = dyn_cast<PartialApplyInst>(Inst.get())) {
|
|
mangleClosureProp(PAI);
|
|
return;
|
|
}
|
|
|
|
auto *TTTFI = cast<ThinToThickFunctionInst>(Inst.get());
|
|
mangleClosureProp(TTTFI);
|
|
return;
|
|
}
|
|
|
|
if (ArgMod == ArgumentModifierIntBase(ArgumentModifier::Unmodified)) {
|
|
M.append("n");
|
|
return;
|
|
}
|
|
|
|
if (ArgMod == ArgumentModifierIntBase(ArgumentModifier::BoxToValue)) {
|
|
M.append("i");
|
|
return;
|
|
}
|
|
|
|
if (ArgMod == ArgumentModifierIntBase(ArgumentModifier::BoxToStack)) {
|
|
M.append("k");
|
|
return;
|
|
}
|
|
|
|
bool hasSomeMod = false;
|
|
if (ArgMod & ArgumentModifierIntBase(ArgumentModifier::Dead)) {
|
|
M.append("d");
|
|
hasSomeMod = true;
|
|
}
|
|
|
|
if (ArgMod & ArgumentModifierIntBase(ArgumentModifier::OwnedToGuaranteed)) {
|
|
M.append("g");
|
|
hasSomeMod = true;
|
|
}
|
|
if (ArgMod & ArgumentModifierIntBase(ArgumentModifier::SROA)) {
|
|
M.append("s");
|
|
hasSomeMod = true;
|
|
}
|
|
|
|
assert(hasSomeMod && "Unknown modifier");
|
|
}
|
|
|
|
void FunctionSignatureSpecializationMangler::
|
|
mangleReturnValue(ReturnValueModifierIntBase RetMod) {
|
|
if (RetMod == ReturnValueModifierIntBase(ReturnValueModifier::Unmodified)) {
|
|
return;
|
|
}
|
|
|
|
if (RetMod & ReturnValueModifierIntBase(ReturnValueModifier::Dead)) {
|
|
M.append("d");
|
|
}
|
|
|
|
if (RetMod & ReturnValueModifierIntBase(ReturnValueModifier::OwnedToUnowned)) {
|
|
M.append("g");
|
|
}
|
|
}
|
|
|
|
void FunctionSignatureSpecializationMangler::mangleSpecialization() {
|
|
|
|
for (unsigned i : indices(Args)) {
|
|
ArgumentModifierIntBase ArgMod;
|
|
NullablePtr<SILInstruction> Inst;
|
|
std::tie(ArgMod, Inst) = Args[i];
|
|
mangleArgument(ArgMod, Inst);
|
|
M.append("_");
|
|
}
|
|
|
|
mangleReturnValue(ReturnValue);
|
|
}
|