comparison gen/functions.cpp @ 240:0db62b770a49 trunk

[svn r257] Fixed: array .sort and .reverse runtime code was incorrect. Fixed: most runtime calls did not get correct param attrs.
author lindquist
date Mon, 09 Jun 2008 00:01:10 +0200
parents 9760f54af0b7
children 53568c37cfa7
comparison
equal deleted inserted replaced
239:fa691b1c0498 240:0db62b770a49
317 gIR->declareList.push_back(fdecl); 317 gIR->declareList.push_back(fdecl);
318 } 318 }
319 319
320 ////////////////////////////////////////////////////////////////////////////////////////// 320 //////////////////////////////////////////////////////////////////////////////////////////
321 321
322 static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl)
323 {
324 assert(f->parameters);
325
326 int llidx = 1;
327 if (f->llvmRetInPtr) ++llidx;
328 if (f->llvmUsesThis) ++llidx;
329 if (f->linkage == LINKd && f->varargs == 1)
330 llidx += 2;
331
332 int funcNumArgs = func->getArgumentList().size();
333 std::vector<llvm::ParamAttrsWithIndex> attrs;
334 int k = 0;
335
336 int nbyval = 0;
337
338 if (fdecl->isMain() && Argument::dim(f->parameters) == 0)
339 {
340 llvm::ParamAttrsWithIndex PAWI;
341 PAWI.Index = llidx;
342 PAWI.Attrs = llvm::ParamAttr::ByVal;
343 attrs.push_back(PAWI);
344 llidx++;
345 nbyval++;
346 }
347
348 for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k)
349 {
350 Argument* fnarg = (Argument*)f->parameters->data[k];
351 assert(fnarg);
352 if (fnarg->llvmByVal)
353 {
354 llvm::ParamAttrsWithIndex PAWI;
355 PAWI.Index = llidx;
356 PAWI.Attrs = llvm::ParamAttr::ByVal;
357 attrs.push_back(PAWI);
358 nbyval++;
359 }
360 }
361
362 if (nbyval) {
363 llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end());
364 func->setParamAttrs(palist);
365 }
366 }
367
368 //////////////////////////////////////////////////////////////////////////////////////////
369
322 void DtoDeclareFunction(FuncDeclaration* fdecl) 370 void DtoDeclareFunction(FuncDeclaration* fdecl)
323 { 371 {
324 if (fdecl->ir.declared) return; 372 if (fdecl->ir.declared) return;
325 fdecl->ir.declared = true; 373 fdecl->ir.declared = true;
326 374
333 if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) { 381 if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) {
334 error(fdecl->loc, "intrinsics cannot have function bodies"); 382 error(fdecl->loc, "intrinsics cannot have function bodies");
335 fatal(); 383 fatal();
336 } 384 }
337 385
386 // get TypeFunction*
387 Type* t = DtoDType(fdecl->type);
388 TypeFunction* f = (TypeFunction*)t;
389
390 // runtime function special handling
338 if (fdecl->runTimeHack) { 391 if (fdecl->runTimeHack) {
339 Logger::println("runtime hack func chars: %s", fdecl->toChars()); 392 Logger::println("runtime hack func chars: %s", fdecl->toChars());
340 if (!fdecl->ir.irFunc) { 393 if (!fdecl->ir.irFunc) {
341 fdecl->ir.irFunc = new IrFunction(fdecl); 394 IrFunction* irfunc = new IrFunction(fdecl);
342 fdecl->ir.irFunc->func = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); 395 llvm::Function* llfunc = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars());
396 fdecl->ir.irFunc = irfunc;
397 fdecl->ir.irFunc->func = llfunc;
343 } 398 }
344 return; 399 return;
345 } 400 }
346 401
347 bool declareOnly = false; 402 bool declareOnly = false;
369 424
370 llvm::Function* vafunc = 0; 425 llvm::Function* vafunc = 0;
371 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { 426 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) {
372 vafunc = DtoDeclareVaFunction(fdecl); 427 vafunc = DtoDeclareVaFunction(fdecl);
373 } 428 }
374
375 Type* t = DtoDType(fdecl->type);
376 TypeFunction* f = (TypeFunction*)t;
377 429
378 // construct function 430 // construct function
379 const llvm::FunctionType* functype = DtoFunctionType(fdecl); 431 const llvm::FunctionType* functype = DtoFunctionType(fdecl);
380 llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name); 432 llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name);
381 if (!func) 433 if (!func)
394 446
395 fdecl->ir.irFunc->func = func; 447 fdecl->ir.irFunc->func = func;
396 assert(llvm::isa<llvm::FunctionType>(f->ir.type->get())); 448 assert(llvm::isa<llvm::FunctionType>(f->ir.type->get()));
397 449
398 // parameter attributes 450 // parameter attributes
399 if (f->parameters) 451 if (f->parameters) {
400 { 452 set_param_attrs(f, func, fdecl);
401 int llidx = 1;
402 if (f->llvmRetInPtr) ++llidx;
403 if (f->llvmUsesThis) ++llidx;
404 if (f->linkage == LINKd && f->varargs == 1)
405 llidx += 2;
406
407 int funcNumArgs = func->getArgumentList().size();
408 std::vector<llvm::ParamAttrsWithIndex> attrs;
409 int k = 0;
410
411 int nbyval = 0;
412
413 if (fdecl->isMain() && Argument::dim(f->parameters) == 0)
414 {
415 llvm::ParamAttrsWithIndex PAWI;
416 PAWI.Index = llidx;
417 PAWI.Attrs = llvm::ParamAttr::ByVal;
418 attrs.push_back(PAWI);
419 llidx++;
420 nbyval++;
421 }
422
423 for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k)
424 {
425 Argument* fnarg = (Argument*)f->parameters->data[k];
426 assert(fnarg);
427 if (fnarg->llvmByVal)
428 {
429 llvm::ParamAttrsWithIndex PAWI;
430 PAWI.Index = llidx;
431 PAWI.Attrs = llvm::ParamAttr::ByVal;
432 attrs.push_back(PAWI);
433 nbyval++;
434 }
435 }
436
437 //warning("set %d byval args for function: %s", nbyval, func->getName().c_str());
438
439 if (nbyval) {
440 llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end());
441 func->setParamAttrs(palist);
442 }
443 } 453 }
444 454
445 // main 455 // main
446 if (fdecl->isMain()) { 456 if (fdecl->isMain()) {
447 gIR->mainFunc = func; 457 gIR->mainFunc = func;