@@ -348,70 +348,103 @@ JL_DLLEXPORT Type *julia_type_to_llvm(jl_value_t *jt, bool *isboxed)
348
348
}
349
349
}
350
350
351
+ // Set jst->struct_decl to the LLVM type corresponding to jst.
352
+ // jst must be a tuple or structtype.
353
+ static void set_struct_decl (jl_datatype_t *jst) {
354
+ assert (jst->struct_decl == nullptr );
355
+ bool isTuple = jl_is_tuple_type (jst);
356
+ bool isVecElement = is_vecelement_type ((jl_value_t *)jst);
357
+ StructType *structdecl;
358
+ if (!isTuple) {
359
+ if (!isVecElement) {
360
+ structdecl = StructType::create (jl_LLVMContext, jl_symbol_name (jst->name ->name ));
361
+ jst->struct_decl = structdecl;
362
+ }
363
+ }
364
+ size_t ntypes = jl_datatype_nfields (jst);
365
+ assert (ntypes > 0 );
366
+ std::vector<Type*> latypes (0 );
367
+ bool isvector = true ;
368
+ Type *lasttype = NULL ;
369
+ for (size_t i = 0 ; i < ntypes; ++i) {
370
+ Type *lty;
371
+ if (jl_field_isptr (jst, i))
372
+ lty = T_pjlvalue;
373
+ else {
374
+ jl_value_t *ty = jl_svecref (jst->types , i);
375
+ lty = ty==(jl_value_t *)jl_bool_type ? T_int8 : julia_type_to_llvm (ty);
376
+ }
377
+ if (lasttype != NULL && lasttype != lty)
378
+ isvector = false ;
379
+ lasttype = lty;
380
+ if (type_is_ghost (lty))
381
+ lty = NoopType;
382
+ latypes.push_back (lty);
383
+ }
384
+ if (!isTuple) {
385
+ if (!isVecElement)
386
+ structdecl->setBody (latypes);
387
+ else
388
+ // VecElement type is unwrapped in LLVM
389
+ jst->struct_decl = latypes[0 ];
390
+ }
391
+ else {
392
+ if (isvector && lasttype != T_int1 && !type_is_ghost (lasttype)) {
393
+ // Homogeneous tuple
394
+ // TODO: currently we get LLVM assertion failures for other vector sizes
395
+ bool validVectorSize = (ntypes == 2 || ntypes == 4 || ntypes == 8 || ntypes == 16 );
396
+ if (lasttype->isSingleValueType () && !lasttype->isVectorTy () && validVectorSize && is_vecelement_type (jl_svecref (jst->types ,0 )))
397
+ jst->struct_decl = VectorType::get (lasttype, ntypes);
398
+ else
399
+ jst->struct_decl = ArrayType::get (lasttype, ntypes);
400
+ }
401
+ else {
402
+ // Heterogeneous tuple
403
+ jst->struct_decl = StructType::get (jl_LLVMContext,ArrayRef<Type*>(&latypes[0 ],ntypes));
404
+ }
405
+ }
406
+ }
407
+
351
408
static Type *julia_struct_to_llvm (jl_value_t *jt, bool *isboxed)
352
409
{
353
410
// this function converts a Julia Type into the equivalent LLVM struct
354
411
// use this where C-compatible (unboxed) structs are desired
355
412
// use julia_type_to_llvm directly when you want to preserve Julia's type semantics
356
- bool isTuple = jl_is_tuple_type (jt);
357
413
if (isboxed) *isboxed = false ;
358
- if ((isTuple || jl_is_structtype (jt)) && !jl_is_array_type (jt)) {
414
+ if ((jl_is_tuple_type (jt) || jl_is_structtype (jt)) && !jl_is_array_type (jt)) {
359
415
if (!jl_is_leaf_type (jt))
360
- return NULL ;
416
+ return nullptr ;
361
417
jl_datatype_t *jst = (jl_datatype_t *)jt;
362
- if (jst->struct_decl == NULL ) {
363
- size_t ntypes = jl_datatype_nfields ( jst);
364
- if (ntypes == 0 || jst->size == 0 )
418
+ if (jst->struct_decl == nullptr ) {
419
+ assert ( jl_datatype_nfields (jst) != 0 || jst-> size == 0 );
420
+ if (jst->size == 0 )
365
421
return T_void;
366
- StructType *structdecl;
367
- if (!isTuple) {
368
- structdecl = StructType::create (jl_LLVMContext, jl_symbol_name (jst->name ->name ));
369
- jst->struct_decl = structdecl;
370
- }
371
- std::vector<Type*> latypes (0 );
372
- size_t i;
373
- bool isvector = true ;
374
- Type *lasttype = NULL ;
375
- for (i = 0 ; i < ntypes; i++) {
376
- jl_value_t *ty = jl_svecref (jst->types , i);
377
- Type *lty;
378
- if (jl_field_isptr (jst, i))
379
- lty = T_pjlvalue;
380
- else
381
- lty = ty==(jl_value_t *)jl_bool_type ? T_int8 : julia_type_to_llvm (ty);
382
- if (lasttype != NULL && lasttype != lty)
383
- isvector = false ;
384
- lasttype = lty;
385
- if (type_is_ghost (lty))
386
- lty = NoopType;
387
- latypes.push_back (lty);
388
- }
389
- if (!isTuple) {
390
- if (is_vecelement_type (jt))
391
- // VecElement type is unwrapped in LLVM
392
- jst->struct_decl = latypes[0 ];
393
- else
394
- structdecl->setBody (latypes);
395
- }
396
- else {
397
- if (isvector && lasttype != T_int1 && !type_is_ghost (lasttype)) {
398
- // TODO: currently we get LLVM assertion failures for other vector sizes
399
- bool validVectorSize = (ntypes == 2 || ntypes == 4 || ntypes == 8 || ntypes == 16 );
400
- if (lasttype->isSingleValueType () && !lasttype->isVectorTy () && validVectorSize && is_vecelement_type (jl_svecref (jst->types ,0 )))
401
- jst->struct_decl = VectorType::get (lasttype, ntypes);
402
- else
403
- jst->struct_decl = ArrayType::get (lasttype, ntypes);
404
- }
405
- else {
406
- jst->struct_decl = StructType::get (jl_LLVMContext,ArrayRef<Type*>(&latypes[0 ],ntypes));
407
- }
408
- }
422
+ set_struct_decl (jst);
409
423
}
410
424
return (Type*)jst->struct_decl ;
411
425
}
412
426
return julia_type_to_llvm (jt, isboxed);
413
427
}
414
428
429
+ // Returns 0 if no special rule applies
430
+ unsigned jl_llvm_special_tuple_alignment (jl_tupletype_t *st)
431
+ {
432
+ size_t ntypes = jl_datatype_nfields (st);
433
+ // Run fast rejection tests
434
+ if (ntypes==0 )
435
+ return 0 ;
436
+ for (size_t i = 0 ; i < ntypes; i++) {
437
+ jl_value_t *ty = jl_svecref (st->types , i);
438
+ if (!is_vecelement_type (ty))
439
+ return 0 ;
440
+ }
441
+ // Not rejected. Get definitive answer from corresponding LLVM type.
442
+ jl_datatype_t *jst = (jl_datatype_t *)st;
443
+ if (!jst->struct_decl )
444
+ set_struct_decl (jst);
445
+ return jl_ExecutionEngine->getDataLayout ().getABITypeAlignment ((Type*)jst->struct_decl );
446
+ }
447
+
415
448
static bool is_datatype_all_pointers (jl_datatype_t *dt)
416
449
{
417
450
size_t i, l = jl_datatype_nfields (dt);
@@ -766,9 +799,9 @@ static Value *emit_bounds_check(const jl_cgval_t &ainfo, jl_value_t *ty, Value *
766
799
// Parameter ptr should be the pointer argument for the LoadInst or StoreInst.
767
800
// It is currently unused, but might be used in the future for a more precise answer.
768
801
static unsigned julia_alignment (Value* /* ptr*/ , jl_value_t *jltype, unsigned alignment) {
769
- if (!alignment && ((jl_datatype_t *)jltype)->size >= 32 ) {
770
- // Type might contain a 32-byte vector. Use Julia alignment to prevent llvm from assuming default alignment.
771
- return (( jl_datatype_t *)jltype)-> alignment ;
802
+ if (!alignment && ((jl_datatype_t *)jltype)->alignment > MAX_ALIGN ) {
803
+ // Type's natural alignment exceeds strictess alignment promised in heap, so return the heap alignment.
804
+ return MAX_ALIGN ;
772
805
}
773
806
return alignment;
774
807
}
0 commit comments