mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Use real types instead of "Self" for the IR value names of local type data.
Since that's somewhat expensive, allow the generation of meaningful IR value names to be efficiently controlled in IRGen. By default, enable meaningful value names only when generating .ll output. I considered giving protocol witness tables the name T:Protocol instead of T.Protocol, but decided that I didn't want to update that many test cases.
This commit is contained in:
@@ -126,6 +126,10 @@ public:
|
|||||||
/// Whether we should embed the bitcode file.
|
/// Whether we should embed the bitcode file.
|
||||||
IRGenEmbedMode EmbedMode : 2;
|
IRGenEmbedMode EmbedMode : 2;
|
||||||
|
|
||||||
|
/// Add names to LLVM values.
|
||||||
|
unsigned HasValueNamesSetting : 1;
|
||||||
|
unsigned ValueNames : 1;
|
||||||
|
|
||||||
/// List of backend command-line options for -embed-bitcode.
|
/// List of backend command-line options for -embed-bitcode.
|
||||||
std::vector<uint8_t> CmdArgs;
|
std::vector<uint8_t> CmdArgs;
|
||||||
|
|
||||||
@@ -135,7 +139,8 @@ public:
|
|||||||
DisableLLVMARCOpts(false), DisableLLVMSLPVectorizer(false),
|
DisableLLVMARCOpts(false), DisableLLVMSLPVectorizer(false),
|
||||||
DisableFPElim(true), Playground(false),
|
DisableFPElim(true), Playground(false),
|
||||||
EmitStackPromotionChecks(false), GenerateProfile(false),
|
EmitStackPromotionChecks(false), GenerateProfile(false),
|
||||||
EmbedMode(IRGenEmbedMode::None)
|
EmbedMode(IRGenEmbedMode::None),
|
||||||
|
HasValueNamesSetting(false), ValueNames(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// Gets the name of the specified output filename.
|
/// Gets the name of the specified output filename.
|
||||||
|
|||||||
@@ -181,6 +181,12 @@ def disable_llvm_slp_vectorizer : Flag<["-"], "disable-llvm-slp-vectorizer">,
|
|||||||
def disable_llvm_verify : Flag<["-"], "disable-llvm-verify">,
|
def disable_llvm_verify : Flag<["-"], "disable-llvm-verify">,
|
||||||
HelpText<"Don't run the LLVM IR verifier.">;
|
HelpText<"Don't run the LLVM IR verifier.">;
|
||||||
|
|
||||||
|
def disable_llvm_value_names : Flag<["-"], "disable-llvm-value-names">,
|
||||||
|
HelpText<"Don't add names to local values in LLVM IR">;
|
||||||
|
|
||||||
|
def enable_llvm_value_names : Flag<["-"], "enable-llvm-value-names">,
|
||||||
|
HelpText<"Add names to local values in LLVM IR">;
|
||||||
|
|
||||||
def stack_promotion_checks : Flag<["-"], "emit-stack-promotion-checks">,
|
def stack_promotion_checks : Flag<["-"], "emit-stack-promotion-checks">,
|
||||||
HelpText<"Emit runtime checks for correct stack promotion of objects.">;
|
HelpText<"Emit runtime checks for correct stack promotion of objects.">;
|
||||||
|
|
||||||
|
|||||||
@@ -1125,6 +1125,13 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
|||||||
Opts.LinkLibraries.push_back(LinkLibrary(A->getValue(), Kind));
|
Opts.LinkLibraries.push_back(LinkLibrary(A->getValue(), Kind));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto valueNames = Args.getLastArg(OPT_disable_llvm_value_names,
|
||||||
|
OPT_enable_llvm_value_names)) {
|
||||||
|
Opts.HasValueNamesSetting = true;
|
||||||
|
Opts.ValueNames =
|
||||||
|
valueNames->getOption().matches(OPT_enable_llvm_value_names);
|
||||||
|
}
|
||||||
|
|
||||||
Opts.DisableLLVMOptzns |= Args.hasArg(OPT_disable_llvm_optzns);
|
Opts.DisableLLVMOptzns |= Args.hasArg(OPT_disable_llvm_optzns);
|
||||||
Opts.DisableLLVMARCOpts |= Args.hasArg(OPT_disable_llvm_arc_opts);
|
Opts.DisableLLVMARCOpts |= Args.hasArg(OPT_disable_llvm_arc_opts);
|
||||||
Opts.DisableLLVMSLPVectorizer |= Args.hasArg(OPT_disable_llvm_slp_vectorizer);
|
Opts.DisableLLVMSLPVectorizer |= Args.hasArg(OPT_disable_llvm_slp_vectorizer);
|
||||||
|
|||||||
@@ -277,20 +277,6 @@ static void setMetadataRef(IRGenFunction &IGF,
|
|||||||
IGF.setUnscopedLocalTypeData(CanType(archetype),
|
IGF.setUnscopedLocalTypeData(CanType(archetype),
|
||||||
LocalTypeDataKind::forTypeMetadata(),
|
LocalTypeDataKind::forTypeMetadata(),
|
||||||
metadata);
|
metadata);
|
||||||
|
|
||||||
// Create a shadow copy of the metadata in an alloca for the debug info.
|
|
||||||
StringRef Name = metadata->getName();
|
|
||||||
if (!IGF.IGM.Opts.Optimize) {
|
|
||||||
auto Alloca = IGF.createAlloca(metadata->getType(),
|
|
||||||
IGF.IGM.getPointerAlignment(), Name);
|
|
||||||
IGF.Builder.CreateAlignedStore(metadata, Alloca.getAddress(),
|
|
||||||
IGF.IGM.getPointerAlignment().getValue());
|
|
||||||
metadata = Alloca.getAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit debug info for the metadata.
|
|
||||||
if (IGF.IGM.DebugInfo)
|
|
||||||
IGF.IGM.DebugInfo->emitTypeMetadata(IGF, metadata, Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setWitnessTable(IRGenFunction &IGF,
|
static void setWitnessTable(IRGenFunction &IGF,
|
||||||
@@ -311,9 +297,7 @@ void IRGenFunction::bindArchetype(ArchetypeType *archetype,
|
|||||||
llvm::Value *metadata,
|
llvm::Value *metadata,
|
||||||
ArrayRef<llvm::Value*> wtables) {
|
ArrayRef<llvm::Value*> wtables) {
|
||||||
// Set the metadata pointer.
|
// Set the metadata pointer.
|
||||||
bool setNames = !archetype->getOpenedExistentialType();
|
setTypeMetadataName(IGM, metadata, CanType(archetype));
|
||||||
if (setNames)
|
|
||||||
metadata->setName(archetype->getFullName());
|
|
||||||
setMetadataRef(*this, archetype, metadata);
|
setMetadataRef(*this, archetype, metadata);
|
||||||
|
|
||||||
// Set the protocol witness tables.
|
// Set the protocol witness tables.
|
||||||
@@ -324,10 +308,7 @@ void IRGenFunction::bindArchetype(ArchetypeType *archetype,
|
|||||||
if (!Lowering::TypeConverter::protocolRequiresWitnessTable(proto))
|
if (!Lowering::TypeConverter::protocolRequiresWitnessTable(proto))
|
||||||
continue;
|
continue;
|
||||||
auto wtable = wtables[wtableI++];
|
auto wtable = wtables[wtableI++];
|
||||||
if (setNames) {
|
setProtocolWitnessTableName(IGM, wtable, CanType(archetype), proto);
|
||||||
wtable->setName(Twine(archetype->getFullName()) + "." +
|
|
||||||
proto->getName().str());
|
|
||||||
}
|
|
||||||
setWitnessTable(*this, archetype, i, wtable);
|
setWitnessTable(*this, archetype, i, wtable);
|
||||||
}
|
}
|
||||||
assert(wtableI == wtables.size());
|
assert(wtableI == wtables.size());
|
||||||
|
|||||||
@@ -102,8 +102,7 @@ namespace {
|
|||||||
/// Given the address of an existential object, load its witness table.
|
/// Given the address of an existential object, load its witness table.
|
||||||
llvm::Value *loadWitnessTable(IRGenFunction &IGF, Address addr,
|
llvm::Value *loadWitnessTable(IRGenFunction &IGF, Address addr,
|
||||||
unsigned which) const {
|
unsigned which) const {
|
||||||
return IGF.Builder.CreateLoad(projectWitnessTable(IGF, addr, which),
|
return IGF.Builder.CreateLoad(projectWitnessTable(IGF, addr, which));
|
||||||
"witness-table");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the address of an existential object, drill down to the
|
/// Given the address of an existential object, drill down to the
|
||||||
@@ -115,8 +114,7 @@ namespace {
|
|||||||
/// Given the address of an existential object, load its metadata
|
/// Given the address of an existential object, load its metadata
|
||||||
/// object.
|
/// object.
|
||||||
llvm::Value *loadMetadataRef(IRGenFunction &IGF, Address addr) {
|
llvm::Value *loadMetadataRef(IRGenFunction &IGF, Address addr) {
|
||||||
return IGF.Builder.CreateLoad(projectMetadataRef(IGF, addr),
|
return IGF.Builder.CreateLoad(projectMetadataRef(IGF, addr));
|
||||||
addr.getAddress()->getName() + ".metadata");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2514,6 +2514,7 @@ irgen::emitFieldTypeAccessor(IRGenModule &IGM,
|
|||||||
|
|
||||||
CanType formalType = type->getDeclaredTypeInContext()->getCanonicalType();
|
CanType formalType = type->getDeclaredTypeInContext()->getCanonicalType();
|
||||||
llvm::Value *metadata = IGF.collectParameters().claimNext();
|
llvm::Value *metadata = IGF.collectParameters().claimNext();
|
||||||
|
setTypeMetadataName(IGM, metadata, formalType);
|
||||||
|
|
||||||
// Get the address at which the field type vector reference should be
|
// Get the address at which the field type vector reference should be
|
||||||
// cached.
|
// cached.
|
||||||
@@ -3719,7 +3720,7 @@ emitInvariantLoadFromMetadataAtIndex(IRGenFunction &IGF,
|
|||||||
llvm::Value *metadata,
|
llvm::Value *metadata,
|
||||||
int index,
|
int index,
|
||||||
llvm::Type *objectTy,
|
llvm::Type *objectTy,
|
||||||
const llvm::Twine &suffix = "") {
|
const Twine &suffix = Twine::createNull()) {
|
||||||
auto result = emitLoadFromMetadataAtIndex(IGF, metadata, index, objectTy,
|
auto result = emitLoadFromMetadataAtIndex(IGF, metadata, index, objectTy,
|
||||||
suffix);
|
suffix);
|
||||||
IGF.setInvariantLoad(result);
|
IGF.setInvariantLoad(result);
|
||||||
@@ -4128,7 +4129,8 @@ static llvm::Value *emitLoadOfHeapMetadataRef(IRGenFunction &IGF,
|
|||||||
|
|
||||||
auto metadata = IGF.Builder.CreateLoad(Address(slot,
|
auto metadata = IGF.Builder.CreateLoad(Address(slot,
|
||||||
IGF.IGM.getPointerAlignment()));
|
IGF.IGM.getPointerAlignment()));
|
||||||
metadata->setName(llvm::Twine(object->getName()) + ".metadata");
|
if (IGF.IGM.EnableValueNames && object->hasName())
|
||||||
|
metadata->setName(llvm::Twine(object->getName()) + ".metadata");
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,43 @@
|
|||||||
using namespace swift;
|
using namespace swift;
|
||||||
using namespace irgen;
|
using namespace irgen;
|
||||||
|
|
||||||
|
static bool shouldSetName(IRGenModule &IGM, llvm::Value *value, CanType type) {
|
||||||
|
// If value names are globally disabled, honor that.
|
||||||
|
if (!IGM.EnableValueNames) return false;
|
||||||
|
|
||||||
|
// Suppress value names for values with opened existentials.
|
||||||
|
if (type->hasOpenedExistential()) return false;
|
||||||
|
|
||||||
|
// If the value already has a name, honor that.
|
||||||
|
if (value->hasName()) return false;
|
||||||
|
|
||||||
|
// Only do this for local values.
|
||||||
|
return (isa<llvm::Instruction>(value) || isa<llvm::Argument>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void irgen::setTypeMetadataName(IRGenModule &IGM, llvm::Value *metadata,
|
||||||
|
CanType type) {
|
||||||
|
if (!shouldSetName(IGM, metadata, type)) return;
|
||||||
|
|
||||||
|
SmallString<128> name; {
|
||||||
|
llvm::raw_svector_ostream out(name);
|
||||||
|
type.print(out);
|
||||||
|
}
|
||||||
|
metadata->setName(type->getString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void irgen::setProtocolWitnessTableName(IRGenModule &IGM, llvm::Value *wtable,
|
||||||
|
CanType type,
|
||||||
|
ProtocolDecl *requirement) {
|
||||||
|
if (!shouldSetName(IGM, wtable, type)) return;
|
||||||
|
|
||||||
|
SmallString<128> name; {
|
||||||
|
llvm::raw_svector_ostream out(name);
|
||||||
|
type.print(out);
|
||||||
|
out << '.' << requirement->getNameStr();
|
||||||
|
}
|
||||||
|
wtable->setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/// A concrete witness table, together with its known layout.
|
/// A concrete witness table, together with its known layout.
|
||||||
@@ -1886,10 +1923,11 @@ getAssociatedTypeMetadataAccessFunction(AssociatedTypeDecl *requirement,
|
|||||||
Explosion parameters = IGF.collectParameters();
|
Explosion parameters = IGF.collectParameters();
|
||||||
|
|
||||||
llvm::Value *self = parameters.claimNext();
|
llvm::Value *self = parameters.claimNext();
|
||||||
self->setName("Self");
|
setTypeMetadataName(IGM, self, ConcreteType);
|
||||||
|
|
||||||
Address destTable(parameters.claimNext(), IGM.getPointerAlignment());
|
Address destTable(parameters.claimNext(), IGM.getPointerAlignment());
|
||||||
destTable.getAddress()->setName("wtable");
|
setProtocolWitnessTableName(IGM, destTable.getAddress(), ConcreteType,
|
||||||
|
requirement->getProtocol());
|
||||||
|
|
||||||
// If the associated type is directly fulfillable from the type,
|
// If the associated type is directly fulfillable from the type,
|
||||||
// we don't need a cache entry.
|
// we don't need a cache entry.
|
||||||
@@ -1968,13 +2006,16 @@ getAssociatedTypeWitnessTableAccessFunction(AssociatedTypeDecl *requirement,
|
|||||||
Explosion parameters = IGF.collectParameters();
|
Explosion parameters = IGF.collectParameters();
|
||||||
|
|
||||||
llvm::Value *associatedTypeMetadata = parameters.claimNext();
|
llvm::Value *associatedTypeMetadata = parameters.claimNext();
|
||||||
associatedTypeMetadata->setName(Twine("Self.") + requirement->getNameStr());
|
if (IGM.EnableValueNames)
|
||||||
|
associatedTypeMetadata->setName(Twine(ConcreteType->getString())
|
||||||
|
+ "." + requirement->getNameStr());
|
||||||
|
|
||||||
llvm::Value *self = parameters.claimNext();
|
llvm::Value *self = parameters.claimNext();
|
||||||
self->setName("Self");
|
setTypeMetadataName(IGM, self, ConcreteType);
|
||||||
|
|
||||||
Address destTable(parameters.claimNext(), IGM.getPointerAlignment());
|
Address destTable(parameters.claimNext(), IGM.getPointerAlignment());
|
||||||
destTable.getAddress()->setName("wtable");
|
setProtocolWitnessTableName(IGM, destTable.getAddress(), ConcreteType,
|
||||||
|
requirement->getProtocol());
|
||||||
|
|
||||||
const ConformanceInfo *conformanceI = nullptr;
|
const ConformanceInfo *conformanceI = nullptr;
|
||||||
if (associatedConformance.isConcrete()) {
|
if (associatedConformance.isConcrete()) {
|
||||||
@@ -2944,7 +2985,7 @@ namespace {
|
|||||||
CanType argTy = getArgTypeInContext(source.getParamIndex());
|
CanType argTy = getArgTypeInContext(source.getParamIndex());
|
||||||
|
|
||||||
llvm::Value *metatype = in.claimNext();
|
llvm::Value *metatype = in.claimNext();
|
||||||
metatype->setName("Self");
|
setTypeMetadataName(IGF.IGM, metatype, argTy);
|
||||||
|
|
||||||
// Mark this as the cached metatype for the l-value's object type.
|
// Mark this as the cached metatype for the l-value's object type.
|
||||||
IGF.setUnscopedLocalTypeData(argTy, LocalTypeDataKind::forTypeMetadata(),
|
IGF.setUnscopedLocalTypeData(argTy, LocalTypeDataKind::forTypeMetadata(),
|
||||||
@@ -2959,6 +3000,7 @@ namespace {
|
|||||||
|
|
||||||
// Mark this as the cached metatype for Self.
|
// Mark this as the cached metatype for Self.
|
||||||
CanType argTy = getArgTypeInContext(FnType->getParameters().size() - 1);
|
CanType argTy = getArgTypeInContext(FnType->getParameters().size() - 1);
|
||||||
|
setTypeMetadataName(IGF.IGM, metadata, argTy);
|
||||||
IGF.setUnscopedLocalTypeData(argTy,
|
IGF.setUnscopedLocalTypeData(argTy,
|
||||||
LocalTypeDataKind::forTypeMetadata(), metadata);
|
LocalTypeDataKind::forTypeMetadata(), metadata);
|
||||||
return metadata;
|
return metadata;
|
||||||
@@ -3173,6 +3215,7 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF,
|
|||||||
|
|
||||||
if (source) {
|
if (source) {
|
||||||
source = emitArgumentMetadataRef(IGF, generic->getDecl(), index, source);
|
source = emitArgumentMetadataRef(IGF, generic->getDecl(), index, source);
|
||||||
|
setTypeMetadataName(IGF.IGM, source, sourceKey.Type);
|
||||||
}
|
}
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
@@ -3191,9 +3234,10 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF,
|
|||||||
sourceKey.Kind = LocalTypeDataKind::forProtocolWitnessTable(conformance);
|
sourceKey.Kind = LocalTypeDataKind::forProtocolWitnessTable(conformance);
|
||||||
|
|
||||||
if (source) {
|
if (source) {
|
||||||
|
auto protocol = conformance.getRequirement();
|
||||||
source = emitArgumentWitnessTableRef(IGF, generic->getDecl(), argIndex,
|
source = emitArgumentWitnessTableRef(IGF, generic->getDecl(), argIndex,
|
||||||
conformance.getRequirement(),
|
protocol, source);
|
||||||
source);
|
setProtocolWitnessTableName(IGF.IGM, source, sourceKey.Type, protocol);
|
||||||
}
|
}
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
@@ -3212,6 +3256,7 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF,
|
|||||||
|
|
||||||
if (source) {
|
if (source) {
|
||||||
source = emitParentMetadataRef(IGF, nominalDecl, source);
|
source = emitParentMetadataRef(IGF, nominalDecl, source);
|
||||||
|
setTypeMetadataName(IGF.IGM, source, sourceKey.Type);
|
||||||
}
|
}
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
@@ -3240,6 +3285,8 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF,
|
|||||||
source = emitInvariantLoadOfOpaqueWitness(IGF, source,
|
source = emitInvariantLoadOfOpaqueWitness(IGF, source,
|
||||||
entry.getOutOfLineBaseIndex());
|
entry.getOutOfLineBaseIndex());
|
||||||
source = IGF.Builder.CreateBitCast(source, IGF.IGM.WitnessTablePtrTy);
|
source = IGF.Builder.CreateBitCast(source, IGF.IGM.WitnessTablePtrTy);
|
||||||
|
setProtocolWitnessTableName(IGF.IGM, source, sourceKey.Type,
|
||||||
|
inheritedProtocol);
|
||||||
}
|
}
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
@@ -3282,7 +3329,6 @@ static void getArgAsLocalSelfTypeMetadata(IRGenFunction &IGF,
|
|||||||
llvm::Function::arg_iterator &it,
|
llvm::Function::arg_iterator &it,
|
||||||
CanType abstractType) {
|
CanType abstractType) {
|
||||||
llvm::Value *arg = &*it++;
|
llvm::Value *arg = &*it++;
|
||||||
arg->setName("Self");
|
|
||||||
assert(arg->getType() == IGF.IGM.TypeMetadataPtrTy &&
|
assert(arg->getType() == IGF.IGM.TypeMetadataPtrTy &&
|
||||||
"Self argument is not a type?!");
|
"Self argument is not a type?!");
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,13 @@ namespace irgen {
|
|||||||
class IRGenModule;
|
class IRGenModule;
|
||||||
class ProtocolInfo;
|
class ProtocolInfo;
|
||||||
class TypeInfo;
|
class TypeInfo;
|
||||||
|
|
||||||
|
/// Set an LLVM value name for the given type metadata.
|
||||||
|
void setTypeMetadataName(IRGenModule &IGM, llvm::Value *value, CanType type);
|
||||||
|
|
||||||
|
/// Set an LLVM value name for the given protocol witness table.
|
||||||
|
void setProtocolWitnessTableName(IRGenModule &IGM, llvm::Value *value,
|
||||||
|
CanType type, ProtocolDecl *protocol);
|
||||||
|
|
||||||
/// Extract the method pointer from an archetype's witness table
|
/// Extract the method pointer from an archetype's witness table
|
||||||
/// as a function value.
|
/// as a function value.
|
||||||
|
|||||||
@@ -131,6 +131,15 @@ IRGenModule::IRGenModule(IRGenModuleDispatcher &dispatcher, SourceFile *SF,
|
|||||||
Types(*new TypeConverter(*this))
|
Types(*new TypeConverter(*this))
|
||||||
{
|
{
|
||||||
dispatcher.addGenModule(SF, this);
|
dispatcher.addGenModule(SF, this);
|
||||||
|
|
||||||
|
// If the command line contains an explicit request about whether to add
|
||||||
|
// LLVM value names, honor it. Otherwise, add value names only if the
|
||||||
|
// final result is textual LLVM assembly.
|
||||||
|
if (Opts.HasValueNamesSetting) {
|
||||||
|
EnableValueNames = Opts.ValueNames;
|
||||||
|
} else {
|
||||||
|
EnableValueNames = (Opts.OutputKind == IRGenOutputKind::LLVMAssembly);
|
||||||
|
}
|
||||||
|
|
||||||
VoidTy = llvm::Type::getVoidTy(getLLVMContext());
|
VoidTy = llvm::Type::getVoidTy(getLLVMContext());
|
||||||
Int1Ty = llvm::Type::getInt1Ty(getLLVMContext());
|
Int1Ty = llvm::Type::getInt1Ty(getLLVMContext());
|
||||||
|
|||||||
@@ -322,6 +322,9 @@ public:
|
|||||||
/// Does the current target require Objective-C interoperation?
|
/// Does the current target require Objective-C interoperation?
|
||||||
bool ObjCInterop = true;
|
bool ObjCInterop = true;
|
||||||
|
|
||||||
|
/// Should we add value names to local IR values?
|
||||||
|
bool EnableValueNames = false;
|
||||||
|
|
||||||
llvm::Type *VoidTy; /// void (usually {})
|
llvm::Type *VoidTy; /// void (usually {})
|
||||||
llvm::IntegerType *Int1Ty; /// i1
|
llvm::IntegerType *Int1Ty; /// i1
|
||||||
llvm::IntegerType *Int8Ty; /// i8
|
llvm::IntegerType *Int8Ty; /// i8
|
||||||
|
|||||||
@@ -18,8 +18,11 @@
|
|||||||
#include "LocalTypeData.h"
|
#include "LocalTypeData.h"
|
||||||
#include "Fulfillment.h"
|
#include "Fulfillment.h"
|
||||||
#include "GenMeta.h"
|
#include "GenMeta.h"
|
||||||
|
#include "GenProto.h"
|
||||||
|
#include "IRGenDebugInfo.h"
|
||||||
#include "IRGenFunction.h"
|
#include "IRGenFunction.h"
|
||||||
#include "IRGenModule.h"
|
#include "IRGenModule.h"
|
||||||
|
#include "swift/AST/IRGenOptions.h"
|
||||||
#include "swift/SIL/SILModule.h"
|
#include "swift/SIL/SILModule.h"
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
@@ -176,8 +179,37 @@ LocalTypeDataCache::AbstractCacheEntry::follow(IRGenFunction &IGF,
|
|||||||
llvm_unreachable("bad source kind");
|
llvm_unreachable("bad source kind");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void maybeEmitDebugInfoForLocalTypeData(IRGenFunction &IGF,
|
||||||
|
LocalTypeDataKey key,
|
||||||
|
llvm::Value *data) {
|
||||||
|
// Only if debug info is enabled.
|
||||||
|
if (!IGF.IGM.DebugInfo) return;
|
||||||
|
|
||||||
|
// Only for type metadata.
|
||||||
|
if (key.Kind != LocalTypeDataKind::forTypeMetadata()) return;
|
||||||
|
|
||||||
|
// Only for archetypes, and not for opened archetypes.
|
||||||
|
auto type = dyn_cast<ArchetypeType>(key.Type);
|
||||||
|
if (!type) return;
|
||||||
|
if (type->getOpenedExistentialType()) return;
|
||||||
|
|
||||||
|
// At -O0, create an alloca to keep the type alive.
|
||||||
|
auto name = type->getFullName();
|
||||||
|
if (!IGF.IGM.Opts.Optimize) {
|
||||||
|
auto temp = IGF.createAlloca(data->getType(), IGF.IGM.getPointerAlignment(),
|
||||||
|
name);
|
||||||
|
IGF.Builder.CreateStore(data, temp);
|
||||||
|
data = temp.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit debug info for the metadata.
|
||||||
|
IGF.IGM.DebugInfo->emitTypeMetadata(IGF, data, name);
|
||||||
|
}
|
||||||
|
|
||||||
void IRGenFunction::setScopedLocalTypeData(LocalTypeDataKey key,
|
void IRGenFunction::setScopedLocalTypeData(LocalTypeDataKey key,
|
||||||
llvm::Value *data) {
|
llvm::Value *data) {
|
||||||
|
maybeEmitDebugInfoForLocalTypeData(*this, key, data);
|
||||||
|
|
||||||
// Register with the active ConditionalDominanceScope if necessary.
|
// Register with the active ConditionalDominanceScope if necessary.
|
||||||
bool isConditional = isConditionalDominancePoint();
|
bool isConditional = isConditionalDominancePoint();
|
||||||
if (isConditional) {
|
if (isConditional) {
|
||||||
@@ -190,6 +222,8 @@ void IRGenFunction::setScopedLocalTypeData(LocalTypeDataKey key,
|
|||||||
|
|
||||||
void IRGenFunction::setUnscopedLocalTypeData(LocalTypeDataKey key,
|
void IRGenFunction::setUnscopedLocalTypeData(LocalTypeDataKey key,
|
||||||
llvm::Value *data) {
|
llvm::Value *data) {
|
||||||
|
maybeEmitDebugInfoForLocalTypeData(*this, key, data);
|
||||||
|
|
||||||
// This is supportable, but it would require ensuring that we add the
|
// This is supportable, but it would require ensuring that we add the
|
||||||
// entry after any conditional entries; otherwise the stack discipline
|
// entry after any conditional entries; otherwise the stack discipline
|
||||||
// will get messed up.
|
// will get messed up.
|
||||||
@@ -204,6 +238,7 @@ void IRGenFunction::bindLocalTypeDataFromTypeMetadata(CanType type,
|
|||||||
llvm::Value *metadata) {
|
llvm::Value *metadata) {
|
||||||
// Remember that we have this type metadata concretely.
|
// Remember that we have this type metadata concretely.
|
||||||
if (isExact) {
|
if (isExact) {
|
||||||
|
if (!metadata->hasName()) setTypeMetadataName(IGM, metadata, type);
|
||||||
setScopedLocalTypeData(type, LocalTypeDataKind::forTypeMetadata(), metadata);
|
setScopedLocalTypeData(type, LocalTypeDataKind::forTypeMetadata(), metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,9 @@ public:
|
|||||||
bool operator==(LocalTypeDataKind other) const {
|
bool operator==(LocalTypeDataKind other) const {
|
||||||
return Value == other.Value;
|
return Value == other.Value;
|
||||||
}
|
}
|
||||||
|
bool operator!=(LocalTypeDataKind other) const {
|
||||||
|
return Value != other.Value;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class LocalTypeDataKey {
|
class LocalTypeDataKey {
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ class AClass : AProtocol {
|
|||||||
// CHECK: define hidden void @_TF17ProtocolContainer3foo
|
// CHECK: define hidden void @_TF17ProtocolContainer3foo
|
||||||
// CHECK-NEXT: entry:
|
// CHECK-NEXT: entry:
|
||||||
// CHECK: [[XADDR:[%].*]] = alloca %P17ProtocolContainer9AProtocol_*, align {{(4|8)}}
|
// CHECK: [[XADDR:[%].*]] = alloca %P17ProtocolContainer9AProtocol_*, align {{(4|8)}}
|
||||||
// CHECK: %.metadata1 = alloca %swift.type*, align {{(4|8)}}
|
|
||||||
// CHECK: store %P17ProtocolContainer9AProtocol_* %0, %P17ProtocolContainer9AProtocol_** [[XADDR]], align {{(4|8)}}
|
// CHECK: store %P17ProtocolContainer9AProtocol_* %0, %P17ProtocolContainer9AProtocol_** [[XADDR]], align {{(4|8)}}
|
||||||
// CHECK: call void @llvm.dbg.declare(metadata %P17ProtocolContainer9AProtocol_** [[XADDR]], metadata ![[XMD:.*]], metadata !{{[0-9]+}})
|
// CHECK: call void @llvm.dbg.declare(metadata %P17ProtocolContainer9AProtocol_** [[XADDR]], metadata ![[XMD:.*]], metadata !{{[0-9]+}})
|
||||||
// CHECK-NOT: !DILocalVariable({{.*}} name: "x"
|
// CHECK-NOT: !DILocalVariable({{.*}} name: "x"
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ struct SomeWeak {
|
|||||||
// CHECK: @_TwtTV21array_value_witnesses8SomeWeak
|
// CHECK: @_TwtTV21array_value_witnesses8SomeWeak
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden void @_TwXxV21array_value_witnesses8SomeWeak
|
// CHECK-LABEL: define linkonce_odr hidden void @_TwXxV21array_value_witnesses8SomeWeak
|
||||||
// CHECK: (%swift.opaque* [[ARRAY_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %Self) {{.*}} {
|
// CHECK: (%swift.opaque* [[ARRAY_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %SomeWeak) {{.*}} {
|
||||||
// CHECK: [[BEGIN:%.*]] = bitcast %swift.opaque* [[ARRAY_PTR]] to [[SOMEWEAK:%V21array_value_witnesses8SomeWeak]]*
|
// CHECK: [[BEGIN:%.*]] = bitcast %swift.opaque* [[ARRAY_PTR]] to [[SOMEWEAK:%V21array_value_witnesses8SomeWeak]]*
|
||||||
// CHECK: br label %iter
|
// CHECK: br label %iter
|
||||||
// CHECK: iter:
|
// CHECK: iter:
|
||||||
@@ -68,7 +68,7 @@ struct SomeWeak {
|
|||||||
// CHECK: ret
|
// CHECK: ret
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwCcV21array_value_witnesses8SomeWeak
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwCcV21array_value_witnesses8SomeWeak
|
||||||
// CHECK: (%swift.opaque* [[DEST_PTR:%.*]], %swift.opaque* [[SRC_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %Self) {{.*}} {
|
// CHECK: (%swift.opaque* [[DEST_PTR:%.*]], %swift.opaque* [[SRC_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %SomeWeak) {{.*}} {
|
||||||
// CHECK: [[DEST_BEGIN:%.*]] = bitcast %swift.opaque* [[DEST_PTR]] to [[SOMEWEAK]]*
|
// CHECK: [[DEST_BEGIN:%.*]] = bitcast %swift.opaque* [[DEST_PTR]] to [[SOMEWEAK]]*
|
||||||
// CHECK: [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
|
// CHECK: [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
|
||||||
// CHECK: br label %iter
|
// CHECK: br label %iter
|
||||||
@@ -90,7 +90,7 @@ struct SomeWeak {
|
|||||||
// CHECK: ret
|
// CHECK: ret
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwTtV21array_value_witnesses8SomeWeak
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwTtV21array_value_witnesses8SomeWeak
|
||||||
// CHECK: (%swift.opaque* [[DEST_PTR:%.*]], %swift.opaque* [[SRC_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %Self) {{.*}} {
|
// CHECK: (%swift.opaque* [[DEST_PTR:%.*]], %swift.opaque* [[SRC_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %SomeWeak) {{.*}} {
|
||||||
// CHECK: [[DEST_BEGIN:%.*]] = bitcast %swift.opaque* [[DEST_PTR]] to [[SOMEWEAK]]*
|
// CHECK: [[DEST_BEGIN:%.*]] = bitcast %swift.opaque* [[DEST_PTR]] to [[SOMEWEAK]]*
|
||||||
// CHECK: [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
|
// CHECK: [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
|
||||||
// CHECK: br label %iter
|
// CHECK: br label %iter
|
||||||
@@ -112,7 +112,7 @@ struct SomeWeak {
|
|||||||
// CHECK: ret
|
// CHECK: ret
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtTV21array_value_witnesses8SomeWeak
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtTV21array_value_witnesses8SomeWeak
|
||||||
// CHECK: (%swift.opaque* [[DEST_PTR:%.*]], %swift.opaque* [[SRC_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %Self) {{.*}} {
|
// CHECK: (%swift.opaque* [[DEST_PTR:%.*]], %swift.opaque* [[SRC_PTR:%.*]], [[WORD:i[0-9]+]] [[COUNT:%.*]], %swift.type* %SomeWeak) {{.*}} {
|
||||||
// CHECK: [[DEST_BEGIN:%.*]] = bitcast %swift.opaque* [[DEST_PTR]] to [[SOMEWEAK]]*
|
// CHECK: [[DEST_BEGIN:%.*]] = bitcast %swift.opaque* [[DEST_PTR]] to [[SOMEWEAK]]*
|
||||||
// CHECK: [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
|
// CHECK: [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
|
||||||
// CHECK: [[DEST_END:%.*]] = getelementptr inbounds [[SOMEWEAK]], [[SOMEWEAK]]* [[DEST_BEGIN]], [[WORD]] [[COUNT]]
|
// CHECK: [[DEST_END:%.*]] = getelementptr inbounds [[SOMEWEAK]], [[SOMEWEAK]]* [[DEST_BEGIN]], [[WORD]] [[COUNT]]
|
||||||
|
|||||||
@@ -49,22 +49,22 @@ struct Fulfilled<T : protocol<P, Q> > : Assocked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Associated type metadata access function for Fulfilled.Assoc.
|
// Associated type metadata access function for Fulfilled.Assoc.
|
||||||
// CHECK-LABEL: define internal %swift.type* @_TWtuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5Assoc(%swift.type* %Self, i8** %wtable)
|
// CHECK-LABEL: define internal %swift.type* @_TWtuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5Assoc(%swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
|
||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type**
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Fulfilled<T>" to %swift.type**
|
||||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 3
|
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 3
|
||||||
// CHECK-NEXT: [[T2:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
|
// CHECK-NEXT: [[T2:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
|
||||||
// CHECK-NEXT: ret %swift.type* [[T2]]
|
// CHECK-NEXT: ret %swift.type* [[T2]]
|
||||||
|
|
||||||
// Associated type witness table access function for Fulfilled.Assoc : P.
|
// Associated type witness table access function for Fulfilled.Assoc : P.
|
||||||
// CHECK-LABEL: define internal i8** @_TWTuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5AssocPS_1P_(%swift.type* %Self.Assoc, %swift.type* %Self, i8** %wtable)
|
// CHECK-LABEL: define internal i8** @_TWTuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5AssocPS_1P_(%swift.type* %"Fulfilled<T>.Assoc", %swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
|
||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to i8***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Fulfilled<T>" to i8***
|
||||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 4
|
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 4
|
||||||
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load
|
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load
|
||||||
// CHECK-NEXT: ret i8** [[T2]]
|
// CHECK-NEXT: ret i8** [[T2]]
|
||||||
|
|
||||||
// Associated type witness table access function for Fulfilled.Assoc : Q.
|
// Associated type witness table access function for Fulfilled.Assoc : Q.
|
||||||
// CHECK-LABEL: define internal i8** @_TWTuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5AssocPS_1Q_(%swift.type* %Self.Assoc, %swift.type* %Self, i8** %wtable)
|
// CHECK-LABEL: define internal i8** @_TWTuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5AssocPS_1Q_(%swift.type* %"Fulfilled<T>.Assoc", %swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
|
||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to i8***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Fulfilled<T>" to i8***
|
||||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 5
|
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 5
|
||||||
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load
|
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load
|
||||||
// CHECK-NEXT: ret i8** [[T2]]
|
// CHECK-NEXT: ret i8** [[T2]]
|
||||||
@@ -90,9 +90,9 @@ struct Computed<T, U> : Assocked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Associated type metadata access function for Computed.Assoc.
|
// Associated type metadata access function for Computed.Assoc.
|
||||||
// CHECK-LABEL: define internal %swift.type* @_TWtu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_5Assoc(%swift.type* %Self, i8** %wtable)
|
// CHECK-LABEL: define internal %swift.type* @_TWtu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_5Assoc(%swift.type* %"Computed<T, U>", i8** %"Computed<T, U>.Assocked")
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** %wtable, i32 3
|
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** %"Computed<T, U>.Assocked", i32 3
|
||||||
// CHECK-NEXT: [[CACHE:%.*]] = bitcast i8** [[T0]] to %swift.type**
|
// CHECK-NEXT: [[CACHE:%.*]] = bitcast i8** [[T0]] to %swift.type**
|
||||||
// CHECK-NEXT: [[CACHE_RESULT:%.*]] = load %swift.type*, %swift.type** [[CACHE]], align 8
|
// CHECK-NEXT: [[CACHE_RESULT:%.*]] = load %swift.type*, %swift.type** [[CACHE]], align 8
|
||||||
// CHECK-NEXT: [[T1:%.*]] = icmp eq %swift.type* [[CACHE_RESULT]], null
|
// CHECK-NEXT: [[T1:%.*]] = icmp eq %swift.type* [[CACHE_RESULT]], null
|
||||||
@@ -101,10 +101,10 @@ struct Computed<T, U> : Assocked {
|
|||||||
// CHECK-NEXT: [[T0:%.*]] = phi %swift.type* [ [[CACHE_RESULT]], %entry ], [ [[FETCH_RESULT:%.*]], %fetch ]
|
// CHECK-NEXT: [[T0:%.*]] = phi %swift.type* [ [[CACHE_RESULT]], %entry ], [ [[FETCH_RESULT:%.*]], %fetch ]
|
||||||
// CHECK-NEXT: ret %swift.type* [[T0]]
|
// CHECK-NEXT: ret %swift.type* [[T0]]
|
||||||
// CHECK: fetch:
|
// CHECK: fetch:
|
||||||
// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type**
|
// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* %"Computed<T, U>" to %swift.type**
|
||||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 3
|
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 3
|
||||||
// CHECK-NEXT: [[T:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
|
// CHECK-NEXT: [[T:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
|
||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type**
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Computed<T, U>" to %swift.type**
|
||||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 4
|
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 4
|
||||||
// CHECK-NEXT: [[U:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
|
// CHECK-NEXT: [[U:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
|
||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T]] to i8*
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T]] to i8*
|
||||||
|
|||||||
@@ -198,8 +198,7 @@ public class MyResilientChild : MyResilientParent {
|
|||||||
// FIXME: we could eliminate the unnecessary isa load by lazily emitting
|
// FIXME: we could eliminate the unnecessary isa load by lazily emitting
|
||||||
// metadata sources in EmitPolymorphicParameters
|
// metadata sources in EmitPolymorphicParameters
|
||||||
|
|
||||||
// CHECK: [[T_BOX:%.*]] = alloca %swift.type*
|
// CHECK: %T = load
|
||||||
// CHECK: store {{.*}}, %swift.type** [[T_BOX]]
|
|
||||||
|
|
||||||
// CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds %C16class_resilience21ResilientGenericChild, %C16class_resilience21ResilientGenericChild* %0, i32 0, i32 0, i32 0
|
// CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds %C16class_resilience21ResilientGenericChild, %C16class_resilience21ResilientGenericChild* %0, i32 0, i32 0, i32 0
|
||||||
// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]]
|
// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]]
|
||||||
|
|||||||
@@ -52,8 +52,7 @@ public class GenericObjCSubclass<T> : NSCoder {
|
|||||||
// FIXME: we could eliminate the unnecessary isa load by lazily emitting
|
// FIXME: we could eliminate the unnecessary isa load by lazily emitting
|
||||||
// metadata sources in EmitPolymorphicParameters
|
// metadata sources in EmitPolymorphicParameters
|
||||||
|
|
||||||
// CHECK: [[T_BOX:%.*]] = alloca %swift.type*
|
// CHECK: %T = load
|
||||||
// CHECK: store {{.*}}, %swift.type** [[T_BOX]]
|
|
||||||
|
|
||||||
// CHECK-32-NEXT: [[ADDR:%.*]] = bitcast %C21class_resilience_objc19GenericObjCSubclass* %0 to %swift.type**
|
// CHECK-32-NEXT: [[ADDR:%.*]] = bitcast %C21class_resilience_objc19GenericObjCSubclass* %0 to %swift.type**
|
||||||
// CHECK-32-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]]
|
// CHECK-32-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]]
|
||||||
|
|||||||
@@ -2617,7 +2617,7 @@ bb4:
|
|||||||
// CHECK: define private %swift.type* @create_generic_metadata_DynamicSinglePayload(%swift.type_pattern*, i8**) {{.*}} {
|
// CHECK: define private %swift.type* @create_generic_metadata_DynamicSinglePayload(%swift.type_pattern*, i8**) {{.*}} {
|
||||||
// CHECK: call void @swift_initEnumValueWitnessTableSinglePayload
|
// CHECK: call void @swift_initEnumValueWitnessTableSinglePayload
|
||||||
|
|
||||||
// CHECK-64-LABEL: define linkonce_odr hidden void @_TwxsV4enum17StructWithWeakVar(%swift.opaque* %dest, i32 %index, %swift.type* %Self)
|
// CHECK-64-LABEL: define linkonce_odr hidden void @_TwxsV4enum17StructWithWeakVar(%swift.opaque* %dest, i32 %index, %swift.type* %StructWithWeakVar)
|
||||||
// -- TODO: some pointless masking here.
|
// -- TODO: some pointless masking here.
|
||||||
// -- TODO: should use EnumPayload word-chunking.
|
// -- TODO: should use EnumPayload word-chunking.
|
||||||
// CHECK-64: %1 = zext i32 %index to i128
|
// CHECK-64: %1 = zext i32 %index to i128
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ bb0(%0 : $SinglePayloadNontrivial):
|
|||||||
|
|
||||||
|
|
||||||
// -- SinglePayloadNontrivial destroyBuffer
|
// -- SinglePayloadNontrivial destroyBuffer
|
||||||
// CHECK: define linkonce_odr hidden void @_TwxxO20enum_value_semantics23SinglePayloadNontrivial(%swift.opaque* [[OBJ:%.*]], %swift.type* %Self) {{.*}} {
|
// CHECK: define linkonce_odr hidden void @_TwxxO20enum_value_semantics23SinglePayloadNontrivial(%swift.opaque* [[OBJ:%.*]], %swift.type* %SinglePayloadNontrivial) {{.*}} {
|
||||||
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %O20enum_value_semantics23SinglePayloadNontrivial*
|
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %O20enum_value_semantics23SinglePayloadNontrivial*
|
||||||
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics23SinglePayloadNontrivial* [[ADDR]] to i64*
|
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics23SinglePayloadNontrivial* [[ADDR]] to i64*
|
||||||
// CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
|
// CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
|
||||||
@@ -464,7 +464,7 @@ bb0(%0 : $SinglePayloadNontrivial):
|
|||||||
|
|
||||||
|
|
||||||
// -- MultiPayloadNontrivial destroyBuffer
|
// -- MultiPayloadNontrivial destroyBuffer
|
||||||
// CHECK: define linkonce_odr hidden void @_TwxxO20enum_value_semantics22MultiPayloadNontrivial(%swift.opaque* [[OBJ:%.*]], %swift.type* %Self)
|
// CHECK: define linkonce_odr hidden void @_TwxxO20enum_value_semantics22MultiPayloadNontrivial(%swift.opaque* [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivial)
|
||||||
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %O20enum_value_semantics22MultiPayloadNontrivial*
|
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %O20enum_value_semantics22MultiPayloadNontrivial*
|
||||||
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics22MultiPayloadNontrivial* [[ADDR]] to { i64, i64 }*
|
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics22MultiPayloadNontrivial* [[ADDR]] to { i64, i64 }*
|
||||||
// CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
|
// CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
|
||||||
@@ -498,7 +498,7 @@ bb0(%0 : $SinglePayloadNontrivial):
|
|||||||
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics19MultiPayloadGeneric
|
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_value_semantics19MultiPayloadGeneric
|
||||||
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics19MultiPayloadGeneric*
|
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics19MultiPayloadGeneric*
|
||||||
// CHECK-NEXT: [[OPAQUE:%.*]] = bitcast %O20enum_value_semantics19MultiPayloadGeneric* [[SELF]] to %swift.opaque*
|
// CHECK-NEXT: [[OPAQUE:%.*]] = bitcast %O20enum_value_semantics19MultiPayloadGeneric* [[SELF]] to %swift.opaque*
|
||||||
// CHECK-NEXT: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload(%swift.opaque* [[OPAQUE]], %swift.type* %Self) #5
|
// CHECK-NEXT: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload(%swift.opaque* [[OPAQUE]], %swift.type* %"MultiPayloadGeneric<T>") #5
|
||||||
// CHECK-NEXT: ret i32 [[TAG]]
|
// CHECK-NEXT: ret i32 [[TAG]]
|
||||||
|
|
||||||
|
|
||||||
@@ -509,7 +509,7 @@ bb0(%0 : $SinglePayloadNontrivial):
|
|||||||
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics19MultiPayloadGeneric
|
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics19MultiPayloadGeneric
|
||||||
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics19MultiPayloadGeneric*
|
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics19MultiPayloadGeneric*
|
||||||
// CHECK: [[OPAQUE:%.*]] = bitcast %O20enum_value_semantics19MultiPayloadGeneric* [[SELF]] to %swift.opaque*
|
// CHECK: [[OPAQUE:%.*]] = bitcast %O20enum_value_semantics19MultiPayloadGeneric* [[SELF]] to %swift.opaque*
|
||||||
// CHECK-NEXT: call void @swift_storeEnumTagMultiPayload(%swift.opaque* [[OPAQUE]], %swift.type* %Self, i32 %tag)
|
// CHECK-NEXT: call void @swift_storeEnumTagMultiPayload(%swift.opaque* [[OPAQUE]], %swift.type* %"MultiPayloadGeneric<T>", i32 %tag)
|
||||||
// CHECK-NEXT: ret void
|
// CHECK-NEXT: ret void
|
||||||
|
|
||||||
|
|
||||||
@@ -519,7 +519,8 @@ bb0(%0 : $SinglePayloadNontrivial):
|
|||||||
|
|
||||||
|
|
||||||
// -- MultiPayloadNontrivialSpareBits destroyBuffer
|
// -- MultiPayloadNontrivialSpareBits destroyBuffer
|
||||||
// CHECK: define linkonce_odr hidden void @_TwxxO20enum_value_semantics31MultiPayloadNontrivialSpareBits(%swift.opaque* [[OBJ:%.*]], %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO20enum_value_semantics31MultiPayloadNontrivialSpareBits
|
||||||
|
// CHECK-SAME: (%swift.opaque* [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivialSpareBits) {{.*}} {
|
||||||
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %O20enum_value_semantics31MultiPayloadNontrivialSpareBits*
|
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %O20enum_value_semantics31MultiPayloadNontrivialSpareBits*
|
||||||
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics31MultiPayloadNontrivialSpareBits* [[ADDR]] to { i64, i64 }*
|
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics31MultiPayloadNontrivialSpareBits* [[ADDR]] to { i64, i64 }*
|
||||||
// CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
|
// CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ enum NullableRefcounted {
|
|||||||
case None
|
case None
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO34enum_value_semantics_special_cases18NullableRefcounted(%swift.opaque* %object, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO34enum_value_semantics_special_cases18NullableRefcounted(%swift.opaque* %object, %swift.type* %NullableRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
||||||
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases18NullableRefcounted* %0 to %swift.refcounted**
|
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases18NullableRefcounted* %0 to %swift.refcounted**
|
||||||
@@ -20,7 +20,7 @@ enum NullableRefcounted {
|
|||||||
// CHECK: ret void
|
// CHECK: ret void
|
||||||
// CHECK: }
|
// CHECK: }
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcpO34enum_value_semantics_special_cases18NullableRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcpO34enum_value_semantics_special_cases18NullableRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
||||||
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
||||||
@@ -33,7 +33,7 @@ enum NullableRefcounted {
|
|||||||
// CHECK: ret %swift.opaque* %5
|
// CHECK: ret %swift.opaque* %5
|
||||||
// CHECK: }
|
// CHECK: }
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcaO34enum_value_semantics_special_cases18NullableRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcaO34enum_value_semantics_special_cases18NullableRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
||||||
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
||||||
@@ -48,7 +48,7 @@ enum NullableRefcounted {
|
|||||||
// CHECK: ret %swift.opaque* %6
|
// CHECK: ret %swift.opaque* %6
|
||||||
// CHECK: }
|
// CHECK: }
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtaO34enum_value_semantics_special_cases18NullableRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtaO34enum_value_semantics_special_cases18NullableRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
||||||
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases18NullableRefcounted*
|
||||||
@@ -69,7 +69,7 @@ enum NullableBlockRefcounted {
|
|||||||
case None
|
case None
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO34enum_value_semantics_special_cases23NullableBlockRefcounted(%swift.opaque* %object, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO34enum_value_semantics_special_cases23NullableBlockRefcounted(%swift.opaque* %object, %swift.type* %NullableBlockRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
||||||
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases23NullableBlockRefcounted* %0 to %objc_block**
|
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases23NullableBlockRefcounted* %0 to %objc_block**
|
||||||
@@ -78,7 +78,7 @@ enum NullableBlockRefcounted {
|
|||||||
// CHECK: ret void
|
// CHECK: ret void
|
||||||
// CHECK: }
|
// CHECK: }
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcpO34enum_value_semantics_special_cases23NullableBlockRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcpO34enum_value_semantics_special_cases23NullableBlockRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
||||||
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
||||||
@@ -91,7 +91,7 @@ enum NullableBlockRefcounted {
|
|||||||
// CHECK: ret %swift.opaque* %6
|
// CHECK: ret %swift.opaque* %6
|
||||||
// CHECK: }
|
// CHECK: }
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcaO34enum_value_semantics_special_cases23NullableBlockRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcaO34enum_value_semantics_special_cases23NullableBlockRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
||||||
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
||||||
@@ -106,7 +106,7 @@ enum NullableBlockRefcounted {
|
|||||||
// CHECK: ret %swift.opaque* %7
|
// CHECK: ret %swift.opaque* %7
|
||||||
// CHECK: }
|
// CHECK: }
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtaO34enum_value_semantics_special_cases23NullableBlockRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtaO34enum_value_semantics_special_cases23NullableBlockRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %dest to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
||||||
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
// CHECK: %1 = bitcast %swift.opaque* %src to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
|
||||||
@@ -127,7 +127,7 @@ enum MultipleEmptyRefcounted {
|
|||||||
case B
|
case B
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO34enum_value_semantics_special_cases23MultipleEmptyRefcounted(%swift.opaque* %object, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO34enum_value_semantics_special_cases23MultipleEmptyRefcounted(%swift.opaque* %object, %swift.type* %MultipleEmptyRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases23MultipleEmptyRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases23MultipleEmptyRefcounted*
|
||||||
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases23MultipleEmptyRefcounted* %0 to i64*
|
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases23MultipleEmptyRefcounted* %0 to i64*
|
||||||
@@ -164,7 +164,7 @@ enum AllRefcounted {
|
|||||||
case None
|
case None
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO34enum_value_semantics_special_cases13AllRefcounted(%swift.opaque* %object, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO34enum_value_semantics_special_cases13AllRefcounted(%swift.opaque* %object, %swift.type* %AllRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases13AllRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases13AllRefcounted*
|
||||||
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases13AllRefcounted* %0 to i64*
|
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases13AllRefcounted* %0 to i64*
|
||||||
@@ -176,7 +176,7 @@ enum AllRefcounted {
|
|||||||
// CHECK: ret void
|
// CHECK: ret void
|
||||||
// CHECK: }
|
// CHECK: }
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcpO34enum_value_semantics_special_cases13AllRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwcpO34enum_value_semantics_special_cases13AllRefcounted(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %AllRefcounted) {{.*}} {
|
||||||
// CHECK: %3 = load i64, i64* %2, align 8
|
// CHECK: %3 = load i64, i64* %2, align 8
|
||||||
// -- 0x3fffffffffffffff
|
// -- 0x3fffffffffffffff
|
||||||
// CHECK: %4 = and i64 %3, 4611686018427387903
|
// CHECK: %4 = and i64 %3, 4611686018427387903
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ enum NullableObjCRefcounted {
|
|||||||
case Ref(Builtin.UnknownObject)
|
case Ref(Builtin.UnknownObject)
|
||||||
case None
|
case None
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO39enum_value_semantics_special_cases_objc22NullableObjCRefcounted(%swift.opaque* %object, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO39enum_value_semantics_special_cases_objc22NullableObjCRefcounted(%swift.opaque* %object, %swift.type* %NullableObjCRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %object to %O39enum_value_semantics_special_cases_objc22NullableObjCRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %object to %O39enum_value_semantics_special_cases_objc22NullableObjCRefcounted*
|
||||||
// CHECK: %1 = bitcast %O39enum_value_semantics_special_cases_objc22NullableObjCRefcounted* %0 to %objc_object**
|
// CHECK: %1 = bitcast %O39enum_value_semantics_special_cases_objc22NullableObjCRefcounted* %0 to %objc_object**
|
||||||
@@ -31,7 +31,7 @@ enum AllMixedRefcounted {
|
|||||||
case None
|
case None
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO39enum_value_semantics_special_cases_objc18AllMixedRefcounted(%swift.opaque* %object, %swift.type* %Self) {{.*}} {
|
// CHECK-LABEL: define linkonce_odr hidden void @_TwxxO39enum_value_semantics_special_cases_objc18AllMixedRefcounted(%swift.opaque* %object, %swift.type* %AllMixedRefcounted) {{.*}} {
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// CHECK: %0 = bitcast %swift.opaque* %object to %O39enum_value_semantics_special_cases_objc18AllMixedRefcounted*
|
// CHECK: %0 = bitcast %swift.opaque* %object to %O39enum_value_semantics_special_cases_objc18AllMixedRefcounted*
|
||||||
// CHECK: %1 = bitcast %O39enum_value_semantics_special_cases_objc18AllMixedRefcounted* %0 to i64*
|
// CHECK: %1 = bitcast %O39enum_value_semantics_special_cases_objc18AllMixedRefcounted* %0 to i64*
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ sil_vtable StorageQualified {}
|
|||||||
|
|
||||||
// CHECK: [[FOO_TYPE_VECTOR_SLOT:@.*Foo.*]] = private global %swift.type** null
|
// CHECK: [[FOO_TYPE_VECTOR_SLOT:@.*Foo.*]] = private global %swift.type** null
|
||||||
|
|
||||||
// CHECK: define private %swift.type** [[FOO_TYPES_ACCESSOR]](%swift.type*)
|
// CHECK: define private %swift.type** [[FOO_TYPES_ACCESSOR]](%swift.type* %Foo)
|
||||||
// CHECK: [[EXISTING:%.*]] = load %swift.type**, %swift.type*** [[FOO_TYPE_VECTOR_SLOT]]
|
// CHECK: [[EXISTING:%.*]] = load %swift.type**, %swift.type*** [[FOO_TYPE_VECTOR_SLOT]]
|
||||||
// CHECK: [[IS_NULL:%.*]] = icmp eq %swift.type** [[EXISTING]], null
|
// CHECK: [[IS_NULL:%.*]] = icmp eq %swift.type** [[EXISTING]], null
|
||||||
// CHECK: br i1 [[IS_NULL]], label %[[BUILD_FIELD_TYPES:.*]], label %[[DONE:.*]]
|
// CHECK: br i1 [[IS_NULL]], label %[[BUILD_FIELD_TYPES:.*]], label %[[DONE:.*]]
|
||||||
@@ -81,8 +81,8 @@ sil_vtable StorageQualified {}
|
|||||||
// CHECK: store {{.*}} @_TMSi
|
// CHECK: store {{.*}} @_TMSi
|
||||||
// CHECK: cmpxchg {{.*}} [[FOO_TYPE_VECTOR_SLOT]]
|
// CHECK: cmpxchg {{.*}} [[FOO_TYPE_VECTOR_SLOT]]
|
||||||
|
|
||||||
// CHECK: define private %swift.type** [[BAR_TYPES_ACCESSOR]](%swift.type*)
|
// CHECK: define private %swift.type** [[BAR_TYPES_ACCESSOR]](%swift.type* %"Bar<T>")
|
||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to %swift.type***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Bar<T>" to %swift.type***
|
||||||
// -- 5 words between the address point and the slot
|
// -- 5 words between the address point and the slot
|
||||||
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 5
|
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 5
|
||||||
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
|
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
|
||||||
@@ -91,24 +91,24 @@ sil_vtable StorageQualified {}
|
|||||||
// CHECK: store {{.*}} @_TMSi
|
// CHECK: store {{.*}} @_TMSi
|
||||||
|
|
||||||
|
|
||||||
// CHECK: define private %swift.type** [[BAS_TYPES_ACCESSOR]](%swift.type*)
|
// CHECK: define private %swift.type** [[BAS_TYPES_ACCESSOR]](%swift.type* %"Bas<T, U>")
|
||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to %swift.type***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Bas<T, U>" to %swift.type***
|
||||||
// -- 7 words between the address point and the slot
|
// -- 7 words between the address point and the slot
|
||||||
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 7
|
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 7
|
||||||
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
|
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
|
||||||
// CHECK: br
|
// CHECK: br
|
||||||
// CHECK: store {{.*}} @_TMfV18field_type_vectors3Foo
|
// CHECK: store {{.*}} @_TMfV18field_type_vectors3Foo
|
||||||
// CHECK: [[T:%.*]] = bitcast %swift.type* {{.*}} to i8*
|
// CHECK: [[T:%.*]] = bitcast %swift.type* %T to i8*
|
||||||
// CHECK: call %swift.type* @swift_getGenericMetadata1({{.*}} @_TMPV18field_type_vectors3Bar {{.*}}, i8* [[T]])
|
// CHECK: call %swift.type* @swift_getGenericMetadata1({{.*}} @_TMPV18field_type_vectors3Bar {{.*}}, i8* [[T]])
|
||||||
|
|
||||||
// CHECK: define private %swift.type** [[ZIM_TYPES_ACCESSOR]](%swift.type*)
|
// CHECK: define private %swift.type** [[ZIM_TYPES_ACCESSOR]](%swift.type* %"Zim<T, U>")
|
||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to %swift.type***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Zim<T, U>" to %swift.type***
|
||||||
// -- 14 words between the address point and the slot
|
// -- 14 words between the address point and the slot
|
||||||
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 16
|
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 16
|
||||||
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
|
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
|
||||||
|
|
||||||
// CHECK: define private %swift.type** [[ZANG_TYPES_ACCESSOR]](%swift.type*)
|
// CHECK: define private %swift.type** [[ZANG_TYPES_ACCESSOR]](%swift.type* %"Zang<V>")
|
||||||
// CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to %swift.type***
|
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Zang<V>" to %swift.type***
|
||||||
// -- 16 words between the address point and the slot
|
// -- 16 words between the address point and the slot
|
||||||
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 18
|
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 18
|
||||||
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
|
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ entry(%0 : $*ComplexDynamic<A, B>, %1 : $*Byteful, %2 : $*A, %3 : $*B, %4 : $*Ch
|
|||||||
return %v : $()
|
return %v : $()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: define linkonce_odr hidden void @_TwXXV15generic_structs13SingleDynamic([24 x i8]* %buffer, %swift.type* %Self) {{.*}} {
|
// CHECK: define linkonce_odr hidden void @_TwXXV15generic_structs13SingleDynamic([24 x i8]* %buffer, %swift.type* %"SingleDynamic<T>") {{.*}} {
|
||||||
// CHECK: [[T0:%.*]] = load i8*, i8** %1, align 8
|
// CHECK: [[T0:%.*]] = load i8*, i8** %1, align 8
|
||||||
// CHECK: %T = bitcast i8* [[T0]] to %swift.type*
|
// CHECK: %T = bitcast i8* [[T0]] to %swift.type*
|
||||||
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_pattern* %0, i8** %1)
|
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_pattern* %0, i8** %1)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// <rdar://problem/13793646>
|
// <rdar://problem/13793646>
|
||||||
struct OptionalStreamAdaptor<T: GeneratorType> {
|
struct OptionalStreamAdaptor<T: GeneratorType> {
|
||||||
// CHECK: define hidden void @_TFV15generic_ternary21OptionalStreamAdaptor4next{{.*}}(%Sq{{.*}}* noalias nocapture sret, %swift.type* %Self, %V15generic_ternary21OptionalStreamAdaptor* nocapture dereferenceable({{.*}}))
|
// CHECK: define hidden void @_TFV15generic_ternary21OptionalStreamAdaptor4next{{.*}}(%Sq{{.*}}* noalias nocapture sret, %swift.type* %"OptionalStreamAdaptor<T>", %V15generic_ternary21OptionalStreamAdaptor* nocapture dereferenceable({{.*}}))
|
||||||
mutating
|
mutating
|
||||||
func next() -> Optional<T.Element> {
|
func next() -> Optional<T.Element> {
|
||||||
return x[0].next()
|
return x[0].next()
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ func dup<T>(x: T) -> (T, T) {
|
|||||||
// CHECK: define hidden void @_TF14generic_tuples3dup{{.*}}(<{}>* noalias nocapture sret
|
// CHECK: define hidden void @_TF14generic_tuples3dup{{.*}}(<{}>* noalias nocapture sret
|
||||||
// CHECK: entry:
|
// CHECK: entry:
|
||||||
// Allocate a local variable for 'x'.
|
// Allocate a local variable for 'x'.
|
||||||
// CHECK-NEXT: alloca %swift.type*, align 8
|
|
||||||
// CHECK-NEXT: [[XBUF:%.*]] = alloca [[BUFFER:.*]], align 8
|
// CHECK-NEXT: [[XBUF:%.*]] = alloca [[BUFFER:.*]], align 8
|
||||||
// CHECK-NEXT: store %swift.type*
|
|
||||||
// CHECK-NEXT: [[XBUFLIFE:%.*]] = bitcast {{.*}} [[XBUF]]
|
// CHECK-NEXT: [[XBUFLIFE:%.*]] = bitcast {{.*}} [[XBUF]]
|
||||||
// CHECK-NEXT: call void @llvm.lifetime.start({{.*}} [[XBUFLIFE]])
|
// CHECK-NEXT: call void @llvm.lifetime.start({{.*}} [[XBUFLIFE]])
|
||||||
// CHECK-NEXT: [[T0:%.*]] = bitcast [[TYPE]]* %T to i8***
|
// CHECK-NEXT: [[T0:%.*]] = bitcast [[TYPE]]* %T to i8***
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import Swift
|
|||||||
|
|
||||||
// CHECK-LABEL: define private %swift.type** @get_field_types_TreeA
|
// CHECK-LABEL: define private %swift.type** @get_field_types_TreeA
|
||||||
// -- Leaf(T)
|
// -- Leaf(T)
|
||||||
// CHECK: [[BITS:%.*]] = ptrtoint %swift.type* {{.*}} to [[WORD]]
|
// CHECK: [[BITS:%.*]] = ptrtoint %swift.type* %T to [[WORD]]
|
||||||
// CHECK: [[INDIRECT_FLAG:%.*]] = or [[WORD]] [[BITS]], 1
|
// CHECK: [[INDIRECT_FLAG:%.*]] = or [[WORD]] [[BITS]], 1
|
||||||
// -- Branch(TreeA, TreeA)
|
// -- Branch(TreeA, TreeA)
|
||||||
// CHECK: [[TUPLE:%.*]] = call %swift.type* @swift_getTupleTypeMetadata2
|
// CHECK: [[TUPLE:%.*]] = call %swift.type* @swift_getTupleTypeMetadata2
|
||||||
|
|||||||
@@ -18,11 +18,8 @@ bb0(%x : $*T):
|
|||||||
return %0 : $()
|
return %0 : $()
|
||||||
}
|
}
|
||||||
// CHECK: define void @generic([[OPAQUE]]* noalias nocapture, [[TYPE]]* %T) {{.*}} {
|
// CHECK: define void @generic([[OPAQUE]]* noalias nocapture, [[TYPE]]* %T) {{.*}} {
|
||||||
// Type metadata.
|
|
||||||
// CHECK: alloca
|
|
||||||
// The fixed-size buffer.
|
// The fixed-size buffer.
|
||||||
// CHECK: [[YBUF:%.*]] = alloca [[BUFFER:.*]], align
|
// CHECK: [[YBUF:%.*]] = alloca [[BUFFER:.*]], align
|
||||||
// CHECK-NEXT: store %swift.type
|
|
||||||
// CHECK-NEXT: [[YBUFLIFE:%.*]] = bitcast [[BUFFER]]* [[YBUF]] to i8*
|
// CHECK-NEXT: [[YBUFLIFE:%.*]] = bitcast [[BUFFER]]* [[YBUF]] to i8*
|
||||||
// CHECK-NEXT: call void @llvm.lifetime.start(i64 [[BUFFER_SIZE:12|24]], i8* [[YBUFLIFE]])
|
// CHECK-NEXT: call void @llvm.lifetime.start(i64 [[BUFFER_SIZE:12|24]], i8* [[YBUFLIFE]])
|
||||||
// Allocate it.
|
// Allocate it.
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ struct Gen<T> {
|
|||||||
// CHECK-NOT: @_TwTKV20weak_value_witnesses6NoWeak
|
// CHECK-NOT: @_TwTKV20weak_value_witnesses6NoWeak
|
||||||
|
|
||||||
// Weak references must be taken by swift_weakTakeInit.
|
// Weak references must be taken by swift_weakTakeInit.
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtkV20weak_value_witnesses8SomeWeak(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self)
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtkV20weak_value_witnesses8SomeWeak(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %SomeWeak)
|
||||||
// CHECK: call void @swift_weakTakeInit
|
// CHECK: call void @swift_weakTakeInit
|
||||||
|
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwTKV20weak_value_witnesses8SomeWeak(
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwTKV20weak_value_witnesses8SomeWeak(
|
||||||
@@ -57,5 +57,5 @@ struct Gen<T> {
|
|||||||
// CHECK-NEXT: ret %swift.opaque* [[T0]]
|
// CHECK-NEXT: ret %swift.opaque* [[T0]]
|
||||||
|
|
||||||
// Generic types must be taken using their value witness.
|
// Generic types must be taken using their value witness.
|
||||||
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtkV20weak_value_witnesses3Gen(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self)
|
// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @_TwtkV20weak_value_witnesses3Gen(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %"Gen<T>")
|
||||||
// CHECK: call %swift.opaque* %initializeWithTake
|
// CHECK: call %swift.opaque* %initializeWithTake
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ func bar() {
|
|||||||
// CHECK: [[BUFFER:%[0-9]+]] = call %swift.opaque* %projectBuffer
|
// CHECK: [[BUFFER:%[0-9]+]] = call %swift.opaque* %projectBuffer
|
||||||
// CHECK-NEXT: [[WITNESS_TABLE_ADDR:%[0-9]+]] = getelementptr inbounds [[P_WITNESS_TABLE]], [[P_WITNESS_TABLE]]* %0, i32 0, i32 2
|
// CHECK-NEXT: [[WITNESS_TABLE_ADDR:%[0-9]+]] = getelementptr inbounds [[P_WITNESS_TABLE]], [[P_WITNESS_TABLE]]* %0, i32 0, i32 2
|
||||||
// CHECK-NEXT: [[WITNESS_TABLE:%[A-Za-z0-9_-]+]] = load i8**, i8*** [[WITNESS_TABLE_ADDR]]
|
// CHECK-NEXT: [[WITNESS_TABLE:%[A-Za-z0-9_-]+]] = load i8**, i8*** [[WITNESS_TABLE_ADDR]]
|
||||||
// CHECK-NEXT: store
|
|
||||||
// CHECK-NEXT: getelementptr inbounds i8*, i8** [[WITNESS_TABLE]], i32 3
|
// CHECK-NEXT: getelementptr inbounds i8*, i8** [[WITNESS_TABLE]], i32 3
|
||||||
go().foo()
|
go().foo()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user