Merge pull request #60231 from aschwaighofer/generic_objc_method_list_section

IRGen: Add a list of class_ro_t referenced from generic class metadata patterns to a section __swift_rodatas
This commit is contained in:
Arnold Schwaighofer
2022-08-02 08:23:52 -07:00
committed by GitHub
7 changed files with 108 additions and 6 deletions

View File

@@ -401,6 +401,9 @@ public:
/// Internalize symbols (static library) - do not export any public symbols.
unsigned InternalizeSymbols : 1;
/// Emit a section with references to class_ro_t* in generic class patterns.
unsigned EmitGenericRODatas : 1;
/// Whether to avoid emitting zerofill globals as preallocated type metadata
/// and protocol conformance caches.
unsigned NoPreallocatedInstantiationCaches : 1;
@@ -475,7 +478,7 @@ public:
EnableGlobalISel(false), VirtualFunctionElimination(false),
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
InternalizeAtLink(false), InternalizeSymbols(false),
NoPreallocatedInstantiationCaches(false),
EmitGenericRODatas(false), NoPreallocatedInstantiationCaches(false),
DisableReadonlyStaticObjects(false), CmdArgs(),
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
TypeInfoFilter(TypeInfoDumpFilter::All) {

View File

@@ -1085,4 +1085,13 @@ def enable_new_llvm_pass_manager :
def disable_new_llvm_pass_manager :
Flag<["-"], "disable-new-llvm-pass-manager">,
HelpText<"Disable the new llvm pass manager">;
def disable_emit_generic_class_ro_t_list :
Flag<["-"], "disable-emit-generic-class-ro_t-list">,
HelpText<"Disable emission of a section with references to class_ro_t of "
"generic class patterns">;
def enable_emit_generic_class_ro_t_list :
Flag<["-"], "enable-emit-generic-class-ro_t-list">,
HelpText<"Enable emission of a section with references to class_ro_t of "
"generic class patterns">;
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

View File

@@ -2397,6 +2397,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Never;
}
Opts.EmitGenericRODatas =
Args.hasFlag(OPT_enable_emit_generic_class_ro_t_list,
OPT_disable_emit_generic_class_ro_t_list,
Opts.EmitGenericRODatas);
Opts.LegacyPassManager =
Args.hasFlag(OPT_disable_new_llvm_pass_manager,
OPT_enable_new_llvm_pass_manager,

View File

@@ -556,7 +556,7 @@ static llvm::GlobalVariable *
emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
StringRef name, StringRef section,
llvm::GlobalValue::LinkageTypes linkage, llvm::Type *eltTy,
bool isConstant, bool asContiguousArray) {
bool isConstant, bool asContiguousArray, bool canBeStrippedByLinker = false) {
// Do nothing if the list is empty.
if (handles.empty()) return nullptr;
@@ -578,8 +578,12 @@ emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
var->setSection(section);
var->setAlignment(llvm::MaybeAlign(alignment.getValue()));
disableAddressSanitizer(IGM, var);
if (llvm::GlobalValue::isLocalLinkage(linkage))
IGM.addUsedGlobal(var);
if (llvm::GlobalValue::isLocalLinkage(linkage)) {
if (canBeStrippedByLinker)
IGM.addCompilerUsedGlobal(var);
else
IGM.addUsedGlobal(var);
}
if (IGM.IRGen.Opts.ConditionalRuntimeRecords) {
// Allow dead-stripping `var` (the runtime record from the global list)
@@ -616,8 +620,12 @@ emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
// Mark the variable as used if doesn't have external linkage.
// (Note that we'd specifically like to not put @llvm.used in itself.)
if (llvm::GlobalValue::isLocalLinkage(linkage))
IGM.addUsedGlobal(var);
if (llvm::GlobalValue::isLocalLinkage(linkage)) {
if (canBeStrippedByLinker)
IGM.addCompilerUsedGlobal(var);
else
IGM.addUsedGlobal(var);
}
return var;
}
@@ -962,6 +970,10 @@ void IRGenModule::addCompilerUsedGlobal(llvm::GlobalValue *global) {
LLVMCompilerUsed.push_back(global);
}
void IRGenModule::addGenericROData(llvm::Constant *RODataAddr) {
GenericRODatas.push_back(RODataAddr);
}
/// Add the given global value to the Objective-C class list.
void IRGenModule::addObjCClass(llvm::Constant *classPtr, bool nonlazy) {
ObjCClasses.push_back(classPtr);
@@ -1067,6 +1079,14 @@ void IRGenModule::SetCStringLiteralSection(llvm::GlobalVariable *GV,
void IRGenModule::emitGlobalLists() {
if (ObjCInterop) {
if (IRGen.Opts.EmitGenericRODatas) {
emitGlobalList(
*this, GenericRODatas, "generic_ro_datas",
GetObjCSectionName("__swift_rodatas", "regular"),
llvm::GlobalValue::InternalLinkage, Int8PtrTy, /*isConstant*/ false,
/*asContiguousArray*/ true, /*canBeStrippedByLinker*/ true);
}
// Objective-C class references go in a variable with a meaningless
// name but a magic section.
emitGlobalList(

View File

@@ -4043,6 +4043,8 @@ namespace {
// Any bytes before this will be zeroed. Currently we don't take
// advantage of this.
Size patternOffset = Size(0);
Size classROData = Size(0);
Size metaclassROData = Size(0);
if (IGM.ObjCInterop) {
// Add the metaclass object.
@@ -4057,13 +4059,27 @@ namespace {
IGM.getOffsetInWords(patternOffset + roDataPoints.first));
B.fillPlaceholderWithInt(*MetaclassRODataOffset, IGM.Int16Ty,
IGM.getOffsetInWords(patternOffset + roDataPoints.second));
classROData = patternOffset + roDataPoints.first;
metaclassROData = patternOffset + roDataPoints.second;
}
auto patternSize = subB.getNextOffsetFromGlobal();
auto global = subB.finishAndCreateGlobal("", IGM.getPointerAlignment(),
/*constant*/ true);
if (IGM.ObjCInterop) {
auto getRODataAtOffset = [&] (Size offset) -> llvm::Constant * {
auto t0 = llvm::ConstantExpr::getBitCast(global, IGM.Int8PtrTy);
llvm::Constant *indices[] = {llvm::ConstantInt::get(IGM.Int32Ty, offset.getValue())};
return llvm::ConstantExpr::getBitCast(
llvm::ConstantExpr::getInBoundsGetElementPtr(IGM.Int8Ty,
t0, indices),
IGM.Int8PtrTy);
};
IGM.addGenericROData(getRODataAtOffset(classROData));
IGM.addGenericROData(getRODataAtOffset(metaclassROData));
}
return { global, patternOffset, patternSize };
}

View File

@@ -1080,6 +1080,7 @@ public:
void addUsedGlobal(llvm::GlobalValue *global);
void addCompilerUsedGlobal(llvm::GlobalValue *global);
void addGenericROData(llvm::Constant *addr);
void addObjCClass(llvm::Constant *addr, bool nonlazy);
void addObjCClassStub(llvm::Constant *addr);
void addProtocolConformance(ConformanceDescription &&conformance);
@@ -1198,6 +1199,8 @@ private:
/// Metadata nodes for autolinking info.
SmallVector<LinkLibrary, 32> AutolinkEntries;
// List of ro_data_t referenced from generic class patterns.
SmallVector<llvm::WeakTrackingVH, 4> GenericRODatas;
/// List of Objective-C classes, bitcast to i8*.
SmallVector<llvm::WeakTrackingVH, 4> ObjCClasses;
/// List of Objective-C classes that require nonlazy realization, bitcast to

View File

@@ -0,0 +1,46 @@
// RUN: %target-swift-frontend -enable-emit-generic-class-ro_t-list -S %s -o - | %FileCheck %s
// REQUIRES: objc_interop
// REQUIRES: CPU=x86_64 || CPU=arm64
// REQUIRES: OS=macosx
// CHECK: ___unnamed_1:
// CHECK: .quad _OBJC_METACLASS_$__TtCs12_SwiftObject
// CHECK: .quad 0
// CHECK: .quad __objc_empty_cache
// CHECK: .quad 0
// CHECK: .quad 0
// Start of rodata_t
// CHECK: .long 128
// CHECK: .long 16
// CHECK: .long 16
// CHECK: .long 0
// CHECK: .quad 0
// CHECK: .quad 0
// CHECK: .quad __INSTANCE_METHODS__TtC25generic_class_rodata_list9Something
// CHECK: .quad 0
// CHECK: .quad 0
// CHECK: .quad 0
// CHECK: .quad 0
// Start of rodata_t
// CHECK: .long 129
// CHECK: .long 40
// CHECK: .long 40
// CHECK: .long 0
// CHECK: .quad 0
// CHECK: .quad 0
// CHECK: .quad __CLASS_METHODS__TtC25generic_class_rodata_list9Somethin
// CHECK: .section __DATA,__swift_rodatas
// CHECK: .p2align 3
// CHECK:_generic_ro_datas:
// CHECK: .quad ___unnamed_1+40
// CHECK: .quad ___unnamed_1+112
import Foundation
public class Something<T> {
@objc
public func myMethod() { print("hello") }
@objc
public static func myStaticMethod() { print("static") }
}