Skip to content

Commit

Permalink
Merge pull request #588 from swiftwasm/master
Browse files Browse the repository at this point in the history
[pull] swiftwasm from master
  • Loading branch information
pull[bot] authored Apr 7, 2020
2 parents 64ea425 + 3a317b3 commit 6f0e43c
Show file tree
Hide file tree
Showing 34 changed files with 730 additions and 72 deletions.
6 changes: 4 additions & 2 deletions include/swift/ClangImporter/BuiltinMappedTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ MAP_BUILTIN_INTEGER_TYPE(Int, CInt)
MAP_BUILTIN_INTEGER_TYPE(Long, CLong)
MAP_BUILTIN_INTEGER_TYPE(LongLong, CLongLong)
MAP_BUILTIN_INTEGER_TYPE(Int128, CInt128)
MAP_BUILTIN_TYPE(Float, CFloat)
MAP_BUILTIN_TYPE(Double, CDouble)
MAP_BUILTIN_TYPE(Float16, CFloat16)
MAP_BUILTIN_TYPE(Half, CFloat16)
MAP_BUILTIN_TYPE(Float, CFloat)
MAP_BUILTIN_TYPE(Double, CDouble)
MAP_BUILTIN_TYPE(LongDouble, CLongDouble)

#undef MAP_BUILTIN_TYPE
Expand Down
32 changes: 31 additions & 1 deletion lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,28 @@ std::string ASTMangler::mangleSILDifferentiabilityWitnessKey(
return result;
}

// In order for the remangler to work correctly, it must agree with
// AST mangler on the substitution scheme. The AST mangler will use a
// substitution if a mangled type is identical to a previous type.
//
// In the DWARF mangling, we don't canonicalize types. Therefore, any
// two types that differ by sugar must have distinct manglings. If this
// invariant is not maintained, then demangling and remangling a type
// will no longer be idempotent.
//
// Since we don't have a distinct mangling for sugared generic
// parameter types, we must desugar them here.
static Type getTypeForDWARFMangling(Type t) {
return t.subst(
[](SubstitutableType *t) -> Type {
if (isa<GenericTypeParamType>(t))
return t->getCanonicalType();
return t;
},
MakeAbstractConformanceForGenericType(),
SubstFlags::AllowLoweredTypes);
}

std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) {
PrettyStackTraceType prettyStackTrace(Ty->getASTContext(),
"mangling type for debugger", Ty);
Expand All @@ -453,6 +475,8 @@ std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) {
OptimizeProtocolNames = false;
beginMangling();

Ty = getTypeForDWARFMangling(Ty);

if (DC)
bindGenericParameters(DC);

Expand Down Expand Up @@ -552,7 +576,9 @@ std::string ASTMangler::mangleTypeAsContextUSR(const NominalTypeDecl *type) {
std::string ASTMangler::mangleTypeAsUSR(Type Ty) {
DWARFMangling = true;
beginMangling();


Ty = getTypeForDWARFMangling(Ty);

if (auto *fnType = Ty->getAs<AnyFunctionType>()) {
appendFunction(fnType, false);
} else {
Expand Down Expand Up @@ -1130,6 +1156,10 @@ void ASTMangler::appendType(Type type, const ValueDecl *forDecl) {

case TypeKind::GenericTypeParam: {
auto paramTy = cast<GenericTypeParamType>(tybase);
// If this assertion fires, it probably means the type being mangled here
// didn't go through getTypeForDWARFMangling().
assert(paramTy->getDecl() == nullptr &&
"cannot mangle non-canonical generic parameter");
// A special mangling for the very first generic parameter. This shows up
// frequently because it corresponds to 'Self' in protocol requirement
// generic signatures.
Expand Down
7 changes: 0 additions & 7 deletions lib/Basic/Mangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,8 @@ std::string Mangler::finalize() {
Storage.clear();

#ifndef NDEBUG
/*
Verification is temporarily disabled, because of:
rdar://problem/59813007
rdar://problem/59496022
https://bugs.swift.org/browse/SR-12204
if (StringRef(result).startswith(MANGLING_PREFIX_STR))
verify(result);
*/
#endif

return result;
Expand Down
2 changes: 0 additions & 2 deletions lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,6 @@ namespace {
case clang::BuiltinType::SatUShortFract:
case clang::BuiltinType::SatUFract:
case clang::BuiltinType::SatULongFract:
case clang::BuiltinType::Half:
case clang::BuiltinType::Float16:
case clang::BuiltinType::Float128:
case clang::BuiltinType::NullPtr:
case clang::BuiltinType::Char8:
Expand Down
93 changes: 89 additions & 4 deletions lib/IRGen/LoadableByAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,14 +403,17 @@ SILParameterInfo LargeSILTypeMapper::getNewParameter(GenericEnvironment *env,
} else if (isLargeLoadableType(env, storageType, IGM)) {
if (param.getConvention() == ParameterConvention::Direct_Guaranteed)
return SILParameterInfo(storageType.getASTType(),
ParameterConvention::Indirect_In_Guaranteed);
ParameterConvention::Indirect_In_Guaranteed,
param.getDifferentiability());
else
return SILParameterInfo(storageType.getASTType(),
ParameterConvention::Indirect_In_Constant);
ParameterConvention::Indirect_In_Constant,
param.getDifferentiability());
} else {
auto newType = getNewSILType(env, storageType, IGM);
return SILParameterInfo(newType.getASTType(),
param.getConvention());
param.getConvention(),
param.getDifferentiability());
}
}

Expand Down Expand Up @@ -1704,6 +1707,9 @@ class LoadableByAddress : public SILModuleTransform {
bool fixStoreToBlockStorageInstr(SILInstruction &I,
SmallVectorImpl<SILInstruction *> &Delete);

bool recreateDifferentiabilityWitnessFunction(
SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete);

private:
llvm::SetVector<SILFunction *> modFuncs;
llvm::SetVector<SingleValueInstruction *> conversionInstrs;
Expand Down Expand Up @@ -2708,6 +2714,33 @@ bool LoadableByAddress::fixStoreToBlockStorageInstr(
return true;
}

bool LoadableByAddress::recreateDifferentiabilityWitnessFunction(
SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
auto *instr = dyn_cast<DifferentiabilityWitnessFunctionInst>(&I);
if (!instr)
return false;

// Check if we need to recreate the instruction.
auto *currIRMod = getIRGenModule()->IRGen.getGenModule(instr->getFunction());
auto resultFnTy = instr->getType().castTo<SILFunctionType>();
auto genSig = resultFnTy->getSubstGenericSignature();
GenericEnvironment *genEnv = nullptr;
if (genSig)
genEnv = genSig->getGenericEnvironment();
auto newResultFnTy =
MapperCache.getNewSILFunctionType(genEnv, resultFnTy, *currIRMod);
if (resultFnTy == newResultFnTy)
return true;

SILBuilderWithScope builder(instr);
auto *newInstr = builder.createDifferentiabilityWitnessFunction(
instr->getLoc(), instr->getWitnessKind(), instr->getWitness(),
SILType::getPrimitiveObjectType(newResultFnTy));
instr->replaceAllUsesWith(newInstr);
Delete.push_back(instr);
return true;
}

bool LoadableByAddress::recreateTupleInstr(
SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
auto *tupleInstr = dyn_cast<TupleInst>(&I);
Expand Down Expand Up @@ -2750,6 +2783,19 @@ bool LoadableByAddress::recreateConvInstr(SILInstruction &I,
auto currSILFunctionType = currSILType.castTo<SILFunctionType>();
GenericEnvironment *genEnv =
getSubstGenericEnvironment(convInstr->getFunction());
// Differentiable function conversion instructions can happen while the
// function is still generic. In that case, we must calculate the new type
// using the converted function's generic environment rather than the
// converting function's generic environment.
//
// This happens in witness thunks for default implementations of derivative
// requirements.
if (convInstr->getKind() == SILInstructionKind::DifferentiableFunctionInst ||
convInstr->getKind() == SILInstructionKind::DifferentiableFunctionExtractInst ||
convInstr->getKind() == SILInstructionKind::LinearFunctionInst ||
convInstr->getKind() == SILInstructionKind::LinearFunctionExtractInst)
if (auto genSig = currSILFunctionType->getSubstGenericSignature())
genEnv = genSig->getGenericEnvironment();
CanSILFunctionType newFnType = MapperCache.getNewSILFunctionType(
genEnv, currSILFunctionType, *currIRMod);
SILType newType = SILType::getPrimitiveObjectType(newFnType);
Expand Down Expand Up @@ -2790,6 +2836,34 @@ bool LoadableByAddress::recreateConvInstr(SILInstruction &I,
instr->getLoc(), instr->getValue(), instr->getBase());
break;
}
case SILInstructionKind::DifferentiableFunctionInst: {
auto instr = cast<DifferentiableFunctionInst>(convInstr);
newInstr = convBuilder.createDifferentiableFunction(
instr->getLoc(), instr->getParameterIndices(),
instr->getOriginalFunction(),
instr->getOptionalDerivativeFunctionPair());
break;
}
case SILInstructionKind::DifferentiableFunctionExtractInst: {
auto instr = cast<DifferentiableFunctionExtractInst>(convInstr);
// Rewrite `differentiable_function_extract` with explicit extractee type.
newInstr = convBuilder.createDifferentiableFunctionExtract(
instr->getLoc(), instr->getExtractee(), instr->getOperand(), newType);
break;
}
case SILInstructionKind::LinearFunctionInst: {
auto instr = cast<LinearFunctionInst>(convInstr);
newInstr = convBuilder.createLinearFunction(
instr->getLoc(), instr->getParameterIndices(),
instr->getOriginalFunction(), instr->getOptionalTransposeFunction());
break;
}
case SILInstructionKind::LinearFunctionExtractInst: {
auto instr = cast<LinearFunctionExtractInst>(convInstr);
newInstr = convBuilder.createLinearFunctionExtract(
instr->getLoc(), instr->getExtractee(), instr->getFunctionOperand());
break;
}
default:
llvm_unreachable("Unexpected conversion instruction");
}
Expand Down Expand Up @@ -2878,7 +2952,11 @@ void LoadableByAddress::run() {
case SILInstructionKind::ConvertEscapeToNoEscapeInst:
case SILInstructionKind::MarkDependenceInst:
case SILInstructionKind::ThinFunctionToPointerInst:
case SILInstructionKind::ThinToThickFunctionInst: {
case SILInstructionKind::ThinToThickFunctionInst:
case SILInstructionKind::DifferentiableFunctionInst:
case SILInstructionKind::LinearFunctionInst:
case SILInstructionKind::LinearFunctionExtractInst:
case SILInstructionKind::DifferentiableFunctionExtractInst: {
conversionInstrs.insert(
cast<SingleValueInstruction>(currInstr));
break;
Expand Down Expand Up @@ -2945,6 +3023,11 @@ void LoadableByAddress::run() {
if (modApplies.count(PAI) == 0) {
modApplies.insert(PAI);
}
} else if (isa<DifferentiableFunctionInst>(&I) ||
isa<LinearFunctionInst>(&I) ||
isa<DifferentiableFunctionExtractInst>(&I) ||
isa<LinearFunctionExtractInst>(&I)) {
conversionInstrs.insert(cast<SingleValueInstruction>(&I));
}
}
}
Expand Down Expand Up @@ -2988,6 +3071,8 @@ void LoadableByAddress::run() {
continue;
else if (recreateApply(I, Delete))
continue;
else if (recreateDifferentiabilityWitnessFunction(I, Delete))
continue;
else
fixStoreToBlockStorageInstr(I, Delete);
}
Expand Down
8 changes: 6 additions & 2 deletions lib/SILOptimizer/Utils/ConstantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -995,14 +995,18 @@ struct IEEESemantics {

IEEESemantics getFPSemantics(BuiltinFloatType *fpType) {
switch (fpType->getFPKind()) {
case BuiltinFloatType::IEEE16:
return IEEESemantics(16, 5, 10, false);
case BuiltinFloatType::IEEE32:
return IEEESemantics(32, 8, 23, false);
case BuiltinFloatType::IEEE64:
return IEEESemantics(64, 11, 52, false);
case BuiltinFloatType::IEEE80:
return IEEESemantics(80, 15, 63, true);
default:
llvm_unreachable("Unexpected semantics");
case BuiltinFloatType::IEEE128:
return IEEESemantics(128, 15, 112, false);
case BuiltinFloatType::PPC128:
llvm_unreachable("ppc128 is not supported");
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/TBDGen/TBDGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,7 @@ GenerateTBDRequest::evaluate(Evaluator &evaluator,
/*forcePublicDecls*/ false);

llvm::MachO::InterfaceFile file;
file.setFileType(llvm::MachO::FileType::TBD_V3);
file.setFileType(llvm::MachO::FileType::TBD_V4);
file.setApplicationExtensionSafe(
isApplicationExtensionSafe(M->getASTContext().LangOpts));
file.setInstallName(opts.InstallName);
Expand Down
5 changes: 5 additions & 0 deletions stdlib/public/SwiftShims/RuntimeShims.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ const char *_swift_stdlib_strtod_clocale(const char *nptr, double *outResult);
/// overflow.
SWIFT_RUNTIME_STDLIB_API
const char *_swift_stdlib_strtof_clocale(const char *nptr, float *outResult);
/// Call strtof_l with the C locale, swapping argument and return
/// types so we can operate consistently on Float80. Return NULL on
/// overflow.
SWIFT_RUNTIME_STDLIB_API
const char *_swift_stdlib_strtof16_clocale(const char *nptr, __fp16 *outResult);

SWIFT_RUNTIME_STDLIB_API
void _swift_stdlib_immortalize(void *obj);
Expand Down
4 changes: 4 additions & 0 deletions stdlib/public/core/CTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public typealias CLong = Int
/// The C 'long long' type.
public typealias CLongLong = Int64

/// The C '_Float16' type.
@available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *)
public typealias CFloat16 = Float16

/// The C 'float' type.
public typealias CFloat = Float

Expand Down
32 changes: 32 additions & 0 deletions stdlib/public/core/Codable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4592,6 +4592,38 @@ extension RawRepresentable where RawValue == Float, Self: Decodable {
}
}

@available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *)
extension Float16: Codable {
/// Creates a new instance by decoding from the given decoder.
///
/// This initializer throws an error if reading from the decoder fails, or
/// if the data read is corrupted or otherwise invalid.
///
/// - Parameter decoder: The decoder to read data from.
public init(from decoder: Decoder) throws {
let floatValue = try Float(from: decoder)
self = Float16(floatValue)
if isInfinite && floatValue.isFinite {
throw DecodingError.dataCorrupted(
DecodingError.Context(
codingPath: decoder.codingPath,
debugDescription: "Parsed JSON number \(floatValue) does not fit in Float16."
)
)
}
}

/// Encodes this value into the given encoder.
///
/// This function throws an error if any values are invalid for the given
/// encoder's format.
///
/// - Parameter encoder: The encoder to write data to.
public func encode(to encoder: Encoder) throws {
try Float(self).encode(to: encoder)
}
}

extension Int: Codable {
/// Creates a new instance by decoding from the given decoder.
///
Expand Down
13 changes: 11 additions & 2 deletions stdlib/public/core/FloatingPointParsing.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@ import SwiftShims

%{

allFloatBits = [32, 64, 80]
allFloatBits = [16, 32, 64, 80]

def floatName(bits):
if bits == 16:
return 'Float16'
if bits == 32:
return 'Float'
if bits == 64:
return 'Double'
if bits == 80:
return 'Float80'

cFuncSuffix2 = {32: 'f', 64: 'd', 80: 'ld'}
cFuncSuffix2 = {16: 'f16', 32: 'f', 64: 'd', 80: 'ld'}

}%

Expand All @@ -43,6 +45,9 @@ internal func _isspace_clocale(_ u: UTF16.CodeUnit) -> Bool {
% end

//===--- Parsing ----------------------------------------------------------===//
%if bits == 16:
@available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *)
%end
extension ${Self}: LosslessStringConvertible {
/// Creates a new instance from the given string.
///
Expand Down Expand Up @@ -126,6 +131,9 @@ extension ${Self}: LosslessStringConvertible {
/// is `nil`.
@inlinable
public init?<S: StringProtocol>(_ text: S) {
%if bits == 16:
self.init(Substring(text))
%else:
if #available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) {
self.init(Substring(text))
} else {
Expand All @@ -149,6 +157,7 @@ extension ${Self}: LosslessStringConvertible {
return nil
}
}
%end
}

// Caveat: This implementation used to be inlineable.
Expand Down
Loading

0 comments on commit 6f0e43c

Please sign in to comment.