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.
|
||||
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.
|
||||
|
||||
@@ -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.">;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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?!");
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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]]
|
||||
|
||||
@@ -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*
|
||||
|
||||
@@ -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]]
|
||||
|
||||
@@ -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]]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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***
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user