Skip to content

[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

Closed
wants to merge 3 commits into from

Conversation

KoVuInc
Copy link

@KoVuInc KoVuInc commented Mar 12, 2018

Support variadics on aarch64 aapcs64

Resolves SR-2239.

@KoVuInc
Copy link
Author

KoVuInc commented Mar 12, 2018

@swift-ci Please smoke test

@KoVuInc KoVuInc changed the title stdlib: add support for AAPCS64 variadics [stdlib][SR-2239]: add support for AAPCS64 variadics Mar 12, 2018
if (ClangTypeSize != ClangCtx.getTypeSize(ClangCtx.VoidPtrTy)){
if(ClangCtx.getTargetInfo().getBuiltinVaListKind() != clang::TargetInfo::AArch64ABIBuiltinVaList)
return std::make_pair(Type(), "");
}
Copy link
Member

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.

@@ -227,6 +227,29 @@ extension UInt {
}
}

#if arch(arm64) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS))
Copy link
Member

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.

@_versioned
internal let _countFPRegisters = 8

//128bit, 2 64bit word
Copy link
Member

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

Copy link
Collaborator

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.


//128bit, 2 64bit word
@_versioned
internal let _fpRegisterWords = 2
Copy link
Member

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.

@_fixed_layout // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
final internal class _VaListBuilder {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary newline

@@ -467,6 +491,140 @@ final internal class _VaListBuilder {
internal var storage: ContiguousArray<Int>
}

#elseif arch(arm64) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS))


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary newline

startIndex += 1
}
fpRegistersUsed += 1
}else if encoded.count == 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after }.

var startIndex = ( _fpRegisterWords * _countFPRegisters) + gpRegistersUsed
storage[startIndex] = encoded[0]
gpRegistersUsed += 1
}else{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space around else

@compnerd
Copy link
Member

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 22d98a1

Copy link
Collaborator

@xwu xwu left a 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.

@_versioned
internal let _countFPRegisters = 8

//128bit, 2 64bit word
Copy link
Collaborator

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.

internal let _fpRegisterWords = 2

@_versioned
internal let _registerSaveWords = _countGPRegisters + (_countFPRegisters * _fpRegisterWords)
Copy link
Collaborator

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.


if arg is _CVarArgPassedAsDouble
&& fpRegistersUsed < _countFPRegisters {
var startIndex = (fpRegistersUsed * _fpRegisterWords)
Copy link
Collaborator

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.

gpRegistersUsed += 1
}else{
//arguments in stack slot
appendWords(encoded)
Copy link
Collaborator

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.

allocated = max(newCount, allocated * 2)
let newStorage = allocStorage(wordCount: allocated)
storage = newStorage
// count is updated below
Copy link
Collaborator

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.

#elseif arch(arm64)

// ARM IHI 0055B
// va_list may refer to any paramenter may be in one of three memory locations:
Copy link
Collaborator

@xwu xwu Mar 12, 2018

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.

@KoVuInc
Copy link
Author

KoVuInc commented Mar 13, 2018

Just fix spacing, indentation and formatting.

@compnerd
Copy link
Member

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 22d98a1

@compnerd
Copy link
Member

@swift-ci please test macOS platform

@jasonm128
Copy link

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:

/scratch/jasonm/swift-4.1-DEV-2018-03-05_AAPCS64-patch/swift/test/stdlib/VarArgs.swift:21:12: error: expected string not found in input
 // CHECK: The answer to life and everything is 42, 42, -42, 3.14
           ^
<stdin>:1:1: note: scanning from here
The answer to life and everything is 42, 42, -42, 0.000000
^

NB: I'm a swift newbie so I apologize if I'm doing something wrong here but I thought my input might help.

@KoVuInc
Copy link
Author

KoVuInc commented Mar 24, 2018

@jasonm128
The VarArgs.swift should pass in the last patch. Just tested on aarch64 android.

@jasonm128
Copy link

I can confirm that this latest version fixes the VarArgs.swift test on Linux aarch64 (Ubuntu 16.04).

However, since the whole sizeof(double)/sizeof(int) thing didn't work, I think it might be clearer to just set _fpRegisterWords = 2. This would match the style of the other architectures in this file. I'll defer to @compnerd on this though.

@compnerd
Copy link
Member

compnerd commented Apr 3, 2018

@swift-ci please test

@futurejones
Copy link
Contributor

Can we get this merged with the "swift-4.1-branch" and the "swift-4.2-branch"?

@vielmetti
Copy link

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 .

@vielmetti
Copy link

@compnerd please take a look?

@futurejones
Copy link
Contributor

@airspeedswift @jrose-apple can you help?
This issue is blocking all the builds on https://ci-external.swift.org/computer/ubuntu-16.04-aarch64/
What do we need to do to get this approved and merged?
Thanks.

Copy link
Contributor

@jrose-apple jrose-apple left a 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,
Copy link
Contributor

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 {
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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)
Copy link
Contributor

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 jrose-apple requested a review from rjmccall July 10, 2018 16:30
@futurejones
Copy link
Contributor

@jrose-apple thanks for looking at this.

@futurejones
Copy link
Contributor

@KoVuInc @jasonm128 are you available to update this PR?

@jasonm128
Copy link

@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.

@KoVuInc
Copy link
Author

KoVuInc commented Jul 12, 2018

@futurejones @jasonm128 Sure, I'll spend sometime to update this PR.

if (ClangCtx.getTargetInfo().getBuiltinVaListKind() !=
clang::TargetInfo::AArch64ABIBuiltinVaList)
return std::make_pair(Type(), "");
}
Copy link
Member

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(), "");

Copy link
Contributor

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?

Copy link
Contributor

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.

Copy link
Member

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
Copy link
Member

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

@CodaFi
Copy link
Contributor

CodaFi commented Nov 21, 2019

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants