Mercurial > projects > ldc
comparison gen/nested.cpp @ 1224:919fafcc505c
Copy alloca'd parameters referenced by nested functions to the nesting frame.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sat, 18 Apr 2009 00:34:20 +0200 |
parents | 5f340a6dc749 |
children | 15e9762bb620 |
comparison
equal
deleted
inserted
replaced
1223:5f340a6dc749 | 1224:919fafcc505c |
---|---|
424 | 424 |
425 vd->ir.irLocal->nestedIndex = types.size(); | 425 vd->ir.irLocal->nestedIndex = types.size(); |
426 vd->ir.irLocal->nestedDepth = depth; | 426 vd->ir.irLocal->nestedDepth = depth; |
427 if (vd->isParameter()) { | 427 if (vd->isParameter()) { |
428 // Parameters already have storage associated with them (to handle byref etc.), | 428 // Parameters already have storage associated with them (to handle byref etc.), |
429 // so handle specially for now by storing a pointer instead of a value. | 429 // so handle those cases specially by storing a pointer instead of a value. |
430 assert(vd->ir.irLocal->value); | 430 assert(vd->ir.irLocal->value); |
431 // FIXME: don't do this for normal parameters? | 431 LLValue* value = vd->ir.irLocal->value; |
432 types.push_back(vd->ir.irLocal->value->getType()); | 432 const LLType* type = value->getType(); |
433 if (llvm::isa<llvm::AllocaInst>(value->getUnderlyingObject())) | |
434 // This will be copied to the nesting frame. | |
435 type = type->getContainedType(0); | |
436 types.push_back(type); | |
433 } else if (vd->isRef() || vd->isOut()) { | 437 } else if (vd->isRef() || vd->isOut()) { |
434 // Foreach variables can also be by reference, for instance. | 438 // Foreach variables can also be by reference, for instance. |
435 types.push_back(DtoType(vd->type->pointerTo())); | 439 types.push_back(DtoType(vd->type->pointerTo())); |
436 } else { | 440 } else { |
437 types.push_back(DtoType(vd->type)); | 441 types.push_back(DtoType(vd->type)); |
451 IrFunction* irfunction = fd->ir.irFunc; | 455 IrFunction* irfunction = fd->ir.irFunc; |
452 irfunction->frameType = frameType; | 456 irfunction->frameType = frameType; |
453 | 457 |
454 // Create frame for current function and append to frames list | 458 // Create frame for current function and append to frames list |
455 // FIXME: For D2, this should be a gc_malloc (or similar) call, not alloca | 459 // FIXME: For D2, this should be a gc_malloc (or similar) call, not alloca |
460 // (Note that it'd also require more aggressive copying of | |
461 // by-value parameters instead of just alloca'd ones) | |
456 LLValue* frame = DtoAlloca(frameType, ".frame"); | 462 LLValue* frame = DtoAlloca(frameType, ".frame"); |
457 | 463 |
458 // copy parent frames into beginning | 464 // copy parent frames into beginning |
459 if (depth != 0) { | 465 if (depth != 0) { |
460 LLValue* src = irfunction->nestArg; | 466 LLValue* src = irfunction->nestArg; |
489 VarDeclaration* vd = *i; | 495 VarDeclaration* vd = *i; |
490 | 496 |
491 LLValue* gep = DtoGEPi(frame, 0, vd->ir.irLocal->nestedIndex, vd->toChars()); | 497 LLValue* gep = DtoGEPi(frame, 0, vd->ir.irLocal->nestedIndex, vd->toChars()); |
492 if (vd->isParameter()) { | 498 if (vd->isParameter()) { |
493 Logger::println("nested param: %s", vd->toChars()); | 499 Logger::println("nested param: %s", vd->toChars()); |
494 DtoAlignedStore(vd->ir.irLocal->value, gep); | 500 LOG_SCOPE |
495 vd->ir.irLocal->byref = true; | 501 LLValue* value = vd->ir.irLocal->value; |
502 if (llvm::isa<llvm::AllocaInst>(value->getUnderlyingObject())) { | |
503 Logger::println("Copying to nested frame"); | |
504 // The parameter value is an alloca'd stack slot. | |
505 // Copy to the nesting frame and leave the alloca for | |
506 // the optimizers to clean up. | |
507 DtoStore(DtoLoad(value), gep); | |
508 gep->takeName(value); | |
509 vd->ir.irLocal->value = gep; | |
510 vd->ir.irLocal->byref = false; | |
511 } else { | |
512 Logger::println("Adding pointer to nested frame"); | |
513 // The parameter value is something else, such as a | |
514 // passed-in pointer (for 'ref' or 'out' parameters) or | |
515 // a pointer arg with byval attribute. | |
516 // Store the address into the frame and set the byref flag. | |
517 DtoAlignedStore(vd->ir.irLocal->value, gep); | |
518 vd->ir.irLocal->byref = true; | |
519 } | |
496 } else if (vd->isRef() || vd->isOut()) { | 520 } else if (vd->isRef() || vd->isOut()) { |
497 // This slot is initialized in DtoNestedInit, to handle things like byref foreach variables | 521 // This slot is initialized in DtoNestedInit, to handle things like byref foreach variables |
498 // which move around in memory. | 522 // which move around in memory. |
499 vd->ir.irLocal->byref = true; | 523 vd->ir.irLocal->byref = true; |
500 } else { | 524 } else { |