diff --git a/src/core/atomic.d b/src/core/atomic.d index 1490ad2436..af9e03ea11 100644 --- a/src/core/atomic.d +++ b/src/core/atomic.d @@ -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" ) ) ) { @@ -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)); diff --git a/src/core/bitop.d b/src/core/bitop.d index 9ee77eb415..1f3ea6d0ee 100644 --- a/src/core/bitop.d +++ b/src/core/bitop.d @@ -16,6 +16,7 @@ nothrow: @nogc: version (LDC) { + import ldc.intrinsics; // Do not use the DMD inline assembler. } else { @@ -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 @@ -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 @@ -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); @@ -325,6 +329,7 @@ ulong bswap(ulong v) pure return (cast(ulong) sv.hi << 32) | sv.lo; } +} version (DigitalMars) version (AnyX86) @system // not pure { @@ -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); } } @@ -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 @@ -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 @@ -704,6 +709,12 @@ uint bitswap( uint x ) pure { if (!__ctfe) { + version (LDC) + { + static if (is(typeof(llvm_bitreverse(x)))) + return llvm_bitreverse(x); + } + else static if (is(typeof(asmBitswap32(x)))) return asmBitswap32(x); } @@ -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); } diff --git a/src/core/checkedint.d b/src/core/checkedint.d index bbc5642482..edf4155d47 100644 --- a/src/core/checkedint.d +++ b/src/core/checkedint.d @@ -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; @@ -317,6 +318,7 @@ ucent addu(ucent x, ucent y, ref bool overflow) { version(LDC) { + pragma(inline, true); if (__ctfe) { ucent r = x + y; @@ -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; @@ -634,6 +637,7 @@ ucent subu(ucent x, ucent y, ref bool overflow) { version(LDC) { + pragma(inline, true); if (__ctfe) { if (x < y) diff --git a/src/ldc/intrinsics.di b/src/ldc/intrinsics.di index 70b0dd7468..ea6a784301 100644 --- a/src/ldc/intrinsics.di +++ b/src/ldc/intrinsics.di @@ -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);