00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00014 
00015 
00016 #include "BoundsEmitter.h"
00017 #include "CGContext.h"
00018 #include "CodeGenRoutine.h"
00019 #include "CodeGenTypes.h"
00020 #include "CommaRT.h"
00021 #include "comma/ast/AggExpr.h"
00022 #include "comma/ast/Type.h"
00023 
00024 #include <algorithm>
00025 
00026 using namespace comma;
00027 
00028 using llvm::dyn_cast;
00029 using llvm::cast;
00030 using llvm::isa;
00031 
00032 namespace {
00033 
00034 
00038 class ArrayEmitter {
00039 
00040 public:
00041     ArrayEmitter(CodeGenRoutine &CGR, llvm::IRBuilder<> &Builder)
00042         : CGR(CGR),
00043           emitter(CGR),
00044           Builder(Builder) { }
00045 
00046     CValue emit(Expr *expr, llvm::Value *dst, bool genTmp);
00047 
00048     CValue emitAllocator(AllocatorExpr *expr);
00049 
00050 private:
00051     CodeGenRoutine &CGR;
00052     BoundsEmitter emitter;
00053     llvm::IRBuilder<> &Builder;
00054 
00055     SRFrame *frame() { return CGR.getSRFrame(); }
00056 
00069     void fillInOthers(AggregateExpr *agg, llvm::Value *dst,
00070                       llvm::Value *lower, llvm::Value *upper);
00071 
00085     void emitOthers(Expr *others, llvm::Value *dst,
00086                     llvm::Value *start, llvm::Value *end,
00087                     llvm::Value *bias);
00088 
00089     void emitOthers(AggregateExpr *expr, llvm::Value *dst,
00090                     llvm::Value *bounds, uint64_t numComponents);
00091 
00092     CValue emitPositionalAgg(AggregateExpr *expr, llvm::Value *dst);
00093     CValue emitKeyedAgg(AggregateExpr *expr, llvm::Value *dst);
00094     CValue emitStaticKeyedAgg(AggregateExpr *expr, llvm::Value *dst);
00095     CValue emitDynamicKeyedAgg(AggregateExpr *expr, llvm::Value *dst);
00096     CValue emitOthersKeyedAgg(AggregateExpr *expr, llvm::Value *dst);
00097 
00098     CValue emitArrayConversion(ConversionExpr *convert, llvm::Value *dst,
00099                                bool genTmp);
00100     CValue emitCall(FunctionCallExpr *call, llvm::Value *dst);
00101     CValue emitAggregate(AggregateExpr *expr, llvm::Value *dst);
00102     CValue emitDefault(ArrayType *type, llvm::Value *dst);
00103     CValue emitStringLiteral(StringLiteral *expr);
00104 
00115     llvm::Value *allocArray(ArrayType *arrTy, llvm::Value *bounds,
00116                             llvm::Value *&dst);
00117 
00127     void emitDiscreteComponent(AggregateExpr::key_iterator &I,
00128                                llvm::Value *dst, llvm::Value *bias);
00129 
00132     void emitComponent(Expr *expr, llvm::Value *dst);
00133 
00135     llvm::Value *convertIndex(llvm::Value *idx);
00136 
00138 
00139 
00141     CValue emitDefiniteAllocator(AllocatorExpr *expr, ArrayType *arrTy);
00142 
00145     CValue emitConstrainedAllocator(AllocatorExpr *expr, ArrayType *arrTy);
00146 
00148     CValue emitCallAllocator(AllocatorExpr *expr,
00149                              FunctionCallExpr *call, ArrayType *arrTy);
00150 
00152     CValue emitValueAllocator(AllocatorExpr *expr,
00153                               ValueDecl *value, ArrayType *arrTy);
00155 };
00156 
00157 llvm::Value *ArrayEmitter::convertIndex(llvm::Value *idx)
00158 {
00159     const llvm::Type *intptrTy = CGR.getCodeGen().getIntPtrTy();
00160     if (idx->getType() != intptrTy)
00161         return Builder.CreateIntCast(idx, intptrTy, false);
00162     return idx;
00163 }
00164 
00165 CValue ArrayEmitter::emitAllocator(AllocatorExpr *expr)
00166 {
00167     ArrayType *arrTy;
00168     arrTy = cast<ArrayType>(CGR.resolveType(expr->getAllocatedType()));
00169 
00170     if (arrTy->isDefiniteType())
00171         return emitDefiniteAllocator(expr, arrTy);
00172 
00173     assert(expr->isInitialized() &&
00174            "Cannot codegen uninitialized indefinite allocators!");
00175     Expr *operand = expr->getInitializer();
00176 
00177     if (QualifiedExpr *qual = dyn_cast<QualifiedExpr>(operand))
00178         operand = qual->getOperand();
00179 
00180     ArrayType *operandTy = cast<ArrayType>(CGR.resolveType(operand));
00181     if (operandTy->isConstrained())
00182         return emitConstrainedAllocator(expr, operandTy);
00183 
00184     
00185     
00186     if (FunctionCallExpr *call = dyn_cast<FunctionCallExpr>(operand))
00187         return emitCallAllocator(expr, call, arrTy);
00188 
00189     if (DeclRefExpr *ref = dyn_cast<DeclRefExpr>(operand)) {
00190         ValueDecl *value = dyn_cast<ValueDecl>(ref->getDeclaration());
00191         if (value)
00192             return emitValueAllocator(expr, value, arrTy);
00193     }
00194 
00195     assert(false && "Unexpected unconstrained allocator initializer!");
00196     return CValue::getFat(0);
00197 }
00198 
00199 CValue ArrayEmitter::emitDefiniteAllocator(AllocatorExpr *expr,
00200                                            ArrayType *arrTy)
00201 {
00202     assert(arrTy->isDefiniteType());
00203 
00204     const llvm::ArrayType *loweredTy;
00205     const llvm::PointerType *resultTy;
00206     CodeGenTypes &CGT = CGR.getCGC().getCGT();
00207     CommaRT &CRT = CGR.getCodeGen().getRuntime();
00208 
00209     loweredTy = CGT.lowerArrayType(arrTy);
00210     resultTy = CGT.lowerThinAccessType(expr->getType());
00211 
00212     uint64_t size = CGT.getTypeSize(loweredTy);
00213     unsigned align = CGT.getTypeAlignment(loweredTy);
00214 
00215     llvm::Value *result = CRT.comma_alloc(Builder, size, align);
00216     result = Builder.CreatePointerCast(result, resultTy);
00217 
00218     if (expr->isInitialized())
00219         emit(expr->getInitializer(), result, false);
00220 
00221     return CValue::get(result);
00222 }
00223 
00224 CValue ArrayEmitter::emitConstrainedAllocator(AllocatorExpr *expr,
00225                                               ArrayType *arrTy)
00226 {
00227     assert(arrTy->isConstrained());
00228 
00229     const llvm::ArrayType *loweredTy;
00230     const llvm::StructType *resultTy;
00231     const llvm::PointerType *dataTy;
00232     CodeGenTypes &CGT = CGR.getCGC().getCGT();
00233     CodeGen &CG = CGR.getCodeGen();
00234     CommaRT &CRT = CG.getRuntime();
00235 
00236     loweredTy = CGT.lowerArrayType(arrTy);
00237     resultTy = CGT.lowerFatAccessType(expr->getType());
00238     dataTy = cast<llvm::PointerType>(resultTy->getElementType(0));
00239 
00240     
00241     
00242     llvm::Value *size;
00243     if (arrTy->isStaticallyConstrained()) {
00244         uint64_t staticSize = CGT.getTypeSize(loweredTy);
00245         size = llvm::ConstantInt::get(CG.getInt32Ty(), staticSize);
00246     }
00247     else {
00248         BoundsEmitter emitter(CGR);
00249         uint64_t staticSize = CGT.getTypeSize(loweredTy->getElementType());
00250         llvm::Value *bounds = emitter.synthArrayBounds(Builder, arrTy);
00251         llvm::Value *length = emitter.computeTotalBoundLength(Builder, bounds);
00252         size = llvm::ConstantInt::get(CG.getInt32Ty(), staticSize);
00253         size = Builder.CreateMul(size, length);
00254     }
00255 
00256     
00257     
00258     
00259     unsigned align = CGT.getTypeAlignment(loweredTy);
00260     llvm::Value *data = CRT.comma_alloc(Builder, size, align);
00261     data = Builder.CreatePointerCast(data, dataTy);
00262     CValue agg = emit(expr->getInitializer(), data, false);
00263 
00264     
00265     llvm::Value *fatPtr = frame()->createTemp(resultTy);
00266     llvm::Value *bounds = agg.second();
00267     Builder.CreateStore(data, Builder.CreateStructGEP(fatPtr, 0));
00268 
00269     
00270     if (isa<llvm::PointerType>(bounds->getType()))
00271         bounds = Builder.CreateLoad(bounds);
00272     Builder.CreateStore(bounds, Builder.CreateStructGEP(fatPtr, 1));
00273 
00274     
00275     return CValue::getFat(fatPtr);
00276 }
00277 
00278 CValue ArrayEmitter::emitCallAllocator(AllocatorExpr *expr,
00279                                        FunctionCallExpr *call,
00280                                        ArrayType *arrTy)
00281 {
00282     CodeGen &CG = CGR.getCodeGen();
00283     CommaRT &CRT = CG.getRuntime();
00284     CodeGenTypes &CGT = CGR.getCGC().getCGT();
00285 
00286     const llvm::Type *componentTy;
00287     const llvm::StructType *boundsTy;
00288     const llvm::PointerType *targetTy;
00289     const llvm::StructType *fatTy;
00290 
00291     componentTy = CGT.lowerType(arrTy->getComponentType());
00292     boundsTy = CGT.lowerArrayBounds(arrTy);
00293     targetTy = CG.getVLArrayTy(componentTy)->getPointerTo();
00294     fatTy = CGT.lowerFatAccessType(expr->getType());
00295 
00296     llvm::Value *fatPtr = frame()->createTemp(fatTy);
00297 
00298     
00299     CGR.emitSimpleCall(call);
00300 
00301     
00302     llvm::Value *bounds = CRT.vstack(Builder, boundsTy->getPointerTo());
00303     llvm::Value *length = emitter.computeTotalBoundLength(Builder, bounds);
00304 
00305     uint64_t size = CGT.getTypeSize(componentTy);
00306     unsigned align = CGT.getTypeAlignment(componentTy);
00307 
00308     llvm::Value *dimension = Builder.CreateMul
00309         (length, llvm::ConstantInt::get(length->getType(), size));
00310 
00311     
00312     Builder.CreateStore(Builder.CreateLoad(bounds),
00313                         Builder.CreateStructGEP(fatPtr, 1));
00314 
00315     
00316     llvm::Value *dst = CRT.comma_alloc(Builder, dimension, align);
00317 
00318     
00319     CRT.vstack_pop(Builder);
00320     llvm::Value *data = CRT.vstack(Builder, CG.getInt8PtrTy());
00321 
00322     
00323     llvm::Function *memcpy = CG.getMemcpy32();
00324     Builder.CreateCall4(memcpy, dst, data, dimension,
00325                         llvm::ConstantInt::get(CG.getInt32Ty(), align));
00326 
00327     
00328     Builder.CreateStore(Builder.CreatePointerCast(dst, targetTy),
00329                         Builder.CreateStructGEP(fatPtr, 0));
00330 
00331     
00332     CRT.vstack_pop(Builder);
00333 
00334     return CValue::getFat(fatPtr);
00335 }
00336 
00337 CValue ArrayEmitter::emitValueAllocator(AllocatorExpr *expr,
00338                                         ValueDecl *param,
00339                                         ArrayType *arrTy)
00340 {
00341     CodeGen &CG = CGR.getCodeGen();
00342     CommaRT &CRT = CG.getRuntime();
00343     CodeGenTypes &CGT = CGR.getCGC().getCGT();
00344 
00345     const llvm::Type *componentTy;
00346     const llvm::PointerType *targetTy;
00347     const llvm::StructType *fatTy;
00348 
00349     componentTy = CGT.lowerType(arrTy->getComponentType());
00350     targetTy = CG.getVLArrayTy(componentTy)->getPointerTo();
00351     fatTy = CGT.lowerFatAccessType(expr->getType());
00352 
00353     llvm::Value *fatPtr = frame()->createTemp(fatTy);
00354     llvm::Value *data   = frame()->lookup(param, activation::Slot);
00355     llvm::Value *bounds = frame()->lookup(param, activation::Bounds);
00356     llvm::Value *length = emitter.computeTotalBoundLength(Builder, bounds);
00357 
00358     
00359     uint64_t size = CGT.getTypeSize(componentTy);
00360     unsigned align = CGT.getTypeAlignment(componentTy);
00361 
00362     llvm::Value *dimension = Builder.CreateMul
00363         (length, llvm::ConstantInt::get(length->getType(), size));
00364 
00365     
00366     Builder.CreateStore(Builder.CreateLoad(bounds),
00367                         Builder.CreateStructGEP(fatPtr, 1));
00368 
00369     
00370     
00371     llvm::Value *dst = CRT.comma_alloc(Builder, dimension, align);
00372     llvm::Function *memcpy = CG.getMemcpy32();
00373     data = Builder.CreatePointerCast(data, CG.getInt8PtrTy());
00374     Builder.CreateCall4(memcpy, dst, data, dimension,
00375                         llvm::ConstantInt::get(CG.getInt32Ty(), align));
00376 
00377     
00378     Builder.CreateStore(Builder.CreatePointerCast(dst, targetTy),
00379                         Builder.CreateStructGEP(fatPtr, 0));
00380 
00381     return CValue::getFat(fatPtr);
00382 }
00383 
00384 
00385 CValue ArrayEmitter::emit(Expr *expr, llvm::Value *dst, bool genTmp)
00386 {
00387     llvm::Value *components;
00388     llvm::Value *bounds;
00389     ArrayType *arrTy = cast<ArrayType>(CGR.resolveType(expr->getType()));
00390 
00391     if (ConversionExpr *convert = dyn_cast<ConversionExpr>(expr))
00392         return emitArrayConversion(convert, dst, genTmp);
00393 
00394     if (FunctionCallExpr *call = dyn_cast<FunctionCallExpr>(expr))
00395         return emitCall(call, dst);
00396 
00397     if (AggregateExpr *agg = dyn_cast<AggregateExpr>(expr))
00398         return emitAggregate(agg, dst);
00399 
00400     if (InjExpr *inj = dyn_cast<InjExpr>(expr))
00401         return emit(inj->getOperand(), dst, genTmp);
00402 
00403     if (PrjExpr *prj = dyn_cast<PrjExpr>(expr))
00404         return emit(prj->getOperand(), dst, genTmp);
00405 
00406     if (QualifiedExpr *qual = dyn_cast<QualifiedExpr>(expr))
00407         return emit(qual->getOperand(), dst, genTmp);
00408 
00409     if (isa<DiamondExpr>(expr))
00410         return emitDefault(arrTy, dst);
00411 
00412     if (DeclRefExpr *ref = dyn_cast<DeclRefExpr>(expr)) {
00413         ValueDecl *decl = ref->getDeclaration();
00414         components = frame()->lookup(decl, activation::Slot);
00415         if (!(bounds = frame()->lookup(decl, activation::Bounds)))
00416             bounds = emitter.synthStaticArrayBounds(Builder, arrTy);
00417     }
00418     else if (StringLiteral *lit = dyn_cast<StringLiteral>(expr)) {
00419         CValue value = emitStringLiteral(lit);
00420         components = value.first();
00421         bounds = value.second();
00422     }
00423     else if (IndexedArrayExpr *iae = dyn_cast<IndexedArrayExpr>(expr)) {
00424         CValue value = CGR.emitIndexedArrayRef(iae);
00425         components = value.first();
00426         bounds = value.second();
00427     }
00428     else if (SelectedExpr *sel = dyn_cast<SelectedExpr>(expr)) {
00429         components = CGR.emitSelectedRef(sel).first();
00430         bounds = emitter.synthArrayBounds(Builder, arrTy);
00431     }
00432     else if (DereferenceExpr *deref = dyn_cast<DereferenceExpr>(expr)) {
00433         CValue value = CGR.emitValue(deref->getPrefix());
00434 
00435         
00436         
00437         
00438         
00439         if (value.isFat()) {
00440             llvm::Value *fatPtr = value.first();
00441             components = Builder.CreateStructGEP(fatPtr, 0);
00442             components = Builder.CreateLoad(components);
00443             bounds = Builder.CreateStructGEP(fatPtr, 1);
00444         }
00445         else {
00446             components = value.first();
00447             bounds = emitter.synthArrayBounds(Builder, arrTy);
00448         }
00449 
00450         
00451         CGR.emitNullAccessCheck(components, deref->getLocation());
00452     }
00453     else {
00454         assert(false && "Invalid type of array expr!");
00455         return CValue::getArray(0, 0);
00456     }
00457 
00458     llvm::Value *length = 0;
00459 
00460     
00461     
00462     if (dst == 0 && genTmp)
00463         length = allocArray(arrTy, bounds, dst);
00464 
00465     
00466     
00467     
00468     if (dst) {
00469         const llvm::Type *componentTy = dst->getType();
00470         componentTy = cast<llvm::SequentialType>(componentTy)->getElementType();
00471         componentTy = cast<llvm::SequentialType>(componentTy)->getElementType();
00472         if (!length)
00473             length = emitter.computeTotalBoundLength(Builder, bounds);
00474         CGR.emitArrayCopy(components, dst, length, componentTy);
00475         return CValue::getArray(dst, bounds);
00476     }
00477     else
00478         return CValue::getArray(components, bounds);
00479 }
00480 
00481 void ArrayEmitter::emitComponent(Expr *expr, llvm::Value *dst)
00482 {
00483     Type *exprTy = CGR.resolveType(expr);
00484 
00485     if (exprTy->isCompositeType())
00486         CGR.emitCompositeExpr(expr, dst, false);
00487     else if (exprTy->isFatAccessType()) {
00488         llvm::Value *fatPtr = CGR.emitValue(expr).first();
00489         Builder.CreateStore(Builder.CreateLoad(fatPtr), dst);
00490     }
00491     else
00492         Builder.CreateStore(CGR.emitValue(expr).first(), dst);
00493 }
00494 
00495 CValue ArrayEmitter::emitCall(FunctionCallExpr *call, llvm::Value *dst)
00496 {
00497     ArrayType *arrTy = cast<ArrayType>(CGR.resolveType(call->getType()));
00498 
00499     
00500     if (arrTy->isConstrained()) {
00501         CValue data = CGR.emitCompositeCall(call, dst);
00502         llvm::Value *bounds = emitter.synthArrayBounds(Builder, arrTy);
00503         return CValue::getArray(data.first(), bounds);
00504     }
00505 
00506     
00507     
00508     assert(dst == 0 && "Destination given for indefinite type!");
00509     return CGR.emitVStackCall(call);
00510 }
00511 
00512 CValue ArrayEmitter::emitAggregate(AggregateExpr *expr, llvm::Value *dst)
00513 {
00514     if (expr->isPurelyPositional())
00515         return emitPositionalAgg(expr, dst);
00516     return emitKeyedAgg(expr, dst);
00517 }
00518 
00519 CValue ArrayEmitter::emitDefault(ArrayType *arrTy, llvm::Value *dst)
00520 {
00521     CodeGen &CG = CGR.getCodeGen();
00522     CodeGenTypes &CGT = CGR.getCGC().getCGT();
00523 
00524     llvm::Value *bounds = emitter.synthArrayBounds(Builder, arrTy);
00525     llvm::Value *length = 0;
00526 
00527     
00528     if (!dst)
00529         length = allocArray(arrTy, bounds, dst);
00530     else
00531         length = emitter.computeTotalBoundLength(Builder, bounds);
00532 
00533     
00534     const llvm::Type *componentTy = CGT.lowerType(arrTy->getComponentType());
00535     uint64_t componentSize = CGT.getTypeSize(componentTy);
00536     unsigned align = CGT.getTypeAlignment(componentTy);
00537     llvm::Function *memset = CG.getMemset32();
00538     llvm::Value *size = Builder.CreateMul
00539         (length, llvm::ConstantInt::get(length->getType(), componentSize));
00540     llvm::Value *raw = Builder.CreatePointerCast(dst, CG.getInt8PtrTy());
00541 
00542     Builder.CreateCall4(memset, raw, llvm::ConstantInt::get(CG.getInt8Ty(), 0),
00543                         size, llvm::ConstantInt::get(CG.getInt32Ty(), align));
00544 
00545     
00546     return CValue::getArray(dst, bounds);
00547 }
00548 
00549 CValue ArrayEmitter::emitStringLiteral(StringLiteral *expr)
00550 {
00551     assert(expr->hasType() && "Unresolved string literal type!");
00552 
00553     
00554     CodeGen &CG = CGR.getCodeGen();
00555     CodeGenTypes &CGT = CGR.getCGC().getCGT();
00556     const llvm::ArrayType *arrTy = CGT.lowerArrayType(expr->getType());
00557     const llvm::Type *elemTy = arrTy->getElementType();
00558     llvm::StringRef string = expr->getString();
00559 
00560     std::vector<llvm::Constant *> elements;
00561     const EnumerationDecl *component = expr->getComponentType();
00562     for (llvm::StringRef::iterator I = string.begin(); I != string.end(); ++I) {
00563         unsigned encoding = component->getEncoding(*I);
00564         elements.push_back(llvm::ConstantInt::get(elemTy, encoding));
00565     }
00566 
00567     
00568     llvm::Constant *arrData;
00569     llvm::GlobalVariable *dataPtr;
00570     arrData = CG.getConstantArray(elemTy, elements);
00571     dataPtr = new llvm::GlobalVariable(
00572         *CG.getModule(), arrData->getType(), true,
00573         llvm::GlobalValue::InternalLinkage, arrData, "string.data");
00574 
00575     
00576     
00577     
00578     llvm::Constant *boundData;
00579     llvm::GlobalVariable *boundPtr;
00580     boundData = emitter.synthStaticArrayBounds(Builder, expr->getType());
00581     boundPtr = new llvm::GlobalVariable(
00582         *CG.getModule(), boundData->getType(), true,
00583         llvm::GlobalValue::InternalLinkage, boundData, "bounds.data");
00584     return CValue::getArray(dataPtr, boundPtr);
00585 }
00586 
00587 CValue ArrayEmitter::emitArrayConversion(ConversionExpr *convert,
00588                                          llvm::Value *dst, bool genTmp)
00589 {
00590     
00591     return emit(convert->getOperand(), dst, genTmp);
00592 }
00593 
00594 void ArrayEmitter::emitOthers(Expr *others, llvm::Value *dst,
00595                               llvm::Value *start, llvm::Value *end,
00596                               llvm::Value *bias)
00597 {
00598     llvm::BasicBlock *startBB = Builder.GetInsertBlock();
00599     llvm::BasicBlock *checkBB = frame()->makeBasicBlock("others.check");
00600     llvm::BasicBlock *bodyBB = frame()->makeBasicBlock("others.body");
00601     llvm::BasicBlock *mergeBB = frame()->makeBasicBlock("others.merge");
00602 
00603     
00604     llvm::Value *iterStart = Builder.CreateSub(start, bias);
00605     llvm::Value *iterLimit = Builder.CreateSub(end, bias);
00606 
00607     const llvm::Type *iterTy = iterStart->getType();
00608     llvm::Value *iterZero = llvm::ConstantInt::get(iterTy, 0);
00609     llvm::Value *iterOne = llvm::ConstantInt::get(iterTy, 1);
00610     Builder.CreateBr(checkBB);
00611 
00612     
00613     Builder.SetInsertPoint(checkBB);
00614     llvm::PHINode *phi = Builder.CreatePHI(iterStart->getType());
00615     llvm::Value *pred = Builder.CreateICmpEQ(phi, iterLimit);
00616     Builder.CreateCondBr(pred, mergeBB, bodyBB);
00617 
00618     
00619     Builder.SetInsertPoint(bodyBB);
00620     llvm::Value *indices[2];
00621     indices[0] = iterZero;
00622     indices[1] = convertIndex(phi);
00623 
00624     llvm::Value *ptr = Builder.CreateInBoundsGEP(dst, indices, indices + 2);
00625     emitComponent(others, ptr);
00626     llvm::Value *iterNext = Builder.CreateAdd(phi, iterOne);
00627     Builder.CreateBr(checkBB);
00628 
00629     
00630     phi->addIncoming(iterStart, startBB);
00631     phi->addIncoming(iterNext, Builder.GetInsertBlock());
00632 
00633     
00634     Builder.SetInsertPoint(mergeBB);
00635 }
00636 
00637 void ArrayEmitter::emitOthers(AggregateExpr *expr,
00638                               llvm::Value *dst, llvm::Value *bounds,
00639                               uint64_t numComponents)
00640 {
00641     
00642     
00643     
00644     
00645     Expr *othersExpr = expr->getOthersExpr();
00646     if (!othersExpr)
00647         return;
00648 
00649     
00650     
00651     
00652     
00653     if (numComponents == 0) {
00654         emitComponent(othersExpr, Builder.CreateConstGEP2_32(dst, 0, 0));
00655         numComponents = 1;
00656     }
00657 
00658     
00659     
00660     
00661     llvm::BasicBlock *startBB = Builder.GetInsertBlock();
00662     llvm::BasicBlock *checkBB = frame()->makeBasicBlock("others.check");
00663     llvm::BasicBlock *bodyBB = frame()->makeBasicBlock("others.body");
00664     llvm::BasicBlock *mergeBB = frame()->makeBasicBlock("others.merge");
00665 
00666     
00667     llvm::Value *lower = BoundsEmitter::getLowerBound(Builder, bounds, 0);
00668     llvm::Value *upper = BoundsEmitter::getUpperBound(Builder, bounds, 0);
00669     llvm::Value *max = Builder.CreateSub(upper, lower);
00670 
00671     
00672     
00673     
00674     const llvm::IntegerType *idxTy = cast<llvm::IntegerType>(upper->getType());
00675     llvm::Value *idxZero = llvm::ConstantInt::get(idxTy, 0);
00676     llvm::Value *idxOne = llvm::ConstantInt::get(idxTy, 1);
00677     llvm::Value *idxStart = llvm::ConstantInt::get(idxTy, numComponents - 1);
00678 
00679     
00680     
00681     Builder.CreateBr(checkBB);
00682     Builder.SetInsertPoint(checkBB);
00683     llvm::PHINode *phi = Builder.CreatePHI(idxTy);
00684     Builder.CreateCondBr(Builder.CreateICmpEQ(phi, max), mergeBB, bodyBB);
00685 
00686     
00687     Builder.SetInsertPoint(bodyBB);
00688     llvm::Value *idxNext = Builder.CreateAdd(phi, idxOne);
00689 
00690     llvm::Value *indices[2];
00691     indices[0] = idxZero;
00692     indices[1] = convertIndex(idxNext);
00693     llvm::Value *ptr = Builder.CreateInBoundsGEP(dst, indices, indices + 2);
00694     emitComponent(othersExpr, ptr);
00695     Builder.CreateBr(checkBB);
00696 
00697     
00698     phi->addIncoming(idxStart, startBB);
00699     phi->addIncoming(idxNext, Builder.GetInsertBlock());
00700 
00701     
00702     Builder.SetInsertPoint(mergeBB);
00703 }
00704 
00705 CValue ArrayEmitter::emitPositionalAgg(AggregateExpr *expr, llvm::Value *dst)
00706 {
00707     assert(expr->isPurelyPositional() && "Unexpected type of aggregate!");
00708 
00709     llvm::Value *bounds = emitter.synthAggregateBounds(Builder, expr);
00710     ArrayType *arrTy = cast<ArrayType>(expr->getType());
00711 
00712     std::vector<llvm::Value*> components;
00713 
00714     if (dst == 0)
00715         allocArray(arrTy, bounds, dst);
00716 
00717     typedef AggregateExpr::pos_iterator iterator;
00718     iterator I = expr->pos_begin();
00719     iterator E = expr->pos_end();
00720     for (unsigned idx = 0; I != E; ++I, ++idx)
00721         emitComponent(*I, Builder.CreateConstGEP2_32(dst, 0, idx));
00722 
00723     
00724     emitOthers(expr, dst, bounds, components.size());
00725     return CValue::getArray(dst, bounds);
00726 }
00727 
00728 CValue ArrayEmitter::emitKeyedAgg(AggregateExpr *expr, llvm::Value *dst)
00729 {
00730     assert(expr->isPurelyKeyed() && "Unexpected kind of aggregate!");
00731 
00732     if (expr->hasStaticIndices())
00733         return emitStaticKeyedAgg(expr, dst);
00734 
00735     if (expr->numKeys() == 1)
00736         return emitDynamicKeyedAgg(expr, dst);
00737 
00738     assert(expr->numKeys() == 0);
00739     assert(expr->hasOthers());
00740 
00741     return emitOthersKeyedAgg(expr, dst);
00742 }
00743 
00744 void ArrayEmitter::emitDiscreteComponent(AggregateExpr::key_iterator &I,
00745                                          llvm::Value *dst, llvm::Value *bias)
00746 {
00747     
00748     uint64_t length;
00749 
00750     
00751     llvm::Value *idx;
00752 
00753     if (Range *range = (*I)->getAsRange()) {
00754         length = range->length();
00755         idx = emitter.getLowerBound(Builder, range);
00756     }
00757     else {
00758         Expr *expr = (*I)->getAsExpr();
00759         length = 1;
00760         idx = CGR.emitValue(expr).first();
00761     }
00762 
00763     Expr *expr = I.getExpr();
00764     const llvm::Type *idxTy = idx->getType();
00765 
00766     
00767     
00768     
00769     
00770     
00771     
00772     if (length <= 8) {
00773         llvm::Value *idxZero = llvm::ConstantInt::get(idxTy, 0);
00774         llvm::Value *idxOne = llvm::ConstantInt::get(idxTy, 1);
00775         idx = Builder.CreateSub(idx, bias);
00776         for (uint64_t i = 0; i < length; ++i) {
00777             llvm::Value *indices[2];
00778             llvm::Value *ptr;
00779             indices[0] = idxZero;
00780             indices[1] = convertIndex(idx);
00781             ptr = Builder.CreateInBoundsGEP(dst, indices, indices + 2);
00782             emitComponent(expr, ptr);
00783             idx = Builder.CreateAdd(idx, idxOne);
00784         }
00785     }
00786     else {
00787         llvm::Value *end = llvm::ConstantInt::get(idxTy, length);
00788         end = Builder.CreateAdd(idx, end);
00789         emitOthers(expr, dst, idx, end, bias);
00790     }
00791 }
00792 
00793 CValue ArrayEmitter::emitStaticKeyedAgg(AggregateExpr *agg, llvm::Value *dst)
00794 {
00795     assert(agg->isPurelyKeyed() && "Unexpected type of aggregate!");
00796 
00797     ArrayType *arrTy = cast<ArrayType>(agg->getType());
00798     DiscreteType *idxTy = arrTy->getIndexType(0);
00799 
00800     
00801     llvm::Value *bounds;
00802     llvm::Value *lower;
00803     llvm::Value *upper;
00804 
00805     bounds = emitter.synthScalarBounds(Builder, idxTy);
00806     lower = emitter.getLowerBound(Builder, bounds, 0);
00807     upper = emitter.getUpperBound(Builder, bounds, 0);
00808 
00809     
00810     if (dst == 0)
00811         allocArray(arrTy, bounds, dst);
00812 
00813     
00814     AggregateExpr::key_iterator I = agg->key_begin();
00815     AggregateExpr::key_iterator E = agg->key_end();
00816     for ( ; I != E; ++I)
00817         emitDiscreteComponent(I, dst, lower);
00818     fillInOthers(agg, dst, lower, upper);
00819 
00820     return CValue::getArray(dst, bounds);
00821 }
00822 
00823 void ArrayEmitter::fillInOthers(AggregateExpr *agg, llvm::Value *dst,
00824                                 llvm::Value *lower, llvm::Value *upper)
00825 {
00826     
00827     Expr *others = agg->getOthersExpr();
00828     if (!others)
00829         return;
00830 
00831     DiscreteType *idxTy = cast<ArrayType>(agg->getType())->getIndexType(0);
00832     const llvm::Type *iterTy = lower->getType();
00833 
00834     
00835     typedef std::vector<ComponentKey*> KeyVec;
00836     KeyVec KV(agg->key_begin(), agg->key_end());
00837     if (idxTy->isSigned())
00838         std::sort(KV.begin(), KV.end(), ComponentKey::compareKeysS);
00839     else
00840         std::sort(KV.begin(), KV.end(), ComponentKey::compareKeysU);
00841 
00842     llvm::APInt limit;
00843     llvm::APInt lowerValue;
00844     llvm::APInt upperValue;
00845 
00846     
00847     KV.front()->getLowerValue(lowerValue);
00848     idxTy->getLowerLimit(limit);
00849     if (lowerValue != limit) {
00850         llvm::Value *end = llvm::ConstantInt::get(iterTy, lowerValue);
00851         emitOthers(others, dst, lower, end, lower);
00852     }
00853 
00854     
00855     for (unsigned i = 0; i < KV.size() - 1; ++i) {
00856         
00857         KV[i]->getUpperValue(lowerValue);
00858         KV[i+1]->getLowerValue(upperValue);
00859 
00860         if (lowerValue == upperValue)
00861             continue;
00862 
00863         llvm::Value *start = llvm::ConstantInt::get(iterTy, ++lowerValue);
00864         llvm::Value *end = llvm::ConstantInt::get(iterTy, upperValue);
00865         emitOthers(others, dst, start, end, lower);
00866     }
00867 
00868     
00869     KV.back()->getUpperValue(upperValue);
00870     idxTy->getUpperLimit(limit);
00871     if (upperValue != limit) {
00872         llvm::Value *start;
00873         llvm::Value *end;
00874         start = llvm::ConstantInt::get(iterTy, upperValue);
00875         start = Builder.CreateAdd(start, llvm::ConstantInt::get(iterTy, 1));
00876         end = Builder.CreateAdd(upper, llvm::ConstantInt::get(iterTy, 1));
00877         emitOthers(others, dst, start, end, lower);
00878     }
00879 }
00880 
00881 CValue ArrayEmitter::emitDynamicKeyedAgg(AggregateExpr *expr, llvm::Value *dst)
00882 {
00883     ArrayType *arrTy = cast<ArrayType>(expr->getType());
00884     AggregateExpr::key_iterator I = expr->key_begin();
00885     Range *range = cast<Range>((*I)->getRep());
00886     llvm::Value *bounds = emitter.synthRange(Builder, range);
00887     llvm::Value *length = 0;
00888 
00889     if (dst == 0)
00890         length = allocArray(arrTy, bounds, dst);
00891 
00892     if (length == 0)
00893         length = emitter.computeBoundLength(Builder, bounds, 0);
00894 
00895     
00896     
00897     const llvm::Type *iterTy = length->getType();
00898     llvm::Value *iterZero = llvm::ConstantInt::get(iterTy, 0);
00899     llvm::Value *iterOne = llvm::ConstantInt::get(iterTy, 1);
00900 
00901     
00902     llvm::Value *iter = frame()->createTemp(iterTy);
00903     Builder.CreateStore(iterZero, iter);
00904 
00905     
00906     llvm::BasicBlock *checkBB = frame()->makeBasicBlock("agg.check");
00907     llvm::BasicBlock *bodyBB = frame()->makeBasicBlock("agg.body");
00908     llvm::BasicBlock *mergeBB = frame()->makeBasicBlock("agg.merge");
00909 
00910     
00911     Builder.CreateBr(checkBB);
00912     Builder.SetInsertPoint(checkBB);
00913     llvm::Value *idx = Builder.CreateLoad(iter);
00914     llvm::Value *pred = Builder.CreateICmpULT(idx, length);
00915     Builder.CreateCondBr(pred, bodyBB, mergeBB);
00916 
00917     
00918     Builder.SetInsertPoint(bodyBB);
00919     llvm::Value *indices[2];
00920     llvm::Value *ptr;
00921 
00922     indices[0] = iterZero;
00923     indices[1] = convertIndex(idx);
00924 
00925     ptr = Builder.CreateInBoundsGEP(dst, indices, indices + 2);
00926     emitComponent(I.getExpr(), ptr);
00927     Builder.CreateStore(Builder.CreateAdd(idx, iterOne), iter);
00928     Builder.CreateBr(checkBB);
00929 
00930     
00931     Builder.SetInsertPoint(mergeBB);
00932     return CValue::getArray(dst, bounds);
00933 }
00934 
00935 CValue ArrayEmitter::emitOthersKeyedAgg(AggregateExpr *expr, llvm::Value *dst)
00936 {
00937     assert(expr->hasOthers() && "Empty aggregate!");
00938 
00939     
00940     
00941     ArrayType *arrTy = cast<ArrayType>(expr->getType());
00942     assert(arrTy->isConstrained() && "Aggregate requires constraint!");
00943 
00944     DiscreteType *idxTy = arrTy->getIndexType(0);
00945     llvm::Value *bounds = emitter.synthScalarBounds(Builder, idxTy);
00946 
00947     
00948     if (dst == 0)
00949         allocArray(arrTy, bounds, dst);
00950 
00951     
00952     emitOthers(expr, dst, bounds, 0);
00953     return CValue::getArray(dst, bounds);
00954 }
00955 
00956 llvm::Value *ArrayEmitter::allocArray(ArrayType *arrTy, llvm::Value *bounds,
00957                                       llvm::Value *&dst)
00958 {
00959     CodeGenTypes &CGT = CGR.getCGC().getCGT();
00960 
00961     if (arrTy->isStaticallyConstrained()) {
00962         dst = frame()->createTemp(CGT.lowerArrayType(arrTy));
00963         return 0;
00964     }
00965     else {
00966         CodeGen &CG = CGR.getCodeGen();
00967         const llvm::Type *componentTy;
00968         const llvm::Type *dstTy;
00969         llvm::Value *length;
00970 
00971         length = emitter.computeTotalBoundLength(Builder, bounds);
00972         componentTy = CGT.lowerType(arrTy->getComponentType());
00973         dstTy = CG.getPointerType(CG.getVLArrayTy(componentTy));
00974         frame()->stacksave();
00975         dst = Builder.CreateAlloca(componentTy, length);
00976         dst = Builder.CreatePointerCast(dst, dstTy);
00977         return length;
00978     }
00979 }
00980 
00981 
00985 class RecordEmitter {
00986 
00987 public:
00988     RecordEmitter(CodeGenRoutine &CGR, llvm::IRBuilder<> &Builder)
00989         : CGR(CGR),
00990           CGT(CGR.getCGC().getCGT()),
00991           emitter(CGR),
00992           Builder(Builder) { }
00993 
00994     CValue emit(Expr *expr, llvm::Value *dst, bool genTmp);
00995 
00996     CValue emitAllocator(AllocatorExpr *expr);
00997 
00998 private:
00999     CodeGenRoutine &CGR;
01000     CodeGenTypes &CGT;
01001     BoundsEmitter emitter;
01002     llvm::IRBuilder<> &Builder;
01003 
01004     SRFrame *frame() { return CGR.getSRFrame(); }
01005 
01007     CValue emitCall(FunctionCallExpr *call, llvm::Value *dst);
01008 
01019     CValue emitAggregate(AggregateExpr *agg, llvm::Value *dst);
01020 
01022     CValue emitDefault(RecordType *type, llvm::Value *dst);
01023 
01028     typedef llvm::SmallPtrSet<ComponentDecl*, 16> ComponentSet;
01029 
01035     void emitPositionalComponents(AggregateExpr *agg, llvm::Value *dst,
01036                                   ComponentSet &components);
01037 
01043     void emitKeyedComponents(AggregateExpr *agg, llvm::Value *dst,
01044                              ComponentSet &components);
01045 
01051     void emitOthersComponents(AggregateExpr *agg, llvm::Value *dst,
01052                               ComponentSet &components);
01053 
01057     void emitComponent(Expr *expr, llvm::Value *dst);
01058 };
01059 
01060 CValue RecordEmitter::emitAllocator(AllocatorExpr *expr)
01061 {
01062     
01063     AccessType *exprTy = expr->getType();
01064     const llvm::PointerType *resultTy = CGT.lowerThinAccessType(exprTy);
01065     const llvm::Type *pointeeTy = resultTy->getElementType();
01066 
01067     uint64_t size = CGT.getTypeSize(pointeeTy);
01068     unsigned align = CGT.getTypeAlignment(pointeeTy);
01069 
01070     
01071     
01072     CommaRT &CRT = CGR.getCodeGen().getRuntime();
01073     llvm::Value *pointer = CRT.comma_alloc(Builder, size, align);
01074     pointer = Builder.CreatePointerCast(pointer, resultTy);
01075 
01076     
01077     if (expr->isInitialized()) {
01078         Expr *init = expr->getInitializer();
01079         emit(init, pointer, false);
01080     }
01081 
01082     return CValue::get(pointer);
01083 }
01084 
01085 CValue RecordEmitter::emit(Expr *expr, llvm::Value *dst, bool genTmp)
01086 {
01087     if (AggregateExpr *agg = dyn_cast<AggregateExpr>(expr))
01088         return emitAggregate(agg, dst);
01089 
01090     if (FunctionCallExpr *call = dyn_cast<FunctionCallExpr>(expr))
01091         return emitCall(call, dst);
01092 
01093     if (InjExpr *inj = dyn_cast<InjExpr>(expr))
01094         return emit(inj->getOperand(), dst, genTmp);
01095 
01096     if (PrjExpr *prj = dyn_cast<PrjExpr>(expr))
01097         return emit(prj->getOperand(), dst, genTmp);
01098 
01099     if (QualifiedExpr *qual = dyn_cast<QualifiedExpr>(expr))
01100         return emit(qual->getOperand(), dst, genTmp);
01101 
01102     if (isa<DiamondExpr>(expr)) {
01103         RecordType *recTy = cast<RecordType>(CGR.resolveType(expr));
01104         return emitDefault(recTy, dst);
01105     }
01106 
01107     llvm::Value *rec = 0;
01108 
01109     if (DeclRefExpr *ref = dyn_cast<DeclRefExpr>(expr)) {
01110         ValueDecl *decl = ref->getDeclaration();
01111         rec = frame()->lookup(decl, activation::Slot);
01112     }
01113     else if (IndexedArrayExpr *IAE = dyn_cast<IndexedArrayExpr>(expr)) {
01114         rec = CGR.emitIndexedArrayRef(IAE).first();
01115     }
01116     else if (SelectedExpr *sel = dyn_cast<SelectedExpr>(expr)) {
01117         rec = CGR.emitSelectedRef(sel).first();
01118     }
01119     else if (DereferenceExpr *deref = dyn_cast<DereferenceExpr>(expr)) {
01120         
01121         
01122         rec = CGR.emitValue(deref->getPrefix()).first();
01123         CGR.emitNullAccessCheck(rec, deref->getLocation());
01124     }
01125 
01126     assert(rec && "Could not codegen record expression!");
01127 
01128     CodeGen &CG = CGR.getCodeGen();
01129     const llvm::Type *recTy;
01130     recTy = CGT.lowerType(CGR.resolveType(expr->getType()));
01131 
01132     
01133     if (dst == 0 && genTmp)
01134         dst = frame()->createTemp(recTy);
01135 
01136     
01137     if (dst) {
01138         llvm::Function *memcpy = CG.getMemcpy64();
01139         llvm::Value *source = Builder.CreatePointerCast(rec, CG.getInt8PtrTy());
01140         llvm::Value *target = Builder.CreatePointerCast(dst, CG.getInt8PtrTy());
01141         llvm::Value *len = llvm::ConstantExpr::getSizeOf(recTy);
01142         llvm::Value *align = llvm::ConstantInt::get(
01143             CG.getInt32Ty(), CG.getTargetData().getABITypeAlignment(recTy));
01144         Builder.CreateCall4(memcpy, target, source, len, align);
01145         return CValue::getRecord(dst);
01146     }
01147     else
01148         return CValue::getRecord(rec);
01149 }
01150 
01151 CValue RecordEmitter::emitAggregate(AggregateExpr *agg, llvm::Value *dst)
01152 {
01153     RecordType *recTy = cast<RecordType>(agg->getType());
01154     const llvm::Type *loweredTy = CGT.lowerRecordType(recTy);
01155 
01156     
01157     if (dst == 0)
01158         dst = frame()->createTemp(loweredTy);
01159 
01160     ComponentSet components;
01161 
01162     
01163     emitPositionalComponents(agg, dst, components);
01164 
01165     
01166     emitKeyedComponents(agg, dst, components);
01167 
01168     
01169     emitOthersComponents(agg, dst, components);
01170 
01171     return CValue::getRecord(dst);
01172 }
01173 
01174 CValue RecordEmitter::emitDefault(RecordType *type, llvm::Value *dst)
01175 {
01176     CodeGen &CG = CGR.getCodeGen();
01177     const llvm::StructType *loweredType = CGT.lowerRecordType(type);
01178 
01179     
01180     if (dst == 0)
01181         dst = frame()->createTemp(loweredType);
01182 
01183     
01184     uint64_t size = CGT.getTypeSize(loweredType);
01185     unsigned align = CGT.getTypeAlignment(loweredType);
01186     const llvm::Type *i32Ty = CG.getInt32Ty();
01187     llvm::Function *memset = CG.getMemset32();
01188     llvm::Value *raw = Builder.CreatePointerCast(dst, CG.getInt8PtrTy());
01189 
01190     Builder.CreateCall4(memset, raw,
01191                         llvm::ConstantInt::get(CG.getInt8Ty(), 0),
01192                         llvm::ConstantInt::get(i32Ty, size),
01193                         llvm::ConstantInt::get(i32Ty, align));
01194 
01195     return CValue::getRecord(dst);
01196 }
01197 
01198 void RecordEmitter::emitComponent(Expr *expr, llvm::Value *dst)
01199 {
01200     Type *componentTy = CGR.resolveType(expr->getType());
01201     if (componentTy->isCompositeType())
01202         CGR.emitCompositeExpr(expr, dst, false);
01203     else if (componentTy->isFatAccessType()) {
01204         CValue component = CGR.emitValue(expr);
01205         Builder.CreateStore(Builder.CreateLoad(component.first()), dst);
01206     }
01207     else {
01208         CValue component = CGR.emitValue(expr);
01209         Builder.CreateStore(component.first(), dst);
01210     }
01211 }
01212 
01213 void RecordEmitter::emitPositionalComponents(AggregateExpr *agg, llvm::Value *dst,
01214                                              ComponentSet &components)
01215 {
01216     if (!agg->hasPositionalComponents())
01217         return;
01218 
01219     RecordType *recTy = cast<RecordType>(agg->getType());
01220     RecordDecl *recDecl = recTy->getDefiningDecl();
01221 
01222     
01223     
01224     typedef AggregateExpr::pos_iterator iterator;
01225     iterator I = agg->pos_begin();
01226     iterator E = agg->pos_end();
01227     for (unsigned i = 0; I != E; ++I, ++i) {
01228         ComponentDecl *component = recDecl->getComponent(i);
01229         unsigned index = CGT.getComponentIndex(component);
01230         llvm::Value *componentPtr = Builder.CreateStructGEP(dst, index);
01231         emitComponent(*I, componentPtr);
01232         components.insert(component);
01233     }
01234 }
01235 
01236 void RecordEmitter::emitKeyedComponents(AggregateExpr *agg, llvm::Value *dst,
01237                                         ComponentSet &components)
01238 {
01239     if (!agg->hasKeyedComponents())
01240         return;
01241 
01242     typedef AggregateExpr::key_iterator iterator;
01243     iterator I = agg->key_begin();
01244     iterator E = agg->key_end();
01245     for ( ; I != E; ++I) {
01246         ComponentDecl *component = I->getAsComponent();
01247         unsigned index = CGT.getComponentIndex(component);
01248         llvm::Value *componentPtr = Builder.CreateStructGEP(dst, index);
01249         emitComponent(I.getExpr(), componentPtr);
01250         components.insert(component);
01251     }
01252 }
01253 
01254 void RecordEmitter::emitOthersComponents(AggregateExpr *agg, llvm::Value *dst,
01255                                          ComponentSet &components)
01256 {
01257     if (!agg->hasOthers())
01258         return;
01259 
01260     
01261     
01262     
01263     Expr *others = agg->getOthersExpr();
01264     RecordDecl *recDecl = cast<RecordType>(agg->getType())->getDefiningDecl();
01265     unsigned numComponents = recDecl->numComponents();
01266     for (unsigned i = 0 ; i < numComponents; ++i) {
01267         ComponentDecl *component = recDecl->getComponent(i);
01268         if (!components.count(component)) {
01269             unsigned index = CGT.getComponentIndex(component);
01270             llvm::Value *componentPtr = Builder.CreateStructGEP(dst, index);
01271             emitComponent(others, componentPtr);
01272         }
01273     }
01274 }
01275 
01276 CValue RecordEmitter::emitCall(FunctionCallExpr *call, llvm::Value *dst)
01277 {
01278     
01279     return CGR.emitCompositeCall(call, dst);
01280 }
01281 
01282 } 
01283 
01284 void CodeGenRoutine::emitArrayCopy(llvm::Value *source,
01285                                    llvm::Value *destination,
01286                                    ArrayType *Ty)
01287 {
01288     assert(Ty->isStaticallyConstrained() && "Cannot copy unconstrained arrays!");
01289 
01290     
01291     llvm::Value *src;
01292     llvm::Value *dst;
01293     llvm::Value *len;
01294     llvm::Constant *align;
01295     llvm::Function *memcpy;
01296     const llvm::PointerType *ptrTy;
01297     const llvm::ArrayType *arrTy;
01298 
01299     src = Builder.CreatePointerCast(source, CG.getInt8PtrTy());
01300     dst = Builder.CreatePointerCast(destination, CG.getInt8PtrTy());
01301     ptrTy = cast<llvm::PointerType>(source->getType());
01302     arrTy = cast<llvm::ArrayType>(ptrTy->getElementType());
01303     len = llvm::ConstantExpr::getSizeOf(arrTy);
01304 
01305     
01306     if (len->getType() != CG.getInt64Ty())
01307         len = Builder.CreateZExt(len, CG.getInt64Ty());
01308 
01309     align = llvm::ConstantInt::get(CG.getInt32Ty(), 1);
01310     memcpy = CG.getMemcpy64();
01311 
01312     Builder.CreateCall4(memcpy, dst, src, len, align);
01313 }
01314 
01315 void CodeGenRoutine::emitArrayCopy(llvm::Value *source,
01316                                    llvm::Value *destination,
01317                                    llvm::Value *length,
01318                                    const llvm::Type *componentTy)
01319 {
01320     
01321     
01322     
01323     llvm::Value *compSize;
01324     compSize = llvm::ConstantExpr::getSizeOf(componentTy);
01325     compSize = Builder.CreateTrunc(compSize, CG.getInt32Ty());
01326     length = Builder.CreateMul(length, compSize);
01327 
01328     
01329     
01330     
01331     llvm::Constant *align = llvm::ConstantInt::get(CG.getInt32Ty(), 1);
01332     llvm::Function *memcpy = CG.getMemcpy32();
01333 
01334     const llvm::Type *i8PtrTy = CG.getInt8PtrTy();
01335     llvm::Value *src = Builder.CreatePointerCast(source, i8PtrTy);
01336     llvm::Value *dst = Builder.CreatePointerCast(destination, i8PtrTy);
01337     Builder.CreateCall4(memcpy, dst, src, length, align);
01338 }
01339 
01340 CValue CodeGenRoutine::emitArrayExpr(Expr *expr, llvm::Value *dst, bool genTmp)
01341 {
01342     ArrayEmitter emitter(*this, Builder);
01343     return emitter.emit(expr, dst, genTmp);
01344 }
01345 
01346 CValue CodeGenRoutine::emitRecordExpr(Expr *expr, llvm::Value *dst, bool genTmp)
01347 {
01348     RecordEmitter emitter(*this, Builder);
01349     return emitter.emit(expr, dst, genTmp);
01350 }
01351 
01352 CValue
01353 CodeGenRoutine::emitCompositeExpr(Expr *expr, llvm::Value *dst, bool genTmp)
01354 {
01355     Type *Ty = resolveType(expr->getType());
01356 
01357     if (isa<ArrayType>(Ty)) {
01358         ArrayEmitter emitter(*this, Builder);
01359         return emitter.emit(expr, dst, genTmp);
01360     }
01361     else if (isa<RecordType>(Ty)) {
01362         RecordEmitter emitter(*this, Builder);
01363         return emitter.emit(expr, dst, genTmp);
01364     }
01365 
01366     assert(false && "Not a composite expression!");
01367     return CValue::get(0);
01368 }
01369 
01370 CValue
01371 CodeGenRoutine::emitCompositeAllocator(AllocatorExpr *expr)
01372 {
01373     Type *type = resolveType(expr->getAllocatedType());
01374 
01375     if (isa<ArrayType>(type)) {
01376         ArrayEmitter emitter(*this, Builder);
01377         return emitter.emitAllocator(expr);
01378     }
01379     else {
01380         assert(isa<RecordType>(type) && "Not a composite allocator!");
01381         RecordEmitter emitter(*this, Builder);
01382         return emitter.emitAllocator(expr);
01383     }
01384 }
01385 
01386 void CodeGenRoutine::emitCompositeObjectDecl(ObjectDecl *objDecl)
01387 {
01388     Type *objTy = resolveType(objDecl->getType());
01389 
01390     if (ArrayType *arrTy = dyn_cast<ArrayType>(objTy)) {
01391         BoundsEmitter emitter(*this);
01392         const llvm::Type *loweredTy = CGT.lowerArrayType(arrTy);
01393 
01394         if (!objDecl->hasInitializer()) {
01395             
01396             assert(arrTy->isStaticallyConstrained() &&
01397                    "Cannot codegen non-static arrays without initializer!");
01398 
01399             SRF->createEntry(objDecl, activation::Slot, loweredTy);
01400             SRF->associate(objDecl, activation::Bounds,
01401                            emitter.synthStaticArrayBounds(Builder, arrTy));
01402             return;
01403         }
01404 
01405         llvm::Value *slot = 0;
01406         if (arrTy->isStaticallyConstrained())
01407             slot = SRF->createEntry(objDecl, activation::Slot, loweredTy);
01408 
01409         Expr *init = objDecl->getInitializer();
01410         CValue result = emitArrayExpr(init, slot, true);
01411         if (!slot)
01412             SRF->associate(objDecl, activation::Slot, result.first());
01413         SRF->associate(objDecl, activation::Bounds, result.second());
01414     }
01415     else {
01416         
01417         RecordType *recTy = cast<RecordType>(objTy);
01418 
01419         const llvm::Type *loweredTy = CGT.lowerRecordType(recTy);
01420         llvm::Value *slot = SRF->createEntry(objDecl, activation::Slot, loweredTy);
01421 
01422         
01423         if (!objDecl->hasInitializer())
01424             return;
01425 
01426         Expr *init = objDecl->getInitializer();
01427         emitRecordExpr(init, slot, false);
01428     }
01429 }