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 }