Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[embedded] In -no-allocations, avoid linking allocating/deallocating runtime functions #70357

Merged
merged 2 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 5 additions & 5 deletions include/swift/Runtime/RuntimeFunctions.def
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -2677,7 +2677,7 @@ FUNCTION(GenericInitializeBufferWithCopyOfBuffer,
getFixedBufferTy()->getPointerTo(),
TypeMetadataPtrTy),
ATTRS(NoUnwind),
EFFECT(Refcounting),
EFFECT(RefCounting),
UNKNOWN_MEMEFFECTS)

// unsigned swift_singletonEnum_getEnumTag(swift::OpaqueValue *address,
Expand Down
14 changes: 14 additions & 0 deletions include/swift/SIL/RuntimeEffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 0 additions & 14 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
16 changes: 13 additions & 3 deletions lib/SILOptimizer/UtilityPasses/Link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,35 @@ class SILLinker : public SILModuleTransform {
}

void linkEmbeddedRuntimeFromStdlib() {
using namespace RuntimeConstants;
#define FUNCTION(ID, NAME, CC, AVAILABILITY, RETURNS, ARGS, ATTRS, EFFECT, \
MEMORY_EFFECTS) \
linkEmbeddedRuntimeFunctionByName(#NAME);
linkEmbeddedRuntimeFunctionByName(#NAME, EFFECT);

#define RETURNS(...)
#define ARGS(...)
#define NO_ARGS
#define ATTRS(...)
#define NO_ATTRS
#define EFFECT(...)
#define EFFECT(...) { __VA_ARGS__ }
#define MEMORY_EFFECTS(...)
#define UNKNOWN_MEMEFFECTS

#include "swift/Runtime/RuntimeFunctions.def"
}

void linkEmbeddedRuntimeFunctionByName(StringRef name) {
void linkEmbeddedRuntimeFunctionByName(StringRef name,
ArrayRef<RuntimeEffect> effects) {
SILModule &M = *getModule();

bool allocating = false;
for (RuntimeEffect rt : effects)
if (rt == RuntimeEffect::Allocating || rt == RuntimeEffect::Deallocating)
allocating = true;

// Don't link allocating runtime functions in -no-allocations mode.
if (M.getOptions().NoAllocations && allocating) return;

// Bail if runtime function is already loaded.
if (M.lookUpFunction(name)) return;

Expand Down
44 changes: 44 additions & 0 deletions test/embedded/dependencies-no-allocations.swift
Original file line number Diff line number Diff line change
@@ -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!