Implementing 'swiftcall' calling convention on new target architectures


(Max Desiatov) #1

Hi all,

I'm currently trying to cross-compile Swift standard library for WebAssembly target. I've been able to reuse libc++ and musl from emscripten project, but I constantly stumble upon these and similar errors and warnings about unsupported calling convention:

/Users/maxd/Documents/swift-source/swift/include/swift/ABI/Metadata.h:728:3: warning: calling convention 'swiftcall' ignored for this target [-Wignored-attributes]
  SWIFT_CC(swift) void(SWIFT_CONTEXT HeapObject *);
/Users/maxd/Documents/swift-source/swift/include/swift/Runtime/Config.h:171:22: note: expanded from macro 'SWIFT_CC'
<scratch space>:66:1: note: expanded from here
/Users/maxd/Documents/swift-source/swift/include/swift/Runtime/Config.h:182:39: note: expanded from macro 'SWIFT_CC_swift'
#define SWIFT_CC_swift __attribute__((swiftcall))
In file included from /Users/maxd/Documents/swift-source/swift/stdlib/public/runtime/Heap.cpp:19:
In file included from /Users/maxd/Documents/swift-source/swift/stdlib/public/runtime/Private.h:22:
In file included from /Users/maxd/Documents/swift-source/swift/include/swift/Runtime/Metadata.h:20:
/Users/maxd/Documents/swift-source/swift/include/swift/ABI/Metadata.h:728:50: error: 'swift_context' parameter can only be used with swiftcall calling convention
  SWIFT_CC(swift) void(SWIFT_CONTEXT HeapObject *);

I find that WebAssemblyTargetInfo from LLVM does not override checkCallingConvention function from TargetInfo superclass, which causes issuing warnings for all non-C calling conventions. I guess ignoring those warnings is ok at this stage, but SWIFT_CC and SWIFT_CONTEXT macros cause actual errors.

Does this mean that swiftcall calling convention should be implemented after all for this target, or is there a workaround for SWIFT_CC and SWIFT_CONTEXT errors when ignoring swiftcall CC absence warnings?

(John McCall) #2

You need to implement swiftcc for your target, yes; if nothing else, the rules Swift uses for breaking up aggregates will differ from the rules for your platform C convention. For wasm, that really just means accepting it in the frontend. You could try to teach the frontend to not add the IR attributes, but you'll have to teach that to both Clang and Swift, and the resulting IR will be different coming out of the frontend, which will make it more annoying to test; I would instead suggest stripping it in when finalizing the wasm output. Just removing the attributes and changing the calling convention to C should still produce working code.