Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/core/atomic.d
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ else version( LDC )
{
import ldc.intrinsics;

pragma(inline, true):

HeadUnshared!(T) atomicOp(string op, T, V1)( ref shared T val, V1 mod )
if( __traits( compiles, mixin( "*cast(T*)&val" ~ op ~ "mod" ) ) )
{
Expand Down Expand Up @@ -1509,6 +1511,8 @@ else version( AsmX86_64 )
HeadUnshared!(T) atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)( ref const shared T val ) pure nothrow @nogc
if(__traits(isFloating, T))
{
version (LDC) pragma(inline, true);

static if(T.sizeof == int.sizeof)
{
static assert(is(T : float));
Expand Down
121 changes: 69 additions & 52 deletions src/core/bitop.d
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ nothrow:
@nogc:

version (LDC) {
import ldc.intrinsics;
// Do not use the DMD inline assembler.
}
else {
Expand Down Expand Up @@ -80,10 +81,10 @@ unittest
version (LDC)
{
// KLUDGE: Need to adapt the return type.
private pure pragma(LDC_intrinsic, "llvm.cttz.i#") T cttz(T)(T v, bool is_zero_undef);
pure int bsf(size_t v)
pragma(inline, true)
int bsf(size_t v) pure
{
return cast(int)cttz(v, true);
return cast(int)llvm_cttz(v, true);
}
}
else
Expand Down Expand Up @@ -132,10 +133,10 @@ unittest
*/
version (LDC)
{
private pure pragma(LDC_intrinsic, "llvm.ctlz.i#") T ctlz(T)(T v, bool is_zero_undef);
pure int bsr(size_t v)
pragma(inline, true)
int bsr(size_t v) pure
{
return cast(int)(size_t.sizeof * 8 - 1 - ctlz(v, true));
return cast(int)(size_t.sizeof * 8 - 1 - llvm_ctlz(v, true));
}
}
else
Expand Down Expand Up @@ -302,19 +303,22 @@ int bts(size_t* p, size_t bitnum) pure @system;
*/
version (LDC)
{
pure pragma(LDC_intrinsic, "llvm.bswap.i32")
uint bswap(uint v);
alias bswap = llvm_bswap!uint;
}
else
{
uint bswap(uint v) pure;
}
uint bswap(uint v) pure;


/**
* Swaps bytes in an 8 byte ulong end-to-end, i.e. byte 0 becomes
* byte 7, byte 1 becomes byte 6, etc.
*/
version (LDC)
{
alias bswap = llvm_bswap!ulong;
}
else
{
ulong bswap(ulong v) pure
{
auto sv = Split64(v);
Expand All @@ -325,6 +329,7 @@ ulong bswap(ulong v) pure

return (cast(ulong) sv.hi << 32) | sv.lo;
}
}

version (DigitalMars) version (AnyX86) @system // not pure
{
Expand Down Expand Up @@ -421,20 +426,21 @@ version(LDC) @system // not pure

version (LDC)
{
private pure pragma(LDC_intrinsic, "llvm.ctpop.i#") T ctpop(T)(T v);
pragma(inline, true):

ushort _popcnt(ushort x) pure
{
return ctpop(x);
return llvm_ctpop(x);
}

int _popcnt(uint x) pure
{
return cast(int)ctpop(x);
return cast(int)llvm_ctpop(x);
}

int _popcnt(ulong x) pure
{
return cast(int)ctpop(x);
return cast(int)llvm_ctpop(x);
}
}

Expand All @@ -446,22 +452,21 @@ int popcnt(uint x) pure
// Select the fastest method depending on the compiler and CPU architecture
version(LDC)
{
return _popcnt(x);
pragma(inline, true);
if (!__ctfe)
return _popcnt(x);
}
else
else version(DigitalMars)
{
version(DigitalMars)
static if (is(typeof(_popcnt(uint.max))))
{
static if (is(typeof(_popcnt(uint.max))))
{
import core.cpuid;
if (!__ctfe && hasPopcnt)
return _popcnt(x);
}
import core.cpuid;
if (!__ctfe && hasPopcnt)
return _popcnt(x);
}

return softPopcnt!uint(x);
}

return softPopcnt!uint(x);
}

unittest
Expand All @@ -482,45 +487,45 @@ unittest
/// ditto
int popcnt(ulong x) pure
{
// Select the fastest method depending on the compiler and CPU architecture
version(LDC)
{
return _popcnt(x);
pragma(inline, true);
if (!__ctfe)
return _popcnt(x);
}
else
{
import core.cpuid;

static if (size_t.sizeof == uint.sizeof)
// Select the fastest method depending on the compiler and CPU architecture
import core.cpuid;

static if (size_t.sizeof == uint.sizeof)
{
const sx = Split64(x);
version(DigitalMars)
{
const sx = Split64(x);
version(DigitalMars)
static if (is(typeof(_popcnt(uint.max))))
{
static if (is(typeof(_popcnt(uint.max))))
{
if (!__ctfe && hasPopcnt)
return _popcnt(sx.lo) + _popcnt(sx.hi);
}
if (!__ctfe && hasPopcnt)
return _popcnt(sx.lo) + _popcnt(sx.hi);
}

return softPopcnt!uint(sx.lo) + softPopcnt!uint(sx.hi);
}
else static if (size_t.sizeof == ulong.sizeof)

return softPopcnt!uint(sx.lo) + softPopcnt!uint(sx.hi);
}
else static if (size_t.sizeof == ulong.sizeof)
{
version(DigitalMars)
{
version(DigitalMars)
static if (is(typeof(_popcnt(ulong.max))))
{
static if (is(typeof(_popcnt(ulong.max))))
{
if (!__ctfe && hasPopcnt)
return _popcnt(x);
}
if (!__ctfe && hasPopcnt)
return _popcnt(x);
}

return softPopcnt!ulong(x);
}
else
static assert(false);

return softPopcnt!ulong(x);
}
else
static assert(false);
}

unittest
Expand Down Expand Up @@ -704,6 +709,12 @@ uint bitswap( uint x ) pure
{
if (!__ctfe)
{
version (LDC)
Copy link
Member Author

Choose a reason for hiding this comment

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

The 2 bitswap functions are already marked with pragma(inline, true).

{
static if (is(typeof(llvm_bitreverse(x))))
return llvm_bitreverse(x);
}
else
static if (is(typeof(asmBitswap32(x))))
return asmBitswap32(x);
}
Expand Down Expand Up @@ -738,6 +749,12 @@ ulong bitswap ( ulong x ) pure
{
if (!__ctfe)
{
version (LDC)
{
static if (is(typeof(llvm_bitreverse(x))))
return llvm_bitreverse(x);
}
else
static if (is(typeof(asmBitswap64(x))))
return asmBitswap64(x);
}
Expand Down
4 changes: 4 additions & 0 deletions src/core/checkedint.d
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ cent adds(cent x, cent y, ref bool overflow)
{
version(LDC)
{
pragma(inline, true);
if (__ctfe)
{
cent r = cast(ucent)x + cast(ucent)y;
Expand Down Expand Up @@ -317,6 +318,7 @@ ucent addu(ucent x, ucent y, ref bool overflow)
{
version(LDC)
{
pragma(inline, true);
if (__ctfe)
{
ucent r = x + y;
Expand Down Expand Up @@ -477,6 +479,7 @@ cent subs(cent x, cent y, ref bool overflow)
{
version(LDC)
{
pragma(inline, true);
if (__ctfe)
{
cent r = cast(ucent)x - cast(ucent)y;
Expand Down Expand Up @@ -634,6 +637,7 @@ ucent subu(ucent x, ucent y, ref bool overflow)
{
version(LDC)
{
pragma(inline, true);
if (__ctfe)
{
if (x < y)
Expand Down
4 changes: 2 additions & 2 deletions src/ldc/intrinsics.di
Original file line number Diff line number Diff line change
Expand Up @@ -305,12 +305,12 @@ pragma(LDC_intrinsic, "llvm.ctpop.i#")
/// The 'llvm.ctlz' family of intrinsic functions counts the number of leading
/// zeros in a variable.
pragma(LDC_intrinsic, "llvm.ctlz.i#")
T llvm_ctlz(T)(T src, bool isZerodefined);
T llvm_ctlz(T)(T src, bool isZeroUndefined);

/// The 'llvm.cttz' family of intrinsic functions counts the number of trailing
/// zeros.
pragma(LDC_intrinsic, "llvm.cttz.i#")
T llvm_cttz(T)(T src, bool isZerodefined);
T llvm_cttz(T)(T src, bool isZeroUndefined);



Expand Down