- 
                Notifications
    
You must be signed in to change notification settings  - Fork 13.9k
 
Open
Labels
A-allocatorsArea: Custom and system allocatorsArea: Custom and system allocatorsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
An alignment is guaranteed to be a power of two. However without intrinsics it's not possible to use this guarantee when constructing a new Layout from an old one only changing the size. For testing I used the following code:
pub fn dynamic_slow(layout: Layout, size: usize) -> Result<Layout, LayoutErr>{
    let align = layout.align();
    Layout::from_size_align(size, align)
}
pub fn dynamic_fast(layout: Layout, size: usize) -> Result<Layout, LayoutErr>{
    let align = layout.align();
    unsafe { core::intrinsics::assume(align.is_power_of_two()); }
    Layout::from_size_align(size, align)
}
pub fn static_slow() -> Result<Layout, LayoutErr> {
    dynamic_slow(Layout::new::<u32>(), 12)
}
pub fn static_fast() -> Result<Layout, LayoutErr> {
    dynamic_fast(Layout::new::<u32>(), 12)
}dynamic_fast assumes, that the alignment returned from Layout is a power of two. This results in this assembly:
example::dynamic_slow:
        lea     rax, [rsi - 1]
        mov     r8, rsi
        neg     r8
        xor     ecx, ecx
        test    rsi, rax
        mov     rdi, rsi
        cmovne  rdi, rcx
        test    rsi, rsi
        cmove   rdi, rsi
        mov     rax, rdx
        cmp     r8, rdx
        cmovae  rcx, rdi
        mov     rdx, rcx
        ret
example::dynamic_fast:
        mov     rax, rdx
        mov     rcx, rsi
        neg     rcx
        xor     edx, edx
        cmp     rcx, rax
        cmovae  rdx, rsi
        ret
example::static_slow:
        mov     eax, 12
        mov     edx, 4
        ret
example::static_fast:
        mov     eax, 12
        mov     edx, 4
        retWhile in the static case, this does not matter, the dynamic case don't have to check align.is_power_of_two().
Normally, I would create a pull request, which adds the intrinsic to Layout::align(), but core::intrinsics::assume is not available in const fns.
Metadata
Metadata
Assignees
Labels
A-allocatorsArea: Custom and system allocatorsArea: Custom and system allocatorsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.