mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[embedded] In -no-allocations, avoid linking allocating/deallocating runtime functions
This commit is contained in:
@@ -2635,7 +2635,7 @@ FUNCTION(GenericAssignWithCopy,
|
||||
RETURNS(Int8PtrTy),
|
||||
ARGS(Int8PtrTy, Int8PtrTy, TypeMetadataPtrTy),
|
||||
ATTRS(NoUnwind),
|
||||
EFFECT(Refcounting, Deallocating),
|
||||
EFFECT(RefCounting, Deallocating),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
|
||||
// void *swift_generic_assignWithTake(opaque* dest, opaque* src, const Metadata* type);
|
||||
@@ -2645,7 +2645,7 @@ FUNCTION(GenericAssignWithTake,
|
||||
RETURNS(Int8PtrTy),
|
||||
ARGS(Int8PtrTy, Int8PtrTy, TypeMetadataPtrTy),
|
||||
ATTRS(NoUnwind),
|
||||
EFFECT(Refcounting, Deallocating),
|
||||
EFFECT(RefCounting, Deallocating),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
|
||||
// void *swift_generic_initWithCopy(opaque* dest, opaque* src, const Metadata* type);
|
||||
@@ -2655,7 +2655,7 @@ FUNCTION(GenericInitWithCopy,
|
||||
RETURNS(Int8PtrTy),
|
||||
ARGS(Int8PtrTy, Int8PtrTy, TypeMetadataPtrTy),
|
||||
ATTRS(NoUnwind),
|
||||
EFFECT(Refcounting),
|
||||
EFFECT(RefCounting),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
|
||||
// void *swift_generic_initWithTake(opaque* dest, opaque* src, const Metadata* type);
|
||||
@@ -2665,7 +2665,7 @@ FUNCTION(GenericInitWithTake,
|
||||
RETURNS(Int8PtrTy),
|
||||
ARGS(Int8PtrTy, Int8PtrTy, TypeMetadataPtrTy),
|
||||
ATTRS(NoUnwind),
|
||||
EFFECT(Refcounting),
|
||||
EFFECT(RefCounting),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
|
||||
// void *swift_generic_initializeBufferWithCopyOfBuffer(ValueBuffer* dest, ValueBuffer* src, const Metadata* type);
|
||||
@@ -2677,7 +2677,7 @@ FUNCTION(GenericInitializeBufferWithCopyOfBuffer,
|
||||
getFixedBufferTy()->getPointerTo(),
|
||||
TypeMetadataPtrTy),
|
||||
ATTRS(NoUnwind),
|
||||
EFFECT(Refcounting),
|
||||
EFFECT(RefCounting),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
|
||||
// unsigned swift_singletonEnum_getEnumTag(swift::OpaqueValue *address,
|
||||
|
||||
@@ -79,6 +79,20 @@ inline bool operator&(RuntimeEffect lhs, RuntimeEffect rhs) {
|
||||
|
||||
} // end swift namespace
|
||||
|
||||
namespace RuntimeConstants {
|
||||
const auto NoEffect = swift::RuntimeEffect::NoEffect;
|
||||
const auto Locking = swift::RuntimeEffect::Locking;
|
||||
const auto Allocating = swift::RuntimeEffect::Allocating;
|
||||
const auto Deallocating = swift::RuntimeEffect::Deallocating;
|
||||
const auto RefCounting = swift::RuntimeEffect::RefCounting;
|
||||
const auto ObjectiveC = swift::RuntimeEffect::ObjectiveC;
|
||||
const auto Concurrency = swift::RuntimeEffect::Concurrency;
|
||||
const auto AutoDiff = swift::RuntimeEffect::AutoDiff;
|
||||
const auto MetaData = swift::RuntimeEffect::MetaData;
|
||||
const auto Casting = swift::RuntimeEffect::Casting;
|
||||
const auto ExclusivityChecking = swift::RuntimeEffect::ExclusivityChecking;
|
||||
}
|
||||
|
||||
// Enable the following macro to perform validation check on the runtime effects
|
||||
// of instructions in IRGen.
|
||||
// #define CHECK_RUNTIME_EFFECT_ANALYSIS
|
||||
|
||||
@@ -787,20 +787,6 @@ namespace RuntimeConstants {
|
||||
const auto FirstParamReturned = llvm::Attribute::Returned;
|
||||
const auto WillReturn = llvm::Attribute::WillReturn;
|
||||
|
||||
#ifdef CHECK_RUNTIME_EFFECT_ANALYSIS
|
||||
const auto NoEffect = RuntimeEffect::NoEffect;
|
||||
const auto Locking = RuntimeEffect::Locking;
|
||||
const auto Allocating = RuntimeEffect::Allocating;
|
||||
const auto Deallocating = RuntimeEffect::Deallocating;
|
||||
const auto RefCounting = RuntimeEffect::RefCounting;
|
||||
const auto ObjectiveC = RuntimeEffect::ObjectiveC;
|
||||
const auto Concurrency = RuntimeEffect::Concurrency;
|
||||
const auto AutoDiff = RuntimeEffect::AutoDiff;
|
||||
const auto MetaData = RuntimeEffect::MetaData;
|
||||
const auto Casting = RuntimeEffect::Casting;
|
||||
const auto ExclusivityChecking = RuntimeEffect::ExclusivityChecking;
|
||||
#endif
|
||||
|
||||
RuntimeAvailability AlwaysAvailable(ASTContext &Context) {
|
||||
return RuntimeAvailability::AlwaysAvailable;
|
||||
}
|
||||
|
||||
@@ -43,21 +43,33 @@ public:
|
||||
// In embedded Swift, the stdlib contains all the runtime functions needed
|
||||
// (swift_retain, etc.). Link them in so they can be referenced in IRGen.
|
||||
if (M.getOptions().EmbeddedSwift && LinkEmbeddedRuntime) {
|
||||
linkEmbeddedRuntimeFromStdlib();
|
||||
linkEmbeddedRuntimeFromStdlib(!M.getOptions().NoAllocations);
|
||||
}
|
||||
}
|
||||
|
||||
void linkEmbeddedRuntimeFromStdlib() {
|
||||
void linkEmbeddedRuntimeFromStdlib(bool includeAllocatingFunctions) {
|
||||
#define FUNCTION(ID, NAME, CC, AVAILABILITY, RETURNS, ARGS, ATTRS, EFFECT, \
|
||||
MEMORY_EFFECTS) \
|
||||
linkEmbeddedRuntimeFunctionByName(#NAME);
|
||||
{ \
|
||||
using namespace RuntimeConstants; \
|
||||
ArrayRef<RuntimeEffect> effects = {EFFECT}; \
|
||||
bool allocating = false; \
|
||||
for (RuntimeEffect rt : effects) { \
|
||||
if (rt == RuntimeEffect::Allocating || \
|
||||
rt == RuntimeEffect::Deallocating) \
|
||||
allocating = true; \
|
||||
} \
|
||||
bool include = true; \
|
||||
if (allocating) include = includeAllocatingFunctions; \
|
||||
if (include) linkEmbeddedRuntimeFunctionByName(#NAME); \
|
||||
}
|
||||
|
||||
#define RETURNS(...)
|
||||
#define ARGS(...)
|
||||
#define NO_ARGS
|
||||
#define ATTRS(...)
|
||||
#define NO_ATTRS
|
||||
#define EFFECT(...)
|
||||
#define EFFECT(...) __VA_ARGS__
|
||||
#define MEMORY_EFFECTS(...)
|
||||
#define UNKNOWN_MEMEFFECTS
|
||||
|
||||
|
||||
44
test/embedded/dependencies-no-allocations.swift
Normal file
44
test/embedded/dependencies-no-allocations.swift
Normal file
@@ -0,0 +1,44 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend -enable-experimental-feature Embedded -no-allocations %s -c -o %t/a.o
|
||||
|
||||
// RUN: grep DEP\: %s | sed 's#// DEP\: ##' | sort > %t/allowed-dependencies.txt
|
||||
|
||||
// Linux/ELF doesn't use the "_" prefix in symbol mangling.
|
||||
// RUN: if [ %target-os == "linux-gnu" ]; then sed -E -i -e 's/^_(.*)$/\1/' %t/allowed-dependencies.txt; fi
|
||||
|
||||
// RUN: %llvm-nm --undefined-only --format=just-symbols %t/a.o | sort | tee %t/actual-dependencies.txt
|
||||
|
||||
// Fail if there is any entry in actual-dependencies.txt that's not in allowed-dependencies.txt
|
||||
// RUN: test -z "`comm -13 %t/allowed-dependencies.txt %t/actual-dependencies.txt`"
|
||||
|
||||
// DEP: ___stack_chk_fail
|
||||
// DEP: ___stack_chk_guard
|
||||
// DEP: _memset
|
||||
// DEP: _putchar
|
||||
|
||||
// RUN: %target-clang -x c -c %S/Inputs/print.c -o %t/print.o
|
||||
// RUN: %target-clang %t/a.o %t/print.o -o %t/a.out
|
||||
// RUN: %target-run %t/a.out | %FileCheck %s
|
||||
|
||||
// REQUIRES: swift_in_compiler
|
||||
// REQUIRES: executable_test
|
||||
// REQUIRES: optimized_stdlib
|
||||
// REQUIRES: OS=macosx || OS=linux-gnu
|
||||
|
||||
@_silgen_name("putchar")
|
||||
func putchar(_: UInt8)
|
||||
|
||||
public func print(_ s: StaticString, terminator: StaticString = "\n") {
|
||||
var p = s.utf8Start
|
||||
while p.pointee != 0 {
|
||||
putchar(p.pointee)
|
||||
p += 1
|
||||
}
|
||||
p = terminator.utf8Start
|
||||
while p.pointee != 0 {
|
||||
putchar(p.pointee)
|
||||
p += 1
|
||||
}
|
||||
}
|
||||
|
||||
print("Hello Embedded Swift!") // CHECK: Hello Embedded Swift!
|
||||
Reference in New Issue
Block a user