Thread overview
CT BitArray
Oct 31, 2018
Bastiaan Veelo
Nov 01, 2018
Stefan Koch
Nov 01, 2018
Bastiaan Veelo
Apr 02, 2020
Bastiaan Veelo
Apr 03, 2020
Johan
Apr 04, 2020
Johan
Nov 01, 2018
Bastiaan Veelo
Apr 05, 2020
Johan
October 31, 2018
Currently, BitArray is not usable at compile time, so you cannot do
```
enum e = BitArray([1, 1, 1, 0]);
```
This gives
> /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` cannot be interpreted at compile time, because it has no available source code

IIUC, that is because `bts` comes from core.bitop but no source code is there. I am guessing these are filled in by compiler intrinsics or the like, and they are unavailable at CT, correct?

I suppose that alternative implementations of `btc`, `bts`, `btr`, `bsf` and `bt` could exist that do not use the runtime that could be used if(__ctfe) in the implementation of BitArray, that would make the above code work. Is this feasible? Is there precedent in phobos? Are there complications?

Thanks!

November 01, 2018
On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo wrote:
> Currently, BitArray is not usable at compile time, so you cannot do
> ```
> enum e = BitArray([1, 1, 1, 0]);
> ```
> This gives
>> /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` cannot be interpreted at compile time, because it has no available source code
>
> IIUC, that is because `bts` comes from core.bitop but no source code is there. I am guessing these are filled in by compiler intrinsics or the like, and they are unavailable at CT, correct?
>
> I suppose that alternative implementations of `btc`, `bts`, `btr`, `bsf` and `bt` could exist that do not use the runtime that could be used if(__ctfe) in the implementation of BitArray, that would make the above code work. Is this feasible? Is there precedent in phobos? Are there complications?
>
> Thanks!

Oh that ... actually I can fix that with a small patch to dmd.

Tell me which version are you using and I'll make it for you.

Cheers,

Stefan
November 01, 2018
On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote:
> On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo wrote:
>> Currently, BitArray is not usable at compile time, so you cannot do
>> ```
>> enum e = BitArray([1, 1, 1, 0]);
>> ```
>> This gives
>>> /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` cannot be interpreted at compile time, because it has no available source code
>>
>> IIUC, that is because `bts` comes from core.bitop but no source code is there. I am guessing these are filled in by compiler intrinsics or the like, and they are unavailable at CT, correct?
>>
>> I suppose that alternative implementations of `btc`, `bts`, `btr`, `bsf` and `bt` could exist that do not use the runtime that could be used if(__ctfe) in the implementation of BitArray, that would make the above code work. Is this feasible? Is there precedent in phobos? Are there complications?
>>
>> Thanks!
>
> Oh that ... actually I can fix that with a small patch to dmd.
>
> Tell me which version are you using and I'll make it for you.
>
> Cheers,
>
> Stefan

Thank you, Stefan. At the moment we are using latest stable dmd, v2.082.1. I expect to switch to ldc or gdc at a later time. I don't think we'll be patching the compiler, support in the mainline compilers would be much preferable. It is not a blocker either, we can wait as long as it takes and meanwhile use module level BitArrays like
```
immutable BitArray e;
static this()
{
    e = BitArray([1, 1, 1, 0]);
}
```

It just seemed like a fixable limitation to me, hence my question here. Shall we start with a feature request?

Bastiaan.
November 01, 2018
On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote:
> Tell me which version are you using and I'll make it for you.

By the way this is a really generous offer, thanks for being like that!
April 02, 2020
On Thursday, 1 November 2018 at 08:50:38 UTC, Bastiaan Veelo wrote:
> On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote:
>> On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo wrote:
>>> Currently, BitArray is not usable at compile time, so you cannot do
>>> ```
>>> enum e = BitArray([1, 1, 1, 0]);
>>> ```
>>> This gives
>>>> /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` cannot be interpreted at compile time, because it has no available source code

[....]

> meanwhile use module level BitArrays like
> ```
> immutable BitArray e;
> static this()
> {
>     e = BitArray([1, 1, 1, 0]);
> }
> ```

Note to self: when this occurs, the above error message does not offer a trace to the place where this originates. To get that, temporarily insert the following at the indicated line in bitmanip.d:
```
if(__ctfe) assert(false, "trap");
```

--Bastiaan.
April 02, 2020
On 4/2/20 8:26 AM, Bastiaan Veelo wrote:
> On Thursday, 1 November 2018 at 08:50:38 UTC, Bastiaan Veelo wrote:
>> On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote:
>>> On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo wrote:
>>>> Currently, BitArray is not usable at compile time, so you cannot do
>>>> ```
>>>> enum e = BitArray([1, 1, 1, 0]);
>>>> ```
>>>> This gives
>>>>> /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` cannot be interpreted at compile time, because it has no available source code
> 
> [....]
> 
>> meanwhile use module level BitArrays like
>> ```
>> immutable BitArray e;
>> static this()
>> {
>>     e = BitArray([1, 1, 1, 0]);
>> }
>> ```
> 
> Note to self: when this occurs, the above error message does not offer a trace to the place where this originates. To get that, temporarily insert the following at the indicated line in bitmanip.d:
> ```
> if(__ctfe) assert(false, "trap");
> ```
> 

Hm... I thought there was precedent for providing fallback implementations for intrinsics. That is, you define the function, which is only used if the intrinsic is not available.

I can't remember where I saw this. But you could try this by simply implementing the bitops in core.bitop, and see if they are used outside ctfe.

-Steve
April 03, 2020
On Thursday, 2 April 2020 at 12:41:28 UTC, Steven Schveighoffer wrote:
> On 4/2/20 8:26 AM, Bastiaan Veelo wrote:
>> On Thursday, 1 November 2018 at 08:50:38 UTC, Bastiaan Veelo wrote:
>>> On Thursday, 1 November 2018 at 00:01:04 UTC, Stefan Koch wrote:
>>>> On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo wrote:
>>>>> Currently, BitArray is not usable at compile time, so you cannot do
>>>>> ```
>>>>> enum e = BitArray([1, 1, 1, 0]);
>>>>> ```
>>>>> This gives
>>>>>> /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` cannot be interpreted at compile time, because it has no available source code
>> 
>
> Hm... I thought there was precedent for providing fallback implementations for intrinsics. That is, you define the function, which is only used if the intrinsic is not available.
>
> I can't remember where I saw this. But you could try this by simply implementing the bitops in core.bitop, and see if they are used outside ctfe.

There are a bunch of functions implemented with `if (!__ctfe)`. DMD and LDC are smart enough to elide `if(false/true)` control flow completely even in debug code, so there is no penalty to using `if (!__ctfe)`.
See for example: https://github.com/ldc-developers/druntime/blob/ldc/src/core/bitop.d#L85

-Johan



April 03, 2020
On 4/3/20 3:13 PM, Johan wrote:
> On Thursday, 2 April 2020 at 12:41:28 UTC, Steven Schveighoffer wrote:

>>
>> Hm... I thought there was precedent for providing fallback implementations for intrinsics. That is, you define the function, which is only used if the intrinsic is not available.
>>
>> I can't remember where I saw this. But you could try this by simply implementing the bitops in core.bitop, and see if they are used outside ctfe.
> 
> There are a bunch of functions implemented with `if (!__ctfe)`. DMD and LDC are smart enough to elide `if(false/true)` control flow completely even in debug code, so there is no penalty to using `if (!__ctfe)`.
> See for example: https://github.com/ldc-developers/druntime/blob/ldc/src/core/bitop.d#L85

Nice!

I'm trying to understand that. It looks like you are calling the intrinsic that llvm recognizes. What can you do when bsf *is* the intrinsic? Does DMD have to change its intrinsic to something that's not core.bitop.bsf so we can call it? Or would that code as written work if ported to druntime mainline? I.e. the compiler replaces the bsf with the intrinsic and ignores the implementation in runtime code, but works at comiple time.

-Steve
April 04, 2020
On Friday, 3 April 2020 at 20:06:50 UTC, Steven Schveighoffer wrote:
> On 4/3/20 3:13 PM, Johan wrote:
>> On Thursday, 2 April 2020 at 12:41:28 UTC, Steven Schveighoffer wrote:
>
>>>
>>> Hm... I thought there was precedent for providing fallback implementations for intrinsics. That is, you define the function, which is only used if the intrinsic is not available.
>>>
>>> I can't remember where I saw this. But you could try this by simply implementing the bitops in core.bitop, and see if they are used outside ctfe.
>> 
>> There are a bunch of functions implemented with `if (!__ctfe)`. DMD and LDC are smart enough to elide `if(false/true)` control flow completely even in debug code, so there is no penalty to using `if (!__ctfe)`.
>> See for example: https://github.com/ldc-developers/druntime/blob/ldc/src/core/bitop.d#L85
>
> Nice!
>
> I'm trying to understand that. It looks like you are calling the intrinsic that llvm recognizes. What can you do when bsf *is* the intrinsic? Does DMD have to change its intrinsic to something that's not core.bitop.bsf so we can call it? Or would that code as written work if ported to druntime mainline?

I think it'd work without any changes needed. (note the version statements)

> I.e. the compiler replaces the bsf with the intrinsic and ignores the implementation in runtime code, but works at comiple time.

I think that's correct, yes.

-Johan

April 05, 2020
On Wednesday, 31 October 2018 at 23:14:08 UTC, Bastiaan Veelo wrote:
> Currently, BitArray is not usable at compile time, so you cannot do
> ```
> enum e = BitArray([1, 1, 1, 0]);
> ```
> This gives
>> /dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(1190): Error: `bts` cannot be interpreted at compile time, because it has no available source code
>
> IIUC, that is because `bts` comes from core.bitop but no source code is there. I am guessing these are filled in by compiler intrinsics or the like, and they are unavailable at CT, correct?
>
> I suppose that alternative implementations of `btc`, `bts`, `btr`, `bsf` and `bt` could exist that do not use the runtime that could be used if(__ctfe) in the implementation of BitArray, that would make the above code work. Is this feasible? Is there precedent in phobos? Are there complications?

https://github.com/ldc-developers/druntime/pull/182