Mercurial > projects > ldc
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; |