Skip to content

Commit 050407f

Browse files
committedAug 13, 2014
Merge branch 'master' into release-0.14.0
2 parents f115139 + 6aca85a commit 050407f

11 files changed

+283
-12
lines changed
 

‎.travis.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ before_install:
77
# the official Clang binary package from the llvm.org download page.
88
- echo yes | sudo add-apt-repository ppa:h-rayflood/llvm
99

10-
# LLVM 3.5 snapshots
10+
# LLVM 3.4 / 3.5 / snapshots
11+
- sudo sh -c "echo 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.4 main' >> /etc/apt/sources.list"
12+
- sudo sh -c "echo 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.5 main' >> /etc/apt/sources.list"
1113
- sudo sh -c "echo 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise main' >> /etc/apt/sources.list"
1214
- wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
1315

@@ -48,6 +50,12 @@ env:
4850
- LLVM_PACKAGE="llvm-3.4 llvm-3.4-dev" OPTS="-DBUILD_SHARED_LIBS=ON"
4951
- LLVM_PACKAGE="llvm-3.5 llvm-3.5-dev libedit2 libedit-dev" TEST_DEBUG=1
5052
- LLVM_PACKAGE="llvm-3.5 llvm-3.5-dev libedit2 libedit-dev"
53+
- LLVM_PACKAGE="llvm-3.6 llvm-3.6-dev libedit2 libedit-dev" TEST_DEBUG=1
54+
- LLVM_PACKAGE="llvm-3.6 llvm-3.6-dev libedit2 libedit-dev"
55+
matrix:
56+
allow_failures:
57+
- env: LLVM_PACKAGE="llvm-3.6 llvm-3.6-dev libedit2 libedit-dev" TEST_DEBUG=1
58+
- env: LLVM_PACKAGE="llvm-3.6 llvm-3.6-dev libedit2 libedit-dev"
5159
script:
5260
- cmake $OPTS .
5361
- make -j2

‎dmd2/builtin.c

+202
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
#include "identifier.h"
2424
#include "id.h"
2525
#include "module.h"
26+
#if IN_LLVM
27+
#include "template.h"
28+
#include "gen/pragma.h"
29+
#endif
2630

2731
StringTable builtins;
2832

@@ -78,6 +82,154 @@ Expression *eval_fabs(Loc loc, FuncDeclaration *fd, Expressions *arguments)
7882
return new RealExp(loc, fabsl(arg0->toReal()), arg0->type);
7983
}
8084

85+
#if IN_LLVM
86+
87+
static inline Type *getTypeOfOverloadedIntrinsic(FuncDeclaration *fd)
88+
{
89+
// Depending on the state of the code generation we have to look at
90+
// the template instance or the function declaration.
91+
assert(fd->parent && "function declaration requires parent");
92+
TemplateInstance* tinst = fd->parent->isTemplateInstance();
93+
if (tinst)
94+
{
95+
// See DtoOverloadedIntrinsicName
96+
assert(tinst->tdtypes.dim == 1);
97+
return static_cast<Type*>(tinst->tdtypes.data[0]);
98+
}
99+
else
100+
{
101+
assert(fd->type->ty == Tfunction);
102+
TypeFunction *tf = static_cast<TypeFunction *>(fd->type);
103+
assert(tf->parameters->dim >= 1);
104+
return tf->parameters->data[0]->type;
105+
}
106+
}
107+
108+
static inline int getBitsizeOfType(Loc loc, Type *type)
109+
{
110+
switch (type->toBasetype()->ty)
111+
{
112+
case Tint64:
113+
case Tuns64: return 64;
114+
case Tint32:
115+
case Tuns32: return 32;
116+
case Tint16:
117+
case Tuns16: return 16;
118+
case Tint128:
119+
case Tuns128:
120+
error(loc, "cent/ucent not supported");
121+
break;
122+
default:
123+
error(loc, "unsupported type");
124+
break;
125+
}
126+
return 32; // in case of error
127+
}
128+
129+
Expression *eval_cttz(Loc loc, FuncDeclaration *fd, Expressions *arguments)
130+
{
131+
Type* type = getTypeOfOverloadedIntrinsic(fd);
132+
133+
Expression *arg0 = (*arguments)[0];
134+
assert(arg0->op == TOKint64);
135+
uinteger_t x = arg0->toInteger();
136+
137+
int n = getBitsizeOfType(loc, type);
138+
139+
if (x == 0)
140+
{
141+
if ((*arguments)[1]->toInteger())
142+
error(loc, "llvm.cttz.i#(0) is undefined");
143+
}
144+
else
145+
{
146+
int c = n >> 1;
147+
n -= 1;
148+
const uinteger_t mask = (static_cast<uinteger_t>(1L) << n)
149+
| (static_cast<uinteger_t>(1L) << n)-1;
150+
do {
151+
uinteger_t y = (x << c) & mask; if (y != 0) { n -= c; x = y; }
152+
c = c >> 1;
153+
} while (c != 0);
154+
}
155+
156+
return new IntegerExp(loc, n, type);
157+
}
158+
159+
Expression *eval_ctlz(Loc loc, FuncDeclaration *fd, Expressions *arguments)
160+
{
161+
Type* type = getTypeOfOverloadedIntrinsic(fd);
162+
163+
Expression *arg0 = (*arguments)[0];
164+
assert(arg0->op == TOKint64);
165+
uinteger_t x = arg0->toInteger();
166+
if (x == 0 && (*arguments)[1]->toInteger())
167+
error(loc, "llvm.ctlz.i#(0) is undefined");
168+
169+
int n = getBitsizeOfType(loc, type);
170+
int c = n >> 1;
171+
do {
172+
uinteger_t y = x >> c; if (y != 0) { n -= c; x = y; }
173+
c = c >> 1;
174+
} while (c != 0);
175+
176+
return new IntegerExp(loc, n - x, type);
177+
}
178+
179+
Expression *eval_bswap(Loc loc, FuncDeclaration *fd, Expressions *arguments)
180+
{
181+
Type* type = getTypeOfOverloadedIntrinsic(fd);
182+
183+
Expression *arg0 = (*arguments)[0];
184+
assert(arg0->op == TOKint64);
185+
uinteger_t n = arg0->toInteger();
186+
#define BYTEMASK 0x00FF00FF00FF00FFLL
187+
#define SHORTMASK 0x0000FFFF0000FFFFLL
188+
#define INTMASK 0x0000FFFF0000FFFFLL
189+
switch (type->toBasetype()->ty)
190+
{
191+
case Tint64:
192+
case Tuns64:
193+
// swap high and low uints
194+
n = ((n >> 32) & INTMASK) | ((n & INTMASK) << 32);
195+
case Tint32:
196+
case Tuns32:
197+
// swap adjacent ushorts
198+
n = ((n >> 16) & SHORTMASK) | ((n & SHORTMASK) << 16);
199+
case Tint16:
200+
case Tuns16:
201+
// swap adjacent ubytes
202+
n = ((n >> 8 ) & BYTEMASK) | ((n & BYTEMASK) << 8 );
203+
break;
204+
case Tint128:
205+
case Tuns128:
206+
error(loc, "cent/ucent not supported");
207+
break;
208+
default:
209+
error(loc, "unsupported type");
210+
break;
211+
}
212+
return new IntegerExp(loc, n, type);
213+
}
214+
215+
Expression *eval_ctpop(Loc loc, FuncDeclaration *fd, Expressions *arguments)
216+
{
217+
// FIXME Does not work for cent/ucent
218+
Type* type = getTypeOfOverloadedIntrinsic(fd);
219+
220+
Expression *arg0 = (*arguments)[0];
221+
assert(arg0->op == TOKint64);
222+
uinteger_t n = arg0->toInteger();
223+
n = n - ((n >> 1) & 0x5555555555555555);
224+
n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333);
225+
n = n + ((n >> 4) & 0x0F0F0F0F0F0F0F0F);
226+
n = n + (n >> 8);
227+
n = n + (n >> 16);
228+
n = n + (n >> 32);
229+
return new IntegerExp(loc, n, type);
230+
}
231+
#else
232+
81233
Expression *eval_bsf(Loc loc, FuncDeclaration *fd, Expressions *arguments)
82234
{
83235
Expression *arg0 = (*arguments)[0];
@@ -127,10 +279,15 @@ Expression *eval_bswap(Loc loc, FuncDeclaration *fd, Expressions *arguments)
127279
n = ((n >> 32) & INTMASK) | ((n & INTMASK) << 32);
128280
return new IntegerExp(loc, n, arg0->type);
129281
}
282+
#endif
130283

131284
void builtin_init()
132285
{
286+
#if IN_LLVM
287+
builtins._init(67); // Prime number like default value
288+
#else
133289
builtins._init(45);
290+
#endif
134291

135292
// @safe pure nothrow real function(real)
136293
add_builtin("_D4core4math3sinFNaNbNfeZe", &eval_sin);
@@ -194,6 +351,38 @@ void builtin_init()
194351
// @safe pure nothrow long function(real)
195352
add_builtin("_D3std4math6rndtolFNaNbNfeZl", &eval_unimp);
196353

354+
#if IN_LLVM
355+
// intrinsic llvm.bswap.i16/i32/i64/i128
356+
add_builtin("llvm.bswap.i#", &eval_bswap);
357+
add_builtin("llvm.bswap.i16", &eval_bswap);
358+
add_builtin("llvm.bswap.i32", &eval_bswap);
359+
add_builtin("llvm.bswap.i64", &eval_bswap);
360+
add_builtin("llvm.bswap.i128", &eval_bswap);
361+
362+
// intrinsic llvm.cttz.i8/i16/i32/i64/i128
363+
add_builtin("llvm.cttz.i#", &eval_cttz);
364+
add_builtin("llvm.cttz.i8", &eval_cttz);
365+
add_builtin("llvm.cttz.i16", &eval_cttz);
366+
add_builtin("llvm.cttz.i32", &eval_cttz);
367+
add_builtin("llvm.cttz.i64", &eval_cttz);
368+
add_builtin("llvm.cttz.i128", &eval_cttz);
369+
370+
// intrinsic llvm.ctlz.i8/i16/i32/i64/i128
371+
add_builtin("llvm.ctlz.i#", &eval_ctlz);
372+
add_builtin("llvm.ctlz.i8", &eval_ctlz);
373+
add_builtin("llvm.ctlz.i16", &eval_ctlz);
374+
add_builtin("llvm.ctlz.i32", &eval_ctlz);
375+
add_builtin("llvm.ctlz.i64", &eval_ctlz);
376+
add_builtin("llvm.ctlz.i128", &eval_ctlz);
377+
378+
// intrinsic llvm.ctpop.i8/i16/i32/i64/i128
379+
add_builtin("llvm.ctpop.i#", &eval_ctpop);
380+
add_builtin("llvm.ctpop.i8", &eval_ctpop);
381+
add_builtin("llvm.ctpop.i16", &eval_ctpop);
382+
add_builtin("llvm.ctpop.i32", &eval_ctpop);
383+
add_builtin("llvm.ctpop.i64", &eval_ctpop);
384+
add_builtin("llvm.ctpop.i128", &eval_ctpop);
385+
#else
197386
// @safe pure nothrow int function(uint)
198387
add_builtin("_D4core5bitop3bsfFNaNbNfkZi", &eval_bsf);
199388
add_builtin("_D4core5bitop3bsrFNaNbNfkZi", &eval_bsr);
@@ -204,6 +393,7 @@ void builtin_init()
204393

205394
// @safe pure nothrow uint function(uint)
206395
add_builtin("_D4core5bitop5bswapFNaNbNfkZk", &eval_bswap);
396+
#endif
207397
}
208398

209399
/**********************************
@@ -214,7 +404,13 @@ BUILTIN FuncDeclaration::isBuiltin()
214404
{
215405
if (builtin == BUILTINunknown)
216406
{
407+
#if IN_LLVM
408+
const char *name = llvmInternal == LLVMintrinsic ? intrinsicName.c_str()
409+
: mangleExact();
410+
builtin_fp fp = builtin_lookup(name);
411+
#else
217412
builtin_fp fp = builtin_lookup(mangleExact());
413+
#endif
218414
builtin = fp ? BUILTINyes : BUILTINno;
219415
}
220416
return builtin;
@@ -229,7 +425,13 @@ Expression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments)
229425
{
230426
if (fd->builtin == BUILTINyes)
231427
{
428+
#if IN_LLVM
429+
const char *name = fd->llvmInternal == LLVMintrinsic ? fd->intrinsicName.c_str()
430+
: fd->mangleExact();
431+
builtin_fp fp = builtin_lookup(name);
432+
#else
232433
builtin_fp fp = builtin_lookup(fd->mangleExact());
434+
#endif
233435
assert(fp);
234436
return fp(loc, fd, arguments);
235437
}

‎dmd2/init.h

-6
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ class ArrayInitializer;
2929
class ExpInitializer;
3030
struct HdrGenState;
3131

32-
#if IN_LLVM
33-
namespace llvm {
34-
class StructType;
35-
}
36-
#endif
37-
3832
enum NeedInterpret { INITnointerpret, INITinterpret };
3933

4034
class Initializer : public RootObject

‎driver/linker.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -199,19 +199,31 @@ static int linkObjToBinaryGcc(bool sharedLib)
199199
// solaris TODO
200200
break;
201201

202+
#if LDC_LLVM_VER <= 305
202203
case llvm::Triple::MinGW32:
203204
// This is really more of a kludge, as linking in the Winsock functions
204205
// should be handled by the pragma(lib, ...) in std.socket, but it
205206
// makes LDC behave as expected for now.
206207
args.push_back("-lws2_32");
207208
break;
209+
#endif
208210

209211
default:
210212
// OS not yet handled, will probably lead to linker errors.
211213
// FIXME: Win32.
212214
break;
213215
}
214216

217+
#if LDC_LLVM_VER >= 306
218+
if (global.params.targetTriple.isWindowsGNUEnvironment())
219+
{
220+
// This is really more of a kludge, as linking in the Winsock functions
221+
// should be handled by the pragma(lib, ...) in std.socket, but it
222+
// makes LDC behave as expected for now.
223+
args.push_back("-lws2_32");
224+
}
225+
#endif
226+
215227
// Only specify -m32/-m64 for architectures where the two variants actually
216228
// exist (as e.g. the GCC ARM toolchain doesn't recognize the switches).
217229
if (global.params.targetTriple.get64BitArchVariant().getArch() !=

‎driver/main.cpp

+25-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
#include "llvm/Support/TargetRegistry.h"
4949
#include "llvm/Support/TargetSelect.h"
5050
#include "llvm/Target/TargetMachine.h"
51+
#if LDC_LLVM_VER >= 306
52+
#include "llvm/Target/TargetSubtargetInfo.h"
53+
#endif
5154
#if LDC_LLVM_VER >= 303
5255
#include "llvm/LinkAllIR.h"
5356
#include "llvm/IR/LLVMContext.h"
@@ -589,12 +592,14 @@ static void registerPredefinedTargetVersions() {
589592
VersionCondition::addPredefinedGlobalIdent("ARM_Thumb");
590593
registerPredefinedFloatABI("ARM_SoftFloat", "ARM_HardFloat");
591594
break;
595+
#if LDC_LLVM_VER == 305
596+
case llvm::Triple::arm64:
597+
case llvm::Triple::arm64_be:
598+
#endif
592599
#if LDC_LLVM_VER >= 303
593600
case llvm::Triple::aarch64:
594601
#if LDC_LLVM_VER >= 305
595602
case llvm::Triple::aarch64_be:
596-
case llvm::Triple::arm64:
597-
case llvm::Triple::arm64_be:
598603
#endif
599604
VersionCondition::addPredefinedGlobalIdent("AArch64");
600605
registerPredefinedFloatABI("ARM_SoftFloat", "ARM_HardFloat");
@@ -661,6 +666,20 @@ static void registerPredefinedTargetVersions() {
661666
case llvm::Triple::Win32:
662667
VersionCondition::addPredefinedGlobalIdent("Windows");
663668
VersionCondition::addPredefinedGlobalIdent(global.params.is64bit ? "Win64" : "Win32");
669+
#if LDC_LLVM_VER >= 306
670+
if (global.params.targetTriple.isWindowsGNUEnvironment())
671+
{
672+
VersionCondition::addPredefinedGlobalIdent("mingw32"); // For backwards compatibility.
673+
VersionCondition::addPredefinedGlobalIdent("MinGW");
674+
}
675+
if (global.params.targetTriple.isWindowsCygwinEnvironment())
676+
{
677+
error(Loc(), "Cygwin is not yet supported");
678+
fatal();
679+
VersionCondition::addPredefinedGlobalIdent("Cygwin");
680+
}
681+
break;
682+
#else
664683
break;
665684
case llvm::Triple::MinGW32:
666685
VersionCondition::addPredefinedGlobalIdent("Windows");
@@ -673,6 +692,7 @@ static void registerPredefinedTargetVersions() {
673692
fatal();
674693
VersionCondition::addPredefinedGlobalIdent("Cygwin");
675694
break;
695+
#endif
676696
case llvm::Triple::Linux:
677697
#if LDC_LLVM_VER >= 302
678698
if (global.params.targetTriple.getEnvironment() == llvm::Triple::Android)
@@ -969,7 +989,9 @@ int main(int argc, char **argv)
969989
global.params.is64bit = triple.isArch64Bit();
970990
}
971991

972-
#if LDC_LLVM_VER >= 302
992+
#if LDC_LLVM_VER >= 306
993+
gDataLayout = gTargetMachine->getSubtargetImpl()->getDataLayout();
994+
#elif LDC_LLVM_VER >= 302
973995
gDataLayout = gTargetMachine->getDataLayout();
974996
#else
975997
gDataLayout = gTargetMachine->getTargetData();

‎driver/toobj.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
#include "llvm/Support/PathV1.h"
2929
#endif
3030
#include "llvm/Target/TargetMachine.h"
31+
#if LDC_LLVM_VER >= 306
32+
#include "llvm/Target/TargetSubtargetInfo.h"
33+
#endif
3134
#if LDC_LLVM_VER >= 303
3235
#include "llvm/IR/Module.h"
3336
#else
@@ -61,7 +64,12 @@ static void codegenModule(llvm::TargetMachine &Target, llvm::Module& m,
6164
// about to build.
6265
PassManager Passes;
6366

64-
#if LDC_LLVM_VER >= 305
67+
#if LDC_LLVM_VER >= 306
68+
if (const DataLayout *DL = Target.getSubtargetImpl()->getDataLayout())
69+
Passes.add(new DataLayoutPass(*DL));
70+
else
71+
Passes.add(new DataLayoutPass(&m));
72+
#elif LDC_LLVM_VER == 305
6573
if (const DataLayout *DL = Target.getDataLayout())
6674
Passes.add(new DataLayoutPass(*DL));
6775
else
@@ -124,7 +132,11 @@ void writeModule(llvm::Module* m, std::string filename)
124132
// We don't use the integrated assembler with MinGW as it does not support
125133
// emitting DW2 exception handling tables.
126134
bool const assembleExternally = global.params.output_o &&
135+
#if LDC_LLVM_VER >= 306
136+
global.params.targetTriple.isWindowsGNUEnvironment();
137+
#else
127138
global.params.targetTriple.getOS() == llvm::Triple::MinGW32;
139+
#endif
128140

129141
// eventually do our own path stuff, dmd's is a bit strange.
130142
typedef llvm::SmallString<128> LLPath;

‎gen/cl_helpers.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ MultiSetter::MultiSetter(bool invert, bool* p, ...) {
5959
while ((p = va_arg(va, bool*))) {
6060
locations.push_back(p);
6161
}
62+
va_end(va);
6263
}
6364
}
6465

‎gen/declarations.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,11 @@ class CodegenVisitor : public Visitor {
388388
StringExp *se = static_cast<StringExp *>(e);
389389

390390
size_t nameLen = se->len;
391+
#if LDC_LLVM_VER >= 306
392+
if (global.params.targetTriple.isWindowsGNUEnvironment())
393+
#else
391394
if (global.params.targetTriple.getOS() == llvm::Triple::MinGW32)
395+
#endif
392396
{
393397
if (nameLen > 4 &&
394398
!memcmp(static_cast<char*>(se->string) + nameLen - 4, ".lib", 4))

‎gen/dibuilder.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,11 @@ ldc::DIFunctionType ldc::DIBuilder::CreateFunctionType(Type *type)
465465
// Create "dummy" subroutine type for the return type
466466
llvm::SmallVector<llvm::Value*, 16> Elts;
467467
Elts.push_back(CreateTypeDescription(retType, NULL, true));
468+
#if LDC_LLVM_VER >= 306
469+
llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
470+
#else
468471
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
472+
#endif
469473
return DBuilder.createSubroutineType(file, EltTypeArray);
470474
}
471475

@@ -486,7 +490,11 @@ ldc::DIFunctionType ldc::DIBuilder::CreateDelegateType(Type *type)
486490
llvm::DIType(NULL)
487491
#endif
488492
);
493+
#if LDC_LLVM_VER >= 306
494+
llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
495+
#else
489496
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
497+
#endif
490498
return DBuilder.createSubroutineType(file, EltTypeArray);
491499
}
492500

@@ -620,7 +628,11 @@ llvm::DISubprogram ldc::DIBuilder::EmitSubProgramInternal(llvm::StringRef pretty
620628
#else
621629
Elts.push_back(llvm::DIType(NULL));
622630
#endif
631+
#if LDC_LLVM_VER >= 306
632+
llvm::DITypeArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);
633+
#else
623634
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
635+
#endif
624636
ldc::DIFunctionType DIFnType = DBuilder.createSubroutineType(file, EltTypeArray);
625637

626638
// FIXME: duplicates ?

‎gen/naked.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,11 @@ void DtoDefineNakedFunction(FuncDeclaration* fd)
191191
else if (isWin)
192192
{
193193
std::string fullMangle;
194+
#if LDC_LLVM_VER >= 306
195+
if (global.params.targetTriple.isWindowsGNUEnvironment())
196+
#else
194197
if (global.params.targetTriple.getOS() == llvm::Triple::MinGW32)
198+
#endif
195199
{
196200
fullMangle = "_";
197201
}

‎runtime/druntime

Submodule druntime updated 1 file

0 commit comments

Comments
 (0)
Please sign in to comment.