-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[stdlib][SR-2239]: add support for AAPCS64 variadics #15174
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
Conversation
@swift-ci Please smoke test |
lib/ClangImporter/ImportDecl.cpp
Outdated
if (ClangTypeSize != ClangCtx.getTypeSize(ClangCtx.VoidPtrTy)){ | ||
if(ClangCtx.getTargetInfo().getBuiltinVaListKind() != clang::TargetInfo::AArch64ABIBuiltinVaList) | ||
return std::make_pair(Type(), ""); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please clang-format this bit.
stdlib/public/core/CTypes.swift
Outdated
@@ -227,6 +227,29 @@ extension UInt { | |||
} | |||
} | |||
|
|||
#if arch(arm64) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should also include Windows, as Windows ARM64 handles variadics similar to macOS.
stdlib/public/core/VarArgs.swift
Outdated
@_versioned | ||
internal let _countFPRegisters = 8 | ||
|
||
//128bit, 2 64bit word |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space after the comment leader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hyphen between “128” and “bit” and between “64” and “bit”; noun-verb agreement requires “words,” not “word.” End the comment with punctuation.
stdlib/public/core/VarArgs.swift
Outdated
|
||
//128bit, 2 64bit word | ||
@_versioned | ||
internal let _fpRegisterWords = 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be nicer to express this as a sizeof(double) / sizeof(int)
or something like that.
stdlib/public/core/VarArgs.swift
Outdated
@_fixed_layout // FIXME(sil-serialize-all) | ||
@_versioned // FIXME(sil-serialize-all) | ||
final internal class _VaListBuilder { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary newline
stdlib/public/core/VarArgs.swift
Outdated
@@ -467,6 +491,140 @@ final internal class _VaListBuilder { | |||
internal var storage: ContiguousArray<Int> | |||
} | |||
|
|||
#elseif arch(arm64) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS)) | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary newline
stdlib/public/core/VarArgs.swift
Outdated
startIndex += 1 | ||
} | ||
fpRegistersUsed += 1 | ||
}else if encoded.count == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space after }.
stdlib/public/core/VarArgs.swift
Outdated
var startIndex = ( _fpRegisterWords * _countFPRegisters) + gpRegistersUsed | ||
storage[startIndex] = encoded[0] | ||
gpRegistersUsed += 1 | ||
}else{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space around else
@swift-ci please test |
Build failed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more code formatting comments.
stdlib/public/core/VarArgs.swift
Outdated
@_versioned | ||
internal let _countFPRegisters = 8 | ||
|
||
//128bit, 2 64bit word |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hyphen between “128” and “bit” and between “64” and “bit”; noun-verb agreement requires “words,” not “word.” End the comment with punctuation.
stdlib/public/core/VarArgs.swift
Outdated
internal let _fpRegisterWords = 2 | ||
|
||
@_versioned | ||
internal let _registerSaveWords = _countGPRegisters + (_countFPRegisters * _fpRegisterWords) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please wrap to 80 characters.
stdlib/public/core/VarArgs.swift
Outdated
|
||
if arg is _CVarArgPassedAsDouble | ||
&& fpRegistersUsed < _countFPRegisters { | ||
var startIndex = (fpRegistersUsed * _fpRegisterWords) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indenting should be increased by two spaces compared to “if”—you can choose to move the brace down to its own line when the conditional expression is multi-line, if that helps you.
stdlib/public/core/VarArgs.swift
Outdated
gpRegistersUsed += 1 | ||
}else{ | ||
//arguments in stack slot | ||
appendWords(encoded) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise here, the indent should be increased by two and not four spaces.
stdlib/public/core/VarArgs.swift
Outdated
allocated = max(newCount, allocated * 2) | ||
let newStorage = allocStorage(wordCount: allocated) | ||
storage = newStorage | ||
// count is updated below |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please write comments in sentence case, with a beginning capital letter and a closing period.
stdlib/public/core/VarArgs.swift
Outdated
#elseif arch(arm64) | ||
|
||
// ARM IHI 0055B | ||
// va_list may refer to any paramenter may be in one of three memory locations: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: parameter; missing word between “parameter” and “may”; needs wrapping to 80 characters.
Just fix spacing, indentation and formatting. |
@swift-ci please test |
Build failed |
@swift-ci please test macOS platform |
I tried applying these changes as a patch to swift-4.1-DEVELOPMENT-SNAPSHOT-2018-03-05-a since that branch has many fewer test failures than master on Linux aarch64. The ClangImporter/ctypes_parse.swift test passes now but the stdlib/VarArgs.swift test still fails (although it does much better). It looks like handling of FP arguments is not correct:
NB: I'm a swift newbie so I apologize if I'm doing something wrong here but I thought my input might help. |
@jasonm128 |
I can confirm that this latest version fixes the VarArgs.swift test on Linux aarch64 (Ubuntu 16.04). However, since the whole |
@swift-ci please test |
Can we get this merged with the "swift-4.1-branch" and the "swift-4.2-branch"? |
This PR will address a problem that's blocking a clean build by the new arm64 CI for Swift, referenced at swiftlang/swift-community-hosted-continuous-integration#10 . |
@compnerd please take a look? |
@airspeedswift @jrose-apple can you help? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof, this has been open a while. I'd still hope to have someone more ABI-savvy than me review this, but here's some initial comments. (@compnerd only works on Swift in his free time, so we can't force him to participate.)
let vr_top = storage + (_fpRegisterWords * _countFPRegisters) | ||
let gr_top = vr_top + _countGPRegisters | ||
|
||
return CVaListPointer(__stack: gr_top, __gr_top: gr_top, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
__stack
and __gr_top
are not always the same for long argument lists, right?
|
||
@_fixed_layout // FIXME(sil-serialize-all) | ||
@_versioned // FIXME(sil-serialize-all) | ||
final internal class _VaListBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems heavily duplicated with the x86_64 / s390x implementation. Is it possible to merge them?
} | ||
|
||
@_versioned // FIXME(sil-serialize-all) | ||
internal let requiredAlignmentInBytes = MemoryLayout<Double>.alignment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the AAPCS doc I see a 16-byte alignment for some of the fields. Is that accounted for elsewhere?
__vr_off: Int32) | ||
|
||
@_inlineable // FIXME(sil-serialize-all) | ||
public // @testable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any direct tests of this initializer, but that's probably okay. That means you can leave it internal
.
#if arch(arm64) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(Windows)) | ||
@_fixed_layout | ||
public struct CVaListPointer { | ||
@_versioned // FIXME(sil-serialize-all) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: we now have non-underscored forms of _versioned
and _inlineable
(usableFromInline
and 'inlinable`, respectively). I know this is an artifact of how long this patch has sat here, though!
@jrose-apple thanks for looking at this. |
@KoVuInc @jasonm128 are you available to update this PR? |
@futurejones I'm willing to help but I'm not sure I'm able. I'm still new to Swift so I'm not familiar with a lot of the subtleties. I maintain an aarch64 system and have been trying to make Swift available for other users. I also don't have push access to the OP's repo. Let's see if @KoVuInc is available and I'll try to help if not. |
@futurejones @jasonm128 Sure, I'll spend sometime to update this PR. |
if (ClangCtx.getTargetInfo().getBuiltinVaListKind() != | ||
clang::TargetInfo::AArch64ABIBuiltinVaList) | ||
return std::make_pair(Type(), ""); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this might be easier to read as:
if (ClangCtx.getTargetInfo().getBuiltinVaListKind() == clang::TargetInfo::AArch64ABIBuiltinVaList)
break;
if (ClangTypeSize == ClangCtx.getTypeSize(ClangCtx.VoidPtrTy))
break;
return std::make_pair(Type(), "");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we just switch over getBuiltinVaListKind()
instead of considering the size of the type at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the original intent was to make sure it was layout-compatible with Swift.CVaListPointer, which is a simpler proposition, but that would probably work too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jrose-apple, I think that switching over getBuiltinVaListKind
accomplishes that and much more explicit. Just because they they have the same size doesn't necessarily guarantee layout compatibility.
internal func append(_ arg: CVarArg) { | ||
var encoded = arg._cVarArgEncoding | ||
|
||
if arg is _CVarArgPassedAsDouble |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you hoist out arg is _CVarArgPassedAsDouble
into a variable?
let isDouble = arg is _CVarArgPassedAsDouble
@KoVuInc It's been a while and there hasn't been any activity here. The SR has been released back to the community. Thank you for everything you did here. I'm sure some other contributor will find this patch a very helpful place to start. |
Support variadics on aarch64 aapcs64
Resolves SR-2239.