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:
John McCall
2016-01-13 17:42:41 -08:00
parent b38b27cfac
commit f1682cd9a8
29 changed files with 190 additions and 96 deletions

View File

@@ -126,6 +126,10 @@ public:
/// Whether we should embed the bitcode file.
IRGenEmbedMode EmbedMode : 2;
/// Add names to LLVM values.
unsigned HasValueNamesSetting : 1;
unsigned ValueNames : 1;
/// List of backend command-line options for -embed-bitcode.
std::vector<uint8_t> CmdArgs;
@@ -135,7 +139,8 @@ public:
DisableLLVMARCOpts(false), DisableLLVMSLPVectorizer(false),
DisableFPElim(true), Playground(false),
EmitStackPromotionChecks(false), GenerateProfile(false),
EmbedMode(IRGenEmbedMode::None)
EmbedMode(IRGenEmbedMode::None),
HasValueNamesSetting(false), ValueNames(false)
{}
/// Gets the name of the specified output filename.

View File

@@ -181,6 +181,12 @@ def disable_llvm_slp_vectorizer : Flag<["-"], "disable-llvm-slp-vectorizer">,
def disable_llvm_verify : Flag<["-"], "disable-llvm-verify">,
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">,
HelpText<"Emit runtime checks for correct stack promotion of objects.">;

View File

@@ -1125,6 +1125,13 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
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.DisableLLVMARCOpts |= Args.hasArg(OPT_disable_llvm_arc_opts);
Opts.DisableLLVMSLPVectorizer |= Args.hasArg(OPT_disable_llvm_slp_vectorizer);

View File

@@ -277,20 +277,6 @@ static void setMetadataRef(IRGenFunction &IGF,
IGF.setUnscopedLocalTypeData(CanType(archetype),
LocalTypeDataKind::forTypeMetadata(),
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,
@@ -311,9 +297,7 @@ void IRGenFunction::bindArchetype(ArchetypeType *archetype,
llvm::Value *metadata,
ArrayRef<llvm::Value*> wtables) {
// Set the metadata pointer.
bool setNames = !archetype->getOpenedExistentialType();
if (setNames)
metadata->setName(archetype->getFullName());
setTypeMetadataName(IGM, metadata, CanType(archetype));
setMetadataRef(*this, archetype, metadata);
// Set the protocol witness tables.
@@ -324,10 +308,7 @@ void IRGenFunction::bindArchetype(ArchetypeType *archetype,
if (!Lowering::TypeConverter::protocolRequiresWitnessTable(proto))
continue;
auto wtable = wtables[wtableI++];
if (setNames) {
wtable->setName(Twine(archetype->getFullName()) + "." +
proto->getName().str());
}
setProtocolWitnessTableName(IGM, wtable, CanType(archetype), proto);
setWitnessTable(*this, archetype, i, wtable);
}
assert(wtableI == wtables.size());

View File

@@ -102,8 +102,7 @@ namespace {
/// Given the address of an existential object, load its witness table.
llvm::Value *loadWitnessTable(IRGenFunction &IGF, Address addr,
unsigned which) const {
return IGF.Builder.CreateLoad(projectWitnessTable(IGF, addr, which),
"witness-table");
return IGF.Builder.CreateLoad(projectWitnessTable(IGF, addr, which));
}
/// 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
/// object.
llvm::Value *loadMetadataRef(IRGenFunction &IGF, Address addr) {
return IGF.Builder.CreateLoad(projectMetadataRef(IGF, addr),
addr.getAddress()->getName() + ".metadata");
return IGF.Builder.CreateLoad(projectMetadataRef(IGF, addr));
}
};
}

View File

@@ -2514,6 +2514,7 @@ irgen::emitFieldTypeAccessor(IRGenModule &IGM,
CanType formalType = type->getDeclaredTypeInContext()->getCanonicalType();
llvm::Value *metadata = IGF.collectParameters().claimNext();
setTypeMetadataName(IGM, metadata, formalType);
// Get the address at which the field type vector reference should be
// cached.
@@ -3719,7 +3720,7 @@ emitInvariantLoadFromMetadataAtIndex(IRGenFunction &IGF,
llvm::Value *metadata,
int index,
llvm::Type *objectTy,
const llvm::Twine &suffix = "") {
const Twine &suffix = Twine::createNull()) {
auto result = emitLoadFromMetadataAtIndex(IGF, metadata, index, objectTy,
suffix);
IGF.setInvariantLoad(result);
@@ -4128,7 +4129,8 @@ static llvm::Value *emitLoadOfHeapMetadataRef(IRGenFunction &IGF,
auto metadata = IGF.Builder.CreateLoad(Address(slot,
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;
}

View File

@@ -72,6 +72,43 @@
using namespace swift;
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 {
/// A concrete witness table, together with its known layout.
@@ -1886,10 +1923,11 @@ getAssociatedTypeMetadataAccessFunction(AssociatedTypeDecl *requirement,
Explosion parameters = IGF.collectParameters();
llvm::Value *self = parameters.claimNext();
self->setName("Self");
setTypeMetadataName(IGM, self, ConcreteType);
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,
// we don't need a cache entry.
@@ -1968,13 +2006,16 @@ getAssociatedTypeWitnessTableAccessFunction(AssociatedTypeDecl *requirement,
Explosion parameters = IGF.collectParameters();
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();
self->setName("Self");
setTypeMetadataName(IGM, self, ConcreteType);
Address destTable(parameters.claimNext(), IGM.getPointerAlignment());
destTable.getAddress()->setName("wtable");
setProtocolWitnessTableName(IGM, destTable.getAddress(), ConcreteType,
requirement->getProtocol());
const ConformanceInfo *conformanceI = nullptr;
if (associatedConformance.isConcrete()) {
@@ -2944,7 +2985,7 @@ namespace {
CanType argTy = getArgTypeInContext(source.getParamIndex());
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.
IGF.setUnscopedLocalTypeData(argTy, LocalTypeDataKind::forTypeMetadata(),
@@ -2959,6 +3000,7 @@ namespace {
// Mark this as the cached metatype for Self.
CanType argTy = getArgTypeInContext(FnType->getParameters().size() - 1);
setTypeMetadataName(IGF.IGM, metadata, argTy);
IGF.setUnscopedLocalTypeData(argTy,
LocalTypeDataKind::forTypeMetadata(), metadata);
return metadata;
@@ -3173,6 +3215,7 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF,
if (source) {
source = emitArgumentMetadataRef(IGF, generic->getDecl(), index, source);
setTypeMetadataName(IGF.IGM, source, sourceKey.Type);
}
return source;
}
@@ -3191,9 +3234,10 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF,
sourceKey.Kind = LocalTypeDataKind::forProtocolWitnessTable(conformance);
if (source) {
auto protocol = conformance.getRequirement();
source = emitArgumentWitnessTableRef(IGF, generic->getDecl(), argIndex,
conformance.getRequirement(),
source);
protocol, source);
setProtocolWitnessTableName(IGF.IGM, source, sourceKey.Type, protocol);
}
return source;
}
@@ -3212,6 +3256,7 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF,
if (source) {
source = emitParentMetadataRef(IGF, nominalDecl, source);
setTypeMetadataName(IGF.IGM, source, sourceKey.Type);
}
return source;
}
@@ -3240,6 +3285,8 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF,
source = emitInvariantLoadOfOpaqueWitness(IGF, source,
entry.getOutOfLineBaseIndex());
source = IGF.Builder.CreateBitCast(source, IGF.IGM.WitnessTablePtrTy);
setProtocolWitnessTableName(IGF.IGM, source, sourceKey.Type,
inheritedProtocol);
}
return source;
}
@@ -3282,7 +3329,6 @@ static void getArgAsLocalSelfTypeMetadata(IRGenFunction &IGF,
llvm::Function::arg_iterator &it,
CanType abstractType) {
llvm::Value *arg = &*it++;
arg->setName("Self");
assert(arg->getType() == IGF.IGM.TypeMetadataPtrTy &&
"Self argument is not a type?!");

View File

@@ -38,6 +38,13 @@ namespace irgen {
class IRGenModule;
class ProtocolInfo;
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
/// as a function value.

View File

@@ -131,6 +131,15 @@ IRGenModule::IRGenModule(IRGenModuleDispatcher &dispatcher, SourceFile *SF,
Types(*new TypeConverter(*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());
Int1Ty = llvm::Type::getInt1Ty(getLLVMContext());

View File

@@ -322,6 +322,9 @@ public:
/// Does the current target require Objective-C interoperation?
bool ObjCInterop = true;
/// Should we add value names to local IR values?
bool EnableValueNames = false;
llvm::Type *VoidTy; /// void (usually {})
llvm::IntegerType *Int1Ty; /// i1
llvm::IntegerType *Int8Ty; /// i8

View File

@@ -18,8 +18,11 @@
#include "LocalTypeData.h"
#include "Fulfillment.h"
#include "GenMeta.h"
#include "GenProto.h"
#include "IRGenDebugInfo.h"
#include "IRGenFunction.h"
#include "IRGenModule.h"
#include "swift/AST/IRGenOptions.h"
#include "swift/SIL/SILModule.h"
using namespace swift;
@@ -176,8 +179,37 @@ LocalTypeDataCache::AbstractCacheEntry::follow(IRGenFunction &IGF,
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,
llvm::Value *data) {
maybeEmitDebugInfoForLocalTypeData(*this, key, data);
// Register with the active ConditionalDominanceScope if necessary.
bool isConditional = isConditionalDominancePoint();
if (isConditional) {
@@ -190,6 +222,8 @@ void IRGenFunction::setScopedLocalTypeData(LocalTypeDataKey key,
void IRGenFunction::setUnscopedLocalTypeData(LocalTypeDataKey key,
llvm::Value *data) {
maybeEmitDebugInfoForLocalTypeData(*this, key, data);
// This is supportable, but it would require ensuring that we add the
// entry after any conditional entries; otherwise the stack discipline
// will get messed up.
@@ -204,6 +238,7 @@ void IRGenFunction::bindLocalTypeDataFromTypeMetadata(CanType type,
llvm::Value *metadata) {
// Remember that we have this type metadata concretely.
if (isExact) {
if (!metadata->hasName()) setTypeMetadataName(IGM, metadata, type);
setScopedLocalTypeData(type, LocalTypeDataKind::forTypeMetadata(), metadata);
}

View File

@@ -150,6 +150,9 @@ public:
bool operator==(LocalTypeDataKind other) const {
return Value == other.Value;
}
bool operator!=(LocalTypeDataKind other) const {
return Value != other.Value;
}
};
class LocalTypeDataKey {

View File

@@ -14,7 +14,6 @@ class AClass : AProtocol {
// CHECK: define hidden void @_TF17ProtocolContainer3foo
// CHECK-NEXT: entry:
// 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: call void @llvm.dbg.declare(metadata %P17ProtocolContainer9AProtocol_** [[XADDR]], metadata ![[XMD:.*]], metadata !{{[0-9]+}})
// CHECK-NOT: !DILocalVariable({{.*}} name: "x"

View File

@@ -50,7 +50,7 @@ struct SomeWeak {
// CHECK: @_TwtTV21array_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: br label %iter
// CHECK: iter:
@@ -68,7 +68,7 @@ struct SomeWeak {
// CHECK: ret
// 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: [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
// CHECK: br label %iter
@@ -90,7 +90,7 @@ struct SomeWeak {
// CHECK: ret
// 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: [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
// CHECK: br label %iter
@@ -112,7 +112,7 @@ struct SomeWeak {
// CHECK: ret
// 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: [[SRC_BEGIN:%.*]] = bitcast %swift.opaque* [[SRC_PTR]] to [[SOMEWEAK]]*
// CHECK: [[DEST_END:%.*]] = getelementptr inbounds [[SOMEWEAK]], [[SOMEWEAK]]* [[DEST_BEGIN]], [[WORD]] [[COUNT]]

View File

@@ -49,22 +49,22 @@ struct Fulfilled<T : protocol<P, Q> > : Assocked {
}
// 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: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type**
// 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* %"Fulfilled<T>" to %swift.type**
// 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: ret %swift.type* [[T2]]
// 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: [[T0:%.*]] = bitcast %swift.type* %Self to i8***
// 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* %"Fulfilled<T>" to i8***
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 4
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load
// CHECK-NEXT: ret i8** [[T2]]
// 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: [[T0:%.*]] = bitcast %swift.type* %Self to i8***
// 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* %"Fulfilled<T>" to i8***
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 5
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load
// CHECK-NEXT: ret i8** [[T2]]
@@ -90,9 +90,9 @@ struct Computed<T, U> : Assocked {
}
// 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: [[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_RESULT:%.*]] = load %swift.type*, %swift.type** [[CACHE]], align 8
// 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: ret %swift.type* [[T0]]
// 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: [[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: [[U:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T]] to i8*

View File

@@ -198,8 +198,7 @@ public class MyResilientChild : MyResilientParent {
// FIXME: we could eliminate the unnecessary isa load by lazily emitting
// metadata sources in EmitPolymorphicParameters
// CHECK: [[T_BOX:%.*]] = alloca %swift.type*
// CHECK: store {{.*}}, %swift.type** [[T_BOX]]
// CHECK: %T = load
// 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]]

View File

@@ -52,8 +52,7 @@ public class GenericObjCSubclass<T> : NSCoder {
// FIXME: we could eliminate the unnecessary isa load by lazily emitting
// metadata sources in EmitPolymorphicParameters
// CHECK: [[T_BOX:%.*]] = alloca %swift.type*
// CHECK: store {{.*}}, %swift.type** [[T_BOX]]
// CHECK: %T = load
// CHECK-32-NEXT: [[ADDR:%.*]] = bitcast %C21class_resilience_objc19GenericObjCSubclass* %0 to %swift.type**
// CHECK-32-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]]

View File

@@ -2617,7 +2617,7 @@ bb4:
// CHECK: define private %swift.type* @create_generic_metadata_DynamicSinglePayload(%swift.type_pattern*, i8**) {{.*}} {
// 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: should use EnumPayload word-chunking.
// CHECK-64: %1 = zext i32 %index to i128

View File

@@ -299,7 +299,7 @@ bb0(%0 : $SinglePayloadNontrivial):
// -- 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-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics23SinglePayloadNontrivial* [[ADDR]] to i64*
// CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
@@ -464,7 +464,7 @@ bb0(%0 : $SinglePayloadNontrivial):
// -- 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-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics22MultiPayloadNontrivial* [[ADDR]] to { i64, i64 }*
// CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
@@ -498,7 +498,7 @@ bb0(%0 : $SinglePayloadNontrivial):
// CHECK-LABEL: define linkonce_odr hidden i32 @_TwugO20enum_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: [[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]]
@@ -509,7 +509,7 @@ bb0(%0 : $SinglePayloadNontrivial):
// CHECK-LABEL: define linkonce_odr hidden void @_TwuiO20enum_value_semantics19MultiPayloadGeneric
// CHECK: [[SELF:%.*]] = bitcast %swift.opaque* %value to %O20enum_value_semantics19MultiPayloadGeneric*
// 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
@@ -519,7 +519,8 @@ bb0(%0 : $SinglePayloadNontrivial):
// -- 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-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %O20enum_value_semantics31MultiPayloadNontrivialSpareBits* [[ADDR]] to { i64, i64 }*
// CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr

View File

@@ -11,7 +11,7 @@ enum NullableRefcounted {
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: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases18NullableRefcounted*
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases18NullableRefcounted* %0 to %swift.refcounted**
@@ -20,7 +20,7 @@ enum NullableRefcounted {
// CHECK: ret void
// 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: %0 = bitcast %swift.opaque* %dest 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: }
// 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: %0 = bitcast %swift.opaque* %dest 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: }
// 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: %0 = bitcast %swift.opaque* %dest 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
}
// 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: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases23NullableBlockRefcounted*
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases23NullableBlockRefcounted* %0 to %objc_block**
@@ -78,7 +78,7 @@ enum NullableBlockRefcounted {
// CHECK: ret void
// 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: %0 = bitcast %swift.opaque* %dest 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: }
// 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: %0 = bitcast %swift.opaque* %dest 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: }
// 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: %0 = bitcast %swift.opaque* %dest 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
}
// 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: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases23MultipleEmptyRefcounted*
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases23MultipleEmptyRefcounted* %0 to i64*
@@ -164,7 +164,7 @@ enum AllRefcounted {
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: %0 = bitcast %swift.opaque* %object to %O34enum_value_semantics_special_cases13AllRefcounted*
// CHECK: %1 = bitcast %O34enum_value_semantics_special_cases13AllRefcounted* %0 to i64*
@@ -176,7 +176,7 @@ enum AllRefcounted {
// CHECK: ret void
// 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
// -- 0x3fffffffffffffff
// CHECK: %4 = and i64 %3, 4611686018427387903

View File

@@ -10,7 +10,7 @@ enum NullableObjCRefcounted {
case Ref(Builtin.UnknownObject)
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: %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**
@@ -31,7 +31,7 @@ enum AllMixedRefcounted {
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: %0 = bitcast %swift.opaque* %object to %O39enum_value_semantics_special_cases_objc18AllMixedRefcounted*
// CHECK: %1 = bitcast %O39enum_value_semantics_special_cases_objc18AllMixedRefcounted* %0 to i64*

View File

@@ -73,7 +73,7 @@ sil_vtable StorageQualified {}
// 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: [[IS_NULL:%.*]] = icmp eq %swift.type** [[EXISTING]], null
// CHECK: br i1 [[IS_NULL]], label %[[BUILD_FIELD_TYPES:.*]], label %[[DONE:.*]]
@@ -81,8 +81,8 @@ sil_vtable StorageQualified {}
// CHECK: store {{.*}} @_TMSi
// CHECK: cmpxchg {{.*}} [[FOO_TYPE_VECTOR_SLOT]]
// CHECK: define private %swift.type** [[BAR_TYPES_ACCESSOR]](%swift.type*)
// CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to %swift.type***
// CHECK: define private %swift.type** [[BAR_TYPES_ACCESSOR]](%swift.type* %"Bar<T>")
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Bar<T>" to %swift.type***
// -- 5 words between the address point and the slot
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 5
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
@@ -91,24 +91,24 @@ sil_vtable StorageQualified {}
// CHECK: store {{.*}} @_TMSi
// CHECK: define private %swift.type** [[BAS_TYPES_ACCESSOR]](%swift.type*)
// CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to %swift.type***
// CHECK: define private %swift.type** [[BAS_TYPES_ACCESSOR]](%swift.type* %"Bas<T, U>")
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Bas<T, U>" to %swift.type***
// -- 7 words between the address point and the slot
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 7
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
// CHECK: br
// 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: define private %swift.type** [[ZIM_TYPES_ACCESSOR]](%swift.type*)
// CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to %swift.type***
// CHECK: define private %swift.type** [[ZIM_TYPES_ACCESSOR]](%swift.type* %"Zim<T, U>")
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Zim<T, U>" to %swift.type***
// -- 14 words between the address point and the slot
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 16
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8
// CHECK: define private %swift.type** [[ZANG_TYPES_ACCESSOR]](%swift.type*)
// CHECK: [[T0:%.*]] = bitcast %swift.type* %0 to %swift.type***
// CHECK: define private %swift.type** [[ZANG_TYPES_ACCESSOR]](%swift.type* %"Zang<V>")
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Zang<V>" to %swift.type***
// -- 16 words between the address point and the slot
// CHECK: [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 18
// CHECK: load %swift.type**, %swift.type*** [[SLOT]], align 8

View File

@@ -168,7 +168,7 @@ entry(%0 : $*ComplexDynamic<A, B>, %1 : $*Byteful, %2 : $*A, %3 : $*B, %4 : $*Ch
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: %T = bitcast i8* [[T0]] to %swift.type*
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_pattern* %0, i8** %1)

View File

@@ -4,7 +4,7 @@
// <rdar://problem/13793646>
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
func next() -> Optional<T.Element> {
return x[0].next()

View File

@@ -17,9 +17,7 @@ func dup<T>(x: T) -> (T, T) {
// CHECK: define hidden void @_TF14generic_tuples3dup{{.*}}(<{}>* noalias nocapture sret
// CHECK: entry:
// Allocate a local variable for 'x'.
// CHECK-NEXT: alloca %swift.type*, align 8
// CHECK-NEXT: [[XBUF:%.*]] = alloca [[BUFFER:.*]], align 8
// CHECK-NEXT: store %swift.type*
// CHECK-NEXT: [[XBUFLIFE:%.*]] = bitcast {{.*}} [[XBUF]]
// CHECK-NEXT: call void @llvm.lifetime.start({{.*}} [[XBUFLIFE]])
// CHECK-NEXT: [[T0:%.*]] = bitcast [[TYPE]]* %T to i8***

View File

@@ -7,7 +7,7 @@ import Swift
// CHECK-LABEL: define private %swift.type** @get_field_types_TreeA
// -- Leaf(T)
// CHECK: [[BITS:%.*]] = ptrtoint %swift.type* {{.*}} to [[WORD]]
// CHECK: [[BITS:%.*]] = ptrtoint %swift.type* %T to [[WORD]]
// CHECK: [[INDIRECT_FLAG:%.*]] = or [[WORD]] [[BITS]], 1
// -- Branch(TreeA, TreeA)
// CHECK: [[TUPLE:%.*]] = call %swift.type* @swift_getTupleTypeMetadata2

View File

@@ -18,11 +18,8 @@ bb0(%x : $*T):
return %0 : $()
}
// CHECK: define void @generic([[OPAQUE]]* noalias nocapture, [[TYPE]]* %T) {{.*}} {
// Type metadata.
// CHECK: alloca
// The fixed-size buffer.
// CHECK: [[YBUF:%.*]] = alloca [[BUFFER:.*]], align
// CHECK-NEXT: store %swift.type
// CHECK-NEXT: [[YBUFLIFE:%.*]] = bitcast [[BUFFER]]* [[YBUF]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start(i64 [[BUFFER_SIZE:12|24]], i8* [[YBUFLIFE]])
// Allocate it.

View File

@@ -40,7 +40,7 @@ struct Gen<T> {
// CHECK-NOT: @_TwTKV20weak_value_witnesses6NoWeak
// 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-LABEL: define linkonce_odr hidden %swift.opaque* @_TwTKV20weak_value_witnesses8SomeWeak(
@@ -57,5 +57,5 @@ struct Gen<T> {
// CHECK-NEXT: ret %swift.opaque* [[T0]]
// 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

View File

@@ -8,7 +8,6 @@ func bar() {
// 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:%[A-Za-z0-9_-]+]] = load i8**, i8*** [[WITNESS_TABLE_ADDR]]
// CHECK-NEXT: store
// CHECK-NEXT: getelementptr inbounds i8*, i8** [[WITNESS_TABLE]], i32 3
go().foo()
}