@@ -631,7 +631,7 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default
631
631
}
632
632
633
633
// ////////////////////////////////////////////////////////////////////////////////////////
634
- DSliceValue* DtoNewMulDimDynArray (Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit )
634
+ DSliceValue* DtoNewMulDimDynArray (Loc& loc, Type* arrayType, DValue** dims, size_t ndims)
635
635
{
636
636
IF_LOG Logger::println (" DtoNewMulDimDynArray : %s" , arrayType->toChars ());
637
637
LOG_SCOPE;
@@ -641,26 +641,56 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size
641
641
642
642
// get value type
643
643
Type* vtype = arrayType->toBasetype ();
644
- for (size_t i= 0 ; i< ndims; ++i)
644
+ for (size_t i = 0 ; i < ndims; ++i)
645
645
vtype = vtype->nextOf ();
646
646
647
647
// get runtime function
648
- bool zeroInit = vtype->isZeroInit ();
649
- if (defaultInit && !isInitialized (vtype))
650
- defaultInit = false ;
651
-
652
- const char * fnname = zeroInit ? " _d_newarraymT" : " _d_newarraymiT" ;
653
-
648
+ const char * fnname = vtype->isZeroInit () ? " _d_newarraymTX" : " _d_newarraymiTX" ;
654
649
LLFunction* fn = LLVM_D_GetRuntimeFunction (loc, gIR ->module , fnname);
655
650
656
- std::vector<LLValue*> args;
657
- args.reserve (ndims+2 );
658
- args.push_back (arrayTypeInfo);
659
- args.push_back (DtoConstSize_t (ndims));
651
+ // Check if constant
652
+ bool allDimsConst = true ;
653
+ for (size_t i = 0 ; i < ndims; ++i)
654
+ {
655
+ if (!isaConstant (dims[i]->getRVal ()))
656
+ allDimsConst = false ;
657
+ }
660
658
661
659
// build dims
662
- for (size_t i=0 ; i<ndims; ++i)
663
- args.push_back (dims[i]->getRVal ());
660
+ LLValue* array;
661
+ if (allDimsConst)
662
+ {
663
+ // Build constant array for dimensions
664
+ std::vector<LLConstant*> argsdims;
665
+ argsdims.reserve (ndims);
666
+ for (size_t i = 0 ; i < ndims; ++i)
667
+ {
668
+ argsdims.push_back (isaConstant (dims[i]->getRVal ()));
669
+ }
670
+
671
+ llvm::Constant* dims = llvm::ConstantArray::get (llvm::ArrayType::get (DtoSize_t (), ndims), argsdims);
672
+ LLGlobalVariable* gvar = new llvm::GlobalVariable (*gIR ->module , dims->getType (), true , LLGlobalValue::InternalLinkage, dims, " .dimsarray" );
673
+ array = llvm::ConstantExpr::getBitCast (gvar, getPtrToType (dims->getType ()));
674
+ }
675
+ else
676
+ {
677
+ // Build static array for dimensions
678
+ LLArrayType* type = LLArrayType::get (DtoSize_t (), ndims);
679
+ array = DtoRawAlloca (type, 0 , " .dimarray" );
680
+ unsigned int i = 0 ;
681
+ for (size_t i = 0 ; i < ndims; ++i)
682
+ DtoStore (dims[i]->getRVal (), DtoGEPi (array, 0 , i, " .ndim" ));
683
+ }
684
+
685
+ LLStructType* dtype = DtoArrayType (DtoSize_t ());
686
+ LLValue* darray = DtoRawAlloca (dtype, 0 , " .array" );
687
+ DtoStore (DtoConstSize_t (ndims), DtoGEPi (darray, 0 , 0 , " .len" ));
688
+ DtoStore (DtoBitCast (array, getPtrToType (DtoSize_t ())), DtoGEPi (darray, 0 , 1 , " .ptr" ));
689
+
690
+ llvm::Value* args[] = {
691
+ arrayTypeInfo,
692
+ DtoLoad (darray)
693
+ };
664
694
665
695
// call allocator
666
696
LLValue* newptr = gIR ->CreateCallOrInvoke (fn, args, " .gc_mem" ).getInstruction ();
0 commit comments