# HG changeset patch # User Tomas Lindquist Olsen # Date 1242300400 -7200 # Node ID 15e9762bb6207f136bae91585dd7959c4d41be37 # Parent a376776e2301c88bffbf1d1de83762171b438dea Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 . diff -r a376776e2301 -r 15e9762bb620 gen/aa.cpp --- a/gen/aa.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/aa.cpp Thu May 14 13:26:40 2009 +0200 @@ -33,7 +33,7 @@ pkey = key->getRVal(); } else { - LLValue* tmp = DtoAlloca(DtoType(keytype), "aatmpkeystorage"); + LLValue* tmp = DtoAlloca(keytype, "aatmpkeystorage"); DVarValue var(keytype, tmp); DtoAssign(loc, &var, key); return tmp; @@ -41,7 +41,7 @@ // give memory if (needmem) { - LLValue* tmp = DtoAlloca(DtoType(keytype), "aatmpkeystorage"); + LLValue* tmp = DtoAlloca(keytype, "aatmpkeystorage"); DtoStore(pkey, tmp); pkey = tmp; } diff -r a376776e2301 -r 15e9762bb620 gen/abi-x86-64.cpp --- a/gen/abi-x86-64.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/abi-x86-64.cpp Thu May 14 13:26:40 2009 +0200 @@ -455,7 +455,7 @@ } else { // No memory location, create one. LLValue* rval = v->getRVal(); - lval = DtoAlloca(rval->getType()); + lval = DtoRawAlloca(rval->getType(), 0); DtoStore(rval, lval); } @@ -479,7 +479,7 @@ } else { // No memory location, create one. LLValue* rval = v->getRVal(); - lval = DtoAlloca(rval->getType()); + lval = DtoRawAlloca(rval->getType(), 0); DtoStore(rval, lval); } diff -r a376776e2301 -r 15e9762bb620 gen/abi.cpp --- a/gen/abi.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/abi.cpp Thu May 14 13:26:40 2009 +0200 @@ -112,7 +112,7 @@ LLValue* get(Type* dty, DValue* dv) { Logger::println("rewriting int -> struct"); - LLValue* mem = DtoAlloca(DtoType(dty), ".int_to_struct"); + LLValue* mem = DtoAlloca(dty, ".int_to_struct"); LLValue* v = dv->getRVal(); DtoStore(v, DtoBitCast(mem, getPtrToType(v->getType()))); return DtoLoad(mem); diff -r a376776e2301 -r 15e9762bb620 gen/arrays.cpp --- a/gen/arrays.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/arrays.cpp Thu May 14 13:26:40 2009 +0200 @@ -77,7 +77,7 @@ // give slices and complex values storage (and thus an address to pass) if (value->isSlice()) { - val = DtoAlloca(DtoType(value->getType()), ".tmpparam"); + val = DtoAlloca(value->getType(), ".tmpparam"); DVarValue lval(value->getType(), val); DtoAssign(loc, &lval, value); } @@ -448,7 +448,7 @@ LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, fnname); // build dims - LLValue* dimsArg = DtoAlloca(DtoSize_t(), DtoConstUint(ndims), ".newdims"); + LLValue* dimsArg = DtoArrayAlloca(Type::tsize_t, ndims, ".newdims"); LLValue* firstDim = NULL; for (size_t i=0; icode += asmGotoEndLabel.str()+":\n"; // create storage for and initialize the temporary - jump_target = DtoAlloca(LLType::Int32Ty, "__llvm_jump_target"); + jump_target = DtoAlloca(Type::tint32, "__llvm_jump_target"); gIR->ir->CreateStore(DtoConstUint(0), jump_target); // setup variable for output from asm outSetterStmt->out_c = "=*m,"; diff -r a376776e2301 -r 15e9762bb620 gen/classes.cpp --- a/gen/classes.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/classes.cpp Thu May 14 13:26:40 2009 +0200 @@ -129,7 +129,8 @@ LLValue* mem; if (newexp->onstack) { - mem = DtoAlloca(DtoType(tc)->getContainedType(0), ".newclass_alloca"); + // FIXME align scope class to its largest member + mem = DtoRawAlloca(DtoType(tc)->getContainedType(0), 0, ".newclass_alloca"); } // custom allocator else if (newexp->allocator) diff -r a376776e2301 -r 15e9762bb620 gen/functions.cpp --- a/gen/functions.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/functions.cpp Thu May 14 13:26:40 2009 +0200 @@ -683,6 +683,7 @@ gIR->scopes.push_back(IRScope(beginbb, endbb)); // create alloca point + // this gets erased when the function is complete, so alignment etc does not matter at all llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::Int32Ty, "alloca point", beginbb); irfunction->allocapoint = allocaPoint; @@ -704,7 +705,7 @@ LLValue* thisvar = irfunction->thisArg; assert(thisvar); - LLValue* thismem = DtoAlloca(thisvar->getType(), "this"); + LLValue* thismem = DtoRawAlloca(thisvar->getType(), 0, "this"); // FIXME: align? DtoStore(thisvar, thismem); irfunction->thisArg = thismem; @@ -760,7 +761,7 @@ argt = irloc->value->getType(); else argt = DtoType(vd->type); - LLValue* mem = DtoAlloca(argt, vd->ident->toChars()); + LLValue* mem = DtoRawAlloca(argt, 0, vd->ident->toChars()); // let the abi transform the argument back first DImValue arg_dval(vd->type, irloc->value); @@ -796,19 +797,19 @@ DtoNestedInit(fd->vresult); } else if (fd->vresult) { fd->vresult->ir.irLocal = new IrLocal(fd->vresult); - fd->vresult->ir.irLocal->value = DtoAlloca(DtoType(fd->vresult->type), fd->vresult->toChars()); + fd->vresult->ir.irLocal->value = DtoAlloca(fd->vresult->type, fd->vresult->toChars()); } // copy _argptr and _arguments to a memory location if (f->linkage == LINKd && f->varargs == 1) { // _argptr - LLValue* argptrmem = DtoAlloca(fd->ir.irFunc->_argptr->getType(), "_argptr_mem"); + LLValue* argptrmem = DtoRawAlloca(fd->ir.irFunc->_argptr->getType(), 0, "_argptr_mem"); new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb()); fd->ir.irFunc->_argptr = argptrmem; // _arguments - LLValue* argumentsmem = DtoAlloca(fd->ir.irFunc->_arguments->getType(), "_arguments_mem"); + LLValue* argumentsmem = DtoRawAlloca(fd->ir.irFunc->_arguments->getType(), 0, "_arguments_mem"); new llvm::StoreInst(fd->ir.irFunc->_arguments, argumentsmem, gIR->scopebb()); fd->ir.irFunc->_arguments = argumentsmem; } @@ -918,7 +919,7 @@ // byval arg, but expr has no storage yet else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isNull())) { - LLValue* alloc = DtoAlloca(DtoType(argexp->type), ".tmp_arg"); + LLValue* alloc = DtoAlloca(argexp->type, ".tmp_arg"); DVarValue* vv = new DVarValue(argexp->type, alloc); DtoAssign(argexp->loc, vv, arg); arg = vv; diff -r a376776e2301 -r 15e9762bb620 gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/llvmhelpers.cpp Thu May 14 13:26:40 2009 +0200 @@ -95,14 +95,29 @@ ////////////////////////////////////////////////////////////////////////////////////////*/ -llvm::AllocaInst* DtoAlloca(const LLType* lltype, const std::string& name) +llvm::AllocaInst* DtoAlloca(Type* type, const char* name) { - return new llvm::AllocaInst(lltype, name, gIR->topallocapoint()); + const llvm::Type* lltype = DtoType(type); + llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint()); + ai->setAlignment(type->alignsize()); + return ai; } -llvm::AllocaInst* DtoAlloca(const LLType* lltype, LLValue* arraysize, const std::string& name) +llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name) { - return new llvm::AllocaInst(lltype, arraysize, name, gIR->topallocapoint()); + const llvm::Type* lltype = DtoType(type); + llvm::AllocaInst* ai = new llvm::AllocaInst( + lltype, DtoConstUint(arraysize), name, gIR->topallocapoint()); + ai->setAlignment(type->alignsize()); + return ai; +} + +llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const char* name) +{ + llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint()); + if (alignment) + ai->setAlignment(alignment); + return ai; } @@ -894,7 +909,7 @@ if(gTargetData->getTypeSizeInBits(lltype) == 0) allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype)); else - allocainst = DtoAlloca(lltype, vd->toChars()); + allocainst = DtoAlloca(vd->type, vd->toChars()); //allocainst->setAlignment(vd->type->alignsize()); // TODO vd->ir.irLocal = new IrLocal(vd); @@ -1010,7 +1025,7 @@ LLValue* allocaval = NULL; if (!addr && (!var->ir.irLocal || !var->ir.irLocal->value)) { - addr = DtoAlloca(DtoType(var->type), var->toChars()); + addr = DtoAlloca(var->type, var->toChars()); // add debug info if (global.params.symdebug) diff -r a376776e2301 -r 15e9762bb620 gen/llvmhelpers.h --- a/gen/llvmhelpers.h Wed May 13 18:08:40 2009 +0200 +++ b/gen/llvmhelpers.h Thu May 14 13:26:40 2009 +0200 @@ -40,8 +40,9 @@ void DtoDeleteArray(DValue* arr); // emit an alloca -llvm::AllocaInst* DtoAlloca(const LLType* lltype, const std::string& name = ""); -llvm::AllocaInst* DtoAlloca(const LLType* lltype, LLValue* arraysize, const std::string& name = ""); +llvm::AllocaInst* DtoAlloca(Type* type, const char* name = ""); +llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name = ""); +llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const char* name = ""); // assertion generator void DtoAssert(Module* M, Loc loc, DValue* msg); diff -r a376776e2301 -r 15e9762bb620 gen/naked.cpp --- a/gen/naked.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/naked.cpp Thu May 14 13:26:40 2009 +0200 @@ -258,7 +258,7 @@ // generate asm as->out_c = "=*m,=*m,"; - LLValue* tmp = DtoAlloca(llretTy, ".tmp_asm_ret"); + LLValue* tmp = DtoRawAlloca(llretTy, 0, ".tmp_asm_ret"); as->out.push_back( tmp ); as->out.push_back( DtoGEPi(tmp, 0,1) ); as->code = "movd %eax, $<>" "\n\t" "mov %edx, $<>"; @@ -413,7 +413,7 @@ if (type->ty == Tstruct) { // make a copy - llvm::Value* mem = DtoAlloca(ret_type, ".__asm_tuple_ret"); + llvm::Value* mem = DtoAlloca(type, ".__asm_tuple_ret"); TypeStruct* ts = (TypeStruct*)type; size_t n = ts->sym->fields.dim; diff -r a376776e2301 -r 15e9762bb620 gen/nested.cpp --- a/gen/nested.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/nested.cpp Thu May 14 13:26:40 2009 +0200 @@ -167,7 +167,7 @@ if (nestedCtx == NCArray) { // alloca as usual if no value already if (!vd->ir.irLocal->value) - vd->ir.irLocal->value = DtoAlloca(DtoType(vd->type), vd->toChars()); + vd->ir.irLocal->value = DtoAlloca(vd->type, vd->toChars()); // store the address into the nested vars array assert(vd->ir.irLocal->nestedIndex >= 0); @@ -324,7 +324,8 @@ const LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems); // alloca it - LLValue* nestedVars = DtoAlloca(nestedVarsTy, ".nested_vars"); + // FIXME align ? + LLValue* nestedVars = DtoRawAlloca(nestedVarsTy, 0, ".nested_vars"); IrFunction* irfunction = fd->ir.irFunc; @@ -459,7 +460,8 @@ // FIXME: For D2, this should be a gc_malloc (or similar) call, not alloca // (Note that it'd also require more aggressive copying of // by-value parameters instead of just alloca'd ones) - LLValue* frame = DtoAlloca(frameType, ".frame"); + // FIXME: alignment ? + LLValue* frame = DtoRawAlloca(frameType, 0, ".frame"); // copy parent frames into beginning if (depth != 0) { diff -r a376776e2301 -r 15e9762bb620 gen/passes/GarbageCollect2Stack.cpp --- a/gen/passes/GarbageCollect2Stack.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/passes/GarbageCollect2Stack.cpp Thu May 14 13:26:40 2009 +0200 @@ -98,7 +98,7 @@ NumGcToStack++; Instruction* Begin = CS.getCaller()->getEntryBlock().begin(); - return new AllocaInst(Ty, ".nongc_mem", Begin); + return new AllocaInst(Ty, ".nongc_mem", Begin); // FIXME: align? } FunctionInfo(unsigned typeInfoArgNr, bool safeToDelete) @@ -165,7 +165,7 @@ // Convert array size to 32 bits if necessary Value* count = Builder.CreateIntCast(arrSize, Type::Int32Ty, false); - AllocaInst* alloca = Builder.CreateAlloca(Ty, count, ".nongc_mem"); + AllocaInst* alloca = Builder.CreateAlloca(Ty, count, ".nongc_mem"); // FIXME: align? if (Initialized) { // For now, only zero-init is supported. diff -r a376776e2301 -r 15e9762bb620 gen/statements.cpp --- a/gen/statements.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/statements.cpp Thu May 14 13:26:40 2009 +0200 @@ -1025,7 +1025,7 @@ if (key) keyvar = DtoRawVarDeclaration(key); else - keyvar = DtoAlloca(keytype, "foreachkey"); + keyvar = DtoRawAlloca(keytype, 0, "foreachkey"); // FIXME: align? LLValue* zerokey = llvm::ConstantInt::get(keytype,0,false); // value diff -r a376776e2301 -r 15e9762bb620 gen/tocall.cpp --- a/gen/tocall.cpp Wed May 13 18:08:40 2009 +0200 +++ b/gen/tocall.cpp Thu May 14 13:26:40 2009 +0200 @@ -169,7 +169,7 @@ if (Logger::enabled()) Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n'; - LLValue* mem = DtoAlloca(vtype,"_argptr_storage"); + LLValue* mem = DtoRawAlloca(vtype, 0, "_argptr_storage"); // store arguments in the struct for (int i=begin,k=0; i