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 {