This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- codegen/CodeGenAgg.cpp -------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009-2010, Stephen Wilson 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 // Function calls, formal parameters and object declarations are the only 00185 // types of expression which can have an unconstrained type. 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 // Compute the size of the array. Use static information if possible, 00241 // otherwise compute at runtime. 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 // Allocate space for the data and cast the raw memory pointer to the 00257 // expected type. Evaluate the initializer using the allocated memory as 00258 // storage. 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 // Create a temporary to hold the fat pointer and store the data pointer. 00265 llvm::Value *fatPtr = frame()->createTemp(resultTy); 00266 llvm::Value *bounds = agg.second(); 00267 Builder.CreateStore(data, Builder.CreateStructGEP(fatPtr, 0)); 00268 00269 // Load the bounds if needed and populate the fat pointer. 00270 if (isa<llvm::PointerType>(bounds->getType())) 00271 bounds = Builder.CreateLoad(bounds); 00272 Builder.CreateStore(bounds, Builder.CreateStructGEP(fatPtr, 1)); 00273 00274 // Finished. 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 // Emit a "simple" call, thereby leaving the bounds and data on the vstack. 00299 CGR.emitSimpleCall(call); 00300 00301 // Get a reference to the bounds and compute the size of the needed array. 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 // Store the bounds into the fat pointer structure. 00312 Builder.CreateStore(Builder.CreateLoad(bounds), 00313 Builder.CreateStructGEP(fatPtr, 1)); 00314 00315 // Allocate a destination for the array. 00316 llvm::Value *dst = CRT.comma_alloc(Builder, dimension, align); 00317 00318 // Pop the vstack and obtain a pointer to the component data. 00319 CRT.vstack_pop(Builder); 00320 llvm::Value *data = CRT.vstack(Builder, CG.getInt8PtrTy()); 00321 00322 // Store the data into the destination. 00323 llvm::Function *memcpy = CG.getMemcpy32(); 00324 Builder.CreateCall4(memcpy, dst, data, dimension, 00325 llvm::ConstantInt::get(CG.getInt32Ty(), align)); 00326 00327 // Update the fat pointer with the allocated data. 00328 Builder.CreateStore(Builder.CreatePointerCast(dst, targetTy), 00329 Builder.CreateStructGEP(fatPtr, 0)); 00330 00331 // Pop the component data from the vstack. 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 // Allocate the required memory and copy the data over. 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 // Store the bounds into the fat pointer structure. 00366 Builder.CreateStore(Builder.CreateLoad(bounds), 00367 Builder.CreateStructGEP(fatPtr, 1)); 00368 00369 // Allocate a destination for the array and stor the data into the 00370 // destination. 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 // Update the fat pointer with the allocated data. 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 // If the dereference is with respect to a fat pointer then the first 00436 // component is the data pointer and the second is the bounds 00437 // structure. Otherwise we have a simple thin pointer to an array of 00438 // staticly known size. 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 // Check that the component pointer is non-null. 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 // If dst is null build a stack allocated object to hold the components of 00461 // this array. 00462 if (dst == 0 && genTmp) 00463 length = allocArray(arrTy, bounds, dst); 00464 00465 // If a destination is available, fill it in with the associated array 00466 // data. Note that dst is of type [N x T]*, hense the double `dereference' 00467 // to get at the element type. 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 // Constrained types use the sret call convention. 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 // Unconstrained (indefinite type) use the vstack. The callee cannot know 00507 // the size of the result hense dst must be null. 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 // If a destination is not provided allocate a temporary of the required size. 00528 if (!dst) 00529 length = allocArray(arrTy, bounds, dst); 00530 else 00531 length = emitter.computeTotalBoundLength(Builder, bounds); 00532 00533 // Memset the destination to zero. 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 // Return the generated aggregate. 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 // Build a constant array representing the literal. 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 // Build a constant global array to represent this literal. 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 // Likewise, build a constant global to represent the bounds. Emitting the 00576 // bounds into memory should be slightly faster then building them on the 00577 // stack in the majority of cases. 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 // FIXME: Implement. 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 // Initialize the iteration and sentinal values. 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 // Loop header. 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 // Loop body. 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 // Populate the phi node with the incoming values. 00630 phi->addIncoming(iterStart, startBB); 00631 phi->addIncoming(iterNext, Builder.GetInsertBlock()); 00632 00633 // Switch to merge. 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 // If this aggregate does not specify an others component we are done. 00642 // 00643 // FIXME: If an undefined others component is specified we should be 00644 // initializing the components with their default value (if any). 00645 Expr *othersExpr = expr->getOthersExpr(); 00646 if (!othersExpr) 00647 return; 00648 00649 // If there were no positional components emitted, emit a single "others" 00650 // expression. This simplifies emission of the remaining elements since we 00651 // can "count from zero" and compare against the upper bound without 00652 // worrying about overflow. 00653 if (numComponents == 0) { 00654 emitComponent(othersExpr, Builder.CreateConstGEP2_32(dst, 0, 0)); 00655 numComponents = 1; 00656 } 00657 00658 // Synthesize a loop to populate the remaining components. Note that a 00659 // memset is not possible here since we must re-evaluate the associated 00660 // expression for each component. 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 // Compute the number of "other" components minus one that we need to emit. 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 // Initialize the iteration variable to the number of components we have 00672 // already emitted minus one (the subtraction is always valid since we 00673 // guaranteed above that at least one component has been generated). 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 // Branch to the check BB and test if the index is equal to max. If it is 00680 // we are done. 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 // Move to the body block. Increment our index and emit the component. 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 // Add the incoming values to our phi node. 00698 phi->addIncoming(idxStart, startBB); 00699 phi->addIncoming(idxNext, Builder.GetInsertBlock()); 00700 00701 // Set the insert point to the merge BB and return. 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 // Emit an "others" clause if present. 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 // Number of components we need to emit. 00748 uint64_t length; 00749 00750 // Starting index to emit each component (not corrected by the given bias). 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 // Perform the emission using inline code if length is small. Otherwise use 00767 // a loop. 00768 // 00769 // FIXME: The value 8 here was chosen arbitrarily and very likely not ideal. 00770 // In particular, LLVM does a good job of transforming sequential code like 00771 // this into a memset when the expression is constant. 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 // Build a bounds structure for this aggregate. 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 // If the destination is null, create a temporary to hold the aggregate. 00810 if (dst == 0) 00811 allocArray(arrTy, bounds, dst); 00812 00813 // Generate the aggregate. 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 // If there is no others expression we are done. 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 // Build a sorted vector of the keys supplied by the aggregate. 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 // Fill in any missing leading elements. 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 // Fill in each interior "hole". 00855 for (unsigned i = 0; i < KV.size() - 1; ++i) { 00856 // Note the change in the sense of "upper" and "lower" here. 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 // Fill in any missing trailing elements. 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 // Iterate from 0 upto the computed length of the aggregate. Define the 00896 // iteration type and some constance for convenience. 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 // Define the iteration variable as an alloca. 00902 llvm::Value *iter = frame()->createTemp(iterTy); 00903 Builder.CreateStore(iterZero, iter); 00904 00905 // Create check, body, and merge basic blocks. 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 // While iter < length. 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 // Compute and store an element into the aggregate. 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 // Set the insert point to the merge block and return. 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 // For an others expression, obtain bounds from the index type of 00940 // this aggregate. 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 // Allocate a destination if needed. 00948 if (dst == 0) 00949 allocArray(arrTy, bounds, dst); 00950 00951 // Emit the others expression. 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 // Compute the size and alignment of the record to be allocated. 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 // Call into the runtime to allocate the object and cast the result to the 01071 // needed type. 01072 CommaRT &CRT = CGR.getCodeGen().getRuntime(); 01073 llvm::Value *pointer = CRT.comma_alloc(Builder, size, align); 01074 pointer = Builder.CreatePointerCast(pointer, resultTy); 01075 01076 // If an initializer is given emit the record into the allocated memory. 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 // Emit the prefix as a value, yielding a pointer to the record. Check 01121 // that the result is non-null. 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 // If dst is null build a stack allocated object to hold this record; 01133 if (dst == 0 && genTmp) 01134 dst = frame()->createTemp(recTy); 01135 01136 // If a destination is available fill it in with the computed record data. 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 // If the destination is null create a temporary to hold the aggregate. 01157 if (dst == 0) 01158 dst = frame()->createTemp(loweredTy); 01159 01160 ComponentSet components; 01161 01162 // Emit any positional components. 01163 emitPositionalComponents(agg, dst, components); 01164 01165 // Emit any keyed component. 01166 emitKeyedComponents(agg, dst, components); 01167 01168 // Emit any `others' components. 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 // If the destination is null create a temporary to hold the record. 01180 if (dst == 0) 01181 dst = frame()->createTemp(loweredType); 01182 01183 // Zero initialize the record. 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 // Iterate over the positional components of the record declaration. Emit 01223 // each component. 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 // Iterate over the full set of components provided by the underlying record 01261 // declaration. Emit all components that are not already present in the 01262 // provided set. 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 // Functions returning structures always use the sret calling convention. 01279 return CGR.emitCompositeCall(call, dst); 01280 } 01281 01282 } // end anonymous namespace. 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 // Implement array copies via memcpy. 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 // Zero extend the length if not an i64. 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 // Scale the length by the size of the component type of the array. The 01321 // current convention is that array lengths are represented as i32's. 01322 // Truncate the component size (an i64). 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 // Finally, perform a memcpy from the source to the destination. 01329 // 01330 // FIXME: Adjust the intrinsic used to fit the target arch. 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 // FIXME: Support dynamicly sized arrays and default initialization. 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 // We must have a record type. 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 // FIXME: Default initialize the records components. 01423 if (!objDecl->hasInitializer()) 01424 return; 01425 01426 Expr *init = objDecl->getInitializer(); 01427 emitRecordExpr(init, slot, false); 01428 } 01429 }