Skip to content

Commit 750503e

Browse files
committed
Optimize FlagSet
Make it easier to inline the toBits mapping
1 parent 8491d1e commit 750503e

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

compiler/src/dotty/tools/dotc/core/Flags.scala

+29-26
Original file line numberDiff line numberDiff line change
@@ -18,47 +18,50 @@ object Flags {
1818
opaque type Flag <: FlagSet = Long
1919
private[Flags] def Flag(bits: Long): Flag = bits
2020
}
21-
export opaques.FlagSet
21+
import opaques.toBits
2222

2323
type Flag = opaques.Flag
2424

25+
type FlagSet = opaques.FlagSet
26+
def FlagSet(bits: Long): FlagSet = opaques.FlagSet(bits)
27+
2528
extension (x: FlagSet) {
2629

27-
def bits: Long = opaques.toBits(x)
30+
def bits: Long = toBits(x)
2831

2932
/** The union of the given flag sets.
3033
* Combining two FlagSets with `|` will give a FlagSet
3134
* that has the intersection of the applicability to terms/types
3235
* of the two flag sets. It is checked that the intersection is not empty.
3336
*/
3437
def | (y: FlagSet): FlagSet =
35-
if (x.bits == 0) y
36-
else if (y.bits == 0) x
38+
if (toBits(x) == 0) y
39+
else if (toBits(y) == 0) x
3740
else {
38-
val tbits = x.bits & y.bits & KINDFLAGS
41+
val tbits = toBits(x) & toBits(y) & KINDFLAGS
3942
if (tbits == 0)
4043
assert(false, s"illegal flagset combination: ${x.flagsString} and ${y.flagsString}")
41-
FlagSet(tbits | ((x.bits | y.bits) & ~KINDFLAGS))
44+
FlagSet(tbits | ((toBits(x) | toBits(y)) & ~KINDFLAGS))
4245
}
4346

4447
/** The intersection of the given flag sets */
45-
def & (y: FlagSet): FlagSet = FlagSet(x.bits & y.bits)
48+
def & (y: FlagSet): FlagSet = FlagSet(toBits(x) & toBits(y))
4649

4750
/** The intersection of a flag set with the complement of another flag set */
4851
def &~ (y: FlagSet): FlagSet = {
49-
val tbits = x.bits & KINDFLAGS
50-
if ((tbits & y.bits) == 0) x
51-
else FlagSet(tbits | ((x.bits & ~y.bits) & ~KINDFLAGS))
52+
val tbits = toBits(x) & KINDFLAGS
53+
if ((tbits & toBits(y)) == 0) x
54+
else FlagSet(tbits | ((toBits(x) & ~toBits(y)) & ~KINDFLAGS))
5255
}
5356

5457
def ^ (y: FlagSet) =
55-
FlagSet((x.bits | y.bits) & KINDFLAGS | (x.bits ^ y.bits) & ~KINDFLAGS)
58+
FlagSet((toBits(x) | toBits(y)) & KINDFLAGS | (toBits(x) ^ toBits(y)) & ~KINDFLAGS)
5659

5760
/** Does the given flag set contain the given flag?
5861
* This means that both the kind flags and the carrier bits have non-empty intersection.
5962
*/
6063
def is (flag: Flag): Boolean = {
61-
val fs = x.bits & flag.bits
64+
val fs = toBits(x) & toBits(flag)
6265
(fs & KINDFLAGS) != 0 && (fs & ~KINDFLAGS) != 0
6366
}
6467

@@ -71,7 +74,7 @@ object Flags {
7174
* This means that both the kind flags and the carrier bits have non-empty intersection.
7275
*/
7376
def isOneOf (flags: FlagSet): Boolean = {
74-
val fs = x.bits & flags.bits
77+
val fs = toBits(x) & toBits(flags)
7578
(fs & KINDFLAGS) != 0 && (fs & ~KINDFLAGS) != 0
7679
}
7780

@@ -84,9 +87,9 @@ object Flags {
8487
* Pre: The intersection of the term/type flags of both sets must be non-empty.
8588
*/
8689
def isAllOf (flags: FlagSet): Boolean = {
87-
val fs = x.bits & flags.bits
88-
((fs & KINDFLAGS) != 0 || flags.bits == 0) &&
89-
(fs >>> TYPESHIFT) == (flags.bits >>> TYPESHIFT)
90+
val fs = toBits(x) & toBits(flags)
91+
((fs & KINDFLAGS) != 0 || toBits(flags) == 0) &&
92+
(fs >>> TYPESHIFT) == (toBits(flags) >>> TYPESHIFT)
9093
}
9194

9295
/** Does a given flag set have all of the flags in another flag set
@@ -95,35 +98,35 @@ object Flags {
9598
*/
9699
def isAllOf (flags: FlagSet, butNot: FlagSet): Boolean = x.isAllOf(flags) && !x.isOneOf(butNot)
97100

98-
def isEmpty: Boolean = (x.bits & ~KINDFLAGS) == 0
101+
def isEmpty: Boolean = (toBits(x) & ~KINDFLAGS) == 0
99102

100103
/** Is a given flag set a subset of another flag set? */
101-
def <= (y: FlagSet): Boolean = (x.bits & y.bits) == x.bits
104+
def <= (y: FlagSet): Boolean = (toBits(x) & toBits(y)) == toBits(x)
102105

103106
/** Does the given flag set apply to terms? */
104-
def isTermFlags: Boolean = (x.bits & TERMS) != 0
107+
def isTermFlags: Boolean = (toBits(x) & TERMS) != 0
105108

106109
/** Does the given flag set apply to terms? */
107-
def isTypeFlags: Boolean = (x.bits & TYPES) != 0
110+
def isTypeFlags: Boolean = (toBits(x) & TYPES) != 0
108111

109112
/** The given flag set with all flags transposed to be type flags */
110-
def toTypeFlags: FlagSet = if (x.bits == 0) x else FlagSet(x.bits & ~KINDFLAGS | TYPES)
113+
def toTypeFlags: FlagSet = if (toBits(x) == 0) x else FlagSet(toBits(x) & ~KINDFLAGS | TYPES)
111114

112115
/** The given flag set with all flags transposed to be term flags */
113-
def toTermFlags: FlagSet = if (x.bits == 0) x else FlagSet(x.bits & ~KINDFLAGS | TERMS)
116+
def toTermFlags: FlagSet = if (toBits(x) == 0) x else FlagSet(toBits(x) & ~KINDFLAGS | TERMS)
114117

115118
/** The given flag set with all flags transposed to be common flags */
116-
def toCommonFlags: FlagSet = if (x.bits == 0) x else FlagSet(x.bits | KINDFLAGS)
119+
def toCommonFlags: FlagSet = if (toBits(x) == 0) x else FlagSet(toBits(x) | KINDFLAGS)
117120

118121
/** The number of non-kind flags in the given flag set */
119-
def numFlags: Int = java.lang.Long.bitCount(x.bits & ~KINDFLAGS)
122+
def numFlags: Int = java.lang.Long.bitCount(toBits(x) & ~KINDFLAGS)
120123

121124
/** The lowest non-kind bit set in the given flag set */
122-
def firstBit: Int = java.lang.Long.numberOfTrailingZeros(x.bits & ~KINDFLAGS)
125+
def firstBit: Int = java.lang.Long.numberOfTrailingZeros(toBits(x) & ~KINDFLAGS)
123126

124127
/** The list of non-empty names of flags with given index idx that are set in the given flag set */
125128
private def flagString(idx: Int): List[String] =
126-
if ((x.bits & (1L << idx)) == 0) Nil
129+
if ((toBits(x) & (1L << idx)) == 0) Nil
127130
else {
128131
def halfString(kind: Int) =
129132
if ((x.bits & (1L << kind)) != 0) flagName(idx)(kind) else ""

0 commit comments

Comments
 (0)