[Sema] NFC: Reorder misc bits for better code gen

As a general rule, if one wants packs miscellaneous bits into what is
otherwise just a number, the low bits are preferable over the high bits,
at least on x86. On ppc64/ppc64le, the results are more of a wash. For
reference:

struct X {
    unsigned kind : 3;
    unsigned level : 29;
};

X example(X x, unsigned y) {
    x.level += y;
    return x;
}

bool example(X x) {
    return x.level > 1;
}

==== x86_64 with 'kind' first ====

_Z7example1Xj:
        leal    (%rdi,%rsi,8), %eax
        retq

_Z7example1X:
        cmpl    $15, %edi
        seta    %al
        retq

==== x86_64 with 'kind' last ====

_Z7example1Xj:
        leal    (%rsi,%rdi), %eax
        andl    $536870911, %eax        # imm = 0x1FFFFFFF
        andl    $-536870912, %edi       # imm = 0xE0000000
        orl     %edi, %eax
        retq

_Z7example1X:
        testl   $536870910, %edi        # imm = 0x1FFFFFFE
        setne   %al
        retq

==== PPC64 with 'kind' first ====

_Z7example1Xj:
        add 5, 5, 4
        rlwimi 5, 4, 0, 0, 2
        stw 5, 0(3)
        blr

_Z7example1X:
        rlwinm 3, 3, 0, 3, 30
        cntlzw  3, 3
        srwi 3, 3, 5
        xori 3, 3, 1
        blr

==== PPC64 with 'kind' last ====

_Z7example1Xj:
        slwi 5, 5, 3
        add 4, 5, 4
        stw 4, 0(3)
        blr

_Z7example1X:
        clrldi  3, 3, 32
        subfic 3, 3, 15
        rldicl 3, 3, 1, 63
        blr

==== PPC64LE with 'kind' first ====

_Z7example1Xj:
        slwi 4, 4, 3
        add 3, 4, 3
        blr

_Z7example1X:
        clrldi  3, 3, 32
        subfic 3, 3, 15
        rldicl 3, 3, 1, 63
        blr

==== PPC64LE with 'kind' last ====

_Z7example1Xj:
        add 4, 4, 3
        rlwimi 3, 4, 0, 3, 31
        blr

_Z7example1X:
        rlwinm 3, 3, 0, 3, 30
        cntlzw  3, 3
        srwi 3, 3, 5
        xori 3, 3, 1
        blr
This commit is contained in:
David Zarzycki
2018-05-17 16:04:28 -04:00
parent 812e94587e
commit 7a5d9680e1

View File

@@ -86,14 +86,15 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
// Selector for the partial_application_of_function_invalid diagnostic
// message.
struct PartialApplication {
unsigned level : 29;
enum : unsigned {
Function,
MutatingMethod,
SuperInit,
SelfInit,
};
// 'kind' before 'level' is better for code gen.
unsigned kind : 3;
unsigned level : 29;
};
// Partial applications of functions that are not permitted. This is
@@ -121,7 +122,7 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
// Partial applications of delegated initializers aren't allowed, and
// don't really make sense to begin with.
InvalidPartialApplications.insert({ expr, {1, kind} });
InvalidPartialApplications.insert({ expr, {kind, 1} });
return;
}
@@ -141,7 +142,7 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
if (!expr->getArg()->getType()->isMaterializable()) {
// We need to apply all argument clauses.
InvalidPartialApplications.insert({
fnExpr, {fn->getNumParameterLists(), kind}
fnExpr, {kind, fn->getNumParameterLists()}
});
}
}
@@ -172,7 +173,7 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
InvalidPartialApplications.erase(foundApplication);
if (level > 1) {
// We have remaining argument clauses.
InvalidPartialApplications.insert({ AE, {level - 1, kind} });
InvalidPartialApplications.insert({ AE, {kind, level - 1} });
}
return;
}